@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.
- package/dist/brainyrich/BrainyRichRoot.js +53 -88
- package/dist/brainyrich/BrainyRichRoot.js.map +1 -1
- package/dist/brainyrich/BrainyRichRoutes.js +15 -35
- package/dist/brainyrich/BrainyRichRoutes.js.map +1 -1
- package/dist/brainyrich/hooks/useBrainyRichApi.js +543 -0
- package/dist/brainyrich/hooks/useBrainyRichApi.js.map +1 -0
- package/dist/brainyrich/index.js +0 -1
- package/dist/brainyrich/pages/AccountsPage.js +690 -160
- package/dist/brainyrich/pages/AccountsPage.js.map +1 -1
- package/dist/brainyrich/pages/AiAssistantPage.js +537 -363
- package/dist/brainyrich/pages/AiAssistantPage.js.map +1 -1
- package/dist/brainyrich/pages/AnalyticsPage.js +587 -268
- package/dist/brainyrich/pages/AnalyticsPage.js.map +1 -1
- package/dist/brainyrich/pages/DashboardPage.js +350 -232
- package/dist/brainyrich/pages/DashboardPage.js.map +1 -1
- package/dist/brainyrich/pages/FamilyPage.js +550 -337
- package/dist/brainyrich/pages/FamilyPage.js.map +1 -1
- package/dist/brainyrich/pages/GoalsPage.js +775 -142
- package/dist/brainyrich/pages/GoalsPage.js.map +1 -1
- package/dist/brainyrich/pages/InvestmentsPage.js +410 -311
- package/dist/brainyrich/pages/InvestmentsPage.js.map +1 -1
- package/dist/brainyrich/pages/PortfoliosPage.js +823 -154
- package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
- package/dist/brainyrich/pages/ReportsPage.js +388 -251
- package/dist/brainyrich/pages/ReportsPage.js.map +1 -1
- package/dist/brainyrich/pages/RiskPage.js +411 -196
- package/dist/brainyrich/pages/RiskPage.js.map +1 -1
- package/dist/brainyrich/pages/TaxPage.js +622 -221
- package/dist/brainyrich/pages/TaxPage.js.map +1 -1
- package/dist/brainyrich/pages/_shared.js +222 -41
- package/dist/brainyrich/pages/_shared.js.map +1 -1
- package/dist/index.js +2 -3
- package/package.json +1 -1
- package/dist/brainyrich/BrainyRichRoot.d.ts +0 -5
- package/dist/brainyrich/BrainyRichRoot.d.ts.map +0 -1
- package/dist/brainyrich/BrainyRichRoutes.d.ts +0 -2
- package/dist/brainyrich/BrainyRichRoutes.d.ts.map +0 -1
- package/dist/brainyrich/index.d.ts +0 -5
- package/dist/brainyrich/index.d.ts.map +0 -1
- package/dist/brainyrich/pages/AccountsPage.d.ts +0 -2
- package/dist/brainyrich/pages/AccountsPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/AdvisorsPage.d.ts +0 -2
- package/dist/brainyrich/pages/AdvisorsPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/AdvisorsPage.js +0 -375
- package/dist/brainyrich/pages/AdvisorsPage.js.map +0 -1
- package/dist/brainyrich/pages/AiAssistantPage.d.ts +0 -2
- package/dist/brainyrich/pages/AiAssistantPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/AnalyticsPage.d.ts +0 -2
- package/dist/brainyrich/pages/AnalyticsPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/AssistantPage.d.ts +0 -2
- package/dist/brainyrich/pages/AssistantPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/AssistantPage.js +0 -332
- package/dist/brainyrich/pages/AssistantPage.js.map +0 -1
- package/dist/brainyrich/pages/DashboardPage.d.ts +0 -2
- package/dist/brainyrich/pages/DashboardPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/EstatePage.d.ts +0 -2
- package/dist/brainyrich/pages/EstatePage.d.ts.map +0 -1
- package/dist/brainyrich/pages/EstatePage.js +0 -269
- package/dist/brainyrich/pages/EstatePage.js.map +0 -1
- package/dist/brainyrich/pages/FamilyPage.d.ts +0 -2
- package/dist/brainyrich/pages/FamilyPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/GoalsPage.d.ts +0 -2
- package/dist/brainyrich/pages/GoalsPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/InsurancePage.d.ts +0 -2
- package/dist/brainyrich/pages/InsurancePage.d.ts.map +0 -1
- package/dist/brainyrich/pages/InsurancePage.js +0 -181
- package/dist/brainyrich/pages/InsurancePage.js.map +0 -1
- package/dist/brainyrich/pages/InvestmentsPage.d.ts +0 -2
- package/dist/brainyrich/pages/InvestmentsPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/MarketplacePage.d.ts +0 -2
- package/dist/brainyrich/pages/MarketplacePage.d.ts.map +0 -1
- package/dist/brainyrich/pages/MarketplacePage.js +0 -450
- package/dist/brainyrich/pages/MarketplacePage.js.map +0 -1
- package/dist/brainyrich/pages/PortfoliosPage.d.ts +0 -2
- package/dist/brainyrich/pages/PortfoliosPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/ReportsPage.d.ts +0 -2
- package/dist/brainyrich/pages/ReportsPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/RiskPage.d.ts +0 -2
- package/dist/brainyrich/pages/RiskPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/TaxPage.d.ts +0 -2
- package/dist/brainyrich/pages/TaxPage.d.ts.map +0 -1
- package/dist/brainyrich/pages/_shared.d.ts +0 -21
- package/dist/brainyrich/pages/_shared.d.ts.map +0 -1
- package/dist/brainyrich/providers/BrainyRichProvider.d.ts +0 -6
- package/dist/brainyrich/providers/BrainyRichProvider.d.ts.map +0 -1
- package/dist/brainyrich/store/brainyrichStore.d.ts +0 -19
- package/dist/brainyrich/store/brainyrichStore.d.ts.map +0 -1
- package/dist/brainyrich/store/brainyrichStore.js +0 -272
- package/dist/brainyrich/store/brainyrichStore.js.map +0 -1
- package/dist/brainyrich/types/index.d.ts +0 -116
- package/dist/brainyrich/types/index.d.ts.map +0 -1
- package/dist/brainyrich/utils/cn.d.ts +0 -4
- package/dist/brainyrich/utils/cn.d.ts.map +0 -1
- package/dist/brainyrich/utils/i18n.d.ts +0 -6
- package/dist/brainyrich/utils/i18n.d.ts.map +0 -1
- package/dist/brainyrich/utils/navigation.d.ts +0 -2
- package/dist/brainyrich/utils/navigation.d.ts.map +0 -1
- package/dist/dev/main.d.ts +0 -2
- package/dist/dev/main.d.ts.map +0 -1
- package/dist/generated/global-operations.d.ts +0 -2
- package/dist/generated/global-operations.d.ts.map +0 -1
- package/dist/generated/global-types.d.ts +0 -18199
- package/dist/generated/global-types.d.ts.map +0 -1
- package/dist/generated/wspace-operations.d.ts +0 -2
- package/dist/generated/wspace-operations.d.ts.map +0 -1
- package/dist/generated/wspace-types.d.ts +0 -43046
- package/dist/generated/wspace-types.d.ts.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InvestmentsPage.js","names":[],"sources":["../../../src/brainyrich/pages/InvestmentsPage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n CardDescription,\n Badge,\n Button,\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport {\n DollarSign,\n TrendingUp,\n PieChart,\n Target,\n Plus,\n ArrowUpRight,\n ArrowDownRight,\n} from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { useBrainyRichStore } from '../store/brainyrichStore';\nimport { tWithFallback } from '../utils/i18n';\nimport { SectionShell, KpiGrid, formatMoney } from './_shared';\n\nconst tradeHistory = [\n {\n id: 't1',\n date: '2026-05-28',\n symbol: 'AAPL',\n type: 'BUY' as const,\n qty: 25,\n price: 189.4,\n status: 'Executed',\n },\n {\n id: 't2',\n date: '2026-05-22',\n symbol: 'VTI',\n type: 'BUY' as const,\n qty: 50,\n price: 228.1,\n status: 'Executed',\n },\n {\n id: 't3',\n date: '2026-05-15',\n symbol: 'HDFC',\n type: 'SELL' as const,\n qty: 30,\n price: 1620.5,\n status: 'Executed',\n },\n];\n\nconst sectorBreakdown = [\n { sector: 'Technology', value: 142760, pct: 47.8 },\n { sector: 'Index / ETF', value: 113400, pct: 38.0 },\n { sector: 'Financial', value: 42900, pct: 14.2 },\n];\n\nexport function InvestmentsPage() {\n const { t } = useI18n();\n const [tab, setTab] = useState('overview');\n const { holdings, portfolios } = useBrainyRichStore();\n const translate = (key: string, fallback: string, params?: Record<string, string | number>) =>\n tWithFallback(t, key, fallback, params);\n const totalInvested = holdings.reduce((s, h) => s + h.marketValue, 0);\n const totalPortfolioValue = portfolios.reduce((s, p) => s + p.value, 0);\n\n return (\n <SectionShell\n title={translate('brainyrich.investments.title', 'Investment Portfolio')}\n description={translate(\n 'brainyrich.investments.description',\n 'Track, trade, and optimize your investment positions'\n )}\n actionLabel={translate('brainyrich.investments.actions.newTrade', 'New Trade')}\n badges={[\n translate('brainyrich.investments.badges.holdingsCount', '{count} Holdings', {\n count: holdings.length,\n }),\n ]}\n >\n <KpiGrid\n items={[\n {\n label: translate('brainyrich.investments.metrics.totalInvested', 'Total Invested'),\n value: formatMoney(totalInvested),\n trend: translate(\n 'brainyrich.investments.metrics.totalInvestedTrend',\n 'Across all accounts'\n ),\n },\n {\n label: translate('brainyrich.investments.metrics.dayChange', 'Day Change'),\n value: '+$2,410',\n trend: '+0.81%',\n },\n {\n label: translate('brainyrich.investments.metrics.holdingsCount', 'Holdings Count'),\n value: String(holdings.length),\n },\n {\n label: translate('brainyrich.investments.metrics.totalGainLoss', 'Total Gain/Loss'),\n value: '+$45,230',\n trend: translate(\n 'brainyrich.investments.metrics.totalGainLossTrend',\n '+10.2% all-time'\n ),\n },\n ]}\n />\n\n <Tabs value={tab} onValueChange={setTab} className=\"space-y-4\">\n <TabsList className=\"grid w-full grid-cols-4\">\n <TabsTrigger value=\"overview\">\n {translate('brainyrich.investments.tabs.overview', 'Overview')}\n </TabsTrigger>\n <TabsTrigger value=\"holdings\">\n {translate('brainyrich.investments.tabs.holdings', 'Holdings')}\n </TabsTrigger>\n <TabsTrigger value=\"sectors\">\n {translate('brainyrich.investments.tabs.sectors', 'Sector Analysis')}\n </TabsTrigger>\n <TabsTrigger value=\"history\">\n {translate('brainyrich.investments.tabs.history', 'Trade History')}\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"overview\" className=\"space-y-4\">\n <div className=\"grid gap-4 md:grid-cols-2 lg:grid-cols-4\">\n {[\n {\n icon: DollarSign,\n label: translate('brainyrich.investments.overview.totalValue', 'Total Value'),\n val: formatMoney(totalPortfolioValue),\n color: 'bg-blue-100 text-blue-600',\n },\n {\n icon: TrendingUp,\n label: translate('brainyrich.investments.overview.todaysChange', \"Today's Change\"),\n val: '+$2,410',\n color: 'bg-emerald-100 text-emerald-600',\n },\n {\n icon: PieChart,\n label: translate('brainyrich.investments.overview.holdings', 'Holdings'),\n val: String(holdings.length),\n color: 'bg-purple-100 text-purple-600',\n },\n {\n icon: Target,\n label: translate('brainyrich.investments.overview.performance', 'Performance'),\n val: '+10.2%',\n color: 'bg-orange-100 text-orange-600',\n },\n ].map((kpi) => (\n <Card key={kpi.label}>\n <CardContent className=\"flex items-center gap-4 p-4\">\n <div className={`rounded-lg p-2 ${kpi.color}`}>\n <kpi.icon className=\"h-5 w-5\" />\n </div>\n <div>\n <p className=\"text-xs text-muted-foreground\">{kpi.label}</p>\n <p className=\"text-xl font-bold\">{kpi.val}</p>\n </div>\n </CardContent>\n </Card>\n ))}\n </div>\n\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <div>\n <CardTitle>\n {translate('brainyrich.investments.sections.topHoldings', 'Top Holdings')}\n </CardTitle>\n <CardDescription>\n {translate(\n 'brainyrich.investments.sections.topHoldingsDescription',\n 'Largest positions by market value'\n )}\n </CardDescription>\n </div>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setTab('holdings')}>\n {translate('brainyrich.investments.actions.viewAll', 'View All')}\n </Button>\n </CardHeader>\n <CardContent className=\"space-y-3\">\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 className=\"flex items-center gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-lg bg-blue-100 text-xs font-bold text-blue-600\">\n {h.symbol.slice(0, 2)}\n </div>\n <div>\n <p className=\"font-medium text-sm\">{h.symbol}</p>\n <p className=\"text-xs text-muted-foreground\">{h.name}</p>\n </div>\n </div>\n <div className=\"text-right\">\n <p className=\"text-sm font-medium\">{formatMoney(h.marketValue)}</p>\n <p\n className={`text-xs flex items-center justify-end gap-0.5 ${h.changePct >= 0 ? 'text-emerald-600' : 'text-red-600'}`}\n >\n {h.changePct >= 0 ? (\n <ArrowUpRight className=\"h-3 w-3\" />\n ) : (\n <ArrowDownRight className=\"h-3 w-3\" />\n )}\n {h.changePct >= 0 ? '+' : ''}\n {h.changePct}%\n </p>\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"holdings\">\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between\">\n <CardTitle>\n {translate('brainyrich.investments.sections.allHoldings', 'All Holdings')}\n </CardTitle>\n <Button size=\"sm\">\n <Plus className=\"mr-1 h-4 w-4\" />\n {translate('brainyrich.investments.actions.addPosition', 'Add Position')}\n </Button>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>\n {translate('brainyrich.investments.table.symbol', 'Symbol')}\n </TableHead>\n <TableHead>{translate('brainyrich.investments.table.name', 'Name')}</TableHead>\n <TableHead>\n {translate('brainyrich.investments.table.sector', 'Sector')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.investments.table.marketValue', 'Market Value')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.investments.table.changePct', 'Change %')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.investments.table.allocation', 'Allocation')}\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {holdings.map((h) => (\n <TableRow key={h.symbol}>\n <TableCell className=\"font-semibold\">{h.symbol}</TableCell>\n <TableCell>{h.name}</TableCell>\n <TableCell>\n <Badge variant=\"outline\">{h.sector}</Badge>\n </TableCell>\n <TableCell className=\"text-right\">{formatMoney(h.marketValue)}</TableCell>\n <TableCell\n className={`text-right ${h.changePct >= 0 ? 'text-emerald-600' : 'text-red-600'}`}\n >\n {h.changePct >= 0 ? '+' : ''}\n {h.changePct}%\n </TableCell>\n <TableCell className=\"text-right\">\n {((h.marketValue / totalInvested) * 100).toFixed(1)}%\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"sectors\" className=\"space-y-4\">\n <Card>\n <CardHeader>\n <CardTitle>\n {translate('brainyrich.investments.sections.sectorAllocation', 'Sector Allocation')}\n </CardTitle>\n <CardDescription>\n {translate(\n 'brainyrich.investments.sections.sectorAllocationDescription',\n 'How your investments are distributed across sectors'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {sectorBreakdown.map((s) => (\n <div key={s.sector} className=\"space-y-1\">\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"font-medium\">{s.sector}</span>\n <span>\n {formatMoney(s.value)} ({s.pct}%)\n </span>\n </div>\n <div className=\"h-3 rounded bg-muted overflow-hidden\">\n <div className=\"h-3 rounded bg-primary\" style={{ width: `${s.pct}%` }} />\n </div>\n </div>\n ))}\n </CardContent>\n </Card>\n </TabsContent>\n\n <TabsContent value=\"history\">\n <Card>\n <CardHeader>\n <CardTitle>\n {translate('brainyrich.investments.sections.tradeHistory', 'Trade History')}\n </CardTitle>\n <CardDescription>\n {translate(\n 'brainyrich.investments.sections.tradeHistoryDescription',\n 'Your recent trading activity'\n )}\n </CardDescription>\n </CardHeader>\n <CardContent>\n <Table>\n <TableHeader>\n <TableRow>\n <TableHead>\n {translate('brainyrich.investments.history.date', 'Date')}\n </TableHead>\n <TableHead>\n {translate('brainyrich.investments.history.symbol', 'Symbol')}\n </TableHead>\n <TableHead>\n {translate('brainyrich.investments.history.type', 'Type')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.investments.history.qty', 'Qty')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.investments.history.price', 'Price')}\n </TableHead>\n <TableHead className=\"text-right\">\n {translate('brainyrich.investments.history.total', 'Total')}\n </TableHead>\n <TableHead>\n {translate('brainyrich.investments.history.status', 'Status')}\n </TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n {tradeHistory.map((t) => (\n <TableRow key={t.id}>\n <TableCell className=\"text-sm\">{t.date}</TableCell>\n <TableCell className=\"font-semibold\">{t.symbol}</TableCell>\n <TableCell>\n <Badge variant={t.type === 'BUY' ? 'default' : 'destructive'}>\n {t.type}\n </Badge>\n </TableCell>\n <TableCell className=\"text-right\">{t.qty}</TableCell>\n <TableCell className=\"text-right\">${t.price.toLocaleString()}</TableCell>\n <TableCell className=\"text-right\">{formatMoney(t.qty * t.price)}</TableCell>\n <TableCell>\n <Badge variant=\"secondary\">{t.status}</Badge>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </CardContent>\n </Card>\n </TabsContent>\n </Tabs>\n </SectionShell>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"InvestmentsPage.js","names":[],"sources":["../../../src/brainyrich/pages/InvestmentsPage.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport {\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n CardDescription,\n Badge,\n Button,\n Input,\n Label,\n Textarea,\n Select,\n SelectTrigger,\n SelectValue,\n SelectContent,\n SelectItem,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogDescription,\n DialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { PieChart, Plus, Trash2, X } from 'lucide-react';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\nimport {\n useModelPortfolios,\n useModelPortfolio,\n useCreateModelPortfolio,\n} from '../hooks/useBrainyRichApi';\nimport type {\n BraAssetClass,\n BraRiskProfile,\n BraModelAllocationInput,\n} from '../types/bra';\nimport {\n SectionShell,\n KpiGrid,\n AllocationBars,\n EmptyState,\n LoadingState,\n ErrorState,\n formatDate,\n statusBadgeVariant,\n type AllocationDatum,\n} from './_shared';\n\n// ----------------------------------------------------------------------------\n// Enum option sets (mirror the SDL enums in ../types/bra) + humanizers.\n// No fabricated data: these are the exact allowed input values.\n// ----------------------------------------------------------------------------\n\nconst RISK_PROFILES: BraRiskProfile[] = [\n 'CONSERVATIVE',\n 'MODERATE',\n 'BALANCED',\n 'GROWTH',\n 'AGGRESSIVE',\n];\n\nconst ASSET_CLASSES: BraAssetClass[] = [\n 'EQUITY',\n 'FIXED_INCOME',\n 'CASH',\n 'REAL_ESTATE',\n 'COMMODITY',\n 'CRYPTO',\n 'ALTERNATIVE',\n];\n\n/** Turn an UPPER_SNAKE enum member into a readable label (derived, not invented). */\nfunction humanize(value: string): string {\n return value\n .toLowerCase()\n .split('_')\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n}\n\nconst ALLOCATION_TONES: AllocationDatum['tone'][] = [\n 'accent',\n 'default',\n 'positive',\n 'warning',\n 'negative',\n];\n\ninterface AllocationRow {\n assetClass: BraAssetClass;\n targetPct: string;\n}\n\nconst emptyRow = (): AllocationRow => ({ assetClass: 'EQUITY', targetPct: '' });\n\nexport function InvestmentsPage() {\n const { t } = useI18n();\n const translate = (key: string, fallback: string, params?: Record<string, string | number>) =>\n tWithFallback(t, key, fallback, params);\n\n const { data: models, isLoading, isError, refetch } = useModelPortfolios();\n const createModel = useCreateModelPortfolio();\n\n const [createOpen, setCreateOpen] = useState(false);\n const [detailId, setDetailId] = useState<string | null>(null);\n\n // -------- Create form state --------\n const [name, setName] = useState('');\n const [riskProfile, setRiskProfile] = useState<BraRiskProfile>('BALANCED');\n const [baseCurrency, setBaseCurrency] = useState('USD');\n const [description, setDescription] = useState('');\n const [rows, setRows] = useState<AllocationRow[]>([emptyRow()]);\n const [formError, setFormError] = useState<string | null>(null);\n\n const resetForm = () => {\n setName('');\n setRiskProfile('BALANCED');\n setBaseCurrency('USD');\n setDescription('');\n setRows([emptyRow()]);\n setFormError(null);\n };\n\n const allocationSum = useMemo(\n () => rows.reduce((s, r) => s + (Number.isFinite(parseFloat(r.targetPct)) ? parseFloat(r.targetPct) : 0), 0),\n [rows]\n );\n\n const updateRow = (index: number, patch: Partial<AllocationRow>) => {\n setRows((prev) => prev.map((r, i) => (i === index ? { ...r, ...patch } : r)));\n };\n const addRow = () => setRows((prev) => [...prev, emptyRow()]);\n const removeRow = (index: number) =>\n setRows((prev) => (prev.length > 1 ? prev.filter((_, i) => i !== index) : prev));\n\n const handleSubmit = () => {\n setFormError(null);\n const trimmedName = name.trim();\n if (!trimmedName) {\n setFormError(translate('brainyrich.investments.form.errorName', 'A model name is required.'));\n return;\n }\n const allocations: BraModelAllocationInput[] = [];\n for (const r of rows) {\n const pct = parseFloat(r.targetPct);\n if (!r.targetPct.trim() || !Number.isFinite(pct)) {\n setFormError(\n translate(\n 'brainyrich.investments.form.errorPct',\n 'Every allocation row needs a numeric target %.'\n )\n );\n return;\n }\n if (pct < 0) {\n setFormError(\n translate('brainyrich.investments.form.errorNegative', 'Target % cannot be negative.')\n );\n return;\n }\n allocations.push({ assetClass: r.assetClass, targetPct: pct });\n }\n if (Math.abs(allocationSum - 100) > 0.5) {\n setFormError(\n translate('brainyrich.investments.form.errorSum', 'Allocation targets must sum to ~100% (currently {sum}%).', {\n sum: allocationSum.toFixed(1),\n })\n );\n return;\n }\n\n createModel.mutate(\n {\n name: trimmedName,\n riskProfile,\n baseCurrency: baseCurrency.trim() || 'USD',\n description: description.trim() ? description.trim() : null,\n allocations,\n },\n {\n onSuccess: () => {\n setCreateOpen(false);\n resetForm();\n },\n onError: (err: unknown) => {\n setFormError(\n err instanceof Error\n ? err.message\n : translate('brainyrich.investments.form.errorGeneric', 'Could not create the model.')\n );\n },\n }\n );\n };\n\n const title = translate('brainyrich.investments.title', 'Model Portfolios');\n const description2 = translate(\n 'brainyrich.investments.description',\n 'Reusable target allocations you can benchmark and drive rebalancing against'\n );\n\n const activeCount = models.filter((m) => m.isActive).length;\n const riskCount = new Set(models.map((m) => m.riskProfile)).size;\n const classCount = new Set(models.flatMap((m) => m.allocations.map((a) => a.assetClass))).size;\n const kpis = [\n {\n label: translate('brainyrich.investments.kpi.total', 'Model portfolios'),\n value: String(models.length),\n },\n {\n label: translate('brainyrich.investments.kpi.active', 'Active'),\n value: String(activeCount),\n },\n {\n label: translate('brainyrich.investments.kpi.risk', 'Risk profiles'),\n value: String(riskCount),\n },\n {\n label: translate('brainyrich.investments.kpi.classes', 'Asset classes'),\n value: String(classCount),\n },\n ];\n\n const newModelLabel = translate('brainyrich.investments.actions.newModel', 'New model');\n\n const renderBody = () => {\n if (isLoading) return <LoadingState rows={4} />;\n if (isError)\n return (\n <ErrorState\n title={translate('brainyrich.investments.error.title', 'Could not load model portfolios')}\n onRetry={() => refetch()}\n />\n );\n if (models.length === 0)\n return (\n <EmptyState\n icon={<PieChart className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.investments.empty.title', 'No model portfolios yet')}\n description={translate(\n 'brainyrich.investments.empty.description',\n 'Create a target allocation model to benchmark portfolios and drive rebalancing.'\n )}\n action={\n <Button size=\"sm\" onClick={() => setCreateOpen(true)}>\n <Plus className=\"mr-1 size-4\" aria-hidden=\"true\" />\n {newModelLabel}\n </Button>\n }\n />\n );\n\n return (\n <div className=\"grid gap-4 md:grid-cols-2 xl:grid-cols-3\">\n {models.map((m) => {\n const bars: AllocationDatum[] = m.allocations.map((a, i) => ({\n label: humanize(a.assetClass),\n value: a.targetPct,\n tone: ALLOCATION_TONES[i % ALLOCATION_TONES.length],\n }));\n return (\n <Card key={m.id} className=\"flex flex-col\">\n <CardHeader className=\"space-y-2\">\n <div className=\"flex items-start justify-between gap-2\">\n <CardTitle className=\"text-base text-text-primary\">{m.name}</CardTitle>\n <Badge variant={m.isActive ? statusBadgeVariant('ACTIVE') : 'secondary'}>\n {m.isActive\n ? translate('brainyrich.investments.badge.active', 'Active')\n : translate('brainyrich.investments.badge.inactive', 'Inactive')}\n </Badge>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\">{humanize(m.riskProfile)}</Badge>\n <Badge variant=\"outline\">{m.baseCurrency}</Badge>\n </div>\n {m.description ? (\n <CardDescription className=\"text-text-secondary\">{m.description}</CardDescription>\n ) : null}\n </CardHeader>\n <CardContent className=\"mt-auto space-y-4\">\n {bars.length > 0 ? (\n <AllocationBars data={bars} />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {translate('brainyrich.investments.card.noAllocations', 'No target allocations set.')}\n </p>\n )}\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"w-full\"\n onClick={() => setDetailId(m.id)}\n >\n {translate('brainyrich.investments.actions.viewDetails', 'View details')}\n </Button>\n </CardContent>\n </Card>\n );\n })}\n </div>\n );\n };\n\n return (\n <>\n <SectionShell\n title={title}\n description={description2}\n actionLabel={newModelLabel}\n onAction={() => setCreateOpen(true)}\n badges={\n !isLoading && !isError\n ? [\n translate('brainyrich.investments.badges.count', '{count} models', {\n count: models.length,\n }),\n ]\n : []\n }\n >\n {!isLoading && !isError && models.length > 0 ? <KpiGrid items={kpis} /> : null}\n {renderBody()}\n </SectionShell>\n\n {/* ---------------- Create model dialog ---------------- */}\n <Dialog\n open={createOpen}\n onOpenChange={(open) => {\n setCreateOpen(open);\n if (!open) resetForm();\n }}\n >\n <DialogContent className=\"max-h-[90vh] overflow-y-auto sm:max-w-lg\">\n <DialogHeader>\n <DialogTitle>{newModelLabel}</DialogTitle>\n <DialogDescription>\n {translate(\n 'brainyrich.investments.form.subtitle',\n 'Define a target allocation. Targets should sum to about 100%.'\n )}\n </DialogDescription>\n </DialogHeader>\n\n <div className=\"space-y-4 py-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-model-name\">\n {translate('brainyrich.investments.form.name', 'Name')}\n </Label>\n <Input\n id=\"bra-model-name\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder={translate('brainyrich.investments.form.namePlaceholder', 'Balanced Growth 60/40')}\n />\n </div>\n\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-model-risk\">\n {translate('brainyrich.investments.form.risk', 'Risk profile')}\n </Label>\n <Select\n value={riskProfile}\n onValueChange={(v) => setRiskProfile(v as BraRiskProfile)}\n >\n <SelectTrigger id=\"bra-model-risk\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {RISK_PROFILES.map((r) => (\n <SelectItem key={r} value={r}>\n {humanize(r)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-model-currency\">\n {translate('brainyrich.investments.form.currency', 'Base currency')}\n </Label>\n <Input\n id=\"bra-model-currency\"\n value={baseCurrency}\n onChange={(e) => setBaseCurrency(e.target.value.toUpperCase().slice(0, 3))}\n placeholder=\"USD\"\n />\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label htmlFor=\"bra-model-desc\">\n {translate('brainyrich.investments.form.description', 'Description')}\n </Label>\n <Textarea\n id=\"bra-model-desc\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n rows={2}\n placeholder={translate(\n 'brainyrich.investments.form.descriptionPlaceholder',\n 'Who this model is for and how it is used'\n )}\n />\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <Label>{translate('brainyrich.investments.form.allocations', 'Target allocations')}</Label>\n <span\n className={\n Math.abs(allocationSum - 100) <= 0.5\n ? 'text-xs font-medium text-status-success-text'\n : 'text-xs font-medium text-status-warning-text'\n }\n >\n {translate('brainyrich.investments.form.sum', 'Sum: {sum}%', {\n sum: allocationSum.toFixed(1),\n })}\n </span>\n </div>\n <div className=\"space-y-2\">\n {rows.map((r, i) => (\n <div key={i} className=\"flex items-center gap-2\">\n <Select\n value={r.assetClass}\n onValueChange={(v) => updateRow(i, { assetClass: v as BraAssetClass })}\n >\n <SelectTrigger className=\"flex-1\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {ASSET_CLASSES.map((c) => (\n <SelectItem key={c} value={c}>\n {humanize(c)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Input\n type=\"number\"\n inputMode=\"decimal\"\n min={0}\n max={100}\n step=\"0.1\"\n className=\"w-24\"\n value={r.targetPct}\n onChange={(e) => updateRow(i, { targetPct: e.target.value })}\n placeholder=\"%\"\n aria-label={translate('brainyrich.investments.form.targetPct', 'Target percent')}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => removeRow(i)}\n disabled={rows.length <= 1}\n aria-label={translate('brainyrich.investments.form.removeRow', 'Remove allocation row')}\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </div>\n ))}\n </div>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addRow}>\n <Plus className=\"mr-1 size-4\" aria-hidden=\"true\" />\n {translate('brainyrich.investments.form.addRow', 'Add asset class')}\n </Button>\n </div>\n\n {formError ? (\n <p className=\"text-sm text-status-error-text\" role=\"alert\">\n {formError}\n </p>\n ) : null}\n </div>\n\n <DialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => {\n setCreateOpen(false);\n resetForm();\n }}\n disabled={createModel.isPending}\n >\n {translate('brainyrich.investments.form.cancel', 'Cancel')}\n </Button>\n <Button onClick={handleSubmit} disabled={createModel.isPending}>\n {createModel.isPending\n ? translate('brainyrich.investments.form.saving', 'Creating…')\n : translate('brainyrich.investments.form.create', 'Create model')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n\n {/* ---------------- Detail dialog ---------------- */}\n <ModelDetailDialog\n id={detailId}\n onClose={() => setDetailId(null)}\n translate={translate}\n />\n </>\n );\n}\n\n// ----------------------------------------------------------------------------\n// Detail dialog — reads the single model via useModelPortfolio(id).\n// ----------------------------------------------------------------------------\n\nfunction ModelDetailDialog({\n id,\n onClose,\n translate,\n}: {\n id: string | null;\n onClose: () => void;\n translate: (key: string, fallback: string, params?: Record<string, string | number>) => string;\n}) {\n const { data: model, isLoading, isError, refetch } = useModelPortfolio(id ?? undefined);\n\n const bars: AllocationDatum[] = (model?.allocations ?? []).map((a, i) => ({\n label: humanize(a.assetClass),\n value: a.targetPct,\n tone: ALLOCATION_TONES[i % ALLOCATION_TONES.length],\n }));\n\n return (\n <Dialog open={Boolean(id)} onOpenChange={(open) => (!open ? onClose() : undefined)}>\n <DialogContent className=\"max-h-[90vh] overflow-y-auto sm:max-w-lg\">\n <DialogHeader>\n <DialogTitle className=\"flex items-center justify-between gap-2 pr-6\">\n {model?.name ??\n translate('brainyrich.investments.detail.title', 'Model portfolio')}\n </DialogTitle>\n {model?.description ? (\n <DialogDescription>{model.description}</DialogDescription>\n ) : null}\n </DialogHeader>\n\n {isLoading ? (\n <LoadingState rows={3} />\n ) : isError ? (\n <ErrorState\n title={translate('brainyrich.investments.detail.error', 'Could not load this model')}\n onRetry={() => refetch()}\n />\n ) : !model ? (\n <EmptyState\n icon={<X className=\"size-6\" aria-hidden=\"true\" />}\n title={translate('brainyrich.investments.detail.notFound', 'Model not found')}\n />\n ) : (\n <div className=\"space-y-5 py-1\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant={model.isActive ? statusBadgeVariant('ACTIVE') : 'secondary'}>\n {model.isActive\n ? translate('brainyrich.investments.badge.active', 'Active')\n : translate('brainyrich.investments.badge.inactive', 'Inactive')}\n </Badge>\n <Badge variant=\"outline\">{humanize(model.riskProfile)}</Badge>\n <Badge variant=\"outline\">{model.baseCurrency}</Badge>\n </div>\n\n <div>\n <p className=\"mb-2 text-sm font-medium text-text-primary\">\n {translate('brainyrich.investments.detail.allocations', 'Target allocations')}\n </p>\n {bars.length > 0 ? (\n <AllocationBars data={bars} />\n ) : (\n <p className=\"text-sm text-text-secondary\">\n {translate('brainyrich.investments.card.noAllocations', 'No target allocations set.')}\n </p>\n )}\n </div>\n\n <dl className=\"grid grid-cols-2 gap-4 border-t border-border-subtle pt-4 text-sm\">\n <div>\n <dt className=\"text-text-secondary\">\n {translate('brainyrich.investments.detail.created', 'Created')}\n </dt>\n <dd className=\"text-text-primary\">{formatDate(model.createdAt)}</dd>\n </div>\n <div>\n <dt className=\"text-text-secondary\">\n {translate('brainyrich.investments.detail.updated', 'Updated')}\n </dt>\n <dd className=\"text-text-primary\">{formatDate(model.updatedAt)}</dd>\n </div>\n </dl>\n </div>\n )}\n\n <DialogFooter>\n <Button variant=\"outline\" onClick={onClose}>\n {translate('brainyrich.investments.detail.close', 'Close')}\n </Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n );\n}\n"],"mappings":"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"}
|