@burdenoff/microfe-brainyrich 2026.525.1 → 2026.706.1

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