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)}
)}
);
})}
);
};