import { Table, Tabs } from "@tailor-platform/app-shell"; import { Fragment, useState } from "react"; import { useT } from "@/i18n/labels"; import { formatCurrency } from "@/lib/format-currency"; import { formatDate } from "@/lib/format-date"; import { StatusBadge } from "@/lib/status"; export interface JournalViewLine { id: string; accountLabel: string; description?: string | null; debit: string | null; credit: string | null; } export interface JournalViewEntry { id: string; entryDate: string; status: string; heading?: string | null; lines: JournalViewLine[]; } interface Props { entries: JournalViewEntry[]; } const amountNum = (value: string | null | undefined): number => value != null && Number(value) !== 0 ? Number(value) : 0; const amountText = (value: string | null | undefined): string => { const n = amountNum(value); return n !== 0 ? formatCurrency(n) : "—"; }; export const JournalEntriesView = ({ entries }: Props) => { const t = useT(); const [viewMode, setViewMode] = useState<"flat" | "grouped">("flat"); return (
{/* View switcher inside the card: List (flat) ⟷ Voucher (grouped) — a bare capsule toggle, no leading label. */}
setViewMode(value === "flat" ? "flat" : "grouped")} > {t("journal.view.list")} {t("journal.view.voucher")}
{entries.map((entry, index) => { const debitLines = entry.lines.filter((l) => amountNum(l.debit) !== 0); const creditLines = entry.lines.filter((l) => amountNum(l.credit) !== 0); const rowCount = Math.max(debitLines.length, creditLines.length); const totalDebit = entry.lines.reduce((sum, l) => sum + amountNum(l.debit), 0); const totalCredit = entry.lines.reduce((sum, l) => sum + amountNum(l.credit), 0); return ( {/* Each entry is a section within the shared card, separated by a rule. */}
0 ? "border-t border-border" : undefined}> {/* Header: heading (if any) on the left, date + status on the right */}
{entry.heading ? {entry.heading} : }
{formatDate(entry.entryDate, "medium")}
{viewMode === "grouped" ? ( {t("journal.view.debit")} {t("journal.view.credit")} {t("journal.view.account")} {t("journal.view.debit")} {t("journal.view.account")} {t("journal.view.credit")} {Array.from({ length: rowCount }, (_, i) => { const dr = debitLines[i]; const cr = creditLines[i]; return ( {dr ? dr.accountLabel : null} {dr ? amountText(dr.debit) : ""} {cr ? cr.accountLabel : null} {cr ? amountText(cr.credit) : ""} ); })} {t("journal.view.total")} {formatCurrency(totalDebit)} {formatCurrency(totalCredit)} ) : ( {t("journal.view.account")} {t("journal.view.description")} {t("journal.view.debit")} {t("journal.view.credit")} {entry.lines.map((line) => ( {line.accountLabel} {line.description ?? null} {amountText(line.debit)} {amountText(line.credit)} ))} {t("journal.view.total")} {formatCurrency(totalDebit)} {formatCurrency(totalCredit)} )}
); })}
); };