@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,246 +1,647 @@
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 { AlertTriangle as i, Calculator as a, CheckCircle as o, Clock as s, FileText as c, Upload as l } from "lucide-react";
4
- import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
5
- import { Badge as p, Button as m, Card as h, CardContent as g, CardDescription as _, CardHeader as v, CardTitle as y, Table as b, TableBody as x, TableCell as S, TableHead as C, TableHeader as w, TableRow as T, Tabs as E, TabsContent as D, TabsList as O, TabsTrigger as k } from "@burdenoff/fe-libs/ui";
1
+ import { useAccounts as e, useAcknowledgeInsight as t, useCreateInsight as n, useDismissInsight as r, useHoldings as i, useInsights as a, usePortfolios as o, useResolveInsight as ee, useTransactions as te } from "../hooks/useBrainyRichApi.js";
2
+ import { EmptyState as s, ErrorState as ne, KpiGrid as re, LoadingState as ie, SectionShell as ae, deltaToneClass as c, formatDate as l, formatMoney as u, statusBadgeVariant as d } from "./_shared.js";
3
+ import { useMemo as f, useState as p } from "react";
4
+ import { ArrowDownRight as oe, ArrowUpRight as m, Check as se, Coins as ce, Landmark as le, MoreHorizontal as ue, Receipt as de, ReceiptText as fe, ShieldCheck as pe, Sparkles as me, TrendingDown as h, TrendingUp as g, X as _ } from "lucide-react";
5
+ import { Fragment as he, jsx as v, jsxs as y } from "react/jsx-runtime";
6
+ import { Badge as b, Button as x, Card as S, CardContent as C, CardDescription as w, CardHeader as T, CardTitle as E, Dialog as ge, DialogClose as _e, DialogContent as ve, DialogDescription as ye, DialogFooter as be, DialogHeader as xe, DialogTitle as Se, DropdownMenu as D, DropdownMenuContent as O, DropdownMenuItem as k, DropdownMenuLabel as Ce, DropdownMenuSeparator as A, DropdownMenuTrigger as j, Input as we, Label as M, Select as N, SelectContent as P, SelectItem as F, SelectTrigger as I, SelectValue as Te, Table as L, TableBody as R, TableCell as z, TableHead as B, TableHeader as V, TableRow as H, Tabs as Ee, TabsContent as U, TabsList as De, TabsTrigger as W, Textarea as Oe } from "@burdenoff/fe-libs/ui";
6
7
  //#region src/brainyrich/pages/TaxPage.tsx
