@burdenoff/microfe-brainyrich 2026.705.1 → 2026.706.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/brainyrich/BrainyRichRoot.js +13 -13
- package/dist/brainyrich/components/ActorName.js +38 -0
- package/dist/brainyrich/components/ActorName.js.map +1 -0
- package/dist/brainyrich/components/ConfirmDialog.js +25 -0
- package/dist/brainyrich/components/ConfirmDialog.js.map +1 -0
- package/dist/brainyrich/components/LoadMore.js +24 -0
- package/dist/brainyrich/components/LoadMore.js.map +1 -0
- package/dist/brainyrich/components/index.js +5 -0
- package/dist/brainyrich/components/notify.js +38 -0
- package/dist/brainyrich/components/notify.js.map +1 -0
- package/dist/brainyrich/components/pickers.js +232 -0
- package/dist/brainyrich/components/pickers.js.map +1 -0
- package/dist/brainyrich/components/reuse/CommentThread.js +208 -0
- package/dist/brainyrich/components/reuse/CommentThread.js.map +1 -0
- package/dist/brainyrich/components/reuse/DocumentsPanel.js +237 -0
- package/dist/brainyrich/components/reuse/DocumentsPanel.js.map +1 -0
- package/dist/brainyrich/components/reuse/TagField.js +206 -0
- package/dist/brainyrich/components/reuse/TagField.js.map +1 -0
- package/dist/brainyrich/components/reuse/transport.js +24 -0
- package/dist/brainyrich/components/reuse/transport.js.map +1 -0
- package/dist/brainyrich/hooks/useBrainyRichApi.js +644 -372
- package/dist/brainyrich/hooks/useBrainyRichApi.js.map +1 -1
- package/dist/brainyrich/pages/AccountsPage.js +346 -293
- package/dist/brainyrich/pages/AccountsPage.js.map +1 -1
- package/dist/brainyrich/pages/AiAssistantPage.js +339 -320
- package/dist/brainyrich/pages/AiAssistantPage.js.map +1 -1
- package/dist/brainyrich/pages/AnalyticsPage.js +178 -164
- package/dist/brainyrich/pages/AnalyticsPage.js.map +1 -1
- package/dist/brainyrich/pages/DashboardPage.js +195 -169
- package/dist/brainyrich/pages/DashboardPage.js.map +1 -1
- package/dist/brainyrich/pages/FamilyPage.js +247 -198
- package/dist/brainyrich/pages/FamilyPage.js.map +1 -1
- package/dist/brainyrich/pages/GoalsPage.js +478 -442
- package/dist/brainyrich/pages/GoalsPage.js.map +1 -1
- package/dist/brainyrich/pages/InvestmentsPage.js.map +1 -1
- package/dist/brainyrich/pages/PortfoliosPage.js +438 -396
- package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
- package/dist/brainyrich/pages/ReportsPage.js +246 -213
- package/dist/brainyrich/pages/ReportsPage.js.map +1 -1
- package/dist/brainyrich/pages/RiskPage.js +321 -173
- package/dist/brainyrich/pages/RiskPage.js.map +1 -1
- package/dist/brainyrich/pages/TaxPage.js +258 -225
- package/dist/brainyrich/pages/TaxPage.js.map +1 -1
- package/dist/brainyrich/pages/_shared.js.map +1 -1
- package/dist/node_modules/sonner/dist/index.js +163 -0
- package/dist/node_modules/sonner/dist/index.js.map +1 -0
- package/package.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AccountsPage.js","names":[],"sources":["../../../src/brainyrich/pages/AccountsPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport {\n ArrowDownRight,\n ArrowUpRight,\n Landmark,\n MoreHorizontal,\n Pencil,\n Plus,\n Receipt,\n Archive as ArchiveIcon,\n} from 'lucide-react';\nimport {\n useAccounts,\n useAccount,\n useTransactions,\n useCreateAccount,\n useUpdateAccount,\n useArchiveAccount,\n useRecordTransaction,\n} from '../hooks/useBrainyRichApi';\nimport type {\n BraAccount,\n BraAccountType,\n BraTransaction,\n BraTransactionType,\n} from '../types/bra';\nimport {\n SectionShell,\n KpiGrid,\n EmptyState,\n LoadingState,\n ErrorState,\n formatMoney,\n formatDate,\n statusBadgeVariant,\n} from './_shared';\n\n// Schema enum option lists (SDL enum members — not fabricated data).\nconst ACCOUNT_TYPES: BraAccountType[] = [\n 'BANK',\n 'BROKERAGE',\n 'RETIREMENT',\n 'CASH',\n 'CRYPTO',\n 'REAL_ESTATE',\n 'ALTERNATIVE',\n 'LIABILITY',\n];\n\nconst TRANSACTION_TYPES: BraTransactionType[] = [\n 'BUY',\n 'SELL',\n 'DIVIDEND',\n 'INTEREST',\n 'DEPOSIT',\n 'WITHDRAWAL',\n 'FEE',\n 'TRANSFER',\n];\n\n/** Positive = inflow (deposit/dividend/interest/sell/transfer in). */\nfunction isInflow(type: BraTransactionType): boolean {\n return (\n type === 'DEPOSIT' ||\n type === 'DIVIDEND' ||\n type === 'INTEREST' ||\n type === 'SELL' ||\n type === 'TRANSFER'\n );\n}\n\nfunction parseNum(value: string): number | undefined {\n if (value.trim() === '') return undefined;\n const n = Number(value);\n return Number.isFinite(n) ? n : undefined;\n}\n\ninterface AccountFormState {\n name: string;\n type: BraAccountType;\n institution: string;\n currency: string;\n cashBalance: string;\n accountMask: string;\n}\n\nconst EMPTY_ACCOUNT_FORM: AccountFormState = {\n name: '',\n type: 'BANK',\n institution: '',\n currency: 'USD',\n cashBalance: '',\n accountMask: '',\n};\n\ninterface TransactionFormState {\n type: BraTransactionType;\n tradeDate: string;\n symbol: string;\n quantity: string;\n price: string;\n amount: string;\n fee: string;\n notes: string;\n}\n\nconst EMPTY_TX_FORM: TransactionFormState = {\n type: 'DEPOSIT',\n tradeDate: '',\n symbol: '',\n quantity: '',\n price: '',\n amount: '',\n fee: '',\n notes: '',\n};\n\nexport function AccountsPage() {\n const { data: accounts, isLoading, isError, refetch } = useAccounts();\n\n const [selectedId, setSelectedId] = useState<string | undefined>(undefined);\n\n const [createOpen, setCreateOpen] = useState(false);\n const [createForm, setCreateForm] = useState<AccountFormState>(EMPTY_ACCOUNT_FORM);\n\n const [editAccount, setEditAccount] = useState<BraAccount | null>(null);\n const [editForm, setEditForm] = useState<AccountFormState>(EMPTY_ACCOUNT_FORM);\n\n const [archiveTarget, setArchiveTarget] = useState<BraAccount | null>(null);\n\n const [txOpen, setTxOpen] = useState(false);\n const [txForm, setTxForm] = useState<TransactionFormState>(EMPTY_TX_FORM);\n\n const createAccount = useCreateAccount();\n const updateAccount = useUpdateAccount();\n const archiveAccount = useArchiveAccount();\n const recordTransaction = useRecordTransaction();\n\n const totalCash = accounts.reduce((sum, a) => sum + (a.cashBalance ?? 0), 0);\n const activeCount = accounts.filter((a) => a.status === 'ACTIVE').length;\n const institutionCount = new Set(\n accounts.map((a) => a.institution).filter((i): i is string => Boolean(i))\n ).size;\n const displayCurrency = accounts[0]?.currency ?? 'USD';\n\n function openCreate() {\n setCreateForm(EMPTY_ACCOUNT_FORM);\n setCreateOpen(true);\n }\n\n function submitCreate() {\n if (!createForm.name.trim()) return;\n createAccount.mutate(\n {\n name: createForm.name.trim(),\n type: createForm.type,\n institution: createForm.institution.trim() || null,\n currency: createForm.currency.trim() || 'USD',\n cashBalance: parseNum(createForm.cashBalance) ?? 0,\n accountMask: createForm.accountMask.trim() || null,\n },\n { onSuccess: () => setCreateOpen(false) }\n );\n }\n\n function openEdit(account: BraAccount) {\n setEditAccount(account);\n setEditForm({\n name: account.name,\n type: account.type,\n institution: account.institution ?? '',\n currency: account.currency,\n cashBalance: String(account.cashBalance ?? ''),\n accountMask: account.accountMask ?? '',\n });\n }\n\n function submitEdit() {\n if (!editAccount || !editForm.name.trim()) return;\n updateAccount.mutate(\n {\n id: editAccount.id,\n input: {\n name: editForm.name.trim(),\n type: editForm.type,\n institution: editForm.institution.trim() || null,\n currency: editForm.currency.trim() || 'USD',\n cashBalance: parseNum(editForm.cashBalance) ?? 0,\n accountMask: editForm.accountMask.trim() || null,\n },\n },\n { onSuccess: () => setEditAccount(null) }\n );\n }\n\n function submitArchive() {\n if (!archiveTarget) return;\n const id = archiveTarget.id;\n archiveAccount.mutate(id, {\n onSuccess: () => {\n setArchiveTarget(null);\n if (selectedId === id) setSelectedId(undefined);\n },\n });\n }\n\n function openRecordTx() {\n setTxForm(EMPTY_TX_FORM);\n setTxOpen(true);\n }\n\n function submitTx() {\n if (!selectedId || !txForm.tradeDate) return;\n const tradeIso = new Date(txForm.tradeDate);\n if (Number.isNaN(tradeIso.getTime())) return;\n recordTransaction.mutate(\n {\n accountId: selectedId,\n type: txForm.type,\n tradeDate: tradeIso.toISOString(),\n symbol: txForm.symbol.trim() || null,\n quantity: parseNum(txForm.quantity),\n price: parseNum(txForm.price),\n amount: parseNum(txForm.amount),\n fee: parseNum(txForm.fee),\n notes: txForm.notes.trim() || null,\n },\n { onSuccess: () => setTxOpen(false) }\n );\n }\n\n return (\n <SectionShell\n title=\"Accounts\"\n description=\"Linked bank, brokerage and retirement accounts with recent activity.\"\n badges={[`${accounts.length} account${accounts.length === 1 ? '' : 's'}`]}\n actionLabel=\"New account\"\n onAction={openCreate}\n >\n <KpiGrid\n items={[\n { label: 'Total accounts', value: String(accounts.length) },\n { label: 'Total cash', value: formatMoney(totalCash, displayCurrency) },\n { label: 'Active', value: `${activeCount}/${accounts.length}` },\n { label: 'Institutions', value: String(institutionCount) },\n ]}\n />\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Landmark className=\"h-5 w-5\" aria-hidden=\"true\" />\n Linked accounts\n </CardTitle>\n <CardDescription>Select an account to view holdings and transactions.</CardDescription>\n </CardHeader>\n <CardContent>\n {isLoading ? (\n <LoadingState />\n ) : isError ? (\n <ErrorState onRetry={() => refetch()} />\n ) : accounts.length === 0 ? (\n <EmptyState\n icon={<Landmark className=\"size-6\" aria-hidden=\"true\" />}\n title=\"No accounts yet\"\n description=\"Add your first bank, brokerage or retirement account to start tracking net worth.\"\n action={\n <Button size=\"sm\" onClick={openCreate}>\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n New account\n </Button>\n }\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Account</TableHead>\n <TableHead>Type</TableHead>\n <TableHead className=\"text-right\">Cash balance</TableHead>\n <TableHead>Status</TableHead>\n <TableHead className=\"w-12 text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {accounts.map((account) => (\n <TableRow\n key={account.id}\n className=\"cursor-pointer\"\n onClick={() => setSelectedId(account.id)}\n >\n <TableCell>\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-9 w-9 items-center justify-center rounded-full bg-muted text-xs font-semibold text-muted-foreground\">\n {(account.institution ?? account.name).slice(0, 2).toUpperCase()}\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{account.name}</p>\n <p className=\"truncate text-xs text-text-secondary\">\n {account.institution ?? 'Manual account'}\n {account.accountMask ? ` · ••${account.accountMask}` : ''}\n </p>\n </div>\n </div>\n </TableCell>\n <TableCell>\n <Badge variant=\"outline\">{account.type.replace(/_/g, ' ')}</Badge>\n </TableCell>\n <TableCell className=\"text-right font-semibold text-text-primary\">\n {formatMoney(account.cashBalance, account.currency)}\n </TableCell>\n <TableCell>\n <Badge variant={statusBadgeVariant(account.status)}>{account.status}</Badge>\n </TableCell>\n <TableCell\n className=\"text-right\"\n onClick={(e) => e.stopPropagation()}\n >\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"sm\" aria-label={`Actions for ${account.name}`}>\n <MoreHorizontal className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => openEdit(account)}>\n <Pencil className=\"size-4\" aria-hidden=\"true\" />\n Edit\n </DropdownMenuItem>\n <DropdownMenuItem\n className=\"text-status-error-text\"\n onClick={() => setArchiveTarget(account)}\n >\n <ArchiveIcon className=\"size-4\" aria-hidden=\"true\" />\n Archive\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </CardContent>\n </Card>\n\n {/* Create account dialog */}\n <Dialog open={createOpen} onOpenChange={setCreateOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>New account</DialogTitle>\n <DialogDescription>Add a bank, brokerage or retirement account.</DialogDescription>\n </DialogHeader>\n <AccountForm form={createForm} onChange={setCreateForm} />\n <DialogFooter>\n <DialogClose asChild>\n <Button variant=\"outline\">Cancel</Button>\n </DialogClose>\n <Button\n onClick={submitCreate}\n disabled={!createForm.name.trim() || createAccount.isPending}\n >\n {createAccount.isPending ? 'Creating…' : 'Create account'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* Edit account dialog */}\n <Dialog open={Boolean(editAccount)} onOpenChange={(open) => !open && setEditAccount(null)}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Edit account</DialogTitle>\n <DialogDescription>Update account details.</DialogDescription>\n </DialogHeader>\n <AccountForm form={editForm} onChange={setEditForm} />\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setEditAccount(null)}>\n Cancel\n </Button>\n <Button\n onClick={submitEdit}\n disabled={!editForm.name.trim() || updateAccount.isPending}\n >\n {updateAccount.isPending ? 'Saving…' : 'Save changes'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* Archive confirm dialog */}\n <Dialog\n open={Boolean(archiveTarget)}\n onOpenChange={(open) => !open && setArchiveTarget(null)}\n >\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Archive account?</DialogTitle>\n <DialogDescription>\n {archiveTarget\n ? `“${archiveTarget.name}” will be archived and hidden from active lists. This does not delete its history.`\n : ''}\n </DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setArchiveTarget(null)}>\n Cancel\n </Button>\n <Button\n variant=\"destructive\"\n onClick={submitArchive}\n disabled={archiveAccount.isPending}\n >\n {archiveAccount.isPending ? 'Archiving…' : 'Archive account'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* Account detail sheet */}\n <AccountDetailSheet\n accountId={selectedId}\n onClose={() => setSelectedId(undefined)}\n onRecordTransaction={openRecordTx}\n />\n\n {/* Record transaction dialog */}\n <Dialog open={txOpen} onOpenChange={setTxOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Record transaction</DialogTitle>\n <DialogDescription>Log activity against the selected account.</DialogDescription>\n </DialogHeader>\n <div className=\"grid gap-4\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-type\">Type</Label>\n <Select\n value={txForm.type}\n onValueChange={(v) => setTxForm((f) => ({ ...f, type: v as BraTransactionType }))}\n >\n <SelectTrigger id=\"tx-type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {TRANSACTION_TYPES.map((t) => (\n <SelectItem key={t} value={t}>\n {t.replace(/_/g, ' ')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-date\">Trade date</Label>\n <Input\n id=\"tx-date\"\n type=\"date\"\n value={txForm.tradeDate}\n onChange={(e) => setTxForm((f) => ({ ...f, tradeDate: e.target.value }))}\n />\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-symbol\">Symbol</Label>\n <Input\n id=\"tx-symbol\"\n value={txForm.symbol}\n onChange={(e) => setTxForm((f) => ({ ...f, symbol: e.target.value }))}\n placeholder=\"e.g. VOO\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-amount\">Amount</Label>\n <Input\n id=\"tx-amount\"\n type=\"number\"\n value={txForm.amount}\n onChange={(e) => setTxForm((f) => ({ ...f, amount: e.target.value }))}\n />\n </div>\n </div>\n <div className=\"grid grid-cols-3 gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-qty\">Quantity</Label>\n <Input\n id=\"tx-qty\"\n type=\"number\"\n value={txForm.quantity}\n onChange={(e) => setTxForm((f) => ({ ...f, quantity: e.target.value }))}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-price\">Price</Label>\n <Input\n id=\"tx-price\"\n type=\"number\"\n value={txForm.price}\n onChange={(e) => setTxForm((f) => ({ ...f, price: e.target.value }))}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-fee\">Fee</Label>\n <Input\n id=\"tx-fee\"\n type=\"number\"\n value={txForm.fee}\n onChange={(e) => setTxForm((f) => ({ ...f, fee: e.target.value }))}\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-notes\">Notes</Label>\n <Textarea\n id=\"tx-notes\"\n value={txForm.notes}\n onChange={(e) => setTxForm((f) => ({ ...f, notes: e.target.value }))}\n placeholder=\"Optional note\"\n />\n </div>\n </div>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setTxOpen(false)}>\n Cancel\n </Button>\n <Button\n onClick={submitTx}\n disabled={!txForm.tradeDate || recordTransaction.isPending}\n >\n {recordTransaction.isPending ? 'Saving…' : 'Record transaction'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </SectionShell>\n );\n}\n\n// ============================================================================\n// Account form (shared by create + edit dialogs)\n// ============================================================================\n\nfunction AccountForm({\n form,\n onChange,\n}: {\n form: AccountFormState;\n onChange: (updater: (prev: AccountFormState) => AccountFormState) => void;\n}) {\n return (\n <div className=\"grid gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"acct-name\">Name</Label>\n <Input\n id=\"acct-name\"\n value={form.name}\n onChange={(e) => onChange((f) => ({ ...f, name: e.target.value }))}\n placeholder=\"e.g. Everyday Checking\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"acct-type\">Type</Label>\n <Select\n value={form.type}\n onValueChange={(v) => onChange((f) => ({ ...f, type: v as BraAccountType }))}\n >\n <SelectTrigger id=\"acct-type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ACCOUNT_TYPES.map((t) => (\n <SelectItem key={t} value={t}>\n {t.replace(/_/g, ' ')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"acct-currency\">Currency</Label>\n <Input\n id=\"acct-currency\"\n value={form.currency}\n onChange={(e) => onChange((f) => ({ ...f, currency: e.target.value.toUpperCase() }))}\n placeholder=\"USD\"\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"acct-institution\">Institution</Label>\n <Input\n id=\"acct-institution\"\n value={form.institution}\n onChange={(e) => onChange((f) => ({ ...f, institution: e.target.value }))}\n placeholder=\"e.g. Chase\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"acct-balance\">Cash balance</Label>\n <Input\n id=\"acct-balance\"\n type=\"number\"\n value={form.cashBalance}\n onChange={(e) => onChange((f) => ({ ...f, cashBalance: e.target.value }))}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"acct-mask\">Account mask</Label>\n <Input\n id=\"acct-mask\"\n value={form.accountMask}\n onChange={(e) => onChange((f) => ({ ...f, accountMask: e.target.value }))}\n placeholder=\"Last 4 digits\"\n />\n </div>\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// Account detail sheet — holdings + recent transactions\n// ============================================================================\n\nfunction AccountDetailSheet({\n accountId,\n onClose,\n onRecordTransaction,\n}: {\n accountId: string | undefined;\n onClose: () => void;\n onRecordTransaction: () => void;\n}) {\n const { data: account, isLoading, isError, refetch } = useAccount(accountId);\n const txQuery = useTransactions(accountId ? { accountId } : {});\n const transactions: BraTransaction[] = accountId ? txQuery.data : [];\n\n return (\n <Sheet open={Boolean(accountId)} onOpenChange={(open) => !open && onClose()}>\n <SheetContent className=\"w-full overflow-y-auto sm:max-w-lg\">\n <SheetHeader>\n <SheetTitle>{account?.name ?? 'Account'}</SheetTitle>\n <SheetDescription>\n {account\n ? `${account.institution ?? 'Manual account'} · ${account.type.replace(/_/g, ' ')}`\n : 'Loading account details…'}\n </SheetDescription>\n </SheetHeader>\n\n {isLoading ? (\n <div className=\"mt-6\">\n <LoadingState rows={3} />\n </div>\n ) : isError ? (\n <div className=\"mt-6\">\n <ErrorState onRetry={() => refetch()} />\n </div>\n ) : !account ? (\n <div className=\"mt-6\">\n <EmptyState title=\"Account not found\" description=\"This account is no longer available.\" />\n </div>\n ) : (\n <div className=\"mt-6 space-y-6\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Cash balance</p>\n <p className=\"text-xl font-semibold text-text-primary\">\n {formatMoney(account.cashBalance, account.currency)}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Status</p>\n <Badge variant={statusBadgeVariant(account.status)}>{account.status}</Badge>\n </div>\n </div>\n\n {/* Holdings */}\n <div className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Holdings</h3>\n {account.holdings.length === 0 ? (\n <EmptyState\n title=\"No holdings\"\n description=\"This account has no positions recorded yet.\"\n />\n ) : (\n <div className=\"space-y-2\">\n {account.holdings.map((h) => (\n <div\n key={h.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle bg-bg-surface p-3\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{h.symbol}</p>\n {h.name ? (\n <p className=\"truncate text-xs text-text-secondary\">{h.name}</p>\n ) : null}\n </div>\n <span className=\"text-sm font-semibold text-text-primary\">\n {formatMoney(h.marketValue, h.currency)}\n </span>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Recent transactions */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Recent transactions</h3>\n <Button size=\"sm\" variant=\"outline\" onClick={onRecordTransaction}>\n <Receipt className=\"size-4\" aria-hidden=\"true\" />\n Record\n </Button>\n </div>\n {txQuery.isLoading ? (\n <LoadingState rows={2} />\n ) : txQuery.isError ? (\n <ErrorState onRetry={() => txQuery.refetch()} />\n ) : transactions.length === 0 ? (\n <EmptyState\n icon={<Receipt className=\"size-6\" aria-hidden=\"true\" />}\n title=\"No transactions\"\n description=\"Record a transaction to see activity here.\"\n action={\n <Button size=\"sm\" onClick={onRecordTransaction}>\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n Record transaction\n </Button>\n }\n />\n ) : (\n <div className=\"space-y-2\">\n {transactions.map((tx) => {\n const inflow = isInflow(tx.type);\n const Icon = inflow ? ArrowUpRight : ArrowDownRight;\n const tone = inflow\n ? 'text-status-success-text'\n : 'text-status-error-text';\n return (\n <div\n key={tx.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle bg-bg-surface p-3\"\n >\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"outline\">{tx.type.replace(/_/g, ' ')}</Badge>\n {tx.symbol ? (\n <span className=\"truncate text-xs text-text-secondary\">\n {tx.symbol}\n </span>\n ) : null}\n </div>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {formatDate(tx.tradeDate)}\n </p>\n </div>\n <span className={`inline-flex items-center gap-1 text-sm font-semibold ${tone}`}>\n <Icon className=\"size-4\" aria-hidden=\"true\" />\n {inflow ? '+' : '−'}\n {formatMoney(Math.abs(tx.amount), tx.currency)}\n </span>\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n )}\n </SheetContent>\n </Sheet>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AccountsPage.js","names":[],"sources":["../../../src/brainyrich/pages/AccountsPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n Input,\n Label,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Textarea,\n} from '@burdenoff/fe-libs/ui';\nimport {\n ArrowDownRight,\n ArrowUpRight,\n Landmark,\n MoreHorizontal,\n Pencil,\n Plus,\n Receipt,\n Archive as ArchiveIcon,\n} from 'lucide-react';\nimport {\n useAccount,\n useAllAccounts,\n usePagedAccounts,\n usePagedTransactions,\n useCreateAccount,\n useUpdateAccount,\n useArchiveAccount,\n useRecordTransaction,\n} from '../hooks/useBrainyRichApi';\nimport type { BraAccount, BraAccountType, BraTransactionType } from '../types/bra';\nimport { ActorName, ConfirmDialog, HouseholdPicker, LoadMore } from '../components';\nimport { DocumentsPanel } from '../components/reuse/DocumentsPanel';\nimport {\n SectionShell,\n KpiGrid,\n EmptyState,\n LoadingState,\n ErrorState,\n formatMoney,\n formatDate,\n statusBadgeVariant,\n} from './_shared';\n\n// Schema enum option lists (SDL enum members — not fabricated data).\nconst ACCOUNT_TYPES: BraAccountType[] = [\n 'BANK',\n 'BROKERAGE',\n 'RETIREMENT',\n 'CASH',\n 'CRYPTO',\n 'REAL_ESTATE',\n 'ALTERNATIVE',\n 'LIABILITY',\n];\n\nconst TRANSACTION_TYPES: BraTransactionType[] = [\n 'BUY',\n 'SELL',\n 'DIVIDEND',\n 'INTEREST',\n 'DEPOSIT',\n 'WITHDRAWAL',\n 'FEE',\n 'TRANSFER',\n];\n\n/** Positive = inflow (deposit/dividend/interest/sell/transfer in). */\nfunction isInflow(type: BraTransactionType): boolean {\n return (\n type === 'DEPOSIT' ||\n type === 'DIVIDEND' ||\n type === 'INTEREST' ||\n type === 'SELL' ||\n type === 'TRANSFER'\n );\n}\n\nfunction parseNum(value: string): number | undefined {\n if (value.trim() === '') return undefined;\n const n = Number(value);\n return Number.isFinite(n) ? n : undefined;\n}\n\ninterface AccountFormState {\n name: string;\n type: BraAccountType;\n institution: string;\n currency: string;\n cashBalance: string;\n accountMask: string;\n householdId: string | null;\n}\n\nconst EMPTY_ACCOUNT_FORM: AccountFormState = {\n name: '',\n type: 'BANK',\n institution: '',\n currency: 'USD',\n cashBalance: '',\n accountMask: '',\n householdId: null,\n};\n\ninterface TransactionFormState {\n type: BraTransactionType;\n tradeDate: string;\n symbol: string;\n quantity: string;\n price: string;\n amount: string;\n fee: string;\n notes: string;\n}\n\nconst EMPTY_TX_FORM: TransactionFormState = {\n type: 'DEPOSIT',\n tradeDate: '',\n symbol: '',\n quantity: '',\n price: '',\n amount: '',\n fee: '',\n notes: '',\n};\n\nexport function AccountsPage() {\n // Full set drives the KPI aggregates (totals must cover every account).\n const allAccounts = useAllAccounts();\n const accounts = allAccounts.data;\n // Paged connection drives the interactive table + LoadMore.\n const paged = usePagedAccounts();\n\n const [selectedId, setSelectedId] = useState<string | undefined>(undefined);\n\n const [createOpen, setCreateOpen] = useState(false);\n const [createForm, setCreateForm] = useState<AccountFormState>(EMPTY_ACCOUNT_FORM);\n\n const [editAccount, setEditAccount] = useState<BraAccount | null>(null);\n const [editForm, setEditForm] = useState<AccountFormState>(EMPTY_ACCOUNT_FORM);\n\n const [archiveTarget, setArchiveTarget] = useState<BraAccount | null>(null);\n\n const [txOpen, setTxOpen] = useState(false);\n const [txForm, setTxForm] = useState<TransactionFormState>(EMPTY_TX_FORM);\n\n const createAccount = useCreateAccount();\n const updateAccount = useUpdateAccount();\n const archiveAccount = useArchiveAccount();\n const recordTransaction = useRecordTransaction();\n\n const totalCash = accounts.reduce((sum, a) => sum + (a.cashBalance ?? 0), 0);\n const activeCount = accounts.filter((a) => a.status === 'ACTIVE').length;\n const institutionCount = new Set(\n accounts.map((a) => a.institution).filter((i): i is string => Boolean(i))\n ).size;\n const displayCurrency = accounts[0]?.currency ?? 'USD';\n\n function openCreate() {\n setCreateForm(EMPTY_ACCOUNT_FORM);\n setCreateOpen(true);\n }\n\n function submitCreate() {\n if (!createForm.name.trim()) return;\n createAccount.mutate(\n {\n name: createForm.name.trim(),\n type: createForm.type,\n institution: createForm.institution.trim() || null,\n currency: createForm.currency.trim() || 'USD',\n cashBalance: parseNum(createForm.cashBalance) ?? 0,\n accountMask: createForm.accountMask.trim() || null,\n householdId: createForm.householdId,\n },\n { onSuccess: () => setCreateOpen(false) }\n );\n }\n\n function openEdit(account: BraAccount) {\n setEditAccount(account);\n setEditForm({\n name: account.name,\n type: account.type,\n institution: account.institution ?? '',\n currency: account.currency,\n cashBalance: String(account.cashBalance ?? ''),\n accountMask: account.accountMask ?? '',\n householdId: account.householdId,\n });\n }\n\n function submitEdit() {\n if (!editAccount || !editForm.name.trim()) return;\n updateAccount.mutate(\n {\n id: editAccount.id,\n input: {\n name: editForm.name.trim(),\n type: editForm.type,\n institution: editForm.institution.trim() || null,\n currency: editForm.currency.trim() || 'USD',\n cashBalance: parseNum(editForm.cashBalance) ?? 0,\n accountMask: editForm.accountMask.trim() || null,\n householdId: editForm.householdId,\n },\n },\n { onSuccess: () => setEditAccount(null) }\n );\n }\n\n function submitArchive() {\n if (!archiveTarget) return;\n const id = archiveTarget.id;\n archiveAccount.mutate(id, {\n onSuccess: () => {\n setArchiveTarget(null);\n if (selectedId === id) setSelectedId(undefined);\n },\n });\n }\n\n function openRecordTx() {\n setTxForm(EMPTY_TX_FORM);\n setTxOpen(true);\n }\n\n const txAmount = parseNum(txForm.amount);\n const txAmountValid = txAmount !== undefined && txAmount > 0;\n const txValid = Boolean(selectedId && txForm.tradeDate) && txAmountValid;\n\n function submitTx() {\n if (!selectedId || !txForm.tradeDate || !txAmountValid) return;\n const tradeIso = new Date(txForm.tradeDate);\n if (Number.isNaN(tradeIso.getTime())) return;\n recordTransaction.mutate(\n {\n accountId: selectedId,\n type: txForm.type,\n tradeDate: tradeIso.toISOString(),\n symbol: txForm.symbol.trim() || null,\n quantity: parseNum(txForm.quantity),\n price: parseNum(txForm.price),\n amount: txAmount,\n fee: parseNum(txForm.fee),\n notes: txForm.notes.trim() || null,\n },\n { onSuccess: () => setTxOpen(false) }\n );\n }\n\n return (\n <SectionShell\n title=\"Accounts\"\n description=\"Linked bank, brokerage and retirement accounts with recent activity.\"\n badges={[`${accounts.length} account${accounts.length === 1 ? '' : 's'}`]}\n actionLabel=\"New account\"\n onAction={openCreate}\n >\n <KpiGrid\n items={[\n { label: 'Total accounts', value: String(accounts.length) },\n { label: 'Total cash', value: formatMoney(totalCash, displayCurrency) },\n { label: 'Active', value: `${activeCount}/${accounts.length}` },\n { label: 'Institutions', value: String(institutionCount) },\n ]}\n />\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Landmark className=\"h-5 w-5\" aria-hidden=\"true\" />\n Linked accounts\n </CardTitle>\n <CardDescription>Select an account to view holdings and transactions.</CardDescription>\n </CardHeader>\n <CardContent>\n {paged.isLoading ? (\n <LoadingState />\n ) : paged.isError ? (\n <ErrorState onRetry={() => paged.refetch()} />\n ) : paged.items.length === 0 ? (\n <EmptyState\n icon={<Landmark className=\"size-6\" aria-hidden=\"true\" />}\n title=\"No accounts yet\"\n description=\"Add your first bank, brokerage or retirement account to start tracking net worth.\"\n action={\n <Button size=\"sm\" onClick={openCreate}>\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n New account\n </Button>\n }\n />\n ) : (\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Account</TableHead>\n <TableHead>Type</TableHead>\n <TableHead className=\"text-right\">Cash balance</TableHead>\n <TableHead>Status</TableHead>\n <TableHead className=\"w-12 text-right\">Actions</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {paged.items.map((account) => (\n <TableRow\n key={account.id}\n className=\"cursor-pointer\"\n onClick={() => setSelectedId(account.id)}\n >\n <TableCell>\n <div className=\"flex items-center gap-3\">\n <div className=\"flex h-9 w-9 items-center justify-center rounded-full bg-muted text-xs font-semibold text-muted-foreground\">\n {(account.institution ?? account.name).slice(0, 2).toUpperCase()}\n </div>\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium text-text-primary\">{account.name}</p>\n <p className=\"truncate text-xs text-text-secondary\">\n {account.institution ?? 'Manual account'}\n {account.accountMask ? ` · ••${account.accountMask}` : ''}\n </p>\n </div>\n </div>\n </TableCell>\n <TableCell>\n <Badge variant=\"outline\">{account.type.replace(/_/g, ' ')}</Badge>\n </TableCell>\n <TableCell className=\"text-right font-semibold text-text-primary\">\n {formatMoney(account.cashBalance, account.currency)}\n </TableCell>\n <TableCell>\n <Badge variant={statusBadgeVariant(account.status)}>{account.status}</Badge>\n </TableCell>\n <TableCell className=\"text-right\" onClick={(e) => e.stopPropagation()}>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n aria-label={`Actions for ${account.name}`}\n >\n <MoreHorizontal className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => openEdit(account)}>\n <Pencil className=\"size-4\" aria-hidden=\"true\" />\n Edit\n </DropdownMenuItem>\n <DropdownMenuItem\n className=\"text-status-error-text\"\n onClick={() => setArchiveTarget(account)}\n >\n <ArchiveIcon className=\"size-4\" aria-hidden=\"true\" />\n Archive\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n <LoadMore\n hasMore={paged.hasMore}\n onClick={paged.loadMore}\n loading={paged.isFetchingNextPage}\n className=\"mt-4\"\n />\n </div>\n )}\n </CardContent>\n </Card>\n\n {/* Create account dialog */}\n <Dialog open={createOpen} onOpenChange={setCreateOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>New account</DialogTitle>\n <DialogDescription>Add a bank, brokerage or retirement account.</DialogDescription>\n </DialogHeader>\n <AccountForm form={createForm} onChange={setCreateForm} />\n <DialogFooter>\n <DialogClose asChild>\n <Button variant=\"outline\">Cancel</Button>\n </DialogClose>\n <Button\n onClick={submitCreate}\n disabled={!createForm.name.trim() || createAccount.isPending}\n >\n {createAccount.isPending ? 'Creating…' : 'Create account'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* Edit account dialog */}\n <Dialog open={Boolean(editAccount)} onOpenChange={(open) => !open && setEditAccount(null)}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Edit account</DialogTitle>\n <DialogDescription>Update account details.</DialogDescription>\n </DialogHeader>\n <AccountForm form={editForm} onChange={setEditForm} />\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setEditAccount(null)}>\n Cancel\n </Button>\n <Button\n onClick={submitEdit}\n disabled={!editForm.name.trim() || updateAccount.isPending}\n >\n {updateAccount.isPending ? 'Saving…' : 'Save changes'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* Archive confirm dialog */}\n <ConfirmDialog\n open={Boolean(archiveTarget)}\n onOpenChange={(open) => !open && setArchiveTarget(null)}\n title=\"Archive account?\"\n description={\n archiveTarget\n ? `“${archiveTarget.name}” will be archived and hidden from active lists. This does not delete its history.`\n : undefined\n }\n confirmLabel=\"Archive account\"\n pendingLabel=\"Archiving…\"\n destructive\n pending={archiveAccount.isPending}\n onConfirm={submitArchive}\n />\n\n {/* Account detail sheet */}\n <AccountDetailSheet\n accountId={selectedId}\n onClose={() => setSelectedId(undefined)}\n onRecordTransaction={openRecordTx}\n />\n\n {/* Record transaction dialog */}\n <Dialog open={txOpen} onOpenChange={setTxOpen}>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Record transaction</DialogTitle>\n <DialogDescription>Log activity against the selected account.</DialogDescription>\n </DialogHeader>\n <div className=\"grid gap-4\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-type\">Type</Label>\n <Select\n value={txForm.type}\n onValueChange={(v) => setTxForm((f) => ({ ...f, type: v as BraTransactionType }))}\n >\n <SelectTrigger id=\"tx-type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {TRANSACTION_TYPES.map((t) => (\n <SelectItem key={t} value={t}>\n {t.replace(/_/g, ' ')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-date\">Trade date</Label>\n <Input\n id=\"tx-date\"\n type=\"date\"\n value={txForm.tradeDate}\n onChange={(e) => setTxForm((f) => ({ ...f, tradeDate: e.target.value }))}\n />\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-symbol\">Symbol</Label>\n <Input\n id=\"tx-symbol\"\n value={txForm.symbol}\n onChange={(e) => setTxForm((f) => ({ ...f, symbol: e.target.value }))}\n placeholder=\"e.g. VOO\"\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-amount\">Amount</Label>\n <Input\n id=\"tx-amount\"\n type=\"number\"\n min=\"0\"\n step=\"any\"\n value={txForm.amount}\n onChange={(e) => setTxForm((f) => ({ ...f, amount: e.target.value }))}\n aria-invalid={txForm.amount.trim() !== '' && !txAmountValid}\n aria-describedby=\"tx-amount-hint\"\n />\n <p id=\"tx-amount-hint\" className=\"text-xs text-text-secondary\">\n {txForm.amount.trim() !== '' && !txAmountValid\n ? 'Enter an amount greater than 0.'\n : 'Positive amount; direction is set by the type.'}\n </p>\n </div>\n </div>\n <div className=\"grid grid-cols-3 gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-qty\">Quantity</Label>\n <Input\n id=\"tx-qty\"\n type=\"number\"\n value={txForm.quantity}\n onChange={(e) => setTxForm((f) => ({ ...f, quantity: e.target.value }))}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-price\">Price</Label>\n <Input\n id=\"tx-price\"\n type=\"number\"\n value={txForm.price}\n onChange={(e) => setTxForm((f) => ({ ...f, price: e.target.value }))}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-fee\">Fee</Label>\n <Input\n id=\"tx-fee\"\n type=\"number\"\n value={txForm.fee}\n onChange={(e) => setTxForm((f) => ({ ...f, fee: e.target.value }))}\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"tx-notes\">Notes</Label>\n <Textarea\n id=\"tx-notes\"\n value={txForm.notes}\n onChange={(e) => setTxForm((f) => ({ ...f, notes: e.target.value }))}\n placeholder=\"Optional note\"\n />\n </div>\n </div>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setTxOpen(false)}>\n Cancel\n </Button>\n <Button onClick={submitTx} disabled={!txValid || recordTransaction.isPending}>\n {recordTransaction.isPending ? 'Saving…' : 'Record transaction'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </SectionShell>\n );\n}\n\n// ============================================================================\n// Account form (shared by create + edit dialogs)\n// ============================================================================\n\nfunction AccountForm({\n form,\n onChange,\n}: {\n form: AccountFormState;\n onChange: (updater: (prev: AccountFormState) => AccountFormState) => void;\n}) {\n return (\n <div className=\"grid gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"acct-name\">Name</Label>\n <Input\n id=\"acct-name\"\n value={form.name}\n onChange={(e) => onChange((f) => ({ ...f, name: e.target.value }))}\n placeholder=\"e.g. Everyday Checking\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"acct-type\">Type</Label>\n <Select\n value={form.type}\n onValueChange={(v) => onChange((f) => ({ ...f, type: v as BraAccountType }))}\n >\n <SelectTrigger id=\"acct-type\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ACCOUNT_TYPES.map((t) => (\n <SelectItem key={t} value={t}>\n {t.replace(/_/g, ' ')}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"acct-currency\">Currency</Label>\n <Input\n id=\"acct-currency\"\n value={form.currency}\n onChange={(e) => onChange((f) => ({ ...f, currency: e.target.value.toUpperCase() }))}\n placeholder=\"USD\"\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"acct-institution\">Institution</Label>\n <Input\n id=\"acct-institution\"\n value={form.institution}\n onChange={(e) => onChange((f) => ({ ...f, institution: e.target.value }))}\n placeholder=\"e.g. Chase\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"acct-balance\">Cash balance</Label>\n <Input\n id=\"acct-balance\"\n type=\"number\"\n value={form.cashBalance}\n onChange={(e) => onChange((f) => ({ ...f, cashBalance: e.target.value }))}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"acct-mask\">Account mask</Label>\n <Input\n id=\"acct-mask\"\n value={form.accountMask}\n onChange={(e) => onChange((f) => ({ ...f, accountMask: e.target.value }))}\n placeholder=\"Last 4 digits\"\n />\n </div>\n </div>\n <HouseholdPicker\n value={form.householdId}\n onChange={(householdId) => onChange((f) => ({ ...f, householdId }))}\n />\n </div>\n );\n}\n\n// ============================================================================\n// Account detail sheet — holdings + recent transactions\n// ============================================================================\n\nfunction AccountDetailSheet({\n accountId,\n onClose,\n onRecordTransaction,\n}: {\n accountId: string | undefined;\n onClose: () => void;\n onRecordTransaction: () => void;\n}) {\n const { data: account, isLoading, isError, refetch } = useAccount(accountId);\n const txPaged = usePagedTransactions(accountId ? { accountId } : {});\n const transactions = accountId ? txPaged.items : [];\n\n return (\n <Sheet open={Boolean(accountId)} onOpenChange={(open) => !open && onClose()}>\n <SheetContent className=\"w-full overflow-y-auto sm:max-w-lg\">\n <SheetHeader>\n <SheetTitle>{account?.name ?? 'Account'}</SheetTitle>\n <SheetDescription>\n {account\n ? `${account.institution ?? 'Manual account'} · ${account.type.replace(/_/g, ' ')}`\n : 'Loading account details…'}\n </SheetDescription>\n </SheetHeader>\n\n {isLoading ? (\n <div className=\"mt-6\">\n <LoadingState rows={3} />\n </div>\n ) : isError ? (\n <div className=\"mt-6\">\n <ErrorState onRetry={() => refetch()} />\n </div>\n ) : !account ? (\n <div className=\"mt-6\">\n <EmptyState\n title=\"Account not found\"\n description=\"This account is no longer available.\"\n />\n </div>\n ) : (\n <div className=\"mt-6 space-y-6\">\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Cash balance</p>\n <p className=\"text-xl font-semibold text-text-primary\">\n {formatMoney(account.cashBalance, account.currency)}\n </p>\n </div>\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Status</p>\n <Badge variant={statusBadgeVariant(account.status)}>{account.status}</Badge>\n </div>\n </div>\n\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Owner</p>\n <ActorName id={account.ownerId} className=\"text-sm font-medium text-text-primary\" />\n </div>\n\n {/* Holdings */}\n <div className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Holdings</h3>\n {account.holdings.length === 0 ? (\n <EmptyState\n title=\"No holdings\"\n description=\"This account has no positions recorded yet.\"\n />\n ) : (\n <div className=\"space-y-2\">\n {account.holdings.map((h) => (\n <div\n key={h.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle bg-bg-surface p-3\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium text-text-primary\">{h.symbol}</p>\n {h.name ? (\n <p className=\"truncate text-xs text-text-secondary\">{h.name}</p>\n ) : null}\n </div>\n <span className=\"text-sm font-semibold text-text-primary\">\n {formatMoney(h.marketValue, h.currency)}\n </span>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Recent transactions */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <h3 className=\"text-sm font-semibold text-text-primary\">Recent transactions</h3>\n <Button size=\"sm\" variant=\"outline\" onClick={onRecordTransaction}>\n <Receipt className=\"size-4\" aria-hidden=\"true\" />\n Record\n </Button>\n </div>\n {txPaged.isLoading ? (\n <LoadingState rows={2} />\n ) : txPaged.isError ? (\n <ErrorState onRetry={() => txPaged.refetch()} />\n ) : transactions.length === 0 ? (\n <EmptyState\n icon={<Receipt className=\"size-6\" aria-hidden=\"true\" />}\n title=\"No transactions\"\n description=\"Record a transaction to see activity here.\"\n action={\n <Button size=\"sm\" onClick={onRecordTransaction}>\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n Record transaction\n </Button>\n }\n />\n ) : (\n <div className=\"space-y-2\">\n {transactions.map((tx) => {\n const inflow = isInflow(tx.type);\n const Icon = inflow ? ArrowUpRight : ArrowDownRight;\n const tone = inflow ? 'text-status-success-text' : 'text-status-error-text';\n return (\n <div\n key={tx.id}\n className=\"flex items-center justify-between rounded-lg border border-border-subtle bg-bg-surface p-3\"\n >\n <div className=\"min-w-0\">\n <div className=\"flex items-center gap-2\">\n <Badge variant=\"outline\">{tx.type.replace(/_/g, ' ')}</Badge>\n {tx.symbol ? (\n <span className=\"truncate text-xs text-text-secondary\">\n {tx.symbol}\n </span>\n ) : null}\n </div>\n <p className=\"mt-1 text-xs text-text-secondary\">\n {formatDate(tx.tradeDate)}\n </p>\n </div>\n <span\n className={`inline-flex items-center gap-1 text-sm font-semibold ${tone}`}\n >\n <Icon className=\"size-4\" aria-hidden=\"true\" />\n {inflow ? '+' : '−'}\n {formatMoney(Math.abs(tx.amount), tx.currency)}\n </span>\n </div>\n );\n })}\n <LoadMore\n hasMore={txPaged.hasMore}\n onClick={txPaged.loadMore}\n loading={txPaged.isFetchingNextPage}\n />\n </div>\n )}\n </div>\n\n {/* Documents — statements, KYC, tax packs (wspace-files reuse) */}\n <div className=\"space-y-3\">\n <DocumentsPanel entityType=\"brainyrich-account\" entityId={account.id} />\n </div>\n </div>\n )}\n </SheetContent>\n </Sheet>\n );\n}\n"],"mappings":"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"}
|