'use client';
/**
* Top Songs Page — Standalone page for the Top Songs analytics detail view.
*
* Renders the SongsTab content from the analytics detail page as its own route.
* Accessible via sidebar navigation under Analítica > Top Songs.
*/
import { useState, useMemo } from 'react';
import { clientPortal } from '@/lib/mock-data';
import { useCompactCurrencyFormatter } from '@/lib/hooks/useCurrencyFormatter';
import { chartColorArray } from '@/lib/constants/theme';
import type { PortalSongDetail } from '@/lib/mock-data/types';
// ─── Helper Components ───────────────────────────────────────────────────────
function ChevronIcon({ expanded }: { expanded: boolean }) {
return (
);
}
function PercentageBadge({ value }: { value: number }) {
const isPositive = value >= 0;
return (
{isPositive ? '+' : ''}{value.toFixed(1)}%
);
}
function TotalEarningsCard({ total, trend }: { total: number; trend: number }) {
const fmtMoney = useCompactCurrencyFormatter();
return (
Ganancias totales
{fmtMoney(total)}
);
}
// ─── Main Component ──────────────────────────────────────────────────────────
function SongsDetailView({ data }: { data: PortalSongDetail[] }) {
const [expandedRows, setExpandedRows] = useState>(new Set());
const fmtMoney = useCompactCurrencyFormatter();
const sorted = useMemo(
() => [...data].sort((a, b) => b.currentPeriodAmount - a.currentPeriodAmount),
[data]
);
const total = sorted.reduce((sum, s) => sum + s.currentPeriodAmount, 0);
const totalLast = sorted.reduce((sum, s) => sum + s.lastPeriodAmount, 0);
const trend = totalLast > 0 ? ((total - totalLast) / totalLast) * 100 : 0;
const toggleRow = (id: string) => {
setExpandedRows((prev) => {
const next = new Set(prev);
if (next.has(id)) next.delete(id);
else next.add(id);
return next;
});
};
return (
Mejores Canciones
{/* Left Panel */}
{sorted.slice(0, 10).map((song, i) => {
const pct = total > 0 ? (song.currentPeriodAmount / total) * 100 : 0;
return (
-
{i + 1}. {song.title}
{song.composers.join(', ')}
{fmtMoney(song.currentPeriodAmount)}
);
})}
{/* Right Panel - Table */}
#
Las 20 Mejores Canciones
Último Período
Período Actual
{sorted.map((song, i) => {
const isExpanded = expandedRows.has(song.id);
return (
toggleRow(song.id)}
>
{i + 1}
{song.title}
{song.composers.join(', ')}
{fmtMoney(song.lastPeriodAmount)}
{fmtMoney(song.currentPeriodAmount)}
{isExpanded && (
Categoría superior
{song.topCategory}
{fmtMoney(song.topCategoryAmount)}
Fuente principal
{song.topSource}
{fmtMoney(song.topSourceAmount)}
Territorio superior
{song.topTerritory}
{fmtMoney(song.topTerritoryAmount)}
)}
);
})}
);
}
export default function TopSongsPage() {
return ;
}