import { useEffect, useState } from 'react' import { finance } from '@/api/client' import type { JournalEntry } from '@/types/api' import { PageHeader } from '@/components/PageHeader' import { Loading } from '@/components/Loading' import { ErrorBox } from '@/components/ErrorBox' import { StatusBadge } from '@/components/StatusBadge' export function JournalEntriesPage() { const [rows, setRows] = useState([]) const [error, setError] = useState(null) const [loading, setLoading] = useState(true) const [expanded, setExpanded] = useState>(new Set()) useEffect(() => { finance .listJournalEntries() .then((rs) => setRows([...rs].sort((a, b) => (b.postedAt ?? '').localeCompare(a.postedAt ?? ''))), ) .catch((e: unknown) => setError(e instanceof Error ? e : new Error(String(e)))) .finally(() => setLoading(false)) }, []) const toggle = (id: string) => { setExpanded((prev) => { const next = new Set(prev) if (next.has(id)) next.delete(id) else next.add(id) return next }) } return (
{loading && } {error && } {!loading && !error && rows.length === 0 && (
No journal entries yet.
)} {!loading && !error && rows.length > 0 && (
{rows.map((je) => { const isOpen = expanded.has(je.id) return ( <> toggle(je.id)} > {isOpen && je.lines?.length > 0 && ( )} ) })}
Posted Type Status Order Partner Amount Lines
{je.postedAt ? new Date(je.postedAt).toLocaleString() : '—'} {je.type} {je.orderCode} {je.partnerCode} {Number(je.amount).toLocaleString(undefined, { minimumFractionDigits: 2 })}{' '} {je.currencyCode} {je.lines?.length ?? 0}
{je.lines.map((l) => ( ))}
# Account Debit Credit Description
{l.lineNo} {l.accountCode} {Number(l.debit) > 0 ? Number(l.debit).toLocaleString(undefined, { minimumFractionDigits: 2 }) : ''} {Number(l.credit) > 0 ? Number(l.credit).toLocaleString(undefined, { minimumFractionDigits: 2 }) : ''} {l.description ?? ''}
)}
) }