// Inspector — right pane for selected transaction // Shows: source detail, account picker, ledger preview, approve/override/skip function AccountPicker({ value, onChange, mru = [] }) { const accounts = window.AKEFIN_DATA.allAccounts; const [open, setOpen] = React.useState(false); const [q, setQ] = React.useState(""); const matches = q ? accounts.filter(a => a.toLowerCase().includes(q.toLowerCase())).slice(0, 8) : accounts.slice(0, 8); return (
{open && (
setQ(e.target.value)} placeholder="Search accounts…" />
{mru.length > 0 && !q && (
RECENT
{mru.map(a => ( ))}
)}
{q ? "MATCHES" : "ALL ACCOUNTS"}
{matches.map(a => ( ))}
)}
); } function LedgerPreview({ tx, account }) { if (!tx || !account) return (
No posting to preview · choose an account
); const entityHomeCcy = { personal: "KRW", tfox: "KRW", finacode: "EUR" }; const sourceAccount = tx.entity === "personal" ? "Personal:Assets:Bank:Toss" : tx.entity === "tfox" ? "9TFox:Assets:Bank:Kakao" : "Finacode:Assets:Bank:Wise"; const isExpense = tx.amount < 0; const debit = isExpense ? account : sourceAccount; const credit = isExpense ? sourceAccount : account; const abs = Math.abs(tx.amount); const homeCcy = entityHomeCcy[tx.entity]; const needsFx = tx.ccy !== homeCcy; const fxRate = needsFx ? window.AKEFIN_DATA.fx[tx.ccy] / window.AKEFIN_DATA.fx[homeCcy] : null; const converted = needsFx ? Math.round(window.AKEFIN_DATA.convert(abs, tx.ccy, homeCcy)) : null; return (
{tx.date} "{tx.payee}"
{debit} {abs.toLocaleString()} {tx.ccy}
{needsFx && (
@ {fxRate.toFixed(2)} {homeCcy} · FX from ECB · 2026-03-08
)}
{credit} -{(needsFx ? converted : abs).toLocaleString()} {needsFx ? homeCcy : tx.ccy}
{needsFx ? `balanced · 2 legs · FX-converted to ${homeCcy}` : "balanced · 2 legs"} · will commit to {tx.entity === "personal" ? "personal" : tx.entity}-2026-03.ldgr
); } function Inspector({ tx, onApprove, onSkip }) { const [account, setAccount] = React.useState(tx?.suggestedAccount || null); React.useEffect(() => { setAccount(tx?.suggestedAccount || null); }, [tx?.id]); const mru = ["Personal:Expenses:Food:Coffee", "Personal:Expenses:Groceries", "9TFox:Expenses:Software"]; if (!tx) { return ( ); } return ( ); } Object.assign(window, { Inspector, LedgerPreview, AccountPicker });