@burdenoff/microfe-brainyrich 2026.512.1 → 2026.705.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.
Files changed (109) hide show
  1. package/dist/brainyrich/BrainyRichRoot.js +53 -88
  2. package/dist/brainyrich/BrainyRichRoot.js.map +1 -1
  3. package/dist/brainyrich/BrainyRichRoutes.js +15 -35
  4. package/dist/brainyrich/BrainyRichRoutes.js.map +1 -1
  5. package/dist/brainyrich/hooks/useBrainyRichApi.js +543 -0
  6. package/dist/brainyrich/hooks/useBrainyRichApi.js.map +1 -0
  7. package/dist/brainyrich/index.js +0 -1
  8. package/dist/brainyrich/pages/AccountsPage.js +690 -160
  9. package/dist/brainyrich/pages/AccountsPage.js.map +1 -1
  10. package/dist/brainyrich/pages/AiAssistantPage.js +537 -363
  11. package/dist/brainyrich/pages/AiAssistantPage.js.map +1 -1
  12. package/dist/brainyrich/pages/AnalyticsPage.js +587 -268
  13. package/dist/brainyrich/pages/AnalyticsPage.js.map +1 -1
  14. package/dist/brainyrich/pages/DashboardPage.js +350 -232
  15. package/dist/brainyrich/pages/DashboardPage.js.map +1 -1
  16. package/dist/brainyrich/pages/FamilyPage.js +550 -337
  17. package/dist/brainyrich/pages/FamilyPage.js.map +1 -1
  18. package/dist/brainyrich/pages/GoalsPage.js +775 -142
  19. package/dist/brainyrich/pages/GoalsPage.js.map +1 -1
  20. package/dist/brainyrich/pages/InvestmentsPage.js +410 -311
  21. package/dist/brainyrich/pages/InvestmentsPage.js.map +1 -1
  22. package/dist/brainyrich/pages/PortfoliosPage.js +823 -154
  23. package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
  24. package/dist/brainyrich/pages/ReportsPage.js +388 -251
  25. package/dist/brainyrich/pages/ReportsPage.js.map +1 -1
  26. package/dist/brainyrich/pages/RiskPage.js +411 -196
  27. package/dist/brainyrich/pages/RiskPage.js.map +1 -1
  28. package/dist/brainyrich/pages/TaxPage.js +622 -221
  29. package/dist/brainyrich/pages/TaxPage.js.map +1 -1
  30. package/dist/brainyrich/pages/_shared.js +222 -41
  31. package/dist/brainyrich/pages/_shared.js.map +1 -1
  32. package/dist/index.js +2 -3
  33. package/package.json +1 -1
  34. package/dist/brainyrich/BrainyRichRoot.d.ts +0 -5
  35. package/dist/brainyrich/BrainyRichRoot.d.ts.map +0 -1
  36. package/dist/brainyrich/BrainyRichRoutes.d.ts +0 -2
  37. package/dist/brainyrich/BrainyRichRoutes.d.ts.map +0 -1
  38. package/dist/brainyrich/index.d.ts +0 -5
  39. package/dist/brainyrich/index.d.ts.map +0 -1
  40. package/dist/brainyrich/pages/AccountsPage.d.ts +0 -2
  41. package/dist/brainyrich/pages/AccountsPage.d.ts.map +0 -1
  42. package/dist/brainyrich/pages/AdvisorsPage.d.ts +0 -2
  43. package/dist/brainyrich/pages/AdvisorsPage.d.ts.map +0 -1
  44. package/dist/brainyrich/pages/AdvisorsPage.js +0 -375
  45. package/dist/brainyrich/pages/AdvisorsPage.js.map +0 -1
  46. package/dist/brainyrich/pages/AiAssistantPage.d.ts +0 -2
  47. package/dist/brainyrich/pages/AiAssistantPage.d.ts.map +0 -1
  48. package/dist/brainyrich/pages/AnalyticsPage.d.ts +0 -2
  49. package/dist/brainyrich/pages/AnalyticsPage.d.ts.map +0 -1
  50. package/dist/brainyrich/pages/AssistantPage.d.ts +0 -2
  51. package/dist/brainyrich/pages/AssistantPage.d.ts.map +0 -1
  52. package/dist/brainyrich/pages/AssistantPage.js +0 -332
  53. package/dist/brainyrich/pages/AssistantPage.js.map +0 -1
  54. package/dist/brainyrich/pages/DashboardPage.d.ts +0 -2
  55. package/dist/brainyrich/pages/DashboardPage.d.ts.map +0 -1
  56. package/dist/brainyrich/pages/EstatePage.d.ts +0 -2
  57. package/dist/brainyrich/pages/EstatePage.d.ts.map +0 -1
  58. package/dist/brainyrich/pages/EstatePage.js +0 -269
  59. package/dist/brainyrich/pages/EstatePage.js.map +0 -1
  60. package/dist/brainyrich/pages/FamilyPage.d.ts +0 -2
  61. package/dist/brainyrich/pages/FamilyPage.d.ts.map +0 -1
  62. package/dist/brainyrich/pages/GoalsPage.d.ts +0 -2
  63. package/dist/brainyrich/pages/GoalsPage.d.ts.map +0 -1
  64. package/dist/brainyrich/pages/InsurancePage.d.ts +0 -2
  65. package/dist/brainyrich/pages/InsurancePage.d.ts.map +0 -1
  66. package/dist/brainyrich/pages/InsurancePage.js +0 -181
  67. package/dist/brainyrich/pages/InsurancePage.js.map +0 -1
  68. package/dist/brainyrich/pages/InvestmentsPage.d.ts +0 -2
  69. package/dist/brainyrich/pages/InvestmentsPage.d.ts.map +0 -1
  70. package/dist/brainyrich/pages/MarketplacePage.d.ts +0 -2
  71. package/dist/brainyrich/pages/MarketplacePage.d.ts.map +0 -1
  72. package/dist/brainyrich/pages/MarketplacePage.js +0 -450
  73. package/dist/brainyrich/pages/MarketplacePage.js.map +0 -1
  74. package/dist/brainyrich/pages/PortfoliosPage.d.ts +0 -2
  75. package/dist/brainyrich/pages/PortfoliosPage.d.ts.map +0 -1
  76. package/dist/brainyrich/pages/ReportsPage.d.ts +0 -2
  77. package/dist/brainyrich/pages/ReportsPage.d.ts.map +0 -1
  78. package/dist/brainyrich/pages/RiskPage.d.ts +0 -2
  79. package/dist/brainyrich/pages/RiskPage.d.ts.map +0 -1
  80. package/dist/brainyrich/pages/TaxPage.d.ts +0 -2
  81. package/dist/brainyrich/pages/TaxPage.d.ts.map +0 -1
  82. package/dist/brainyrich/pages/_shared.d.ts +0 -21
  83. package/dist/brainyrich/pages/_shared.d.ts.map +0 -1
  84. package/dist/brainyrich/providers/BrainyRichProvider.d.ts +0 -6
  85. package/dist/brainyrich/providers/BrainyRichProvider.d.ts.map +0 -1
  86. package/dist/brainyrich/store/brainyrichStore.d.ts +0 -19
  87. package/dist/brainyrich/store/brainyrichStore.d.ts.map +0 -1
  88. package/dist/brainyrich/store/brainyrichStore.js +0 -272
  89. package/dist/brainyrich/store/brainyrichStore.js.map +0 -1
  90. package/dist/brainyrich/types/index.d.ts +0 -116
  91. package/dist/brainyrich/types/index.d.ts.map +0 -1
  92. package/dist/brainyrich/utils/cn.d.ts +0 -4
  93. package/dist/brainyrich/utils/cn.d.ts.map +0 -1
  94. package/dist/brainyrich/utils/i18n.d.ts +0 -6
  95. package/dist/brainyrich/utils/i18n.d.ts.map +0 -1
  96. package/dist/brainyrich/utils/navigation.d.ts +0 -2
  97. package/dist/brainyrich/utils/navigation.d.ts.map +0 -1
  98. package/dist/dev/main.d.ts +0 -2
  99. package/dist/dev/main.d.ts.map +0 -1
  100. package/dist/generated/global-operations.d.ts +0 -2
  101. package/dist/generated/global-operations.d.ts.map +0 -1
  102. package/dist/generated/global-types.d.ts +0 -18199
  103. package/dist/generated/global-types.d.ts.map +0 -1
  104. package/dist/generated/wspace-operations.d.ts +0 -2
  105. package/dist/generated/wspace-operations.d.ts.map +0 -1
  106. package/dist/generated/wspace-types.d.ts +0 -43046
  107. package/dist/generated/wspace-types.d.ts.map +0 -1
  108. package/dist/index.d.ts +0 -2
  109. package/dist/index.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"AnalyticsPage.js","names":[],"sources":["../../../src/brainyrich/pages/AnalyticsPage.tsx"],"sourcesContent":["import {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n CardDescription,\n Button,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { TrendingUp, TrendingDown, DollarSign, Target, Download, BarChart3 } from 'lucide-react';\nimport { useBrainyRichStore } from '../store/brainyrichStore';\nimport { SectionShell, KpiGrid, formatMoney } from './_shared';\n\nconst performanceData = [\n { month: 'Jan', portfolio: 910000, benchmark: 895000 },\n { month: 'Feb', portfolio: 928000, benchmark: 910000 },\n { month: 'Mar', portfolio: 922000, benchmark: 905000 },\n { month: 'Apr', portfolio: 945000, benchmark: 920000 },\n { month: 'May', portfolio: 948000, benchmark: 925000 },\n { month: 'Jun', portfolio: 970000, benchmark: 940000 },\n];\n\nconst incomeExpenseData = [\n { month: 'Jan', income: 185000, expenses: 92000, savings: 93000 },\n { month: 'Feb', income: 185000, expenses: 98000, savings: 87000 },\n { month: 'Mar', income: 195000, expenses: 88000, savings: 107000 },\n { month: 'Apr', income: 185000, expenses: 95000, savings: 90000 },\n { month: 'May', income: 185000, expenses: 91000, savings: 94000 },\n { month: 'Jun', income: 200000, expenses: 99000, savings: 101000 },\n];\n\nconst maxPortfolio = Math.max(...performanceData.map((d) => d.portfolio));\nconst maxIncome = Math.max(...incomeExpenseData.map((d) => d.income));\n\nexport function AnalyticsPage() {\n const { portfolios, holdings } = useBrainyRichStore();\n const totalValue = portfolios.reduce((s, p) => s + p.value, 0);\n\n return (\n <SectionShell\n title=\"Wealth Analytics\"\n description=\"Comprehensive insights into your wealth performance and financial flows\"\n actionLabel=\"Export PDF\"\n badges={['Live Analytics']}\n >\n <KpiGrid\n items={[\n { label: 'Total Returns', value: '+12.4%', trend: '+2.3% vs last month' },\n { label: 'Portfolio Value', value: formatMoney(totalValue), trend: '+$85K YTD' },\n { label: 'Monthly Savings', value: formatMoney(94000), trend: '51% savings rate' },\n { label: 'Goals Progress', value: '68%', trend: '+7.4% this quarter' },\n ]}\n />\n\n <Tabs defaultValue=\"performance\" className=\"space-y-4\">\n <TabsList className=\"grid w-full grid-cols-3\">\n <TabsTrigger value=\"performance\">Performance</TabsTrigger>\n <TabsTrigger value=\"allocation\">Allocation</TabsTrigger>\n <TabsTrigger value=\"cashflow\">Cash Flow</TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"performance\" className=\"space-y-4\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <div>\n <CardTitle>Portfolio vs Benchmark</CardTitle>\n <CardDescription>6-month performance comparison (CSS bar chart)</CardDescription>\n </div>\n <Button variant=\"outline\" size=\"sm\">\n <Download className=\"mr-1 h-4 w-4\" />\n Export\n </Button>\n </CardHeader>\n <CardContent className=\"space-y-3\">\n {performanceData.map((d) => (\n <div key={d.month} className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-xs text-muted-foreground\">\n <span className=\"w-8 font-medium\">{d.month}</span>\n <span>\n Portfolio: {formatMoney(d.portfolio)} | Benchmark: {formatMoney(d.benchmark)}\n </span>\n </div>\n <div className=\"relative h-5 bg-muted rounded overflow-hidden\">\n <div\n className=\"absolute h-5 bg-blue-400/60 rounded\"\n style={{ width: `${(d.benchmark / maxPortfolio) * 100}%` }}\n />\n <div\n className=\"absolute h-5 bg-blue-600 rounded\"\n style={{ width: `${(d.portfolio / maxPortfolio) * 100}%`, opacity: 0.8 }}\n />\n </div>\n </div>\n ))}\n <div className=\"flex gap-4 text-xs pt-2\">\n <span className=\"flex items-center gap-1\">\n <span className=\"h-2 w-4 bg-blue-600 rounded inline-block\" /> Portfolio\n </span>\n <span className=\"flex items-center gap-1\">\n <span className=\"h-2 w-4 bg-blue-400/60 rounded inline-block\" /> Benchmark\n </span>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Net Worth Trend</CardTitle>\n <CardDescription>Growth trajectory over the past 6 months</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {performanceData.map((d) => (\n <div key={d.month} className=\"flex items-center gap-3\">\n <span className=\"w-8 text-xs text-muted-foreground\">{d.month}</span>\n <div className=\"flex-1 h-4 bg-muted rounded overflow-hidden\">\n <div\n className=\"h-4 bg-emerald-500 rounded\"\n style={{ width: `${(d.portfolio / maxPortfolio) * 100}%` }}\n />\n </div>\n <span className=\"text-xs font-medium w-20 text-right\">\n {formatMoney(d.portfolio)}\n </span>\n </div>\n ))}\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"allocation\" className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle>Asset Allocation</CardTitle>\n <CardDescription>Current distribution by portfolio strategy</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {portfolios.map((p) => {\n const pct = Math.round((p.value / totalValue) * 100);\n return (\n <div key={p.id} className=\"space-y-1\">\n <div className=\"flex justify-between text-sm\">\n <span className=\"font-medium\">{p.name}</span>\n <span>\n {formatMoney(p.value)} ({pct}%)\n </span>\n </div>\n <div className=\"h-4 rounded bg-muted overflow-hidden\">\n <div className=\"h-4 rounded bg-primary\" style={{ width: `${pct}%` }} />\n </div>\n </div>\n );\n })}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle>Sector Exposure</CardTitle>\n <CardDescription>Breakdown by sector from holdings</CardDescription>\n </CardHeader>\n <CardContent>\n <div className=\"grid gap-3 md:grid-cols-2\">\n {holdings.map((h) => (\n <div\n key={h.symbol}\n className=\"flex items-center justify-between rounded-lg border p-3\"\n >\n <div>\n <p className=\"text-sm font-medium\">{h.symbol}</p>\n <p className=\"text-xs text-muted-foreground\">{h.sector}</p>\n </div>\n <span className=\"text-sm font-semibold\">{formatMoney(h.marketValue)}</span>\n </div>\n ))}\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"cashflow\" className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <BarChart3 className=\"h-5 w-5\" />\n Income vs Expenses\n </CardTitle>\n <CardDescription>Monthly financial flow analysis</CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {incomeExpenseData.map((d) => (\n <div key={d.month} className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"font-medium w-8\">{d.month}</span>\n <span className=\"text-emerald-600\">Income: {formatMoney(d.income)}</span>\n <span className=\"text-red-500\">Expenses: {formatMoney(d.expenses)}</span>\n <span className=\"text-blue-600\">Saved: {formatMoney(d.savings)}</span>\n </div>\n <div className=\"flex gap-1\">\n <div\n className=\"h-3 rounded bg-emerald-500\"\n style={{ width: `${(d.income / maxIncome) * 50}%` }}\n />\n <div\n className=\"h-3 rounded bg-red-400\"\n style={{ width: `${(d.expenses / maxIncome) * 50}%` }}\n />\n <div\n className=\"h-3 rounded bg-blue-500\"\n style={{ width: `${(d.savings / maxIncome) * 50}%` }}\n />\n </div>\n </div>\n ))}\n <div className=\"flex gap-4 text-xs pt-2\">\n <span className=\"flex items-center gap-1\">\n <span className=\"h-2 w-4 bg-emerald-500 rounded inline-block\" /> Income\n </span>\n <span className=\"flex items-center gap-1\">\n <span className=\"h-2 w-4 bg-red-400 rounded inline-block\" /> Expenses\n </span>\n <span className=\"flex items-center gap-1\">\n <span className=\"h-2 w-4 bg-blue-500 rounded inline-block\" /> Savings\n </span>\n </div>\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </SectionShell>\n );\n}\n"],"mappings":";;;;;;AAgBA,IAAM,IAAkB;CACtB;EAAE,OAAO;EAAO,WAAW;EAAQ,WAAW;EAAQ;CACtD;EAAE,OAAO;EAAO,WAAW;EAAQ,WAAW;EAAQ;CACtD;EAAE,OAAO;EAAO,WAAW;EAAQ,WAAW;EAAQ;CACtD;EAAE,OAAO;EAAO,WAAW;EAAQ,WAAW;EAAQ;CACtD;EAAE,OAAO;EAAO,WAAW;EAAQ,WAAW;EAAQ;CACtD;EAAE,OAAO;EAAO,WAAW;EAAQ,WAAW;EAAQ;CACvD,EAEK,IAAoB;CACxB;EAAE,OAAO;EAAO,QAAQ;EAAQ,UAAU;EAAO,SAAS;EAAO;CACjE;EAAE,OAAO;EAAO,QAAQ;EAAQ,UAAU;EAAO,SAAS;EAAO;CACjE;EAAE,OAAO;EAAO,QAAQ;EAAQ,UAAU;EAAO,SAAS;EAAQ;CAClE;EAAE,OAAO;EAAO,QAAQ;EAAQ,UAAU;EAAO,SAAS;EAAO;CACjE;EAAE,OAAO;EAAO,QAAQ;EAAQ,UAAU;EAAO,SAAS;EAAO;CACjE;EAAE,OAAO;EAAO,QAAQ;EAAQ,UAAU;EAAO,SAAS;EAAQ;CACnE,EAEK,IAAe,KAAK,IAAI,GAAG,EAAgB,KAAK,MAAM,EAAE,UAAU,CAAC,EACnE,IAAY,KAAK,IAAI,GAAG,EAAkB,KAAK,MAAM,EAAE,OAAO,CAAC;AAErE,SAAgB,IAAgB;CAC9B,IAAM,EAAE,eAAY,gBAAa,GAAoB,EAC/C,IAAa,EAAW,QAAQ,GAAG,MAAM,IAAI,EAAE,OAAO,EAAE;AAE9D,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,aAAY;EACZ,QAAQ,CAAC,iBAAiB;YAJ5B,CAME,kBAAC,GAAD,EACE,OAAO;GACL;IAAE,OAAO;IAAiB,OAAO;IAAU,OAAO;IAAuB;GACzE;IAAE,OAAO;IAAmB,OAAO,EAAY,EAAW;IAAE,OAAO;IAAa;GAChF;IAAE,OAAO;IAAmB,OAAO,EAAY,KAAM;IAAE,OAAO;IAAoB;GAClF;IAAE,OAAO;IAAkB,OAAO;IAAO,OAAO;IAAsB;GACvE,EACD,CAAA,EAEF,kBAAC,GAAD;GAAM,cAAa;GAAc,WAAU;aAA3C;IACE,kBAAC,GAAD;KAAU,WAAU;eAApB;MACE,kBAAC,GAAD;OAAa,OAAM;iBAAc;OAAyB,CAAA;MAC1D,kBAAC,GAAD;OAAa,OAAM;iBAAa;OAAwB,CAAA;MACxD,kBAAC,GAAD;OAAa,OAAM;iBAAW;OAAuB,CAAA;MAC5C;;IAEX,kBAAC,GAAD;KAAa,OAAM;KAAc,WAAU;eAA3C,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAY,WAAU;gBAAtB,CACE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAW,0BAAkC,CAAA,EAC7C,kBAAC,GAAD,EAAA,UAAiB,kDAAgE,CAAA,CAC7E,EAAA,CAAA,EACN,kBAAC,GAAD;OAAQ,SAAQ;OAAU,MAAK;iBAA/B,CACE,kBAAC,GAAD,EAAU,WAAU,gBAAiB,CAAA,EAAA,SAE9B;SACE;SACb,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACG,EAAgB,KAAK,MACpB,kBAAC,OAAD;OAAmB,WAAU;iBAA7B,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,QAAD;SAAM,WAAU;mBAAmB,EAAE;SAAa,CAAA,EAClD,kBAAC,QAAD,EAAA,UAAA;SAAM;SACQ,EAAY,EAAE,UAAU;SAAC;SAAe,EAAY,EAAE,UAAU;SACvE,EAAA,CAAA,CACH;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,OAAD;SACE,WAAU;SACV,OAAO,EAAE,OAAO,GAAI,EAAE,YAAY,IAAgB,IAAI,IAAI;SAC1D,CAAA,EACF,kBAAC,OAAD;SACE,WAAU;SACV,OAAO;UAAE,OAAO,GAAI,EAAE,YAAY,IAAgB,IAAI;UAAI,SAAS;UAAK;SACxE,CAAA,CACE;UACF;SAjBI,EAAE,MAiBN,CACN,EACF,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,QAAD;QAAM,WAAU;kBAAhB,CACE,kBAAC,QAAD,EAAM,WAAU,4CAA6C,CAAA,EAAA,aACxD;WACP,kBAAC,QAAD;QAAM,WAAU;kBAAhB,CACE,kBAAC,QAAD,EAAM,WAAU,+CAAgD,CAAA,EAAA,aAC3D;UACH;SACM;QACT,EAAA,CAAA,EAEP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAW,mBAA2B,CAAA,EACtC,kBAAC,GAAD,EAAA,UAAiB,4CAA0D,CAAA,CAChE,EAAA,CAAA,EACb,kBAAC,GAAD;MAAa,WAAU;gBACpB,EAAgB,KAAK,MACpB,kBAAC,OAAD;OAAmB,WAAU;iBAA7B;QACE,kBAAC,QAAD;SAAM,WAAU;mBAAqC,EAAE;SAAa,CAAA;QACpE,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,OAAD;UACE,WAAU;UACV,OAAO,EAAE,OAAO,GAAI,EAAE,YAAY,IAAgB,IAAI,IAAI;UAC1D,CAAA;SACE,CAAA;QACN,kBAAC,QAAD;SAAM,WAAU;mBACb,EAAY,EAAE,UAAU;SACpB,CAAA;QACH;SAXI,EAAE,MAWN,CACN;MACU,CAAA,CACT,EAAA,CAAA,CACK;;IAEd,kBAAC,GAAD;KAAa,OAAM;KAAa,WAAU;eAA1C,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAW,oBAA4B,CAAA,EACvC,kBAAC,GAAD,EAAA,UAAiB,8CAA4D,CAAA,CAClE,EAAA,CAAA,EACb,kBAAC,GAAD;MAAa,WAAU;gBACpB,EAAW,KAAK,MAAM;OACrB,IAAM,IAAM,KAAK,MAAO,EAAE,QAAQ,IAAc,IAAI;AACpD,cACE,kBAAC,OAAD;QAAgB,WAAU;kBAA1B,CACE,kBAAC,OAAD;SAAK,WAAU;mBAAf,CACE,kBAAC,QAAD;UAAM,WAAU;oBAAe,EAAE;UAAY,CAAA,EAC7C,kBAAC,QAAD,EAAA,UAAA;UACG,EAAY,EAAE,MAAM;UAAC;UAAG;UAAI;UACxB,EAAA,CAAA,CACH;YACN,kBAAC,OAAD;SAAK,WAAU;mBACb,kBAAC,OAAD;UAAK,WAAU;UAAyB,OAAO,EAAE,OAAO,GAAG,EAAI,IAAI;UAAI,CAAA;SACnE,CAAA,CACF;UAVI,EAAE,GAUN;QAER;MACU,CAAA,CACT,EAAA,CAAA,EAEP,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAW,mBAA2B,CAAA,EACtC,kBAAC,GAAD,EAAA,UAAiB,qCAAmD,CAAA,CACzD,EAAA,CAAA,EACb,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAS,KAAK,MACb,kBAAC,OAAD;OAEE,WAAU;iBAFZ,CAIE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,KAAD;QAAG,WAAU;kBAAuB,EAAE;QAAW,CAAA,EACjD,kBAAC,KAAD;QAAG,WAAU;kBAAiC,EAAE;QAAW,CAAA,CACvD,EAAA,CAAA,EACN,kBAAC,QAAD;QAAM,WAAU;kBAAyB,EAAY,EAAE,YAAY;QAAQ,CAAA,CACvE;SARC,EAAE,OAQH,CACN;MACE,CAAA,EACM,CAAA,CACT,EAAA,CAAA,CACK;;IAEd,kBAAC,GAAD;KAAa,OAAM;KAAW,WAAU;eACtC,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;MAAW,WAAU;gBAArB,CACE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,qBAEvB;SACZ,kBAAC,GAAD,EAAA,UAAiB,mCAAiD,CAAA,CACvD,EAAA,CAAA,EACb,kBAAC,GAAD;MAAa,WAAU;gBAAvB,CACG,EAAkB,KAAK,MACtB,kBAAC,OAAD;OAAmB,WAAU;iBAA7B,CACE,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,QAAD;UAAM,WAAU;oBAAmB,EAAE;UAAa,CAAA;SAClD,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CAAmC,YAAS,EAAY,EAAE,OAAO,CAAQ;;SACzE,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CAA+B,cAAW,EAAY,EAAE,SAAS,CAAQ;;SACzE,kBAAC,QAAD;UAAM,WAAU;oBAAhB,CAAgC,WAAQ,EAAY,EAAE,QAAQ,CAAQ;;SAClE;WACN,kBAAC,OAAD;QAAK,WAAU;kBAAf;SACE,kBAAC,OAAD;UACE,WAAU;UACV,OAAO,EAAE,OAAO,GAAI,EAAE,SAAS,IAAa,GAAG,IAAI;UACnD,CAAA;SACF,kBAAC,OAAD;UACE,WAAU;UACV,OAAO,EAAE,OAAO,GAAI,EAAE,WAAW,IAAa,GAAG,IAAI;UACrD,CAAA;SACF,kBAAC,OAAD;UACE,WAAU;UACV,OAAO,EAAE,OAAO,GAAI,EAAE,UAAU,IAAa,GAAG,IAAI;UACpD,CAAA;SACE;UACF;SArBI,EAAE,MAqBN,CACN,EACF,kBAAC,OAAD;OAAK,WAAU;iBAAf;QACE,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CACE,kBAAC,QAAD,EAAM,WAAU,+CAAgD,CAAA,EAAA,UAC3D;;QACP,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CACE,kBAAC,QAAD,EAAM,WAAU,2CAA4C,CAAA,EAAA,YACvD;;QACP,kBAAC,QAAD;SAAM,WAAU;mBAAhB,CACE,kBAAC,QAAD,EAAM,WAAU,4CAA6C,CAAA,EAAA,WACxD;;QACH;SACM;QACT,EAAA,CAAA;KACK,CAAA;IACT;KACM"}
