'use client'; import { useState, useEffect } from 'react'; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'; interface Props { companyId?: string; selectedCompany: 'rmp' | 'jtr'; } interface Stats { revenueThisMonth: number; revenueLastMonth: number; revenueChange: number; outstandingCount: number; outstandingAmount: number; overdueCount: number; overdueAmount: number; paidThisMonthAmount: number; upcomingCount: number; upcomingAmount: number; } function fmt(n: number) { return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', maximumFractionDigits: 0 }).format(n); } export default function OverviewTab({ companyId, selectedCompany }: Props) { const [stats, setStats] = useState(null); const [monthlyRevenue, setMonthlyRevenue] = useState<{ month: string; revenue: number }[]>([]); const [recentInvoices, setRecentInvoices] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { setLoading(true); const params = companyId ? `?companyId=${companyId}` : ''; Promise.all([ fetch(`/api/billing/stats${params}`).then(r => r.json()), fetch(`/api/billing/invoices${params}&limit=10`).then(r => r.json()), ]).then(([statsData, invData]) => { setStats(statsData.stats); setMonthlyRevenue(statsData.monthlyRevenue || []); setRecentInvoices((invData.data || []).slice(0, 10)); }).finally(() => setLoading(false)); }, [companyId]); if (loading) { return (
); } const cards = [ { label: 'Revenue This Month', value: fmt(stats?.revenueThisMonth || 0), sub: stats?.revenueChange !== undefined ? `${stats.revenueChange >= 0 ? '+' : ''}${stats.revenueChange.toFixed(1)}% vs last month` : '', color: 'text-green-400', bg: 'bg-green-900/20 border-green-800', }, { label: 'Outstanding Invoices', value: fmt(stats?.outstandingAmount || 0), sub: `${stats?.outstandingCount || 0} invoices`, color: 'text-blue-400', bg: 'bg-blue-900/20 border-blue-800', }, { label: 'Overdue', value: fmt(stats?.overdueAmount || 0), sub: `${stats?.overdueCount || 0} invoices`, color: 'text-red-400', bg: 'bg-red-900/20 border-red-800', }, { label: 'Paid This Month', value: fmt(stats?.paidThisMonthAmount || 0), sub: '', color: 'text-emerald-400', bg: 'bg-emerald-900/20 border-emerald-800', }, { label: 'Due in 7 Days', value: fmt(stats?.upcomingAmount || 0), sub: `${stats?.upcomingCount || 0} invoices`, color: 'text-yellow-400', bg: 'bg-yellow-900/20 border-yellow-800', }, ]; const statusColors: Record = { draft: 'bg-gray-700 text-gray-300', sent: 'bg-blue-900 text-blue-300', viewed: 'bg-purple-900 text-purple-300', paid: 'bg-green-900 text-green-300', overdue: 'bg-red-900 text-red-300', cancelled: 'bg-gray-800 text-gray-400', }; return (
{/* Summary Cards */}
{cards.map(card => (

{card.label}

{card.value}

{card.sub &&

{card.sub}

}
))}
{/* Revenue Chart */}

Revenue — Last 12 Months

`$${(v / 1000).toFixed(0)}k`} /> [fmt(v), 'Revenue']} />
{/* Recent Activity */}

Recent Invoice Activity

{recentInvoices.length === 0 ? (

No recent activity. Sync from MoonInvoice or create your first invoice.

) : (
{recentInvoices.map((inv: any) => (
{inv.status}
{inv.invoice_number} · {inv.billing_clients?.name || '—'}
{fmt(inv.total || 0)}
))}
)}
); }