// MobileApp โ€” stateful navigation between screens for ONE device frame function MobileApp({ initial = "queue", initialTx = null, initialEntity = "all", initialPickerOpen = false }) { const [screen, setScreen] = React.useState(initial); const [entity, setEntity] = React.useState(initialEntity); const [transactions, setTransactions] = React.useState(window.AKEFIN_DATA.transactions); const [activeTxId, setActiveTxId] = React.useState(initialTx); const [pickerOpen, setPickerOpen] = React.useState(initialPickerOpen); const tx = activeTxId ? transactions.find(t => t.id === activeTxId) : null; const [account, setAccount] = React.useState(tx?.suggestedAccount || null); React.useEffect(() => { if (tx) setAccount(tx.suggestedAccount || null); }, [tx?.id]); const openTx = (id) => { setActiveTxId(id); setScreen("detail"); }; const back = () => { setScreen("queue"); setActiveTxId(null); }; const approve = () => { setTransactions(prev => prev.filter(t => t.id !== activeTxId)); back(); }; const skip = () => { setTransactions(prev => prev.filter(t => t.id !== activeTxId)); back(); }; return (
{screen === "queue" && } {screen === "detail" && setPickerOpen(true)} />} {screen === "rules" && } {screen === "ledger" && } {screen === "import" && }
{ setActiveTxId(null); setScreen(s); }} /> setPickerOpen(false)} onPick={(a) => { setAccount(a); setPickerOpen(false); }} current={account} />
); } // A tiny rules screen for mobile function MRulesScreen({ entity }) { const rules = window.AKEFIN_DATA.ruleSuggestions; return (
{rules.map(r => (
"{r.pattern}"
โ†’ {r.target}
{r.occurrences} matches ยท 30d
))}
); } Object.assign(window, { MobileApp, MRulesScreen });