1
+ {"version":3,"file":"AnalyticsPage.js","names":[],"sources":["../../../src/brainyrich/pages/AnalyticsPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n CardDescription,\n Button,\n Badge,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n Input,\n Label,\n Textarea,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@burdenoff/fe-libs/ui';\nimport {\n ArrowDownRight,\n ArrowUpRight,\n BarChart3,\n Minus,\n PieChart,\n Plus,\n Wallet,\n} from 'lucide-react';\nimport {\n useNetWorthSummary,\n useTransactions,\n useAccounts,\n useHoldings,\n useRecordTransaction,\n} from '../hooks/useBrainyRichApi';\nimport type {\n BraAssetClass,\n BraHolding,\n BraTransaction,\n BraTransactionType,\n} from '../types/bra';\nimport {\n SectionShell,\n KpiGrid,\n AllocationBars,\n EmptyState,\n LoadingState,\n ErrorState,\n formatMoney,\n formatPct,\n formatDate,\n} from './_shared';\nimport type { AllocationDatum } from './_shared';\n\n// ---------------------------------------------------------------------------\n// Pure derivation helpers (every value traces back to backend rows — no mocks)\n// ---------------------------------------------------------------------------\n\nconst TITLE_CASE = (raw: string): string =>\n raw\n .toLowerCase()\n .split('_')\n .map((w) => (w ? w[0].toUpperCase() + w.slice(1) : w))\n .join(' ');\n\nconst INFLOW_TYPES: readonly BraTransactionType[] = ['DEPOSIT', 'DIVIDEND', 'INTEREST', 'SELL'];\nconst OUTFLOW_TYPES: readonly BraTransactionType[] = ['WITHDRAWAL', 'FEE', 'BUY'];\n\nconst flowDirection = (type: BraTransactionType): 'in' | 'out' | 'neutral' => {\n if (INFLOW_TYPES.includes(type)) return 'in';\n if (OUTFLOW_TYPES.includes(type)) return 'out';\n return 'neutral';\n};\n\ninterface MonthFlow {\n key: string;\n label: string;\n inflow: number;\n outflow: number;\n}\n\nconst monthKey = (iso: string): { key: string; label: string } | null => {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return null;\n const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}`;\n const label = new Intl.DateTimeFormat('en-US', { month: 'short', year: 'numeric' }).format(d);\n return { key, label };\n};\n\nconst aggregateByMonth = (transactions: BraTransaction[]): MonthFlow[] => {\n const buckets = new Map<string, MonthFlow>();\n for (const tx of transactions) {\n const parsed = monthKey(tx.tradeDate);\n if (!parsed) continue;\n const dir = flowDirection(tx.type);\n if (dir === 'neutral') continue;\n const value = Math.abs(tx.amount);\n const existing = buckets.get(parsed.key) ?? {\n key: parsed.key,\n label: parsed.label,\n inflow: 0,\n outflow: 0,\n };\n if (dir === 'in') existing.inflow += value;\n else existing.outflow += value;\n buckets.set(parsed.key, existing);\n }\n return Array.from(buckets.values()).sort((a, b) => a.key.localeCompare(b.key));\n};\n\nconst aggregateByType = (\n transactions: BraTransaction[]\n): Array<{ type: BraTransactionType; total: number; dir: 'in' | 'out' | 'neutral' }> => {\n const buckets = new Map<BraTransactionType, number>();\n for (const tx of transactions) {\n buckets.set(tx.type, (buckets.get(tx.type) ?? 0) + Math.abs(tx.amount));\n }\n return Array.from(buckets.entries())\n .map(([type, total]) => ({ type, total, dir: flowDirection(type) }))\n .sort((a, b) => b.total - a.total);\n};\n\n// ---------------------------------------------------------------------------\n// Signed gain/loss cell — color is never the only signal (icon + sign + color)\n// ---------------------------------------------------------------------------\n\nfunction GainCell({ value, currency }: { value: number; currency: string }) {\n const positive = value > 0;\n const negative = value < 0;\n const Icon = positive ? ArrowUpRight : negative ? ArrowDownRight : Minus;\n const tone = positive\n ? 'text-status-success-text'\n : negative\n ? 'text-status-error-text'\n : 'text-text-secondary';\n const sign = positive ? '+' : negative ? '-' : '';\n return (\n <span className={`inline-flex items-center justify-end gap-1 font-medium ${tone}`}>\n <Icon className=\"size-3.5\" aria-hidden=\"true\" />\n {sign}\n {formatMoney(Math.abs(value), currency)}\n </span>\n );\n}\n\nconst emptyTransactionForm = {\n accountId: '',\n type: 'DEPOSIT' as BraTransactionType,\n amount: '',\n symbol: '',\n tradeDate: '',\n notes: '',\n};\n\nconst TRANSACTION_TYPES: readonly BraTransactionType[] = [\n 'DEPOSIT',\n 'WITHDRAWAL',\n 'DIVIDEND',\n 'INTEREST',\n 'FEE',\n 'BUY',\n 'SELL',\n 'TRANSFER',\n];\n\nexport function AnalyticsPage() {\n const summaryQuery = useNetWorthSummary();\n const txQuery = useTransactions();\n const accountsQuery = useAccounts();\n\n const [selectedAccountId, setSelectedAccountId] = useState<string | undefined>(undefined);\n const accounts = accountsQuery.data;\n const effectiveAccountId = selectedAccountId ?? accounts[0]?.id;\n const holdingsQuery = useHoldings({ accountId: effectiveAccountId });\n\n // Record-transaction dialog (real create action → refreshes cashflow)\n const recordTx = useRecordTransaction();\n const [dialogOpen, setDialogOpen] = useState(false);\n const [form, setForm] = useState(emptyTransactionForm);\n\n const summary = summaryQuery.data;\n const currency = summary?.currency ?? 'USD';\n const transactions = txQuery.data;\n\n const assetAllocation = useMemo<AllocationDatum[]>(() => {\n if (!summary || summary.totalMarketValue <= 0) return [];\n return summary.byAssetClass\n .filter((row) => row.marketValue !== 0)\n .map((row) => ({\n label: TITLE_CASE(row.assetClass as BraAssetClass),\n value: (row.marketValue / summary.totalMarketValue) * 100,\n caption: formatMoney(row.marketValue, currency),\n tone: 'accent' as const,\n }))\n .sort((a, b) => b.value - a.value);\n }, [summary, currency]);\n\n const composition = useMemo<AllocationDatum[]>(() => {\n if (!summary) return [];\n const base = summary.totalMarketValue + summary.totalCash;\n if (base <= 0) return [];\n return [\n {\n label: 'Invested (Market Value)',\n value: (summary.totalMarketValue / base) * 100,\n caption: formatMoney(summary.totalMarketValue, currency),\n tone: 'default' as const,\n },\n {\n label: 'Cash',\n value: (summary.totalCash / base) * 100,\n caption: formatMoney(summary.totalCash, currency),\n tone: 'warning' as const,\n },\n ];\n }, [summary, currency]);\n\n const monthFlows = useMemo(() => aggregateByMonth(transactions), [transactions]);\n const typeFlows = useMemo(() => aggregateByType(transactions), [transactions]);\n const flowTotals = useMemo(() => {\n let inflow = 0;\n let outflow = 0;\n for (const m of monthFlows) {\n inflow += m.inflow;\n outflow += m.outflow;\n }\n return { inflow, outflow, net: inflow - outflow };\n }, [monthFlows]);\n const maxFlow = useMemo(\n () => Math.max(1, ...monthFlows.map((m) => Math.max(m.inflow, m.outflow))),\n [monthFlows]\n );\n\n const holdings = holdingsQuery.data;\n const performance = useMemo(() => {\n const rows = holdings\n .map((h: BraHolding) => ({ holding: h, unrealized: h.marketValue - h.costBasis }))\n .sort((a, b) => b.unrealized - a.unrealized);\n const totalUnrealized = rows.reduce((s, r) => s + r.unrealized, 0);\n const totalCost = holdings.reduce((s, h) => s + h.costBasis, 0);\n return { rows, totalUnrealized, totalCost };\n }, [holdings]);\n\n // --- Top-level loading / error gates (summary drives KPIs + allocation) ---\n if (summaryQuery.isLoading) {\n return (\n <SectionShell\n title=\"Wealth Analytics\"\n description=\"Allocation, cash flow, and holdings performance derived from your real accounts.\"\n >\n <LoadingState rows={5} />\n </SectionShell>\n );\n }\n\n if (summaryQuery.isError || !summary) {\n return (\n <SectionShell\n title=\"Wealth Analytics\"\n description=\"Allocation, cash flow, and holdings performance derived from your real accounts.\"\n >\n <ErrorState\n title=\"Could not load analytics\"\n description=\"We couldn't reach the wealth service. Please retry.\"\n onRetry={() => summaryQuery.refetch()}\n />\n </SectionShell>\n );\n }\n\n const amountNum = Number(form.amount);\n const canSubmit =\n Boolean(form.accountId) &&\n Boolean(form.tradeDate) &&\n form.amount.trim() !== '' &&\n Number.isFinite(amountNum) &&\n amountNum > 0 &&\n !recordTx.isPending;\n\n const submitTransaction = () => {\n if (!canSubmit) return;\n recordTx.mutate(\n {\n accountId: form.accountId,\n type: form.type,\n amount: amountNum,\n symbol: form.symbol.trim() ? form.symbol.trim() : undefined,\n tradeDate: new Date(form.tradeDate).toISOString(),\n notes: form.notes.trim() ? form.notes.trim() : undefined,\n },\n {\n onSuccess: () => {\n setDialogOpen(false);\n setForm(emptyTransactionForm);\n },\n }\n );\n };\n\n const recordAction = (\n <Dialog\n open={dialogOpen}\n onOpenChange={(next) => {\n setDialogOpen(next);\n if (!next) setForm(emptyTransactionForm);\n }}\n >\n <DialogTrigger asChild>\n <Button size=\"sm\" disabled={accounts.length === 0}>\n <Plus className=\"mr-1 size-4\" aria-hidden=\"true\" />\n Record Transaction\n </Button>\n </DialogTrigger>\n <DialogContent>\n <DialogHeader>\n <DialogTitle>Record Transaction</DialogTitle>\n <DialogDescription>\n Log a real cash flow or trade. It updates your cash-flow analytics immediately.\n </DialogDescription>\n </DialogHeader>\n <div className=\"space-y-4\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"tx-account\">Account</Label>\n <Select\n value={form.accountId}\n onValueChange={(v) => setForm((f) => ({ ...f, accountId: v }))}\n >\n <SelectTrigger id=\"tx-account\">\n <SelectValue placeholder=\"Select an account\" />\n </SelectTrigger>\n <SelectContent>\n {accounts.map((a) => (\n <SelectItem key={a.id} value={a.id}>\n {a.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"tx-type\">Type</Label>\n <Select\n value={form.type}\n onValueChange={(v) => setForm((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 {TITLE_CASE(t)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"tx-amount\">Amount ({currency})</Label>\n <Input\n id=\"tx-amount\"\n type=\"number\"\n min=\"0\"\n step=\"0.01\"\n inputMode=\"decimal\"\n placeholder=\"0.00\"\n value={form.amount}\n onChange={(e) => setForm((f) => ({ ...f, amount: e.target.value }))}\n />\n </div>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"tx-date\">Trade date</Label>\n <Input\n id=\"tx-date\"\n type=\"date\"\n value={form.tradeDate}\n onChange={(e) => setForm((f) => ({ ...f, tradeDate: e.target.value }))}\n />\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"tx-symbol\">Symbol (optional)</Label>\n <Input\n id=\"tx-symbol\"\n placeholder=\"e.g. AAPL\"\n value={form.symbol}\n onChange={(e) => setForm((f) => ({ ...f, symbol: e.target.value }))}\n />\n </div>\n </div>\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"tx-notes\">Notes (optional)</Label>\n <Textarea\n id=\"tx-notes\"\n rows={2}\n placeholder=\"Context for this transaction\"\n value={form.notes}\n onChange={(e) => setForm((f) => ({ ...f, notes: e.target.value }))}\n />\n </div>\n {recordTx.isError ? (\n <p className=\"text-sm text-status-error-text\">\n {recordTx.error instanceof Error\n ? recordTx.error.message\n : 'Could not record transaction.'}\n </p>\n ) : null}\n </div>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setDialogOpen(false)}>\n Cancel\n </Button>\n <Button onClick={submitTransaction} disabled={!canSubmit}>\n {recordTx.isPending ? 'Recording…' : 'Record'}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n\n return (\n <SectionShell\n title=\"Wealth Analytics\"\n description=\"Allocation, cash flow, and holdings performance derived from your real accounts.\"\n badges={[`${summary.accountCount} accounts`]}\n actions={recordAction}\n >\n <KpiGrid\n items={[\n { label: 'Net Worth', value: formatMoney(summary.totalNetWorth, currency) },\n { label: 'Invested Value', value: formatMoney(summary.totalMarketValue, currency) },\n { label: 'Cash', value: formatMoney(summary.totalCash, currency) },\n {\n label: 'Net Cash Flow',\n value: formatMoney(flowTotals.net, currency),\n deltaTone:\n flowTotals.net > 0 ? 'positive' : flowTotals.net < 0 ? 'negative' : 'neutral',\n trend:\n transactions.length > 0\n ? `${formatMoney(flowTotals.inflow, currency)} in · ${formatMoney(flowTotals.outflow, currency)} out`\n : 'No transactions yet',\n },\n ]}\n />\n\n <Tabs defaultValue=\"allocation\" className=\"space-y-4\">\n <TabsList className=\"grid w-full grid-cols-3\">\n <TabsTrigger value=\"allocation\">Allocation</TabsTrigger>\n <TabsTrigger value=\"cashflow\">Cash Flow</TabsTrigger>\n <TabsTrigger value=\"performance\">Performance</TabsTrigger>\n </TabsList>\n\n {/* ---------------------------------------------------------------- */}\n {/* Allocation */}\n {/* ---------------------------------------------------------------- */}\n <TabsContent value=\"allocation\" className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <PieChart className=\"size-5\" aria-hidden=\"true\" />\n Asset Allocation\n </CardTitle>\n <CardDescription>\n Share of invested value by asset class, from your holdings.\n </CardDescription>\n </CardHeader>\n <CardContent>\n {assetAllocation.length === 0 ? (\n <EmptyState\n icon={<PieChart className=\"size-6\" aria-hidden=\"true\" />}\n title=\"No invested holdings yet\"\n description=\"Add holdings to your accounts to see an asset-class breakdown here.\"\n />\n ) : (\n <div className=\"space-y-4\">\n <AllocationBars data={assetAllocation} />\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Asset class</TableHead>\n <TableHead className=\"text-right\">Market value</TableHead>\n <TableHead className=\"text-right\">Weight</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {assetAllocation.map((row) => (\n <TableRow key={row.label}>\n <TableCell className=\"font-medium text-text-primary\">\n {row.label}\n </TableCell>\n <TableCell className=\"text-right\">{row.caption}</TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {formatPct(row.value)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Wallet className=\"size-5\" aria-hidden=\"true\" />\n Net Worth Composition\n </CardTitle>\n <CardDescription>Invested value versus liquid cash.</CardDescription>\n </CardHeader>\n <CardContent>\n {composition.length === 0 ? (\n <EmptyState\n icon={<Wallet className=\"size-6\" aria-hidden=\"true\" />}\n title=\"No balances yet\"\n description=\"Add accounts with balances or holdings to see your composition.\"\n />\n ) : (\n <AllocationBars data={composition} />\n )}\n </CardContent>\n </Card>\n </TabsContent>\n\n {/* ---------------------------------------------------------------- */}\n {/* Cash flow */}\n {/* ---------------------------------------------------------------- */}\n <TabsContent value=\"cashflow\" className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <BarChart3 className=\"size-5\" aria-hidden=\"true\" />\n Inflows vs Outflows\n </CardTitle>\n <CardDescription>\n Monthly cash flow aggregated from your recorded transactions.\n </CardDescription>\n </CardHeader>\n <CardContent>\n {txQuery.isLoading ? (\n <LoadingState rows={4} />\n ) : txQuery.isError ? (\n <ErrorState onRetry={() => txQuery.refetch()} />\n ) : monthFlows.length === 0 ? (\n <EmptyState\n icon={<BarChart3 className=\"size-6\" aria-hidden=\"true\" />}\n title=\"No cash flow to analyze yet\"\n description=\"Record deposits, withdrawals, or trades to build a cash-flow history.\"\n action={\n <Button size=\"sm\" onClick={() => setDialogOpen(true)} disabled={accounts.length === 0}>\n <Plus className=\"mr-1 size-4\" aria-hidden=\"true\" />\n Record Transaction\n </Button>\n }\n />\n ) : (\n <div className=\"space-y-4\">\n {monthFlows.map((m) => (\n <div key={m.key} className=\"space-y-1.5\">\n <div className=\"flex items-center justify-between text-xs\">\n <span className=\"font-medium text-text-primary\">{m.label}</span>\n <span className=\"flex gap-3\">\n <span className=\"text-status-success-text\">\n <ArrowUpRight className=\"mr-0.5 inline size-3\" aria-hidden=\"true\" />\n {formatMoney(m.inflow, currency)}\n </span>\n <span className=\"text-status-error-text\">\n <ArrowDownRight className=\"mr-0.5 inline size-3\" aria-hidden=\"true\" />\n {formatMoney(m.outflow, currency)}\n </span>\n </span>\n </div>\n <div\n className=\"h-2 w-full overflow-hidden rounded-full bg-bg-sunken\"\n role=\"progressbar\"\n aria-label={`${m.label} inflow`}\n aria-valuenow={Math.round((m.inflow / maxFlow) * 100)}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div\n className=\"h-full rounded-full bg-status-success-bg motion-safe:transition-[width] motion-safe:duration-200\"\n style={{ width: `${(m.inflow / maxFlow) * 100}%` }}\n />\n </div>\n <div\n className=\"h-2 w-full overflow-hidden rounded-full bg-bg-sunken\"\n role=\"progressbar\"\n aria-label={`${m.label} outflow`}\n aria-valuenow={Math.round((m.outflow / maxFlow) * 100)}\n aria-valuemin={0}\n aria-valuemax={100}\n >\n <div\n className=\"h-full rounded-full bg-status-error-bg motion-safe:transition-[width] motion-safe:duration-200\"\n style={{ width: `${(m.outflow / maxFlow) * 100}%` }}\n />\n </div>\n </div>\n ))}\n <div className=\"flex flex-wrap gap-4 pt-1 text-xs text-text-secondary\">\n <span className=\"inline-flex items-center gap-1.5\">\n <span className=\"inline-block size-2.5 rounded-full bg-status-success-bg\" />\n Inflow\n </span>\n <span className=\"inline-flex items-center gap-1.5\">\n <span className=\"inline-block size-2.5 rounded-full bg-status-error-bg\" />\n Outflow\n </span>\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n\n {typeFlows.length > 0 ? (\n <Card>\n <CardHeader>\n <CardTitle>By Transaction Type</CardTitle>\n <CardDescription>Total value moved per transaction type.</CardDescription>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Type</TableHead>\n <TableHead>Direction</TableHead>\n <TableHead className=\"text-right\">Total</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {typeFlows.map((row) => (\n <TableRow key={row.type}>\n <TableCell className=\"font-medium text-text-primary\">\n {TITLE_CASE(row.type)}\n </TableCell>\n <TableCell>\n <Badge\n variant={\n row.dir === 'in'\n ? 'default'\n : row.dir === 'out'\n ? 'destructive'\n : 'secondary'\n }\n >\n {row.dir === 'in' ? 'Inflow' : row.dir === 'out' ? 'Outflow' : 'Neutral'}\n </Badge>\n </TableCell>\n <TableCell className=\"text-right font-medium\">\n {formatMoney(row.total, currency)}\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n ) : null}\n </TabsContent>\n\n {/* ---------------------------------------------------------------- */}\n {/* Performance */}\n {/* ---------------------------------------------------------------- */}\n <TabsContent value=\"performance\" className=\"space-y-4\">\n <Card>\n <CardHeader className=\"flex flex-col gap-3 md:flex-row md:items-start md:justify-between\">\n <div>\n <CardTitle>Holdings Performance</CardTitle>\n <CardDescription>\n Unrealized gain or loss — market value versus cost basis.\n </CardDescription>\n </div>\n {accounts.length > 0 ? (\n <div className=\"w-full md:w-56\">\n <Label htmlFor=\"perf-account\" className=\"sr-only\">\n Account\n </Label>\n <Select\n value={effectiveAccountId ?? ''}\n onValueChange={(v) => setSelectedAccountId(v)}\n >\n <SelectTrigger id=\"perf-account\">\n <SelectValue placeholder=\"Select account\" />\n </SelectTrigger>\n <SelectContent>\n {accounts.map((a) => (\n <SelectItem key={a.id} value={a.id}>\n {a.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n ) : null}\n </CardHeader>\n <CardContent>\n {accountsQuery.isLoading ? (\n <LoadingState rows={3} />\n ) : accounts.length === 0 ? (\n <EmptyState\n icon={<Wallet className=\"size-6\" aria-hidden=\"true\" />}\n title=\"No accounts yet\"\n description=\"Create an account and add holdings to analyze performance.\"\n />\n ) : holdingsQuery.isLoading ? (\n <LoadingState rows={3} />\n ) : holdingsQuery.isError ? (\n <ErrorState onRetry={() => holdingsQuery.refetch()} />\n ) : performance.rows.length === 0 ? (\n <EmptyState\n icon={<BarChart3 className=\"size-6\" aria-hidden=\"true\" />}\n title=\"No holdings in this account\"\n description=\"Add holdings to this account to see unrealized gains and losses.\"\n />\n ) : (\n <div className=\"space-y-4\">\n <div className=\"grid gap-4 sm:grid-cols-3\">\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <p className=\"text-xs text-text-secondary\">Total unrealized</p>\n <p className=\"mt-1 text-xl font-semibold\">\n <GainCell value={performance.totalUnrealized} currency={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\">Cost basis</p>\n <p className=\"mt-1 text-xl font-semibold text-text-primary\">\n {formatMoney(performance.totalCost, 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\">Return on cost</p>\n <p className=\"mt-1 text-xl font-semibold text-text-primary\">\n {formatPct(\n performance.totalCost > 0\n ? (performance.totalUnrealized / performance.totalCost) * 100\n : null\n )}\n </p>\n </div>\n </div>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>Holding</TableHead>\n <TableHead className=\"text-right\">Market value</TableHead>\n <TableHead className=\"text-right\">Cost basis</TableHead>\n <TableHead className=\"text-right\">Unrealized</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {performance.rows.map(({ holding, unrealized }) => (\n <TableRow key={holding.id}>\n <TableCell>\n <div className=\"font-medium text-text-primary\">{holding.symbol}</div>\n <div className=\"text-xs text-text-secondary\">\n {holding.name ?? TITLE_CASE(holding.assetClass)} · as of{' '}\n {formatDate(holding.asOf)}\n </div>\n </TableCell>\n <TableCell className=\"text-right\">\n {formatMoney(holding.marketValue, holding.currency)}\n </TableCell>\n <TableCell className=\"text-right text-text-secondary\">\n {formatMoney(holding.costBasis, holding.currency)}\n </TableCell>\n <TableCell className=\"text-right\">\n <GainCell value={unrealized} currency={holding.currency} />\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </div>\n )}\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </SectionShell>\n );\n}\n"],"mappings":"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"}