@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,222 +1,437 @@
1
- import { useBrainyRichStore as e } from "../store/brainyrichStore.js";
2
- import { KpiGrid as t, SectionShell as n, statusBadgeVariant as r } from "./_shared.js";
3
- import { Activity as i, AlertTriangle as a, BarChart3 as o, ShieldAlert as s } from "lucide-react";
4
- import { jsx as c, jsxs as l } from "react/jsx-runtime";
5
- import { Badge as u, Card as d, CardContent as f, CardDescription as p, CardHeader as m, CardTitle as h, Table as g, TableBody as _, TableCell as v, TableHead as y, TableHeader as b, TableRow as x } from "@burdenoff/fe-libs/ui";
1
+ import { useAcknowledgeInsight as e, useCreateRebalanceProposal as t, useDismissInsight as n, useInsights as r, usePortfolios as i, useRebalanceProposals as a, useResolveInsight as ee, useTransitionRebalanceProposal as te } from "../hooks/useBrainyRichApi.js";
2
+ import { EmptyState as o, ErrorState as s, KpiGrid as ne, LoadingState as re, SectionShell as ie, formatDate as c, formatPct as l, statusBadgeVariant as u } from "./_shared.js";
3
+ import { useMemo as d, useState as f } from "react";
4
+ import { AlertTriangle as ae, ArrowRight as oe, Check as p, MoreHorizontal as m, Plus as se, Scale as h, ShieldAlert as ce, ShieldCheck as g, X as le } from "lucide-react";
5
+ import { jsx as _, jsxs as v } from "react/jsx-runtime";
6
+ import { Badge as y, Button as b, Card as x, CardContent as S, CardDescription as C, CardHeader as w, CardTitle as T, Dialog as ue, DialogClose as de, DialogContent as fe, DialogDescription as pe, DialogFooter as me, DialogHeader as he, DialogTitle as ge, DropdownMenu as E, DropdownMenuContent as D, DropdownMenuItem as O, DropdownMenuLabel as _e, DropdownMenuSeparator as ve, DropdownMenuTrigger as k, Input as ye, Label as A, Select as be, SelectContent as xe, SelectItem as Se, SelectTrigger as Ce, SelectValue as we, Table as Te, TableBody as Ee, TableCell as j, TableHead as M, TableHeader as De, TableRow as N, Textarea as P } from "@burdenoff/fe-libs/ui";
6
7
  //#region src/brainyrich/pages/RiskPage.tsx
