import { useTranslations, useFormatter } from "next-intl"; import { Link } from "@/i18n/navigation"; import { Card } from "@/components/ui/card"; import type { Invoice } from "@/types"; interface Props { invoices: Invoice[]; } const statusColors: Record = { open: "text-text-secondary bg-surface-3", paid: "text-success bg-success/10", overdue: "text-error bg-error/10", void: "text-text-muted bg-surface-3 line-through", // Phase 7: refund states. Red tinting matches the credit-note // PDF accent so customers reading the table get a visual cue // that something was credited back. partially_refunded reads // as a partial state (mixed colour), fully_refunded reads as // closed (line-through like void). partially_refunded: "text-error bg-error/10", fully_refunded: "text-text-muted bg-error/10 line-through", }; /** * Customer's invoice history table. Server component — gets a * pre-fetched Invoice[] from /billing/page.tsx. Each row links * to /billing/ for the full detail view. * * Columns: number, period, due date, total, status. Status is * displayed with a colored badge so the customer can scan for * outstanding ones at a glance. */ export function CustomerInvoiceList({ invoices }: Props) { const t = useTranslations("customerBilling"); const fmt = useFormatter(); if (invoices.length === 0) { return (

{t("emptyHistory")}

); } return (
{invoices.map((inv) => ( ))}
{t("numberCol")} {t("periodCol")} {t("dueCol")} {t("totalCol")} {t("statusCol")}
{inv.invoiceNumber} {inv.periodStart && inv.periodEnd ? ( <> {fmt.dateTime(new Date(inv.periodStart), { dateStyle: "medium", })} {fmt.dateTime(new Date(inv.periodEnd), { dateStyle: "medium", })} ) : ( )} {fmt.dateTime(new Date(inv.dueAt), { dateStyle: "medium" })} CHF {inv.totalChf.toFixed(2)} {t(`status.${inv.status}` as any)}
); }