"use client" import { useWrite } from "@conusai-kit/ui/data" import { CheckField, ConfirmDialog, FactList, FormLayout, type FormValues, Page, PageSection, ResourceList, SelectField, TextField, usePageNavigation, } from "@conusai-kit/ui/patterns" import { Button } from "@conusai-kit/ui/primitives" import { useRef, useState } from "react" import { type AccountView, recordTerms, type TransactionView } from "../contract/index.js" import { ledgerFailure } from "./errors.js" import type { LedgerLabels, LedgerMessages } from "./labels.js" import { retryIdentity } from "./retry.js" const options = (labels: LedgerLabels, values: (keyof LedgerMessages)[]) => values.map((value) => ({ value, label: labels[value] })) export function AccountForm({ org, account, labels, base, }: { org: string account?: AccountView labels: LedgerLabels base: string }) { const navigation = usePageNavigation() const write = useWrite, AccountView>( account ? "ledger.accounts.update" : "ledger.accounts.create", ) const identity = useRef(retryIdentity()) const [pending, setPending] = useState>() return ( ledgerFailure(error, labels)} submitLabel={labels.review} busyLabel={labels.busy} onSubmit={async (values: FormValues) => { setPending( account ? { org, accountId: account.accountId, expectedVersion: account.revision, name: values.name, status: values.status, allowNegative: values.allowNegative === "on", } : { org, ...values, allowNegative: values.allowNegative === "on" }, ) }} > {!account ? ( <> ) : ( )} ledgerFailure(error, labels)} open={pending !== undefined} onOpenChange={(open) => { if (!open) setPending(undefined) }} title={labels.confirm} description={labels.archiveWarning} confirmLabel={labels.save} cancelLabel={labels.cancel} onConfirm={async () => { if (!pending) return const saved = await write.mutate({ ...pending, requestId: identity.current(pending) }) navigation.navigate(`${base}/accounts/${saved.accountId}`) }} > {pending ? ( ) : null} ) } export function RecordForm({ org, labels, base, fenced, }: { org: string labels: LedgerLabels base: string fenced: boolean }) { const navigation = usePageNavigation() const write = useWrite, TransactionView>("ledger.transactions.record") const identity = useRef(retryIdentity()) const [lines, setLines] = useState(2) const [pending, setPending] = useState>() return ( ledgerFailure(error, labels)} submitLabel={labels.review} busyLabel={labels.busy} submitDisabled={fenced} onSubmit={async (values: FormValues) => { if (fenced) throw new Error(labels.drift) const result = recordTerms.safeParse({ effectiveAt: values.effectiveAt, description: values.description, ...(values.reference ? { reference: values.reference } : {}), status: values.status, entries: Array.from({ length: lines }, (_, i) => ({ accountId: values[`account-${i}`], direction: values[`direction-${i}`], amountMinor: values[`amount-${i}`], })), }) if (!result.success) throw new Error(labels.invalid) setPending(result.data) }} > {Array.from({ length: lines }, (_, i) => ( ))} ledgerFailure(error, labels)} open={pending !== undefined} onOpenChange={(open) => { if (!open) setPending(undefined) }} title={labels.confirm} description={labels.confirmDescription} confirmLabel={labels.record} cancelLabel={labels.cancel} onConfirm={async () => { if (!pending || fenced) throw new Error(labels.drift) const saved = await write.mutate({ org, terms: pending, confirmed: true, requestId: identity.current({ org, terms: pending }), }) navigation.navigate(`${base}/transactions/${saved.transactionId}`) }} > {pending ? ( <> ({ ...entry, id: String(index) }))} columns={[ { id: "accountId", header: labels.account }, { id: "direction", header: labels.normalBalance, cell: (row) => labels[row.direction] }, { id: "amountMinor", header: labels.amountMinor }, ]} empty={{ title: labels.empty }} /> ) : null} ) } export function Transition({ org, transaction, action, labels, base, fenced, }: { org: string transaction: TransactionView action: "post" | "void" | "reverse" labels: LedgerLabels base: string fenced: boolean }) { const navigation = usePageNavigation() const write = useWrite, TransactionView>(`ledger.transactions.${action}`) const identity = useRef(retryIdentity()) const payload = { org, transactionId: transaction.transactionId, expectedVersion: transaction.revision, confirmed: true, } return ( ledgerFailure(error, labels)} title={labels.confirm} description={labels.confirmDescription} confirmLabel={labels[action]} cancelLabel={labels.cancel} trigger={} onConfirm={async () => { if (fenced && action !== "void") throw new Error(labels.drift) const saved = await write.mutate({ ...payload, requestId: identity.current(payload) }) navigation.navigate(`${base}/transactions/${saved.transactionId}`) }} > ) }