7
- var S = [
8
- {
9
- metric: "Portfolio Beta",
10
- value: "1.15",
11
- benchmark: "1.0",
12
- status: "Above Market"
13
- },
14
- {
15
- metric: "Value at Risk (95%)",
16
- value: "-8.5%",
17
- benchmark: "-10.0%",
18
- status: "Acceptable"
19
- },
20
- {
21
- metric: "Sharpe Ratio",
22
- value: "1.42",
23
- benchmark: "1.2",
24
- status: "Good"
25
- },
26
- {
27
- metric: "Max Drawdown",
28
- value: "-12.3%",
29
- benchmark: "-15.0%",
30
- status: "Within Limits"
8
+ var Oe = {
9
+ DRAFT: ["PROPOSED", "CANCELLED"],
10
+ PROPOSED: [
11
+ "APPROVED",
12
+ "REJECTED",
13
+ "CANCELLED"
14
+ ],
15
+ APPROVED: ["EXECUTED", "CANCELLED"],
16
+ REJECTED: [],
17
+ EXECUTED: [],
18
+ CANCELLED: []
19
+ }, ke = new Set([
20
+ "DRIFT",
21
+ "CONCENTRATION_RISK",
22
+ "REBALANCE_DUE",
23
+ "CASH_DRAG",
24
+ "FEE_ANOMALY"
25
+ ]);
26
+ function F(e) {
27
+ return e.toLowerCase().split("_").map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" ");
28
+ }
29
+ function Ae(e) {
30
+ if (e == null) return "—";
31
+ if (Array.isArray(e)) return `${e.length} trade${e.length === 1 ? "" : "s"}`;
32
+ if (typeof e == "object") {
33
+ let t = Object.keys(e).length;
34
+ return `${t} field${t === 1 ? "" : "s"}`;
35
+ }
36
+ return String(e);
37
+ }
38
+ var I = {
39
+ portfolioId: "",
40
+ driftPct: "",
41
+ rationale: "",
42
+ trades: ""
43
+ };
44
+ function je(e) {
45
+ if (e.trim() === "") return;
46
+ let t = Number(e);
47
+ return Number.isFinite(t) ? t : void 0;
48
+ }
49
+ function L() {
50
+ let { data: p, isLoading: L, isError: Ne, refetch: Pe } = a(), { data: R } = i(), { data: z, isLoading: Fe, isError: Ie, refetch: Le } = r(), B = t(), V = te(), H = e(), U = n(), W = ee(), [Re, G] = f(!1), [K, q] = f(I), [J, Y] = f(null), X = d(() => {
51
+ let e = /* @__PURE__ */ new Map();
52
+ for (let t of R) e.set(t.id, t);
53
+ return e;
54
+ }, [R]), Z = d(() => z.filter((e) => ke.has(e.type)), [z]), ze = p.filter((e) => e.status === "DRAFT" || e.status === "PROPOSED" || e.status === "APPROVED"), Q = Z.filter((e) => e.status === "OPEN"), Be = p.length > 0 ? p.reduce((e, t) => e + (t.driftPct ?? 0), 0) / p.length : null, $ = R.length > 0;
55
+ function Ve() {
56
+ q(I), Y(null), G(!0);
31
57
  }
32
- ], C = [
33
- {
34
- scenario: "2008 Financial Crisis",
35
- portfolio: -35.2,
36
- market: -37.8,
37
- outperformance: "+2.6%"
38
- },
39
- {
40
- scenario: "COVID-19 Pandemic",
41
- portfolio: -28.1,
42
- market: -33.9,
43
- outperformance: "+5.8%"
44
- },
45
- {
46
- scenario: "Interest Rate Shock",
47
- portfolio: -15.4,
48
- market: -18.2,
49
- outperformance: "+2.8%"
50
- },
51
- {
52
- scenario: "Stagflation Scenario",
53
- portfolio: -12.7,
54
- market: -16.3,
55
- outperformance: "+3.6%"
58
+ function He() {
59
+ if (!K.portfolioId) return;
60
+ let e;
61
+ if (K.trades.trim() !== "") try {
62
+ e = JSON.parse(K.trades);
63
+ } catch {
64
+ Y("Trades must be valid JSON.");
65
+ return;
66
+ }
67
+ let t = X.get(K.portfolioId);
68
+ B.mutate({
69
+ portfolioId: K.portfolioId,
70
+ householdId: t?.householdId ?? null,
71
+ driftPct: je(K.driftPct),
72
+ rationale: K.rationale.trim() || null,
73
+ ...e === void 0 ? {} : { trades: e }
74
+ }, { onSuccess: () => G(!1) });
56
75
  }
57
- ], w = [
58
- {
59
- strategy: "Diversification",
60
- status: "Implemented",
61
- effectiveness: "High"
62
- },
63
- {
64
- strategy: "Hedging (Options)",
65
- status: "Partial",
66
- effectiveness: "Medium"
67
- },
68
- {
69
- strategy: "Stop-Loss Orders",
70
- status: "Active",
71
- effectiveness: "Medium"
72
- },
73
- {
74
- strategy: "Quarterly Rebalancing",
75
- status: "Scheduled",
76
- effectiveness: "High"
76
+ function Ue(e) {
77
+ let t = X.get(e.portfolioId)?.driftThresholdPct;
78
+ return t != null && Number.isFinite(t) && e.driftPct >= t;
77
79
  }
78
- ];
79
- function T() {
80
- let { risks: T } = e();
81
- return /* @__PURE__ */ l(n, {
82
- title: "Risk Management",
83
- description: "Monitor portfolio risk exposure, run stress tests, and manage mitigation strategies",
84
- actionLabel: "Run Stress Test",
85
- badges: [`${T.length} Active Alerts`],
80
+ return /* @__PURE__ */ v(ie, {
81
+ title: "Risk & Rebalancing",
82
+ description: "Review drift-driven rebalance proposals and act on portfolio risk insights.",
83
+ badges: [`${ze.length} active`, `${Q.length} open insight${Q.length === 1 ? "" : "s"}`],
84
+ actionLabel: "New proposal",
85
+ onAction: Ve,
86
86
  children: [
87
- /* @__PURE__ */ c(t, { items: [
87
+ /* @__PURE__ */ _(ne, { items: [
88
88
  {
89
- label: "Risk Score",
90
- value: "7/10",
91
- trend: "Moderate Risk"
89
+ label: "Total proposals",
90
+ value: String(p.length)
92
91
  },
93
92
  {
94
- label: "Portfolio VaR",
95
- value: "-8.5%",
96
- trend: "95% confidence, 1-day"
93
+ label: "Active proposals",
94
+ value: String(ze.length)
97
95
  },
98
96
  {
99
- label: "Sharpe Ratio",
100
- value: "1.42",
101
- trend: "Risk-adjusted return"
97
+ label: "Average drift",
98
+ value: Be === null ? "—" : l(Be)
102
99
  },
103
100
  {
104
- label: "Risk Rating",
105
- value: "B+",
106
- trend: "Overall grade"
101
+ label: "Open risk insights",
102
+ value: String(Q.length)
107
103
  }
108
104
  ] }),
109
- /* @__PURE__ */ l("div", {
110
- className: "grid gap-4 lg:grid-cols-2",
111
- children: [/* @__PURE__ */ l(d, { children: [/* @__PURE__ */ c(m, { children: /* @__PURE__ */ l(h, {
112
- className: "flex items-center gap-2",
113
- children: [/* @__PURE__ */ c(i, { className: "h-5 w-5" }), "Risk Metrics"]
114
- }) }), /* @__PURE__ */ c(f, {
115
- className: "space-y-3",
116
- children: S.map((e) => /* @__PURE__ */ l("div", {
117
- className: "flex items-center justify-between rounded-lg border p-3",
118
- children: [/* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("p", {
119
- className: "font-medium text-sm",
120
- children: e.metric
121
- }), /* @__PURE__ */ l("p", {
122
- className: "text-xs text-muted-foreground",
123
- children: ["Benchmark: ", e.benchmark]
124
- })] }), /* @__PURE__ */ l("div", {
105
+ /* @__PURE__ */ v(x, { children: [/* @__PURE__ */ v(w, { children: [/* @__PURE__ */ v(T, {
106
+ className: "flex items-center gap-2",
107
+ children: [/* @__PURE__ */ _(h, {
108
+ className: "h-5 w-5",
109
+ "aria-hidden": "true"
110
+ }), "Rebalance proposals"]
111
+ }), /* @__PURE__ */ _(C, { children: "Drift against target allocation, with lifecycle actions per proposal." })] }), /* @__PURE__ */ _(S, { children: L ? /* @__PURE__ */ _(re, {}) : Ne ? /* @__PURE__ */ _(s, { onRetry: () => Pe() }) : p.length === 0 ? /* @__PURE__ */ _(o, {
112
+ icon: /* @__PURE__ */ _(h, {
113
+ className: "size-6",
114
+ "aria-hidden": "true"
115
+ }),
116
+ title: "No rebalance proposals",
117
+ description: $ ? "Create a proposal when a portfolio drifts from its target allocation." : "Create a portfolio first, then propose a rebalance when it drifts.",
118
+ action: $ ? /* @__PURE__ */ v(b, {
119
+ size: "sm",
120
+ onClick: Ve,
121
+ children: [/* @__PURE__ */ _(se, {
122
+ className: "size-4",
123
+ "aria-hidden": "true"
124
+ }), "New proposal"]
125
+ }) : void 0
126
+ }) : /* @__PURE__ */ _("div", {
127
+ className: "overflow-x-auto",
128
+ children: /* @__PURE__ */ v(Te, { children: [/* @__PURE__ */ _(De, { children: /* @__PURE__ */ v(N, { children: [
129
+ /* @__PURE__ */ _(M, { children: "Portfolio" }),
130
+ /* @__PURE__ */ _(M, {
131
+ className: "text-right",
132
+ children: "Drift"
133
+ }),
134
+ /* @__PURE__ */ _(M, { children: "Status" }),
135
+ /* @__PURE__ */ _(M, { children: "Rationale" }),
136
+ /* @__PURE__ */ _(M, { children: "Trades" }),
137
+ /* @__PURE__ */ _(M, { children: "Created" }),
138
+ /* @__PURE__ */ _(M, {
139
+ className: "w-12 text-right",
140
+ children: "Actions"
141
+ })
142
+ ] }) }), /* @__PURE__ */ _(Ee, { children: p.map((e) => {
143
+ let t = X.get(e.portfolioId), n = Ue(e), r = Oe[e.status];
144
+ return /* @__PURE__ */ v(N, { children: [
145
+ /* @__PURE__ */ v(j, { children: [/* @__PURE__ */ _("p", {
146
+ className: "font-medium text-text-primary",
147
+ children: t?.name ?? "Unknown portfolio"
148
+ }), /* @__PURE__ */ v("p", {
149
+ className: "text-xs text-text-secondary",
150
+ children: [t?.baseCurrency ?? "—", t?.driftThresholdPct == null ? "" : ` · threshold ${l(t.driftThresholdPct)}`]
151
+ })] }),
152
+ /* @__PURE__ */ v(j, {
125
153
  className: "text-right",
126
- children: [/* @__PURE__ */ c("p", {
127
- className: "font-semibold text-sm",
128
- children: e.value
129
- }), /* @__PURE__ */ c(u, {
130
- variant: e.status === "Good" || e.status === "Acceptable" || e.status === "Within Limits" ? "default" : "secondary",
131
- className: "text-[10px]",
132
- children: e.status
133
- })]
134
- })]
135
- }, e.metric))
136
- })] }), /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ c(m, { children: /* @__PURE__ */ l(h, {
137
- className: "flex items-center gap-2",
138
- children: [/* @__PURE__ */ c(a, { className: "h-5 w-5" }), "Active Risk Alerts"]
139
- }) }), /* @__PURE__ */ c(f, {
140
- className: "space-y-3",
141
- children: T.map((e) => /* @__PURE__ */ l("div", {
142
- className: `rounded-lg border p-3 ${e.severity === "High" ? "border-red-200 bg-red-50" : e.severity === "Medium" ? "border-yellow-200 bg-yellow-50" : "border-blue-200 bg-blue-50"}`,
143
- children: [/* @__PURE__ */ l("div", {
144
- className: "flex items-center justify-between mb-1",
145
- children: [/* @__PURE__ */ c("p", {
146
- className: "font-medium text-sm",
147
- children: e.title
148
- }), /* @__PURE__ */ c(u, {
149
- variant: r(e.severity),
150
- children: e.severity
151
- })]
152
- }), /* @__PURE__ */ c("p", {
153
- className: "text-xs text-muted-foreground",
154
- children: e.description
155
- })]
156
- }, e.id))
157
- })] })]
158
- }),
159
- /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ l(h, {
154
+ children: [/* @__PURE__ */ v("span", {
155
+ className: `inline-flex items-center justify-end gap-1 font-semibold ${n ? "text-status-error-text" : "text-text-primary"}`,
156
+ children: [n ? /* @__PURE__ */ _(ae, {
157
+ className: "size-4",
158
+ "aria-hidden": "true"
159
+ }) : null, l(e.driftPct)]
160
+ }), n ? /* @__PURE__ */ _("p", {
161
+ className: "text-xs text-status-error-text",
162
+ children: "Over threshold"
163
+ }) : null]
164
+ }),
165
+ /* @__PURE__ */ _(j, { children: /* @__PURE__ */ _(y, {
166
+ variant: u(e.status),
167
+ children: F(e.status)
168
+ }) }),
169
+ /* @__PURE__ */ _(j, {
170
+ className: "max-w-xs",
171
+ children: /* @__PURE__ */ _("p", {
172
+ className: "truncate text-sm text-text-secondary",
173
+ children: e.rationale ?? "—"
174
+ })
175
+ }),
176
+ /* @__PURE__ */ _(j, {
177
+ className: "text-sm text-text-secondary",
178
+ children: Ae(e.trades)
179
+ }),
180
+ /* @__PURE__ */ _(j, {
181
+ className: "text-sm text-text-secondary",
182
+ children: c(e.createdAt)
183
+ }),
184
+ /* @__PURE__ */ _(j, {
185
+ className: "text-right",
186
+ children: r.length === 0 ? /* @__PURE__ */ _("span", {
187
+ className: "text-xs text-text-muted",
188
+ children: "—"
189
+ }) : /* @__PURE__ */ v(E, { children: [/* @__PURE__ */ _(k, {
190
+ asChild: !0,
191
+ children: /* @__PURE__ */ _(b, {
192
+ variant: "ghost",
193
+ size: "sm",
194
+ "aria-label": `Lifecycle actions for ${t?.name ?? "proposal"}`,
195
+ children: /* @__PURE__ */ _(m, {
196
+ className: "size-4",
197
+ "aria-hidden": "true"
198
+ })
199
+ })
200
+ }), /* @__PURE__ */ v(D, {
201
+ align: "end",
202
+ children: [
203
+ /* @__PURE__ */ _(_e, { children: "Advance to" }),
204
+ /* @__PURE__ */ _(ve, {}),
205
+ r.map((t) => {
206
+ let n = t === "REJECTED" || t === "CANCELLED";
207
+ return /* @__PURE__ */ v(O, {
208
+ disabled: V.isPending,
209
+ className: n ? "text-status-error-text" : void 0,
210
+ onClick: () => V.mutate({
211
+ id: e.id,
212
+ status: t
213
+ }),
214
+ children: [_(n ? le : oe, {
215
+ className: "size-4",
216
+ "aria-hidden": "true"
217
+ }), F(t)]
218
+ }, t);
219
+ })
220
+ ]
221
+ })] })
222
+ })
223
+ ] }, e.id);
224
+ }) })] })
225
+ }) })] }),
226
+ /* @__PURE__ */ v(x, { children: [/* @__PURE__ */ v(w, { children: [/* @__PURE__ */ v(T, {
160
227
  className: "flex items-center gap-2",
161
- children: [/* @__PURE__ */ c(o, { className: "h-5 w-5" }), "Stress Test Results"]
162
- }), /* @__PURE__ */ c(p, { children: "How your portfolio would perform under historical crisis scenarios" })] }), /* @__PURE__ */ c(f, { children: /* @__PURE__ */ l(g, { children: [/* @__PURE__ */ c(b, { children: /* @__PURE__ */ l(x, { children: [
163
- /* @__PURE__ */ c(y, { children: "Scenario" }),
164
- /* @__PURE__ */ c(y, {
165
- className: "text-right",
166
- children: "Your Portfolio"
228
+ children: [/* @__PURE__ */ _(ce, {
229
+ className: "h-5 w-5",
230
+ "aria-hidden": "true"
231
+ }), "Risk insights"]
232
+ }), /* @__PURE__ */ _(C, { children: "Drift, concentration, cash-drag and fee-anomaly signals detected across your portfolios." })] }), /* @__PURE__ */ _(S, { children: Fe ? /* @__PURE__ */ _(re, {}) : Ie ? /* @__PURE__ */ _(s, { onRetry: () => Le() }) : Z.length === 0 ? /* @__PURE__ */ _(o, {
233
+ icon: /* @__PURE__ */ _(g, {
234
+ className: "size-6",
235
+ "aria-hidden": "true"
167
236
  }),
168
- /* @__PURE__ */ c(y, {
169
- className: "text-right",
170
- children: "Market Benchmark"
237
+ title: "No risk insights",
238
+ description: "No drift, concentration, cash-drag or fee-anomaly signals are open right now."
239
+ }) : /* @__PURE__ */ _("div", {
240
+ className: "space-y-3",
241
+ children: Z.map((e) => /* @__PURE__ */ _(Me, {
242
+ insight: e,
243
+ onAcknowledge: () => H.mutate(e.id),
244
+ onResolve: () => W.mutate(e.id),
245
+ onDismiss: () => U.mutate(e.id),
246
+ actionPending: H.isPending || W.isPending || U.isPending
247
+ }, e.id))
248
+ }) })] }),
249
+ /* @__PURE__ */ _(ue, {
250
+ open: Re,
251
+ onOpenChange: G,
252
+ children: /* @__PURE__ */ v(fe, { children: [
253
+ /* @__PURE__ */ v(he, { children: [/* @__PURE__ */ _(ge, { children: "New rebalance proposal" }), /* @__PURE__ */ _(pe, { children: "Propose a rebalance for a portfolio that has drifted from its target allocation." })] }),
254
+ $ ? /* @__PURE__ */ v("div", {
255
+ className: "grid gap-4",
256
+ children: [
257
+ /* @__PURE__ */ v("div", {
258
+ className: "space-y-2",
259
+ children: [/* @__PURE__ */ _(A, {
260
+ htmlFor: "prop-portfolio",
261
+ children: "Portfolio"
262
+ }), /* @__PURE__ */ v(be, {
263
+ value: K.portfolioId,
264
+ onValueChange: (e) => q((t) => ({
265
+ ...t,
266
+ portfolioId: e
267
+ })),
268
+ children: [/* @__PURE__ */ _(Ce, {
269
+ id: "prop-portfolio",
270
+ children: /* @__PURE__ */ _(we, { placeholder: "Select a portfolio" })
271
+ }), /* @__PURE__ */ _(xe, { children: R.map((e) => /* @__PURE__ */ _(Se, {
272
+ value: e.id,
273
+ children: e.name
274
+ }, e.id)) })]
275
+ })]
276
+ }),
277
+ /* @__PURE__ */ v("div", {
278
+ className: "space-y-2",
279
+ children: [/* @__PURE__ */ _(A, {
280
+ htmlFor: "prop-drift",
281
+ children: "Drift %"
282
+ }), /* @__PURE__ */ _(ye, {
283
+ id: "prop-drift",
284
+ type: "number",
285
+ value: K.driftPct,
286
+ onChange: (e) => q((t) => ({
287
+ ...t,
288
+ driftPct: e.target.value
289
+ })),
290
+ placeholder: "e.g. 6.5"
291
+ })]
292
+ }),
293
+ /* @__PURE__ */ v("div", {
294
+ className: "space-y-2",
295
+ children: [/* @__PURE__ */ _(A, {
296
+ htmlFor: "prop-rationale",
297
+ children: "Rationale"
298
+ }), /* @__PURE__ */ _(P, {
299
+ id: "prop-rationale",
300
+ value: K.rationale,
301
+ onChange: (e) => q((t) => ({
302
+ ...t,
303
+ rationale: e.target.value
304
+ })),
305
+ placeholder: "Why is this rebalance needed?"
306
+ })]
307
+ }),
308
+ /* @__PURE__ */ v("div", {
309
+ className: "space-y-2",
310
+ children: [
311
+ /* @__PURE__ */ _(A, {
312
+ htmlFor: "prop-trades",
313
+ children: "Trades (JSON, optional)"
314
+ }),
315
+ /* @__PURE__ */ _(P, {
316
+ id: "prop-trades",
317
+ value: K.trades,
318
+ onChange: (e) => {
319
+ Y(null), q((t) => ({
320
+ ...t,
321
+ trades: e.target.value
322
+ }));
323
+ },
324
+ placeholder: "e.g. [{\"symbol\":\"VOO\",\"action\":\"SELL\",\"quantity\":10}]"
325
+ }),
326
+ J ? /* @__PURE__ */ _("p", {
327
+ className: "text-xs text-status-error-text",
328
+ children: J
329
+ }) : null
330
+ ]
331
+ })
332
+ ]
333
+ }) : /* @__PURE__ */ _(o, {
334
+ title: "No portfolios available",
335
+ description: "Create a portfolio before proposing a rebalance."
336
+ }),
337
+ /* @__PURE__ */ v(me, { children: [/* @__PURE__ */ _(de, {
338
+ asChild: !0,
339
+ children: /* @__PURE__ */ _(b, {
340
+ variant: "outline",
341
+ children: "Cancel"
342
+ })
343
+ }), /* @__PURE__ */ _(b, {
344
+ onClick: He,
345
+ disabled: !K.portfolioId || B.isPending,
346
+ children: B.isPending ? "Creating…" : "Create proposal"
347
+ })] })
348
+ ] })
349
+ })
350
+ ]
351
+ });
352
+ }
353
+ function Me({ insight: e, onAcknowledge: t, onResolve: n, onDismiss: r, actionPending: i }) {
354
+ let a = e.status === "RESOLVED" || e.status === "DISMISSED";
355
+ return /* @__PURE__ */ v("div", {
356
+ className: "flex items-start justify-between gap-4 rounded-lg border border-border-subtle bg-bg-surface p-4",
357
+ children: [/* @__PURE__ */ v("div", {
358
+ className: "min-w-0 space-y-1",
359
+ children: [
360
+ /* @__PURE__ */ v("div", {
361
+ className: "flex flex-wrap items-center gap-2",
362
+ children: [
363
+ /* @__PURE__ */ _("p", {
364
+ className: "font-medium text-text-primary",
365
+ children: e.title
366
+ }),
367
+ /* @__PURE__ */ _(y, {
368
+ variant: u(e.severity),
369
+ children: F(e.severity)
370
+ }),
371
+ /* @__PURE__ */ _(y, {
372
+ variant: "outline",
373
+ children: F(e.type)
374
+ }),
375
+ /* @__PURE__ */ _(y, {
376
+ variant: u(e.status),
377
+ children: F(e.status)
378
+ })
379
+ ]
171
380
  }),
172
- /* @__PURE__ */ c(y, {
173
- className: "text-right",
174
- children: "Outperformance"
381
+ e.detail ? /* @__PURE__ */ _("p", {
382
+ className: "text-sm text-text-secondary",
383
+ children: e.detail
384
+ }) : null,
385
+ /* @__PURE__ */ v("p", {
386
+ className: "text-xs text-text-muted",
387
+ children: ["Detected ", c(e.createdAt)]
175
388
  })
176
- ] }) }), /* @__PURE__ */ c(_, { children: C.map((e) => /* @__PURE__ */ l(x, { children: [
177
- /* @__PURE__ */ c(v, {
178
- className: "font-medium",
179
- children: e.scenario
180
- }),
181
- /* @__PURE__ */ l(v, {
182
- className: "text-right text-red-600",
183
- children: [e.portfolio, "%"]
184
- }),
185
- /* @__PURE__ */ l(v, {
186
- className: "text-right text-red-600",
187
- children: [e.market, "%"]
389
+ ]
390
+ }), a ? /* @__PURE__ */ _("span", {
391
+ className: "mt-1 text-xs text-text-muted",
392
+ children: "Closed"
393
+ }) : /* @__PURE__ */ v(E, { children: [/* @__PURE__ */ _(k, {
394
+ asChild: !0,
395
+ children: /* @__PURE__ */ _(b, {
396
+ variant: "ghost",
397
+ size: "sm",
398
+ "aria-label": `Actions for ${e.title}`,
399
+ disabled: i,
400
+ children: /* @__PURE__ */ _(m, {
401
+ className: "size-4",
402
+ "aria-hidden": "true"
403
+ })
404
+ })
405
+ }), /* @__PURE__ */ v(D, {
406
+ align: "end",
407
+ children: [
408
+ e.status === "OPEN" ? /* @__PURE__ */ v(O, {
409
+ onClick: t,
410
+ children: [/* @__PURE__ */ _(p, {
411
+ className: "size-4",
412
+ "aria-hidden": "true"
413
+ }), "Acknowledge"]
414
+ }) : null,
415
+ /* @__PURE__ */ v(O, {
416
+ onClick: n,
417
+ children: [/* @__PURE__ */ _(g, {
418
+ className: "size-4",
419
+ "aria-hidden": "true"
420
+ }), "Resolve"]
188
421
  }),
189
- /* @__PURE__ */ c(v, {
190
- className: "text-right text-emerald-600 font-medium",
191
- children: e.outperformance
422
+ /* @__PURE__ */ v(O, {
423
+ className: "text-status-error-text",
424
+ onClick: r,
425
+ children: [/* @__PURE__ */ _(le, {
426
+ className: "size-4",
427
+ "aria-hidden": "true"
428
+ }), "Dismiss"]
192
429
  })
193
- ] }, e.scenario)) })] }) })] }),
194
- /* @__PURE__ */ l(d, { children: [/* @__PURE__ */ l(m, { children: [/* @__PURE__ */ l(h, {
195
- className: "flex items-center gap-2",
196
- children: [/* @__PURE__ */ c(s, { className: "h-5 w-5" }), "Mitigation Strategies"]
197
- }), /* @__PURE__ */ c(p, { children: "Current risk management measures and their effectiveness" })] }), /* @__PURE__ */ c(f, { children: /* @__PURE__ */ c("div", {
198
- className: "grid gap-3 md:grid-cols-2",
199
- children: w.map((e) => /* @__PURE__ */ l("div", {
200
- className: "rounded-lg border p-3",
201
- children: [/* @__PURE__ */ l("div", {
202
- className: "flex items-center justify-between mb-1",
203
- children: [/* @__PURE__ */ c("p", {
204
- className: "font-medium text-sm",
205
- children: e.strategy
206
- }), /* @__PURE__ */ c(u, {
207
- variant: e.status === "Implemented" || e.status === "Active" || e.status === "Scheduled" ? "default" : "secondary",
208
- children: e.status
209
- })]
210
- }), /* @__PURE__ */ l("p", {
211
- className: "text-xs text-muted-foreground",
212
- children: ["Effectiveness: ", e.effectiveness]
213
- })]
214
- }, e.strategy))
215
- }) })] })
216
- ]
430
+ ]
431
+ })] })]
217
432
  });
218
433
  }
219
434
  //#endregion
220
- export { T as RiskPage };
435
+ export { L as RiskPage };
221
436
 
222
437
  //# sourceMappingURL=RiskPage.js.map