import Link from 'next/link'; import { Landmark, FileText, Euro, ArrowRight, Plus, ChevronLeft, ChevronRight, } from 'lucide-react'; import { getTranslations } from 'next-intl/server'; import { createFinanceApi } from '@kit/finance/api'; import { formatDate, formatCurrencyAmount } from '@kit/shared/dates'; import { getSupabaseServerClient } from '@kit/supabase/server-client'; import { Badge } from '@kit/ui/badge'; import { Button } from '@kit/ui/button'; import { Card, CardContent, CardHeader, CardTitle } from '@kit/ui/card'; import { ListToolbar } from '@kit/ui/list-toolbar'; import { AccountNotFound } from '~/components/account-not-found'; import { CmsPageShell } from '~/components/cms-page-shell'; import { EmptyState } from '~/components/empty-state'; import { StatsCard } from '~/components/stats-card'; import { BATCH_STATUS_VARIANT, BATCH_STATUS_LABEL_KEYS, INVOICE_STATUS_VARIANT, INVOICE_STATUS_LABEL_KEYS, } from '~/lib/status-badges'; const PAGE_SIZE = 25; interface PageProps { params: Promise<{ account: string }>; searchParams: Promise>; } function buildQuery( base: Record, overrides: Record, ): string { const params = new URLSearchParams(); for (const [key, value] of Object.entries({ ...base, ...overrides })) { if (value !== undefined && value !== '') { params.set(key, String(value)); } } const qs = params.toString(); return qs ? `?${qs}` : ''; } export default async function FinancePage({ params, searchParams }: PageProps) { const { account } = await params; const search = await searchParams; const client = getSupabaseServerClient(); const t = await getTranslations('finance'); const { data: acct } = await client .from('accounts') .select('id') .eq('slug', account) .single(); if (!acct) return ; const q = typeof search.q === 'string' ? search.q : undefined; const status = typeof search.status === 'string' ? search.status : undefined; const page = Math.max(1, Number(search.page) || 1); const api = createFinanceApi(client); const [batchesResult, invoicesResult] = await Promise.all([ api.listBatches(acct.id, { search: q, status, page, pageSize: PAGE_SIZE }), api.listInvoices(acct.id, { search: q, status, page, pageSize: PAGE_SIZE }), ]); const batches = batchesResult.data; const invoices = invoicesResult.data; const openAmount = invoices .filter( (inv: Record) => inv.status === 'sent' || inv.status === 'overdue', ) .reduce( (sum: number, inv: Record) => sum + (Number(inv.total_amount) || 0), 0, ); // Use the larger of the two totals for pagination const totalPages = Math.max( batchesResult.totalPages, invoicesResult.totalPages, ); const safePage = page; const queryBase = { q, status }; return (
{/* Header */}

{t('dashboard.subtitle')}

{/* Stats */}
} /> } /> } />
{/* Toolbar */} {/* SEPA Batches */} {t('sepa.title')} ({batchesResult.total}) {batches.length === 0 ? ( } title={t('sepa.noBatches')} description={t('sepa.createFirst')} actionLabel={t('nav.newBatch')} actionHref={`/home/${account}/finance/sepa/new`} /> ) : (
{batches.map((batch: Record) => ( ))}
{t('common.status')} {t('common.type')} {t('common.amount')} {t('common.date')}
{t(BATCH_STATUS_LABEL_KEYS[String(batch.status)] ?? String(batch.status))} {batch.batch_type === 'direct_debit' ? t('sepa.directDebit') : t('sepa.creditTransfer')} {batch.total_amount != null ? formatCurrencyAmount(batch.total_amount as number) : '—'} {formatDate( (batch.execution_date ?? batch.created_at) as | string | null, )}
)}
{/* Invoices */} {t('invoices.title')} ({invoicesResult.total}) {invoices.length === 0 ? ( } title={t('invoices.noInvoices')} description={t('invoices.createFirst')} actionLabel={t('invoices.newInvoice')} actionHref={`/home/${account}/finance/invoices/new`} /> ) : (
{invoices.map((invoice: Record) => ( ))}
{t('invoices.invoiceNumber')} {t('invoices.recipient')} {t('common.amount')} {t('common.status')}
{String(invoice.invoice_number ?? '—')} {String(invoice.recipient_name ?? '—')} {invoice.total_amount != null ? formatCurrencyAmount( invoice.total_amount as number, ) : '—'} {t(INVOICE_STATUS_LABEL_KEYS[String(invoice.status)] ?? String(invoice.status))}
)}
{/* Pagination */} {totalPages > 1 && (

{t('common.page')} {safePage} {t('common.of')} {totalPages}

{safePage > 1 ? ( ) : ( )} {safePage} / {totalPages} {safePage < totalPages ? ( ) : ( )}
)}
); }