'use client'; import { useEffect } from 'react'; import { useQuery } from '@tanstack/react-query'; import { dashboardApi } from '@/lib/api'; import { Link, useRouter } from '@/i18n/navigation'; import { useTranslations, useLocale } from 'next-intl'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Badge } from '@/components/ui/badge'; import { Package, PackageCheck, PackageX, Clock, Weight, TrendingUp, Plus, ArrowRight, } from 'lucide-react'; import { useSubscription } from '@/lib/context/subscription-context'; import ExportButton from '@/components/ExportButton'; import { PieChart, Pie, Cell, BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, } from 'recharts'; export default function DashboardPage() { const router = useRouter(); const { hasFeature, loading: subLoading } = useSubscription(); const t = useTranslations('dashboard.home'); const locale = useLocale(); useEffect(() => { if (!subLoading && !hasFeature('dashboard')) { router.replace('/dashboard/bookings'); } }, [subLoading, hasFeature, router]); const { data: csvKpis, isLoading: csvKpisLoading } = useQuery({ queryKey: ['dashboard', 'csv-booking-kpis'], queryFn: () => dashboardApi.getCsvBookingKPIs(), }); const { data: topCarriers, isLoading: carriersLoading } = useQuery({ queryKey: ['dashboard', 'top-carriers'], queryFn: () => dashboardApi.getTopCarriers(), }); const numberFormat = new Intl.NumberFormat(locale === 'fr' ? 'fr-FR' : 'en-US'); const statusDistribution = csvKpis ? [ { name: t('charts.distribution.accepted'), value: csvKpis.totalAccepted, color: '#10b981' }, { name: t('charts.distribution.rejected'), value: csvKpis.totalRejected, color: '#ef4444' }, { name: t('charts.distribution.pending'), value: csvKpis.totalPending, color: '#f59e0b' }, ] : []; const carrierWeightData = topCarriers ? topCarriers.slice(0, 5).map(c => ({ name: c.carrierName.length > 15 ? c.carrierName.substring(0, 15) + '...' : c.carrierName, [t('charts.weightByCarrier.weight')]: Math.round(c.totalWeightKG), })) : []; const weightDataKey = t('charts.weightByCarrier.weight'); return (
{t('subtitle')}
{t('kpi.accepted')}
{csvKpisLoading ? ( ) : ( <>{csvKpis?.totalAccepted || 0}
{t('kpi.thisMonth', { count: csvKpis?.acceptedThisMonth || 0 })}
> )}{t('kpi.rejected')}
{csvKpisLoading ? ( ) : ( <>{csvKpis?.totalRejected || 0}
{t('kpi.thisMonth', { count: csvKpis?.rejectedThisMonth || 0 })}
> )}{t('kpi.pending')}
{csvKpisLoading ? ( ) : ( <>{csvKpis?.totalPending || 0}
{t('kpi.acceptanceRate', { rate: (csvKpis?.acceptanceRate ?? 0).toFixed(1) })}
> )}{t('kpi.totalWeight')}
{csvKpisLoading ? ( ) : ( <>{numberFormat.format(csvKpis?.totalWeightAcceptedKG || 0)}
KG • {(csvKpis?.totalVolumeAcceptedCBM || 0).toFixed(1)} CBM
> )}{t('performance.acceptanceRate')}
{csvKpisLoading ? '--' : `${(csvKpis?.acceptanceRate ?? 0).toFixed(1)}%`}
{t('performance.totalBookings')}
{csvKpisLoading ? '--' : (csvKpis?.totalAccepted || 0) + (csvKpis?.totalRejected || 0) + (csvKpis?.totalPending || 0)}
{t('performance.totalVolume')}
{csvKpisLoading ? '--' : `${(csvKpis?.totalVolumeAcceptedCBM || 0).toFixed(1)}`} CBM
{carrier.acceptanceRate.toFixed(0)}% • ${carrier.avgPriceUSD.toFixed(0)}
{t('topCarriers.empty.description')}