'use client'; import { useState } from 'react'; import { useQuery } from '@tanstack/react-query'; import { ExternalLink, Receipt, Loader2, Download } from 'lucide-react'; import { useLanguage } from '@/lib/i18n'; import { cn } from '@/lib/utils'; interface Invoice { id: string; number: string | null; amount: number; currency: string; status: string | null; date: number; pdfUrl: string | null; } export function BillingHistory() { const { t } = useLanguage(); const [portalLoading, setPortalLoading] = useState(false); const { data: invoices, isLoading, error } = useQuery({ queryKey: ['billing', 'invoices'], queryFn: async () => { const res = await fetch('/api/billing/invoices'); if (!res.ok) throw new Error('Failed to fetch invoices'); return res.json(); }, }); const handleOpenPortal = async () => { setPortalLoading(true); try { const res = await fetch('/api/billing/portal', { method: 'POST' }); const data = await res.json(); if (!res.ok) throw new Error(data.error ?? 'Failed'); window.location.href = data.url; } catch { // ignore } finally { setPortalLoading(false); } }; const formatAmount = (amount: number, currency: string) => { try { const locale = typeof window !== 'undefined' ? window.navigator.language : 'fr-FR'; return new Intl.NumberFormat(locale, { style: 'currency', currency: currency.toUpperCase(), }).format(amount / 100); } catch { return `${(amount / 100).toFixed(2)} ${currency.toUpperCase()}`; } }; const formatDate = (timestamp: number) => { try { const date = new Date(timestamp * 1000); const locale = typeof window !== 'undefined' ? window.navigator.language : 'fr-FR'; return new Intl.DateTimeFormat(locale, { day: 'numeric', month: 'short', year: 'numeric', }).format(date); } catch { return '—'; } }; const getStatusBadge = (status: string | null) => { const s = status?.toLowerCase(); if (s === 'paid') { return 'bg-emerald-50 dark:bg-emerald-950/40 text-emerald-700 dark:text-emerald-300 border border-emerald-200 dark:border-emerald-800/50'; } if (s === 'open' || s === 'pending') { return 'bg-amber-500/10 text-amber-600 dark:text-amber-400 border border-amber-500/20'; } return 'bg-rose-500/10 text-rose-600 dark:text-rose-400 border border-rose-500/20'; }; return (

{t('billing.billingHistory') || 'Historique de facturation'}

{t('billing.invoices') || 'Factures & reçus'}

{isLoading && (
)} {error && (

Impossible de charger l'historique de facturation.

)} {invoices && invoices.length === 0 && (

{t('billing.noInvoices') || 'Aucune facture disponible.'}

)} {invoices && invoices.length > 0 && (
{invoices.map((invoice) => ( ))}
{t('billing.invoiceDate') || 'Date'} {t('billing.invoiceNumber') || 'Numéro'} {t('billing.invoiceAmount') || 'Montant'} {t('billing.invoiceStatus') || 'Statut'} PDF
{formatDate(invoice.date)} {invoice.number || '—'} {formatAmount(invoice.amount, invoice.currency)} {invoice.status ? t(`billing.${invoice.status.toLowerCase()}`) || invoice.status : '—'} {invoice.pdfUrl ? ( ) : ( )}
)}
); }