'use client'; import Link from 'next/link'; import type { Route } from 'next'; import { useParams } from 'next/navigation'; import { useQuery } from '@tanstack/react-query'; import { Globe } from 'lucide-react'; import { Card, CardContent } from '@/components/ui/card'; import { Skeleton } from '@/components/ui/skeleton'; import { PageHeader } from '@/components/shared/page-header'; import { apiFetch } from '@/lib/api/client'; import { CountryFlag } from '@/components/shared/country-flag'; import { getCountryName } from '@/lib/i18n/countries'; import { cn } from '@/lib/utils'; interface ClientsByCountryRow { country: string; count: number; } interface ClientsByCountryResponse { data: ClientsByCountryRow[]; total: number; } /** * Full per-country breakdown of the active (non-archived) client book — the * "Show all" destination for the dashboard `ClientsByCountryWidget`, which * only shows the top N. Same endpoint (it already returns every row); this * page just renders the complete ranked list. Each row deep-links into the * clients list filtered by that nationality. */ export function ClientsByCountryPage() { const params = useParams<{ portSlug: string }>(); const portSlug = params?.portSlug ?? ''; const { data, isLoading } = useQuery({ queryKey: ['dashboard', 'clients-by-country', 'all'], queryFn: () => apiFetch('/api/v1/dashboard/clients-by-country'), staleTime: 60_000, }); const rows = data?.data ?? []; const total = data?.total ?? rows.reduce((s, r) => s + r.count, 0); const maxCount = rows.reduce((m, r) => Math.max(m, r.count), 0) || 1; return (
0 ? `${total} client${total === 1 ? '' : 's'} across ${rows.length} ${ rows.length === 1 ? 'country' : 'countries' }.` : undefined } /> {isLoading ? (
{Array.from({ length: 10 }).map((_, i) => ( ))}
) : rows.length === 0 ? (

No clients with a country recorded yet.

) : (
    {rows.map((row, i) => { const pct = (row.count / maxCount) * 100; const name = getCountryName(row.country) || row.country; return (
  1. {i + 1} {name}
    {row.count}
  2. ); })}
)}
); }