7
- var A = [
8
- {
9
- id: "ts1",
10
- strategy: "Section 80C Investments",
11
- limit: 15e4,
12
- utilized: 142e3,
13
- status: "Almost Full"
14
- },
15
- {
16
- id: "ts2",
17
- strategy: "NPS Contribution (80CCD)",
18
- limit: 5e4,
19
- utilized: 5e4,
20
- status: "Fully Utilized"
21
- },
22
- {
23
- id: "ts3",
24
- strategy: "Health Insurance (80D)",
25
- limit: 75e3,
26
- utilized: 52600,
27
- status: "Available"
28
- },
29
- {
30
- id: "ts4",
31
- strategy: "HRA Exemption",
32
- limit: 24e4,
33
- utilized: 24e4,
34
- status: "Fully Utilized"
35
- }
8
+ var ke = [
9
+ "INFO",
10
+ "LOW",
11
+ "MEDIUM",
12
+ "HIGH",
13
+ "CRITICAL"
36
14
  ];
37
- function j() {
38
- let { taxDocs: j } = e(), M = j.filter((e) => e.status === "Uploaded").length, N = j.filter((e) => e.status === "Pending").length;
39
- return /* @__PURE__ */ f(n, {
40
- title: "Tax Planning & Compliance",
41
- description: "Optimize your tax strategy, track documents, and ensure regulatory compliance",
42
- actionLabel: "Upload Document",
43
- badges: ["FY 2024-25"],
44
- children: [/* @__PURE__ */ d(t, { items: [
15
+ function G(e) {
16
+ return e.toLowerCase().split("_").map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join(" ");
17
+ }
18
+ function K(e) {
19
+ return e.marketValue - e.costBasis;
20
+ }
21
+ var q = {
22
+ title: "",
23
+ detail: "",
24
+ severity: "MEDIUM",
25
+ subject: ""
26
+ };
27
+ function J() {
28
+ let { data: i, isLoading: c, isError: d, refetch: oe } = a(), { data: m, isLoading: se, isError: ue, refetch: pe } = te(), { data: h } = e(), { data: g } = o(), _ = n(), D = t(), O = r(), k = ee(), [Ce, A] = p(!1), [j, K] = p(q), [J, Y] = p(null), X = f(() => i.filter((e) => e.type === "TAX_OPPORTUNITY"), [i]), Me = X.filter((e) => e.status === "OPEN"), Z = f(() => m.filter((e) => e.type === "SELL"), [m]), Q = f(() => m.filter((e) => e.type === "DIVIDEND" || e.type === "INTEREST"), [m]), Ne = Z.reduce((e, t) => e + t.amount, 0), Pe = Q.reduce((e, t) => e + t.amount, 0), Fe = Z[0]?.currency ?? Q[0]?.currency ?? "USD", $ = h.length > 0 || g.length > 0;
29
+ function Ie() {
30
+ K(q), Y(null), A(!0);
31
+ }
32
+ function Le() {
33
+ let e = j.title.trim();
34
+ if (!e) {
35
+ Y("A title is required.");
36
+ return;
37
+ }
38
+ if (!j.subject) {
39
+ Y("Select the account or portfolio this opportunity applies to.");
40
+ return;
41
+ }
42
+ let [t, n] = j.subject.split(":");
43
+ if (!t || !n) {
44
+ Y("Select a valid subject.");
45
+ return;
46
+ }
47
+ _.mutate({
48
+ type: "TAX_OPPORTUNITY",
49
+ severity: j.severity,
50
+ title: e,
51
+ detail: j.detail.trim() || null,
52
+ subjectId: n,
53
+ subjectType: t
54
+ }, {
55
+ onSuccess: () => {
56
+ A(!1), K(q);
57
+ },
58
+ onError: (e) => {
59
+ Y(e instanceof Error ? e.message : "Could not create the tax insight.");
60
+ }
61
+ });
62
+ }
63
+ let Re = D.isPending || O.isPending || k.isPending;
64
+ return /* @__PURE__ */ y(ae, {
65
+ title: "Tax Center",
66
+ description: "Act on tax-opportunity insights and review unrealized and realized gains — all from your live portfolio data.",
67
+ badges: [`${Me.length} open opportunit${Me.length === 1 ? "y" : "ies"}`],
68
+ actionLabel: "New tax insight",
69
+ onAction: Ie,
70
+ children: [
71
+ /* @__PURE__ */ v(re, { items: [
72
+ {
73
+ label: "Open tax opportunities",
74
+ value: String(Me.length)
75
+ },
76
+ {
77
+ label: "Tax insights (all)",
78
+ value: String(X.length)
79
+ },
80
+ {
81
+ label: "Realized proceeds",
82
+ value: u(Ne, Fe),
83
+ trend: `${Z.length} sale${Z.length === 1 ? "" : "s"}`
84
+ },
85
+ {
86
+ label: "Investment income",
87
+ value: u(Pe, Fe),
88
+ trend: `${Q.length} dividend/interest`
89
+ }
90
+ ] }),
91
+ /* @__PURE__ */ y(Ee, {
92
+ defaultValue: "opportunities",
93
+ className: "space-y-4",
94
+ children: [
95
+ /* @__PURE__ */ y(De, {
96
+ className: "grid w-full grid-cols-3",
97
+ children: [
98
+ /* @__PURE__ */ v(W, {
99
+ value: "opportunities",
100
+ children: "Tax Opportunities"
101
+ }),
102
+ /* @__PURE__ */ v(W, {
103
+ value: "unrealized",
104
+ children: "Unrealized Gains"
105
+ }),
106
+ /* @__PURE__ */ v(W, {
107
+ value: "realized",
108
+ children: "Realized Activity"
109
+ })
110
+ ]
111
+ }),
112
+ /* @__PURE__ */ v(U, {
113
+ value: "opportunities",
114
+ children: /* @__PURE__ */ y(S, { children: [/* @__PURE__ */ y(T, { children: [/* @__PURE__ */ y(E, {
115
+ className: "flex items-center gap-2",
116
+ children: [/* @__PURE__ */ v(me, {
117
+ className: "h-5 w-5",
118
+ "aria-hidden": "true"
119
+ }), "Tax-opportunity insights"]
120
+ }), /* @__PURE__ */ v(w, { children: "Tax-loss harvesting and other tax signals detected across your accounts and portfolios." })] }), /* @__PURE__ */ v(C, { children: c ? /* @__PURE__ */ v(ie, {}) : d ? /* @__PURE__ */ v(ne, { onRetry: () => oe() }) : X.length === 0 ? /* @__PURE__ */ v(s, {
121
+ icon: /* @__PURE__ */ v(de, {
122
+ className: "size-6",
123
+ "aria-hidden": "true"
124
+ }),
125
+ title: "No tax opportunities yet",
126
+ description: "Tax-opportunity insights appear here as the backend generates them from your holdings. You can also flag one manually.",
127
+ action: $ ? /* @__PURE__ */ y(x, {
128
+ size: "sm",
129
+ onClick: Ie,
130
+ children: [/* @__PURE__ */ v(me, {
131
+ className: "size-4",
132
+ "aria-hidden": "true"
133
+ }), "New tax insight"]
134
+ }) : void 0
135
+ }) : /* @__PURE__ */ v("div", {
136
+ className: "space-y-3",
137
+ children: X.map((e) => /* @__PURE__ */ v(je, {
138
+ insight: e,
139
+ actionPending: Re,
140
+ onAcknowledge: () => D.mutate(e.id),
141
+ onResolve: () => k.mutate(e.id),
142
+ onDismiss: () => O.mutate(e.id)
143
+ }, e.id))
144
+ }) })] })
145
+ }),
146
+ /* @__PURE__ */ v(U, {
147
+ value: "unrealized",
148
+ children: /* @__PURE__ */ v(Ae, { accounts: h })
149
+ }),
150
+ /* @__PURE__ */ v(U, {
151
+ value: "realized",
152
+ children: /* @__PURE__ */ y(S, { children: [/* @__PURE__ */ y(T, { children: [/* @__PURE__ */ y(E, {
153
+ className: "flex items-center gap-2",
154
+ children: [/* @__PURE__ */ v(fe, {
155
+ className: "h-5 w-5",
156
+ "aria-hidden": "true"
157
+ }), "Realized activity"]
158
+ }), /* @__PURE__ */ v(w, { children: "Realized sales, dividends and interest — the taxable events recorded on your accounts." })] }), /* @__PURE__ */ v(C, {
159
+ className: "space-y-6",
160
+ children: se ? /* @__PURE__ */ v(ie, {}) : ue ? /* @__PURE__ */ v(ne, { onRetry: () => pe() }) : Z.length === 0 && Q.length === 0 ? /* @__PURE__ */ v(s, {
161
+ icon: /* @__PURE__ */ v(fe, {
162
+ className: "size-6",
163
+ "aria-hidden": "true"
164
+ }),
165
+ title: "No taxable activity recorded",
166
+ description: "Sales, dividends and interest show up here once transactions are recorded against your accounts."
167
+ }) : /* @__PURE__ */ y(he, { children: [/* @__PURE__ */ y("div", {
168
+ className: "space-y-2",
169
+ children: [/* @__PURE__ */ y("div", {
170
+ className: "flex items-center gap-2",
171
+ children: [
172
+ /* @__PURE__ */ v(le, {
173
+ className: "size-4 text-text-secondary",
174
+ "aria-hidden": "true"
175
+ }),
176
+ /* @__PURE__ */ v("h3", {
177
+ className: "text-sm font-semibold text-text-primary",
178
+ children: "Realized sales"
179
+ }),
180
+ /* @__PURE__ */ v(b, {
181
+ variant: "secondary",
182
+ children: Z.length
183
+ })
184
+ ]
185
+ }), Z.length === 0 ? /* @__PURE__ */ v("p", {
186
+ className: "text-sm text-text-secondary",
187
+ children: "No sales recorded."
188
+ }) : /* @__PURE__ */ v("div", {
189
+ className: "overflow-x-auto",
190
+ children: /* @__PURE__ */ y(L, { children: [/* @__PURE__ */ v(V, { children: /* @__PURE__ */ y(H, { children: [
191
+ /* @__PURE__ */ v(B, { children: "Symbol" }),
192
+ /* @__PURE__ */ v(B, {
193
+ className: "text-right",
194
+ children: "Quantity"
195
+ }),
196
+ /* @__PURE__ */ v(B, {
197
+ className: "text-right",
198
+ children: "Price"
199
+ }),
200
+ /* @__PURE__ */ v(B, {
201
+ className: "text-right",
202
+ children: "Proceeds"
203
+ }),
204
+ /* @__PURE__ */ v(B, { children: "Trade date" })
205
+ ] }) }), /* @__PURE__ */ v(R, { children: Z.map((e) => /* @__PURE__ */ y(H, { children: [
206
+ /* @__PURE__ */ v(z, {
207
+ className: "font-medium text-text-primary",
208
+ children: e.symbol ?? "—"
209
+ }),
210
+ /* @__PURE__ */ v(z, {
211
+ className: "text-right text-text-secondary",
212
+ children: e.quantity
213
+ }),
214
+ /* @__PURE__ */ v(z, {
215
+ className: "text-right text-text-secondary",
216
+ children: u(e.price, e.currency)
217
+ }),
218
+ /* @__PURE__ */ v(z, {
219
+ className: "text-right font-medium text-text-primary",
220
+ children: u(e.amount, e.currency)
221
+ }),
222
+ /* @__PURE__ */ v(z, {
223
+ className: "text-text-secondary",
224
+ children: l(e.tradeDate)
225
+ })
226
+ ] }, e.id)) })] })
227
+ })]
228
+ }), /* @__PURE__ */ y("div", {
229
+ className: "space-y-2",
230
+ children: [/* @__PURE__ */ y("div", {
231
+ className: "flex items-center gap-2",
232
+ children: [
233
+ /* @__PURE__ */ v(ce, {
234
+ className: "size-4 text-text-secondary",
235
+ "aria-hidden": "true"
236
+ }),
237
+ /* @__PURE__ */ v("h3", {
238
+ className: "text-sm font-semibold text-text-primary",
239
+ children: "Dividends & interest"
240
+ }),
241
+ /* @__PURE__ */ v(b, {
242
+ variant: "secondary",
243
+ children: Q.length
244
+ })
245
+ ]
246
+ }), Q.length === 0 ? /* @__PURE__ */ v("p", {
247
+ className: "text-sm text-text-secondary",
248
+ children: "No income recorded."
249
+ }) : /* @__PURE__ */ v("div", {
250
+ className: "overflow-x-auto",
251
+ children: /* @__PURE__ */ y(L, { children: [/* @__PURE__ */ v(V, { children: /* @__PURE__ */ y(H, { children: [
252
+ /* @__PURE__ */ v(B, { children: "Type" }),
253
+ /* @__PURE__ */ v(B, { children: "Symbol" }),
254
+ /* @__PURE__ */ v(B, {
255
+ className: "text-right",
256
+ children: "Amount"
257
+ }),
258
+ /* @__PURE__ */ v(B, { children: "Trade date" })
259
+ ] }) }), /* @__PURE__ */ v(R, { children: Q.map((e) => /* @__PURE__ */ y(H, { children: [
260
+ /* @__PURE__ */ v(z, { children: /* @__PURE__ */ v(b, {
261
+ variant: "outline",
262
+ children: G(e.type)
263
+ }) }),
264
+ /* @__PURE__ */ v(z, {
265
+ className: "text-text-secondary",
266
+ children: e.symbol ?? "—"
267
+ }),
268
+ /* @__PURE__ */ v(z, {
269
+ className: "text-right font-medium text-status-success-text",
270
+ children: u(e.amount, e.currency)
271
+ }),
272
+ /* @__PURE__ */ v(z, {
273
+ className: "text-text-secondary",
274
+ children: l(e.tradeDate)
275
+ })
276
+ ] }, e.id)) })] })
277
+ })]
278
+ })] })
279
+ })] })
280
+ })
281
+ ]
282
+ }),
283
+ /* @__PURE__ */ v(ge, {
284
+ open: Ce,
285
+ onOpenChange: (e) => {
286
+ A(e), e || Y(null);
287
+ },
288
+ children: /* @__PURE__ */ y(ve, {
289
+ className: "max-h-[90vh] overflow-y-auto sm:max-w-lg",
290
+ children: [
291
+ /* @__PURE__ */ y(xe, { children: [/* @__PURE__ */ v(Se, { children: "New tax insight" }), /* @__PURE__ */ v(ye, { children: "Flag a tax opportunity against one of your accounts or portfolios." })] }),
292
+ $ ? /* @__PURE__ */ y("div", {
293
+ className: "space-y-4 py-2",
294
+ children: [
295
+ /* @__PURE__ */ y("div", {
296
+ className: "space-y-2",
297
+ children: [/* @__PURE__ */ v(M, {
298
+ htmlFor: "tax-title",
299
+ children: "Title"
300
+ }), /* @__PURE__ */ v(we, {
301
+ id: "tax-title",
302
+ value: j.title,
303
+ onChange: (e) => K((t) => ({
304
+ ...t,
305
+ title: e.target.value
306
+ })),
307
+ placeholder: "e.g. Harvest losses in tech holdings"
308
+ })]
309
+ }),
310
+ /* @__PURE__ */ y("div", {
311
+ className: "grid gap-4 sm:grid-cols-2",
312
+ children: [/* @__PURE__ */ y("div", {
313
+ className: "space-y-2",
314
+ children: [/* @__PURE__ */ v(M, {
315
+ htmlFor: "tax-severity",
316
+ children: "Severity"
317
+ }), /* @__PURE__ */ y(N, {
318
+ value: j.severity,
319
+ onValueChange: (e) => K((t) => ({
320
+ ...t,
321
+ severity: e
322
+ })),
323
+ children: [/* @__PURE__ */ v(I, {
324
+ id: "tax-severity",
325
+ children: /* @__PURE__ */ v(Te, {})
326
+ }), /* @__PURE__ */ v(P, { children: ke.map((e) => /* @__PURE__ */ v(F, {
327
+ value: e,
328
+ children: G(e)
329
+ }, e)) })]
330
+ })]
331
+ }), /* @__PURE__ */ y("div", {
332
+ className: "space-y-2",
333
+ children: [/* @__PURE__ */ v(M, {
334
+ htmlFor: "tax-subject",
335
+ children: "Applies to"
336
+ }), /* @__PURE__ */ y(N, {
337
+ value: j.subject,
338
+ onValueChange: (e) => K((t) => ({
339
+ ...t,
340
+ subject: e
341
+ })),
342
+ children: [/* @__PURE__ */ v(I, {
343
+ id: "tax-subject",
344
+ children: /* @__PURE__ */ v(Te, { placeholder: "Select subject" })
345
+ }), /* @__PURE__ */ y(P, { children: [g.map((e) => /* @__PURE__ */ y(F, {
346
+ value: `portfolio:${e.id}`,
347
+ children: ["Portfolio · ", e.name]
348
+ }, `portfolio:${e.id}`)), h.map((e) => /* @__PURE__ */ y(F, {
349
+ value: `account:${e.id}`,
350
+ children: ["Account · ", e.name]
351
+ }, `account:${e.id}`))] })]
352
+ })]
353
+ })]
354
+ }),
355
+ /* @__PURE__ */ y("div", {
356
+ className: "space-y-2",
357
+ children: [/* @__PURE__ */ v(M, {
358
+ htmlFor: "tax-detail",
359
+ children: "Detail"
360
+ }), /* @__PURE__ */ v(Oe, {
361
+ id: "tax-detail",
362
+ value: j.detail,
363
+ onChange: (e) => K((t) => ({
364
+ ...t,
365
+ detail: e.target.value
366
+ })),
367
+ rows: 3,
368
+ placeholder: "What is the opportunity and how should it be actioned?"
369
+ })]
370
+ }),
371
+ J ? /* @__PURE__ */ v("p", {
372
+ className: "text-sm text-status-error-text",
373
+ role: "alert",
374
+ children: J
375
+ }) : null
376
+ ]
377
+ }) : /* @__PURE__ */ v(s, {
378
+ title: "No subject available",
379
+ description: "Create an account or portfolio first, then flag a tax opportunity against it."
380
+ }),
381
+ /* @__PURE__ */ y(be, { children: [/* @__PURE__ */ v(_e, {
382
+ asChild: !0,
383
+ children: /* @__PURE__ */ v(x, {
384
+ variant: "outline",
385
+ disabled: _.isPending,
386
+ children: "Cancel"
387
+ })
388
+ }), /* @__PURE__ */ v(x, {
389
+ onClick: Le,
390
+ disabled: !$ || !j.title.trim() || !j.subject || _.isPending,
391
+ children: _.isPending ? "Creating…" : "Create insight"
392
+ })] })
393
+ ]
394
+ })
395
+ })
396
+ ]
397
+ });
398
+ }
399
+ function Ae({ accounts: e }) {
400
+ let [t, n] = p(""), r = t || e[0]?.id, a = e.find((e) => e.id === r), { data: o, isLoading: ee, isError: te, refetch: ae } = i({ accountId: r }), c = a?.currency ?? o[0]?.currency ?? "USD", l = o.reduce((e, t) => e + K(t), 0), d = o.filter((e) => K(e) > 0).length, oe = o.filter((e) => K(e) < 0).length, m = f(() => {
401
+ let e = /* @__PURE__ */ new Map();
402
+ for (let t of o) {
403
+ let n = e.get(t.assetClass) ?? [];
404
+ n.push(t), e.set(t.assetClass, n);
405
+ }
406
+ return Array.from(e.entries());
407
+ }, [o]);
408
+ return e.length === 0 ? /* @__PURE__ */ v(S, { children: /* @__PURE__ */ v(C, {
409
+ className: "pt-6",
410
+ children: /* @__PURE__ */ v(s, {
411
+ icon: /* @__PURE__ */ v(g, {
412
+ className: "size-6",
413
+ "aria-hidden": "true"
414
+ }),
415
+ title: "No accounts yet",
416
+ description: "Add an account with holdings to see unrealized gains and losses."
417
+ })
418
+ }) }) : /* @__PURE__ */ y(S, { children: [/* @__PURE__ */ y(T, {
419
+ className: "flex flex-col gap-4 md:flex-row md:items-start md:justify-between",
420
+ children: [/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ y(E, {
421
+ className: "flex items-center gap-2",
422
+ children: [/* @__PURE__ */ v(g, {
423
+ className: "h-5 w-5",
424
+ "aria-hidden": "true"
425
+ }), "Unrealized gains & losses"]
426
+ }), /* @__PURE__ */ v(w, { children: "Market value minus cost basis for each holding in the selected account." })] }), /* @__PURE__ */ y("div", {
427
+ className: "w-full md:w-64",
428
+ children: [/* @__PURE__ */ v(M, {
429
+ htmlFor: "unrealized-account",
430
+ className: "sr-only",
431
+ children: "Account"
432
+ }), /* @__PURE__ */ y(N, {
433
+ value: r ?? "",
434
+ onValueChange: n,
435
+ children: [/* @__PURE__ */ v(I, {
436
+ id: "unrealized-account",
437
+ children: /* @__PURE__ */ v(Te, { placeholder: "Select account" })
438
+ }), /* @__PURE__ */ v(P, { children: e.map((e) => /* @__PURE__ */ v(F, {
439
+ value: e.id,
440
+ children: e.name
441
+ }, e.id)) })]
442
+ })]
443
+ })]
444
+ }), /* @__PURE__ */ v(C, {
445
+ className: "space-y-4",
446
+ children: ee ? /* @__PURE__ */ v(ie, {}) : te ? /* @__PURE__ */ v(ne, { onRetry: () => ae() }) : o.length === 0 ? /* @__PURE__ */ v(s, {
447
+ icon: /* @__PURE__ */ v(g, {
448
+ className: "size-6",
449
+ "aria-hidden": "true"
450
+ }),
451
+ title: "No holdings in this account",
452
+ description: "Unrealized gains appear once this account has holdings with a cost basis."
453
+ }) : /* @__PURE__ */ y(he, { children: [/* @__PURE__ */ v(re, { items: [
45
454
  {
46
- label: "Estimated Tax Liability",
47
- value: "$18,400",
48
- trend: "After deductions"
455
+ label: "Unrealized P/L",
456
+ value: u(l, c),
457
+ trend: l >= 0 ? "Net gain" : "Net loss",
458
+ deltaTone: l >= 0 ? "positive" : "negative"
49
459
  },
50
460
  {
51
- label: "Total Deductions",
52
- value: "$28,500",
53
- trend: "Across all sections"
461
+ label: "Holdings",
462
+ value: String(o.length)
54
463
  },
55
464
  {
56
- label: "Effective Tax Rate",
57
- value: "18.5%",
58
- trend: "Below bracket avg"
465
+ label: "Gainers",
466
+ value: String(d)
59
467
  },
60
468
  {
61
- label: "Tax-Loss Harvesting",
62
- value: "$7,200",
63
- trend: "Potential savings"
469
+ label: "Losers",
470
+ value: String(oe)
64
471
  }
65
- ] }), /* @__PURE__ */ f(E, {
66
- defaultValue: "documents",
67
- className: "space-y-4",
472
+ ] }), /* @__PURE__ */ v("div", {
473
+ className: "space-y-6",
474
+ children: m.map(([e, t]) => {
475
+ let n = t.reduce((e, t) => e + K(t), 0);
476
+ return /* @__PURE__ */ y("div", {
477
+ className: "space-y-2",
478
+ children: [/* @__PURE__ */ y("div", {
479
+ className: "flex items-center justify-between",
480
+ children: [/* @__PURE__ */ y("div", {
481
+ className: "flex items-center gap-2",
482
+ children: [/* @__PURE__ */ v("h3", {
483
+ className: "text-sm font-semibold text-text-primary",
484
+ children: G(e)
485
+ }), /* @__PURE__ */ v(b, {
486
+ variant: "secondary",
487
+ children: t.length
488
+ })]
489
+ }), /* @__PURE__ */ v(Y, {
490
+ value: n,
491
+ currency: c
492
+ })]
493
+ }), /* @__PURE__ */ v("div", {
494
+ className: "overflow-x-auto",
495
+ children: /* @__PURE__ */ y(L, { children: [/* @__PURE__ */ v(V, { children: /* @__PURE__ */ y(H, { children: [
496
+ /* @__PURE__ */ v(B, { children: "Symbol" }),
497
+ /* @__PURE__ */ v(B, {
498
+ className: "text-right",
499
+ children: "Quantity"
500
+ }),
501
+ /* @__PURE__ */ v(B, {
502
+ className: "text-right",
503
+ children: "Cost basis"
504
+ }),
505
+ /* @__PURE__ */ v(B, {
506
+ className: "text-right",
507
+ children: "Market value"
508
+ }),
509
+ /* @__PURE__ */ v(B, {
510
+ className: "text-right",
511
+ children: "Unrealized"
512
+ })
513
+ ] }) }), /* @__PURE__ */ v(R, { children: t.map((e) => /* @__PURE__ */ y(H, { children: [
514
+ /* @__PURE__ */ y(z, { children: [/* @__PURE__ */ v("p", {
515
+ className: "font-medium text-text-primary",
516
+ children: e.symbol
517
+ }), e.name ? /* @__PURE__ */ v("p", {
518
+ className: "text-xs text-text-secondary",
519
+ children: e.name
520
+ }) : null] }),
521
+ /* @__PURE__ */ v(z, {
522
+ className: "text-right text-text-secondary",
523
+ children: e.quantity
524
+ }),
525
+ /* @__PURE__ */ v(z, {
526
+ className: "text-right text-text-secondary",
527
+ children: u(e.costBasis, e.currency)
528
+ }),
529
+ /* @__PURE__ */ v(z, {
530
+ className: "text-right text-text-primary",
531
+ children: u(e.marketValue, e.currency)
532
+ }),
533
+ /* @__PURE__ */ v(z, {
534
+ className: "text-right",
535
+ children: /* @__PURE__ */ v(Y, {
536
+ value: K(e),
537
+ currency: e.currency
538
+ })
539
+ })
540
+ ] }, e.id)) })] })
541
+ })]
542
+ }, e);
543
+ })
544
+ })] })
545
+ })] });
546
+ }
547
+ function Y({ value: e, currency: t }) {
548
+ let n = e > 0, r = n ? m : e < 0 ? oe : h, i = n ? "+" : "";
549
+ return /* @__PURE__ */ y("span", {
550
+ className: `inline-flex items-center justify-end gap-1 font-semibold ${c(e)}`,
551
+ children: [
552
+ e === 0 ? null : /* @__PURE__ */ v(r, {
553
+ className: "size-4",
554
+ "aria-hidden": "true"
555
+ }),
556
+ i,
557
+ u(e, t)
558
+ ]
559
+ });
560
+ }
561
+ function je({ insight: e, actionPending: t, onAcknowledge: n, onResolve: r, onDismiss: i }) {
562
+ let a = e.status === "RESOLVED" || e.status === "DISMISSED";
563
+ return /* @__PURE__ */ y("div", {
564
+ className: "flex items-start justify-between gap-4 rounded-lg border border-border-subtle bg-bg-surface p-4",
565
+ children: [/* @__PURE__ */ y("div", {
566
+ className: "min-w-0 space-y-1",
68
567
  children: [
69
- /* @__PURE__ */ f(O, {
70
- className: "grid w-full grid-cols-3",
568
+ /* @__PURE__ */ y("div", {
569
+ className: "flex flex-wrap items-center gap-2",
71
570
  children: [
72
- /* @__PURE__ */ d(k, {
73
- value: "documents",
74
- children: "Documents"
571
+ /* @__PURE__ */ v("p", {
572
+ className: "font-medium text-text-primary",
573
+ children: e.title
75
574
  }),
76
- /* @__PURE__ */ d(k, {
77
- value: "deductions",
78
- children: "Deduction Planner"
575
+ /* @__PURE__ */ v(b, {
576
+ variant: d(e.severity),
577
+ children: G(e.severity)
79
578
  }),
80
- /* @__PURE__ */ d(k, {
81
- value: "actions",
82
- children: "Tax Actions"
579
+ /* @__PURE__ */ v(b, {
580
+ variant: d(e.status),
581
+ children: G(e.status)
83
582
  })
84
583
  ]
85
584
  }),
86
- /* @__PURE__ */ d(D, {
87
- value: "documents",
88
- children: /* @__PURE__ */ f(h, { children: [/* @__PURE__ */ f(v, {
89
- className: "flex flex-row items-center justify-between",
90
- children: [/* @__PURE__ */ f("div", { children: [/* @__PURE__ */ f(y, {
91
- className: "flex items-center gap-2",
92
- children: [/* @__PURE__ */ d(c, { className: "h-5 w-5" }), "Tax Documents"]
93
- }), /* @__PURE__ */ f(_, { children: [
94
- M,
95
- " uploaded, ",
96
- N,
97
- " pending"
98
- ] })] }), /* @__PURE__ */ f(m, {
99
- size: "sm",
100
- children: [/* @__PURE__ */ d(l, { className: "mr-1 h-4 w-4" }), "Upload"]
101
- })]
102
- }), /* @__PURE__ */ d(g, { children: /* @__PURE__ */ f(b, { children: [/* @__PURE__ */ d(w, { children: /* @__PURE__ */ f(T, { children: [
103
- /* @__PURE__ */ d(C, { children: "Document" }),
104
- /* @__PURE__ */ d(C, { children: "Tax Year" }),
105
- /* @__PURE__ */ d(C, { children: "Status" }),
106
- /* @__PURE__ */ d(C, {
107
- className: "text-right",
108
- children: "Action"
109
- })
110
- ] }) }), /* @__PURE__ */ d(x, { children: j.map((e) => /* @__PURE__ */ f(T, { children: [
111
- /* @__PURE__ */ d(S, {
112
- className: "font-medium",
113
- children: e.name
114
- }),
115
- /* @__PURE__ */ d(S, { children: e.taxYear }),
116
- /* @__PURE__ */ d(S, { children: /* @__PURE__ */ d(p, {
117
- variant: r(e.status),
118
- children: e.status === "Uploaded" ? /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d(o, { className: "mr-1 h-3 w-3" }), e.status] }) : /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d(s, { className: "mr-1 h-3 w-3" }), e.status] })
119
- }) }),
120
- /* @__PURE__ */ d(S, {
121
- className: "text-right",
122
- children: /* @__PURE__ */ d(m, {
123
- variant: "outline",
124
- size: "sm",
125
- children: e.status === "Uploaded" ? "View" : "Upload"
126
- })
127
- })
128
- ] }, e.id)) })] }) })] })
129
- }),
130
- /* @__PURE__ */ d(D, {
131
- value: "deductions",
132
- className: "space-y-4",
133
- children: /* @__PURE__ */ f(h, { children: [/* @__PURE__ */ f(v, { children: [/* @__PURE__ */ f(y, {
134
- className: "flex items-center gap-2",
135
- children: [/* @__PURE__ */ d(a, { className: "h-5 w-5" }), "Deduction Utilization"]
136
- }), /* @__PURE__ */ d(_, { children: "Track your progress across all tax-saving sections" })] }), /* @__PURE__ */ d(g, {
137
- className: "space-y-4",
138
- children: A.map((e) => {
139
- let t = Math.round(e.utilized / e.limit * 100), n = e.limit - e.utilized;
140
- return /* @__PURE__ */ f("div", {
141
- className: "space-y-2",
142
- children: [
143
- /* @__PURE__ */ f("div", {
144
- className: "flex items-center justify-between",
145
- children: [/* @__PURE__ */ d("span", {
146
- className: "font-medium text-sm",
147
- children: e.strategy
148
- }), /* @__PURE__ */ d(p, {
149
- variant: t >= 100 ? "default" : t >= 80 ? "secondary" : "destructive",
150
- children: e.status
151
- })]
152
- }),
153
- /* @__PURE__ */ d("div", {
154
- className: "h-3 rounded bg-muted overflow-hidden",
155
- children: /* @__PURE__ */ d("div", {
156
- className: `h-3 rounded ${t >= 100 ? "bg-emerald-500" : "bg-blue-500"}`,
157
- style: { width: `${Math.min(t, 100)}%` }
158
- })
159
- }),
160
- /* @__PURE__ */ f("div", {
161
- className: "flex justify-between text-xs text-muted-foreground",
162
- children: [/* @__PURE__ */ f("span", { children: [
163
- "$",
164
- e.utilized.toLocaleString(),
165
- " / $",
166
- e.limit.toLocaleString()
167
- ] }), /* @__PURE__ */ d("span", { children: n > 0 ? `$${n.toLocaleString()} available` : "Fully utilized" })]
168
- })
169
- ]
170
- }, e.id);
171
- })
172
- })] })
585
+ e.detail ? /* @__PURE__ */ v("p", {
586
+ className: "text-sm text-text-secondary",
587
+ children: e.detail
588
+ }) : null,
589
+ /* @__PURE__ */ y("p", {
590
+ className: "text-xs text-text-muted",
591
+ children: [
592
+ G(e.subjectType),
593
+ " · Detected ",
594
+ l(e.createdAt)
595
+ ]
596
+ })
597
+ ]
598
+ }), a ? /* @__PURE__ */ v("span", {
599
+ className: "mt-1 text-xs text-text-muted",
600
+ children: "Closed"
601
+ }) : /* @__PURE__ */ y(D, { children: [/* @__PURE__ */ v(j, {
602
+ asChild: !0,
603
+ children: /* @__PURE__ */ v(x, {
604
+ variant: "ghost",
605
+ size: "sm",
606
+ "aria-label": `Actions for ${e.title}`,
607
+ disabled: t,
608
+ children: /* @__PURE__ */ v(ue, {
609
+ className: "size-4",
610
+ "aria-hidden": "true"
611
+ })
612
+ })
613
+ }), /* @__PURE__ */ y(O, {
614
+ align: "end",
615
+ children: [
616
+ /* @__PURE__ */ v(Ce, { children: "Actions" }),
617
+ /* @__PURE__ */ v(A, {}),
618
+ e.status === "OPEN" ? /* @__PURE__ */ y(k, {
619
+ onClick: n,
620
+ children: [/* @__PURE__ */ v(se, {
621
+ className: "size-4",
622
+ "aria-hidden": "true"
623
+ }), "Acknowledge"]
624
+ }) : null,
625
+ /* @__PURE__ */ y(k, {
626
+ onClick: r,
627
+ children: [/* @__PURE__ */ v(pe, {
628
+ className: "size-4",
629
+ "aria-hidden": "true"
630
+ }), "Resolve"]
173
631
  }),
174
- /* @__PURE__ */ d(D, {
175
- value: "actions",
176
- className: "space-y-4",
177
- children: /* @__PURE__ */ d("div", {
178
- className: "grid gap-4 md:grid-cols-2",
179
- children: [
180
- {
181
- icon: o,
182
- title: "Maximize 80C Investments",
183
- desc: "You can invest $8,000 more in ELSS funds this year",
184
- color: "bg-emerald-50 border-emerald-200",
185
- iconColor: "text-emerald-600",
186
- action: "Invest Now"
187
- },
188
- {
189
- icon: a,
190
- title: "Tax-Loss Harvesting",
191
- desc: "Potential $7,200 savings from unrealized losses in portfolio",
192
- color: "bg-purple-50 border-purple-200",
193
- iconColor: "text-purple-600",
194
- action: "Analyze Portfolio"
195
- },
196
- {
197
- icon: i,
198
- title: "Advance Tax Deadline",
199
- desc: "Next quarterly advance tax installment of $4,600 due June 15",
200
- color: "bg-yellow-50 border-yellow-200",
201
- iconColor: "text-yellow-600",
202
- action: "Schedule Payment"
203
- },
204
- {
205
- icon: c,
206
- title: "Review Health Insurance",
207
- desc: "Optimize Section 80D benefits - $22,400 still available",
208
- color: "bg-blue-50 border-blue-200",
209
- iconColor: "text-blue-600",
210
- action: "Review Benefits"
211
- }
212
- ].map((e) => /* @__PURE__ */ d(h, {
213
- className: `${e.color} border`,
214
- children: /* @__PURE__ */ f(g, {
215
- className: "flex items-start gap-3 p-4",
216
- children: [/* @__PURE__ */ d(e.icon, { className: `h-5 w-5 mt-0.5 ${e.iconColor}` }), /* @__PURE__ */ f("div", {
217
- className: "flex-1",
218
- children: [
219
- /* @__PURE__ */ d("p", {
220
- className: "font-medium text-sm",
221
- children: e.title
222
- }),
223
- /* @__PURE__ */ d("p", {
224
- className: "text-xs text-muted-foreground mt-1",
225
- children: e.desc
226
- }),
227
- /* @__PURE__ */ d(m, {
228
- variant: "outline",
229
- size: "sm",
230
- className: "mt-2",
231
- children: e.action
232
- })
233
- ]
234
- })]
235
- })
236
- }, e.title))
237
- })
632
+ /* @__PURE__ */ y(k, {
633
+ className: "text-status-error-text",
634
+ onClick: i,
635
+ children: [/* @__PURE__ */ v(_, {
636
+ className: "size-4",
637
+ "aria-hidden": "true"
638
+ }), "Dismiss"]
238
639
  })
239
640
  ]
240
- })]
641
+ })] })]
241
642
  });
242
643
  }
243
644
  //#endregion
244
- export { j as TaxPage };
645
+ export { J as TaxPage };
245
646
 
246
647
  //# sourceMappingURL=TaxPage.js.map