'use client'; import { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import Link from 'next/link'; import { usePortalAuthStore } from '@/lib/portal-auth-store'; import portalApi from '@/lib/portal-api'; import { formatCurrency, formatDate } from '@/lib/utils'; interface PortalInvoice { id: string; invoiceNumber?: string; total: number; balance: number; dueDate?: string; status: string; } const statusBadge: Record = { PAID: { bg: '#DCFCE7', text: '#16A34A' }, PARTIAL: { bg: '#FEF9C3', text: '#CA8A04' }, OVERDUE: { bg: '#FEE2E2', text: '#DC2626' }, SENT: { bg: '#F1F5F9', text: '#64748B' }, DRAFT: { bg: '#F1F5F9', text: '#64748B' }, VOID: { bg: '#F1F5F9', text: '#94A3B8' }, }; export default function PortalInvoicesPage() { const router = useRouter(); const { isAuthenticated } = usePortalAuthStore(); const [mounted, setMounted] = useState(false); const [invoices, setInvoices] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); useEffect(() => { setMounted(true); }, []); useEffect(() => { if (!mounted) return; if (!isAuthenticated) { router.replace('/portal/login'); return; } portalApi.get('/api/v1/portal/invoices') .then((res) => { const data = res.data; setInvoices(Array.isArray(data) ? data : data.data ?? []); }) .catch(() => setError('Failed to load invoices.')) .finally(() => setLoading(false)); }, [mounted, isAuthenticated, router]); if (!mounted || !isAuthenticated) return null; return (
← Back

Invoice History

{error && (
{error}
)}
{loading ? (
Loading…
) : invoices.length === 0 ? (
No invoices found.
) : ( {['Invoice #', 'Amount', 'Balance', 'Due Date', 'Status'].map((h) => ( ))} {invoices.map((inv, i) => { const badge = statusBadge[inv.status] ?? statusBadge.SENT; return ( ); })}
{h}
{inv.invoiceNumber ?? inv.id.slice(0, 8)} {formatCurrency(Number(inv.total ?? 0))} 0 ? 600 : 400, color: Number(inv.balance) > 0 ? '#DC2626' : '#64748B' }}> {formatCurrency(Number(inv.balance ?? 0))} {inv.dueDate ? formatDate(inv.dueDate) : '—'} {inv.status}
)}
); }