@burdenoff/microfe-brainyrich 2026.825.1 → 2026.827.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 (29) hide show
  1. package/dist/brainyrich/components/reuse/DocumentsPanel.d.ts +4 -0
  2. package/dist/brainyrich/components/reuse/DocumentsPanel.d.ts.map +1 -1
  3. package/dist/brainyrich/components/reuse/DocumentsPanel.js +150 -99
  4. package/dist/brainyrich/components/reuse/DocumentsPanel.js.map +1 -1
  5. package/dist/brainyrich/hooks/useBrainyRichApi.d.ts +176 -0
  6. package/dist/brainyrich/hooks/useBrainyRichApi.d.ts.map +1 -1
  7. package/dist/brainyrich/hooks/useBrainyRichApi.js +96 -82
  8. package/dist/brainyrich/hooks/useBrainyRichApi.js.map +1 -1
  9. package/dist/brainyrich/pages/AdminFirmPage.d.ts.map +1 -1
  10. package/dist/brainyrich/pages/AdminFirmPage.js +115 -83
  11. package/dist/brainyrich/pages/AdminFirmPage.js.map +1 -1
  12. package/dist/brainyrich/pages/AiAssistantPage.d.ts.map +1 -1
  13. package/dist/brainyrich/pages/AiAssistantPage.js +251 -230
  14. package/dist/brainyrich/pages/AiAssistantPage.js.map +1 -1
  15. package/dist/brainyrich/pages/FirmPage.d.ts.map +1 -1
  16. package/dist/brainyrich/pages/FirmPage.js +148 -116
  17. package/dist/brainyrich/pages/FirmPage.js.map +1 -1
  18. package/dist/brainyrich/pages/PortfoliosPage.d.ts +14 -0
  19. package/dist/brainyrich/pages/PortfoliosPage.d.ts.map +1 -1
  20. package/dist/brainyrich/pages/PortfoliosPage.js +530 -353
  21. package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
  22. package/dist/brainyrich/pages/RiskPage.d.ts.map +1 -1
  23. package/dist/brainyrich/pages/RiskPage.js +381 -396
  24. package/dist/brainyrich/pages/RiskPage.js.map +1 -1
  25. package/dist/brainyrich/pages/_shared.d.ts +21 -0
  26. package/dist/brainyrich/pages/_shared.d.ts.map +1 -1
  27. package/dist/brainyrich/pages/_shared.js +66 -31
  28. package/dist/brainyrich/pages/_shared.js.map +1 -1
  29. package/package.json +1 -1
@@ -1,20 +1,20 @@
1
- import { useArchivePortfolio as e, useCreateHolding as t, useCreatePortfolio as n, useDeleteHolding as r, useHouseholds as i, useModelPortfolios as a, usePagedPortfolios as o, usePortfolio as s, useUpdateHolding as c, useUpdatePortfolio as l } from "../hooks/useBrainyRichApi.js";
2
- import { LoadMore as u } from "../components/LoadMore.js";
3
- import { ConfirmDialog as d } from "../components/ConfirmDialog.js";
4
- import { DonutChart as f, FadeIn as p, GlassCard as m, StatTile as h } from "../components/viz.js";
5
- import { AccountPicker as g } from "../components/pickers.js";
1
+ import { useAllHoldings as e, useArchivePortfolio as t, useCreateHolding as n, useCreatePortfolio as r, useDeleteHolding as i, useHouseholds as a, useModelPortfolios as o, usePagedPortfolios as s, usePortfolio as c, useUpdateHolding as l, useUpdatePortfolio as u } from "../hooks/useBrainyRichApi.js";
2
+ import { LoadMore as d } from "../components/LoadMore.js";
3
+ import { ConfirmDialog as f } from "../components/ConfirmDialog.js";
4
+ import { DonutChart as p, FadeIn as m, GlassCard as h, StatTile as g } from "../components/viz.js";
5
+ import { AccountPicker as _ } from "../components/pickers.js";
6
6
  import "../components/index.js";
7
- import { AllocationBars as _, EmptyState as ee, ErrorState as te, LoadingState as ne, SectionShell as re, formatCompact as ie, formatMoney as v, formatPct as y, statusBadgeVariant as b } from "./_shared.js";
8
- import { hapticSuccess as x, showToast as S } from "../utils/nativeControls.js";
9
- import { useTrackBrainyRichPageView as C } from "../hooks/useBrainyRichAnalytics.js";
10
- import { TagField as w } from "../components/reuse/TagField.js";
11
- import { CommentThread as ae } from "../components/reuse/CommentThread.js";
12
- import { useMemo as T, useState as E } from "react";
13
- import { ArrowDownRight as D, ArrowUpRight as O, Briefcase as k, MoreHorizontal as oe, Pencil as se, Plus as A, Trash2 as ce } from "lucide-react";
14
- import { Fragment as le, jsx as j, jsxs as M } from "react/jsx-runtime";
15
- import { Badge as N, Button as P, Card as F, CardContent as I, CardDescription as ue, CardHeader as de, CardTitle as fe, Dialog as L, DialogContent as R, DialogDescription as pe, DialogFooter as z, DialogHeader as B, DialogTitle as me, DropdownMenu as he, DropdownMenuContent as ge, DropdownMenuItem as V, DropdownMenuLabel as _e, DropdownMenuSeparator as ve, DropdownMenuTrigger as ye, Input as H, Label as U, Select as W, SelectContent as G, SelectItem as K, SelectTrigger as q, SelectValue as J, Sheet as be, SheetContent as xe, SheetDescription as Se, SheetHeader as Ce, SheetTitle as we, Table as Te, TableBody as Ee, TableCell as Y, TableHead as X, TableHeader as De, TableRow as Oe, Textarea as ke } from "@burdenoff/fe-libs/ui";
7
+ import { AllocationBars as ee, EmptyState as te, ErrorState as ne, LoadingState as re, SectionShell as ie, deltaToneClass as v, formatCompact as y, formatMoney as b, formatPct as x, statusBadgeVariant as S } from "./_shared.js";
8
+ import { hapticSuccess as C, showToast as w } from "../utils/nativeControls.js";
9
+ import { useTrackBrainyRichPageView as T } from "../hooks/useBrainyRichAnalytics.js";
10
+ import { TagField as ae } from "../components/reuse/TagField.js";
11
+ import { CommentThread as oe } from "../components/reuse/CommentThread.js";
12
+ import { useMemo as E, useState as D } from "react";
13
+ import { ArrowDownRight as O, ArrowUpRight as k, Briefcase as A, MoreHorizontal as se, Pencil as ce, Plus as le, Trash2 as ue } from "lucide-react";
14
+ import { Fragment as de, jsx as j, jsxs as M } from "react/jsx-runtime";
15
+ import { Badge as N, Button as P, Card as F, CardContent as I, CardDescription as L, CardHeader as R, CardTitle as z, Dialog as B, DialogContent as V, DialogDescription as fe, DialogFooter as H, DialogHeader as U, DialogTitle as W, DropdownMenu as pe, DropdownMenuContent as me, DropdownMenuItem as G, DropdownMenuLabel as he, DropdownMenuSeparator as ge, DropdownMenuTrigger as _e, Input as K, Label as q, Select as ve, SelectContent as ye, SelectItem as J, SelectTrigger as be, SelectValue as xe, Sheet as Se, SheetContent as Ce, SheetDescription as we, SheetHeader as Te, SheetTitle as Ee, Table as De, TableBody as Oe, TableCell as Y, TableHead as X, TableHeader as ke, TableRow as Ae, Textarea as je } from "@burdenoff/fe-libs/ui";
16
16
  //#region src/brainyrich/pages/PortfoliosPage.tsx
17
- var Ae = [
17
+ var Me = [
18
18
  "EQUITY",
19
19
  "FIXED_INCOME",
20
20
  "CASH",
@@ -22,7 +22,7 @@ var Ae = [
22
22
  "COMMODITY",
23
23
  "CRYPTO",
24
24
  "ALTERNATIVE"
25
- ], je = [
25
+ ], Ne = [
26
26
  "DRAFT",
27
27
  "ACTIVE",
28
28
  "ARCHIVED"
@@ -30,7 +30,7 @@ var Ae = [
30
30
  if (e.trim() === "") return;
31
31
  let t = Number(e);
32
32
  return Number.isFinite(t) ? t : void 0;
33
- }, Me = {
33
+ }, Pe = {
34
34
  EQUITY: "brand",
35
35
  FIXED_INCOME: "blue",
36
36
  CASH: "teal",
@@ -38,29 +38,72 @@ var Ae = [
38
38
  COMMODITY: "warning",
39
39
  CRYPTO: "indigo",
40
40
  ALTERNATIVE: "info"
41
- }, Ne = (e) => Me[e.toUpperCase()] ?? "neutral";
42
- function Pe(e) {
43
- return !e || typeof e != "object" ? [] : Object.entries(e).map(([e, t]) => ({
44
- label: e,
45
- value: Number(t)
46
- })).filter((e) => Number.isFinite(e.value)).map((e) => ({
47
- label: Q(e.label),
48
- value: e.value,
41
+ }, Fe = (e) => Pe[e.toUpperCase()] ?? "neutral";
42
+ function Ie(e) {
43
+ return Array.isArray(e) ? e.flatMap((e) => {
44
+ if (!e || typeof e != "object") return [];
45
+ let { assetClass: t, targetPct: n } = e;
46
+ if (typeof t != "string") return [];
47
+ let r = Number(n);
48
+ return Number.isFinite(r) ? [{
49
+ assetClass: t,
50
+ targetPct: r
51
+ }] : [];
52
+ }) : e && typeof e == "object" ? Object.entries(e).flatMap(([e, t]) => {
53
+ let n = Number(t);
54
+ return Number.isFinite(n) ? [{
55
+ assetClass: e,
56
+ targetPct: n
57
+ }] : [];
58
+ }) : [];
59
+ }
60
+ function Le(e) {
61
+ return Ie(e).map((e) => ({
62
+ label: Q(e.assetClass),
63
+ value: e.targetPct,
49
64
  tone: "accent"
50
65
  }));
51
66
  }
52
- function Fe(e) {
53
- return !e || typeof e != "object" ? [] : Object.entries(e).map(([e, t]) => ({
54
- key: e,
55
- value: Number(t)
56
- })).filter((e) => Number.isFinite(e.value) && e.value > 0).sort((e, t) => t.value - e.value).map((e) => ({
57
- label: Q(e.key),
58
- value: e.value,
59
- tone: Ne(e.key)
67
+ function Re(e) {
68
+ return Ie(e).filter((e) => e.targetPct > 0).sort((e, t) => t.targetPct - e.targetPct).map((e) => ({
69
+ label: Q(e.assetClass),
70
+ value: e.targetPct,
71
+ tone: Fe(e.assetClass)
60
72
  }));
61
73
  }
62
- function Ie({ value: e, currency: t }) {
63
- let n = e > 0, r = e < 0, i = n ? "text-status-success-text" : r ? "text-status-error-text" : "text-text-secondary", a = n ? O : r ? D : null;
74
+ var ze = {
75
+ marketValue: 0,
76
+ costBasis: 0,
77
+ unrealizedGain: 0,
78
+ gainPct: null,
79
+ holdingCount: 0,
80
+ maxDriftPct: null,
81
+ driftAssetClass: null
82
+ };
83
+ function Be(e, t) {
84
+ if (e.length === 0) return ze;
85
+ let n = 0, r = 0, i = /* @__PURE__ */ new Map();
86
+ for (let t of e) n += t.marketValue, r += t.costBasis, i.set(t.assetClass, (i.get(t.assetClass) ?? 0) + t.marketValue);
87
+ let a = n - r, o = Ie(t), s = null, c = null;
88
+ if (o.length > 0 && n > 0) {
89
+ let e = new Set([...i.keys(), ...o.map((e) => e.assetClass)]);
90
+ for (let t of e) {
91
+ let e = (i.get(t) ?? 0) / n * 100 - (o.find((e) => e.assetClass === t)?.targetPct ?? 0);
92
+ (s === null || Math.abs(e) > Math.abs(s)) && (s = e, c = t);
93
+ }
94
+ }
95
+ return {
96
+ marketValue: n,
97
+ costBasis: r,
98
+ unrealizedGain: a,
99
+ gainPct: r > 0 ? a / r * 100 : null,
100
+ holdingCount: e.length,
101
+ maxDriftPct: s,
102
+ driftAssetClass: c
103
+ };
104
+ }
105
+ function Ve({ value: e, currency: t }) {
106
+ let n = e > 0, r = e < 0, i = n ? "text-status-success-text" : r ? "text-status-error-text" : "text-text-secondary", a = n ? k : r ? O : null;
64
107
  return /* @__PURE__ */ M("span", {
65
108
  className: `inline-flex items-center justify-end gap-1 font-medium ${i}`,
66
109
  children: [
@@ -69,11 +112,11 @@ function Ie({ value: e, currency: t }) {
69
112
  "aria-hidden": "true"
70
113
  }) : null,
71
114
  n ? "+" : "",
72
- v(e, t)
115
+ b(e, t)
73
116
  ]
74
117
  });
75
118
  }
76
- function Le() {
119
+ function He() {
77
120
  return {
78
121
  name: "",
79
122
  baseCurrency: "USD",
@@ -84,34 +127,34 @@ function Le() {
84
127
  householdId: Z
85
128
  };
86
129
  }
87
- function Re({ open: e, onOpenChange: t, editing: r }) {
88
- let { data: o } = a(), { data: s } = i(), c = n(), u = l(), [d, f] = E(Le), [p, m] = E(null), h = r?.id ?? "new";
89
- e && p !== h && (m(h), f(r ? {
90
- name: r.name,
91
- baseCurrency: r.baseCurrency,
92
- description: r.description ?? "",
93
- driftThresholdPct: String(r.driftThresholdPct),
94
- status: r.status,
95
- modelPortfolioId: r.modelPortfolioId ?? Z,
96
- householdId: r.householdId ?? Z
97
- } : Le())), !e && p !== null && m(null);
98
- let g = c.isPending || u.isPending, _ = d.name.trim().length > 0;
99
- return /* @__PURE__ */ j(L, {
130
+ function Ue({ open: e, onOpenChange: t, editing: n }) {
131
+ let { data: i } = o(), { data: s } = a(), c = r(), l = u(), [d, f] = D(He), [p, m] = D(null), h = n?.id ?? "new";
132
+ e && p !== h && (m(h), f(n ? {
133
+ name: n.name,
134
+ baseCurrency: n.baseCurrency,
135
+ description: n.description ?? "",
136
+ driftThresholdPct: String(n.driftThresholdPct),
137
+ status: n.status,
138
+ modelPortfolioId: n.modelPortfolioId ?? Z,
139
+ householdId: n.householdId ?? Z
140
+ } : He())), !e && p !== null && m(null);
141
+ let g = c.isPending || l.isPending, _ = d.name.trim().length > 0;
142
+ return /* @__PURE__ */ j(B, {
100
143
  open: e,
101
144
  onOpenChange: t,
102
- children: /* @__PURE__ */ M(R, {
145
+ children: /* @__PURE__ */ M(V, {
103
146
  className: "max-h-[90vh] overflow-y-auto sm:max-w-lg",
104
147
  children: [
105
- /* @__PURE__ */ M(B, { children: [/* @__PURE__ */ j(me, { children: r ? "Edit portfolio" : "New portfolio" }), /* @__PURE__ */ j(pe, { children: r ? "Update this portfolio’s strategy settings." : "Create an investment portfolio to organize and rebalance holdings." })] }),
148
+ /* @__PURE__ */ M(U, { children: [/* @__PURE__ */ j(W, { children: n ? "Edit portfolio" : "New portfolio" }), /* @__PURE__ */ j(fe, { children: n ? "Update this portfolio’s strategy settings." : "Create an investment portfolio to organize and rebalance holdings." })] }),
106
149
  /* @__PURE__ */ M("div", {
107
150
  className: "space-y-4 py-2",
108
151
  children: [
109
152
  /* @__PURE__ */ M("div", {
110
153
  className: "space-y-1.5",
111
- children: [/* @__PURE__ */ j(U, {
154
+ children: [/* @__PURE__ */ j(q, {
112
155
  htmlFor: "pf-name",
113
156
  children: "Name"
114
- }), /* @__PURE__ */ j(H, {
157
+ }), /* @__PURE__ */ j(K, {
115
158
  id: "pf-name",
116
159
  value: d.name,
117
160
  onChange: (e) => f((t) => ({
@@ -126,10 +169,10 @@ function Re({ open: e, onOpenChange: t, editing: r }) {
126
169
  className: "grid grid-cols-2 gap-4",
127
170
  children: [/* @__PURE__ */ M("div", {
128
171
  className: "space-y-1.5",
129
- children: [/* @__PURE__ */ j(U, {
172
+ children: [/* @__PURE__ */ j(q, {
130
173
  htmlFor: "pf-currency",
131
174
  children: "Base currency"
132
- }), /* @__PURE__ */ j(H, {
175
+ }), /* @__PURE__ */ j(K, {
133
176
  id: "pf-currency",
134
177
  value: d.baseCurrency,
135
178
  onChange: (e) => f((t) => ({
@@ -141,10 +184,10 @@ function Re({ open: e, onOpenChange: t, editing: r }) {
141
184
  })]
142
185
  }), /* @__PURE__ */ M("div", {
143
186
  className: "space-y-1.5",
144
- children: [/* @__PURE__ */ j(U, {
187
+ children: [/* @__PURE__ */ j(q, {
145
188
  htmlFor: "pf-drift",
146
189
  children: "Drift threshold %"
147
- }), /* @__PURE__ */ j(H, {
190
+ }), /* @__PURE__ */ j(K, {
148
191
  id: "pf-drift",
149
192
  type: "number",
150
193
  min: 0,
@@ -157,21 +200,21 @@ function Re({ open: e, onOpenChange: t, editing: r }) {
157
200
  })]
158
201
  })]
159
202
  }),
160
- r ? /* @__PURE__ */ M("div", {
203
+ n ? /* @__PURE__ */ M("div", {
161
204
  className: "space-y-1.5",
162
- children: [/* @__PURE__ */ j(U, {
205
+ children: [/* @__PURE__ */ j(q, {
163
206
  htmlFor: "pf-status",
164
207
  children: "Status"
165
- }), /* @__PURE__ */ M(W, {
208
+ }), /* @__PURE__ */ M(ve, {
166
209
  value: d.status,
167
210
  onValueChange: (e) => f((t) => ({
168
211
  ...t,
169
212
  status: e
170
213
  })),
171
- children: [/* @__PURE__ */ j(q, {
214
+ children: [/* @__PURE__ */ j(be, {
172
215
  id: "pf-status",
173
- children: /* @__PURE__ */ j(J, {})
174
- }), /* @__PURE__ */ j(G, { children: je.map((e) => /* @__PURE__ */ j(K, {
216
+ children: /* @__PURE__ */ j(xe, {})
217
+ }), /* @__PURE__ */ j(ye, { children: Ne.map((e) => /* @__PURE__ */ j(J, {
175
218
  value: e,
176
219
  children: Q(e)
177
220
  }, e)) })]
@@ -179,45 +222,45 @@ function Re({ open: e, onOpenChange: t, editing: r }) {
179
222
  }) : null,
180
223
  /* @__PURE__ */ M("div", {
181
224
  className: "space-y-1.5",
182
- children: [/* @__PURE__ */ j(U, {
225
+ children: [/* @__PURE__ */ j(q, {
183
226
  htmlFor: "pf-model",
184
227
  children: "Model portfolio"
185
- }), /* @__PURE__ */ M(W, {
228
+ }), /* @__PURE__ */ M(ve, {
186
229
  value: d.modelPortfolioId,
187
230
  onValueChange: (e) => f((t) => ({
188
231
  ...t,
189
232
  modelPortfolioId: e
190
233
  })),
191
- children: [/* @__PURE__ */ j(q, {
234
+ children: [/* @__PURE__ */ j(be, {
192
235
  id: "pf-model",
193
- children: /* @__PURE__ */ j(J, { placeholder: "None" })
194
- }), /* @__PURE__ */ M(G, { children: [/* @__PURE__ */ j(K, {
236
+ children: /* @__PURE__ */ j(xe, { placeholder: "None" })
237
+ }), /* @__PURE__ */ M(ye, { children: [/* @__PURE__ */ j(J, {
195
238
  value: Z,
196
239
  children: "None"
197
- }), o.map((e) => /* @__PURE__ */ j(K, {
240
+ }), i.map((e) => /* @__PURE__ */ j(J, {
198
241
  value: e.id,
199
242
  children: e.name
200
243
  }, e.id))] })]
201
244
  })]
202
245
  }),
203
- r ? null : /* @__PURE__ */ M("div", {
246
+ n ? null : /* @__PURE__ */ M("div", {
204
247
  className: "space-y-1.5",
205
- children: [/* @__PURE__ */ j(U, {
248
+ children: [/* @__PURE__ */ j(q, {
206
249
  htmlFor: "pf-household",
207
250
  children: "Household"
208
- }), /* @__PURE__ */ M(W, {
251
+ }), /* @__PURE__ */ M(ve, {
209
252
  value: d.householdId,
210
253
  onValueChange: (e) => f((t) => ({
211
254
  ...t,
212
255
  householdId: e
213
256
  })),
214
- children: [/* @__PURE__ */ j(q, {
257
+ children: [/* @__PURE__ */ j(be, {
215
258
  id: "pf-household",
216
- children: /* @__PURE__ */ j(J, { placeholder: "None" })
217
- }), /* @__PURE__ */ M(G, { children: [/* @__PURE__ */ j(K, {
259
+ children: /* @__PURE__ */ j(xe, { placeholder: "None" })
260
+ }), /* @__PURE__ */ M(ye, { children: [/* @__PURE__ */ j(J, {
218
261
  value: Z,
219
262
  children: "None"
220
- }), s.map((e) => /* @__PURE__ */ j(K, {
263
+ }), s.map((e) => /* @__PURE__ */ j(J, {
221
264
  value: e.id,
222
265
  children: e.name
223
266
  }, e.id))] })]
@@ -225,10 +268,10 @@ function Re({ open: e, onOpenChange: t, editing: r }) {
225
268
  }),
226
269
  /* @__PURE__ */ M("div", {
227
270
  className: "space-y-1.5",
228
- children: [/* @__PURE__ */ j(U, {
271
+ children: [/* @__PURE__ */ j(q, {
229
272
  htmlFor: "pf-desc",
230
273
  children: "Description"
231
- }), /* @__PURE__ */ j(ke, {
274
+ }), /* @__PURE__ */ j(je, {
232
275
  id: "pf-desc",
233
276
  value: d.description,
234
277
  onChange: (e) => f((t) => ({
@@ -241,7 +284,7 @@ function Re({ open: e, onOpenChange: t, editing: r }) {
241
284
  })
242
285
  ]
243
286
  }),
244
- /* @__PURE__ */ M(z, { children: [/* @__PURE__ */ j(P, {
287
+ /* @__PURE__ */ M(H, { children: [/* @__PURE__ */ j(P, {
245
288
  variant: "outline",
246
289
  onClick: () => t(!1),
247
290
  disabled: g,
@@ -249,38 +292,38 @@ function Re({ open: e, onOpenChange: t, editing: r }) {
249
292
  }), /* @__PURE__ */ j(P, {
250
293
  onClick: () => {
251
294
  if (!_) return;
252
- let e = $(d.driftThresholdPct), n = d.modelPortfolioId === Z ? null : d.modelPortfolioId, i = d.householdId === Z ? null : d.householdId;
253
- r ? u.mutate({
254
- id: r.id,
295
+ let e = $(d.driftThresholdPct), r = d.modelPortfolioId === Z ? null : d.modelPortfolioId, i = d.householdId === Z ? null : d.householdId;
296
+ n ? l.mutate({
297
+ id: n.id,
255
298
  input: {
256
299
  name: d.name.trim(),
257
300
  baseCurrency: d.baseCurrency.trim() || "USD",
258
301
  description: d.description.trim() || null,
259
302
  driftThresholdPct: e,
260
303
  status: d.status,
261
- modelPortfolioId: n
304
+ modelPortfolioId: r
262
305
  }
263
306
  }, { onSuccess: () => {
264
- x(), S("Portfolio saved"), t(!1);
307
+ C(), w("Portfolio saved"), t(!1);
265
308
  } }) : c.mutate({
266
309
  name: d.name.trim(),
267
310
  baseCurrency: d.baseCurrency.trim() || "USD",
268
311
  description: d.description.trim() || null,
269
312
  driftThresholdPct: e,
270
- modelPortfolioId: n,
313
+ modelPortfolioId: r,
271
314
  householdId: i
272
315
  }, { onSuccess: () => {
273
- x(), S("Portfolio created"), t(!1);
316
+ C(), w("Portfolio created"), t(!1);
274
317
  } });
275
318
  },
276
319
  disabled: !_ || g,
277
- children: g ? "Saving…" : r ? "Save changes" : "Create portfolio"
320
+ children: g ? "Saving…" : n ? "Save changes" : "Create portfolio"
278
321
  })] })
279
322
  ]
280
323
  })
281
324
  });
282
325
  }
283
- function ze() {
326
+ function We() {
284
327
  return {
285
328
  accountId: "",
286
329
  symbol: "",
@@ -291,9 +334,9 @@ function ze() {
291
334
  costBasis: "0"
292
335
  };
293
336
  }
294
- function Be({ open: e, onOpenChange: n, portfolioId: r, editing: i }) {
295
- let a = t(), o = c(), [s, l] = E(ze), [u, d] = E(null), f = i?.id ?? "new";
296
- e && u !== f && (d(f), l(i ? {
337
+ function Ge({ open: e, onOpenChange: t, portfolioId: r, editing: i }) {
338
+ let a = n(), o = l(), [s, c] = D(We), [u, d] = D(null), f = i?.id ?? "new";
339
+ e && u !== f && (d(f), c(i ? {
297
340
  accountId: i.accountId,
298
341
  symbol: i.symbol,
299
342
  name: i.name ?? "",
@@ -301,22 +344,22 @@ function Be({ open: e, onOpenChange: n, portfolioId: r, editing: i }) {
301
344
  quantity: String(i.quantity),
302
345
  lastPrice: String(i.lastPrice),
303
346
  costBasis: String(i.costBasis)
304
- } : ze())), !e && u !== null && d(null);
305
- let p = a.isPending || o.isPending, m = s.symbol.trim().length > 0, h = i ? !0 : s.accountId.trim().length > 0, _ = m && h && !p;
306
- return /* @__PURE__ */ j(L, {
347
+ } : We())), !e && u !== null && d(null);
348
+ let p = a.isPending || o.isPending, m = s.symbol.trim().length > 0, h = i ? !0 : s.accountId.trim().length > 0, g = m && h && !p;
349
+ return /* @__PURE__ */ j(B, {
307
350
  open: e,
308
- onOpenChange: n,
309
- children: /* @__PURE__ */ M(R, {
351
+ onOpenChange: t,
352
+ children: /* @__PURE__ */ M(V, {
310
353
  className: "max-h-[90vh] overflow-y-auto sm:max-w-lg",
311
354
  children: [
312
- /* @__PURE__ */ M(B, { children: [/* @__PURE__ */ j(me, { children: i ? "Edit holding" : "Add holding" }), /* @__PURE__ */ j(pe, { children: i ? "Update the position details for this holding." : "Add a position to this portfolio from one of your accounts." })] }),
355
+ /* @__PURE__ */ M(U, { children: [/* @__PURE__ */ j(W, { children: i ? "Edit holding" : "Add holding" }), /* @__PURE__ */ j(fe, { children: i ? "Update the position details for this holding." : "Add a position to this portfolio from one of your accounts." })] }),
313
356
  /* @__PURE__ */ M("div", {
314
357
  className: "space-y-4 py-2",
315
358
  children: [
316
- i ? null : /* @__PURE__ */ j(g, {
359
+ i ? null : /* @__PURE__ */ j(_, {
317
360
  id: "h-account",
318
361
  value: s.accountId,
319
- onChange: (e) => l((t) => ({
362
+ onChange: (e) => c((t) => ({
320
363
  ...t,
321
364
  accountId: e
322
365
  })),
@@ -326,13 +369,13 @@ function Be({ open: e, onOpenChange: n, portfolioId: r, editing: i }) {
326
369
  className: "grid grid-cols-2 gap-4",
327
370
  children: [/* @__PURE__ */ M("div", {
328
371
  className: "space-y-1.5",
329
- children: [/* @__PURE__ */ j(U, {
372
+ children: [/* @__PURE__ */ j(q, {
330
373
  htmlFor: "h-symbol",
331
374
  children: "Symbol"
332
- }), /* @__PURE__ */ j(H, {
375
+ }), /* @__PURE__ */ j(K, {
333
376
  id: "h-symbol",
334
377
  value: s.symbol,
335
- onChange: (e) => l((t) => ({
378
+ onChange: (e) => c((t) => ({
336
379
  ...t,
337
380
  symbol: e.target.value
338
381
  })),
@@ -342,19 +385,19 @@ function Be({ open: e, onOpenChange: n, portfolioId: r, editing: i }) {
342
385
  })]
343
386
  }), /* @__PURE__ */ M("div", {
344
387
  className: "space-y-1.5",
345
- children: [/* @__PURE__ */ j(U, {
388
+ children: [/* @__PURE__ */ j(q, {
346
389
  htmlFor: "h-class",
347
390
  children: "Asset class"
348
- }), /* @__PURE__ */ M(W, {
391
+ }), /* @__PURE__ */ M(ve, {
349
392
  value: s.assetClass,
350
- onValueChange: (e) => l((t) => ({
393
+ onValueChange: (e) => c((t) => ({
351
394
  ...t,
352
395
  assetClass: e
353
396
  })),
354
- children: [/* @__PURE__ */ j(q, {
397
+ children: [/* @__PURE__ */ j(be, {
355
398
  id: "h-class",
356
- children: /* @__PURE__ */ j(J, {})
357
- }), /* @__PURE__ */ j(G, { children: Ae.map((e) => /* @__PURE__ */ j(K, {
399
+ children: /* @__PURE__ */ j(xe, {})
400
+ }), /* @__PURE__ */ j(ye, { children: Me.map((e) => /* @__PURE__ */ j(J, {
358
401
  value: e,
359
402
  children: Q(e)
360
403
  }, e)) })]
@@ -363,13 +406,13 @@ function Be({ open: e, onOpenChange: n, portfolioId: r, editing: i }) {
363
406
  }),
364
407
  /* @__PURE__ */ M("div", {
365
408
  className: "space-y-1.5",
366
- children: [/* @__PURE__ */ j(U, {
409
+ children: [/* @__PURE__ */ j(q, {
367
410
  htmlFor: "h-name",
368
411
  children: "Name"
369
- }), /* @__PURE__ */ j(H, {
412
+ }), /* @__PURE__ */ j(K, {
370
413
  id: "h-name",
371
414
  value: s.name,
372
- onChange: (e) => l((t) => ({
415
+ onChange: (e) => c((t) => ({
373
416
  ...t,
374
417
  name: e.target.value
375
418
  })),
@@ -381,15 +424,15 @@ function Be({ open: e, onOpenChange: n, portfolioId: r, editing: i }) {
381
424
  children: [
382
425
  /* @__PURE__ */ M("div", {
383
426
  className: "space-y-1.5",
384
- children: [/* @__PURE__ */ j(U, {
427
+ children: [/* @__PURE__ */ j(q, {
385
428
  htmlFor: "h-qty",
386
429
  children: "Quantity"
387
- }), /* @__PURE__ */ j(H, {
430
+ }), /* @__PURE__ */ j(K, {
388
431
  id: "h-qty",
389
432
  type: "number",
390
433
  step: "any",
391
434
  value: s.quantity,
392
- onChange: (e) => l((t) => ({
435
+ onChange: (e) => c((t) => ({
393
436
  ...t,
394
437
  quantity: e.target.value
395
438
  }))
@@ -397,15 +440,15 @@ function Be({ open: e, onOpenChange: n, portfolioId: r, editing: i }) {
397
440
  }),
398
441
  /* @__PURE__ */ M("div", {
399
442
  className: "space-y-1.5",
400
- children: [/* @__PURE__ */ j(U, {
443
+ children: [/* @__PURE__ */ j(q, {
401
444
  htmlFor: "h-price",
402
445
  children: "Last price"
403
- }), /* @__PURE__ */ j(H, {
446
+ }), /* @__PURE__ */ j(K, {
404
447
  id: "h-price",
405
448
  type: "number",
406
449
  step: "any",
407
450
  value: s.lastPrice,
408
- onChange: (e) => l((t) => ({
451
+ onChange: (e) => c((t) => ({
409
452
  ...t,
410
453
  lastPrice: e.target.value
411
454
  }))
@@ -413,15 +456,15 @@ function Be({ open: e, onOpenChange: n, portfolioId: r, editing: i }) {
413
456
  }),
414
457
  /* @__PURE__ */ M("div", {
415
458
  className: "space-y-1.5",
416
- children: [/* @__PURE__ */ j(U, {
459
+ children: [/* @__PURE__ */ j(q, {
417
460
  htmlFor: "h-cost",
418
461
  children: "Cost basis"
419
- }), /* @__PURE__ */ j(H, {
462
+ }), /* @__PURE__ */ j(K, {
420
463
  id: "h-cost",
421
464
  type: "number",
422
465
  step: "any",
423
466
  value: s.costBasis,
424
- onChange: (e) => l((t) => ({
467
+ onChange: (e) => c((t) => ({
425
468
  ...t,
426
469
  costBasis: e.target.value
427
470
  }))
@@ -431,9 +474,9 @@ function Be({ open: e, onOpenChange: n, portfolioId: r, editing: i }) {
431
474
  })
432
475
  ]
433
476
  }),
434
- /* @__PURE__ */ M(z, { children: [/* @__PURE__ */ j(P, {
477
+ /* @__PURE__ */ M(H, { children: [/* @__PURE__ */ j(P, {
435
478
  variant: "outline",
436
- onClick: () => n(!1),
479
+ onClick: () => t(!1),
437
480
  disabled: p,
438
481
  children: "Cancel"
439
482
  }), /* @__PURE__ */ j(P, {
@@ -448,7 +491,7 @@ function Be({ open: e, onOpenChange: n, portfolioId: r, editing: i }) {
448
491
  costBasis: $(s.costBasis)
449
492
  }
450
493
  }, { onSuccess: () => {
451
- x(), S("Holding saved"), n(!1);
494
+ C(), w("Holding saved"), t(!1);
452
495
  } }) : a.mutate({
453
496
  accountId: s.accountId,
454
497
  portfolioId: r,
@@ -459,96 +502,98 @@ function Be({ open: e, onOpenChange: n, portfolioId: r, editing: i }) {
459
502
  lastPrice: $(s.lastPrice),
460
503
  costBasis: $(s.costBasis)
461
504
  }, { onSuccess: () => {
462
- x(), S("Holding added"), n(!1);
505
+ C(), w("Holding added"), t(!1);
463
506
  } }));
464
507
  },
465
- disabled: !_,
508
+ disabled: !g,
466
509
  children: p ? "Saving…" : i ? "Save changes" : "Add holding"
467
510
  })] })
468
511
  ]
469
512
  })
470
513
  });
471
514
  }
472
- function Ve({ portfolioId: e, onOpenChange: t }) {
473
- let { data: n, isLoading: i, isError: a, refetch: o } = s(e ?? void 0), c = r(), [l, u] = E(!1), [g, re] = E(null), [x, S] = E(null), C = n?.holdings ?? [], D = n?.baseCurrency ?? "USD", O = C.reduce((e, t) => e + t.marketValue, 0), L = C.reduce((e, t) => e + t.costBasis, 0), R = O - L, pe = L > 0 ? R / L * 100 : 0, z = T(() => {
474
- if (C.length === 0 || O <= 0) return [];
515
+ function Ke({ portfolioId: t, onOpenChange: n }) {
516
+ let { data: r, isLoading: a, isError: o, refetch: s } = c(t ?? void 0), l = e({ portfolioId: t ?? void 0 }, { enabled: t !== null }), u = i(), [d, _] = D(!1), [ie, v] = D(null), [C, w] = D(null), T = t ? l.data : [], O = r?.baseCurrency ?? "USD", k = T.reduce((e, t) => e + t.marketValue, 0), B = T.reduce((e, t) => e + t.costBasis, 0), V = k - B, fe = B > 0 ? V / B * 100 : 0, H = E(() => {
517
+ if (T.length === 0 || k <= 0) return [];
475
518
  let e = /* @__PURE__ */ new Map();
476
- return C.forEach((t) => e.set(t.assetClass, (e.get(t.assetClass) ?? 0) + t.marketValue)), Array.from(e.entries()).map(([e, t]) => ({
519
+ return T.forEach((t) => e.set(t.assetClass, (e.get(t.assetClass) ?? 0) + t.marketValue)), Array.from(e.entries()).map(([e, t]) => ({
477
520
  label: Q(e),
478
521
  value: t,
479
- tone: Ne(e)
522
+ tone: Fe(e)
480
523
  })).sort((e, t) => t.value - e.value);
481
- }, [C, O]), B = T(() => {
524
+ }, [T, k]), U = E(() => {
482
525
  let e = /* @__PURE__ */ new Map();
483
- return O <= 0 || C.forEach((t) => e.set(Q(t.assetClass), (e.get(Q(t.assetClass)) ?? 0) + t.marketValue / O * 100)), e;
484
- }, [C, O]), me = T(() => Pe(n?.targetAllocation).map((e) => {
485
- let t = B.get(e.label) ?? 0;
526
+ return k <= 0 || T.forEach((t) => e.set(Q(t.assetClass), (e.get(Q(t.assetClass)) ?? 0) + t.marketValue / k * 100)), e;
527
+ }, [T, k]), W = E(() => Le(r?.targetAllocation).map((e) => {
528
+ let t = U.get(e.label) ?? 0;
486
529
  return {
487
530
  label: e.label,
488
531
  value: e.value,
489
532
  tone: "accent",
490
- caption: `${y(e.value, 0)} target · ${y(t, 0)} actual`
533
+ caption: `${x(e.value, 0)} target · ${x(t, 0)} actual`
491
534
  };
492
- }), [n?.targetAllocation, B]), H = () => {
493
- re(null), u(!0);
494
- }, U = (e) => {
495
- re(e), u(!0);
535
+ }), [r?.targetAllocation, U]), K = () => {
536
+ v(null), _(!0);
537
+ }, q = (e) => {
538
+ v(e), _(!0);
496
539
  };
497
- return /* @__PURE__ */ j(be, {
498
- open: e !== null,
499
- onOpenChange: t,
500
- children: /* @__PURE__ */ j(xe, {
540
+ return /* @__PURE__ */ j(Se, {
541
+ open: t !== null,
542
+ onOpenChange: n,
543
+ children: /* @__PURE__ */ j(Ce, {
501
544
  className: "flex w-full flex-col gap-0 overflow-y-auto p-0 sm:max-w-2xl",
502
- children: i ? /* @__PURE__ */ j("div", {
545
+ children: a || t !== null && l.isPending ? /* @__PURE__ */ j("div", {
503
546
  className: "p-6",
504
- children: /* @__PURE__ */ j(ne, { rows: 5 })
505
- }) : a ? /* @__PURE__ */ j("div", {
547
+ children: /* @__PURE__ */ j(re, { rows: 5 })
548
+ }) : o || l.isError ? /* @__PURE__ */ j("div", {
506
549
  className: "p-6",
507
- children: /* @__PURE__ */ j(te, { onRetry: () => o() })
508
- }) : n ? /* @__PURE__ */ M(le, { children: [
509
- /* @__PURE__ */ M(Ce, {
550
+ children: /* @__PURE__ */ j(ne, { onRetry: () => {
551
+ s(), l.refetch();
552
+ } })
553
+ }) : r ? /* @__PURE__ */ M(de, { children: [
554
+ /* @__PURE__ */ M(Te, {
510
555
  className: "border-b border-border-subtle p-6",
511
556
  children: [/* @__PURE__ */ M("div", {
512
557
  className: "flex items-center gap-2",
513
- children: [/* @__PURE__ */ j(we, {
558
+ children: [/* @__PURE__ */ j(Ee, {
514
559
  className: "text-xl",
515
- children: n.name
560
+ children: r.name
516
561
  }), /* @__PURE__ */ j(N, {
517
- variant: b(n.status),
518
- children: Q(n.status)
562
+ variant: S(r.status),
563
+ children: Q(r.status)
519
564
  })]
520
- }), /* @__PURE__ */ j(Se, { children: n.description?.trim() ? n.description : `${n.baseCurrency} · Drift threshold ${y(n.driftThresholdPct)}` })]
565
+ }), /* @__PURE__ */ j(we, { children: r.description?.trim() ? r.description : `${r.baseCurrency} · Drift threshold ${x(r.driftThresholdPct)}` })]
521
566
  }),
522
567
  /* @__PURE__ */ M("div", {
523
568
  className: "space-y-6 p-6",
524
569
  children: [
525
- /* @__PURE__ */ M(p, {
570
+ /* @__PURE__ */ M(m, {
526
571
  className: "grid grid-cols-2 gap-3 lg:grid-cols-4",
527
572
  children: [
528
- /* @__PURE__ */ j(h, {
573
+ /* @__PURE__ */ j(g, {
529
574
  label: "Market value",
530
- value: v(O, D),
575
+ value: b(k, O),
531
576
  glow: !0
532
577
  }),
533
- /* @__PURE__ */ j(h, {
578
+ /* @__PURE__ */ j(g, {
534
579
  label: "Unrealized gain",
535
- value: v(R, D),
536
- delta: L > 0 ? pe : void 0,
537
- deltaTone: R > 0 ? "positive" : R < 0 ? "negative" : "neutral"
580
+ value: b(V, O),
581
+ delta: B > 0 ? fe : void 0,
582
+ deltaTone: V > 0 ? "positive" : V < 0 ? "negative" : "neutral"
538
583
  }),
539
- /* @__PURE__ */ j(h, {
584
+ /* @__PURE__ */ j(g, {
540
585
  label: "Holdings",
541
- value: String(C.length)
586
+ value: String(T.length)
542
587
  }),
543
- /* @__PURE__ */ j(h, {
588
+ /* @__PURE__ */ j(g, {
544
589
  label: "Drift threshold",
545
- value: y(n.driftThresholdPct)
590
+ value: x(r.driftThresholdPct)
546
591
  })
547
592
  ]
548
593
  }),
549
- /* @__PURE__ */ j(p, {
594
+ /* @__PURE__ */ j(m, {
550
595
  index: 1,
551
- children: /* @__PURE__ */ M(m, {
596
+ children: /* @__PURE__ */ M(h, {
552
597
  glow: !0,
553
598
  className: "space-y-5",
554
599
  children: [/* @__PURE__ */ M("div", {
@@ -558,7 +603,7 @@ function Ve({ portfolioId: e, onOpenChange: t }) {
558
603
  children: "Target vs actual allocation"
559
604
  }), /* @__PURE__ */ j(N, {
560
605
  variant: "outline",
561
- children: D
606
+ children: O
562
607
  })]
563
608
  }), /* @__PURE__ */ M("div", {
564
609
  className: "grid gap-6 md:grid-cols-2",
@@ -567,11 +612,11 @@ function Ve({ portfolioId: e, onOpenChange: t }) {
567
612
  children: [/* @__PURE__ */ j("p", {
568
613
  className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
569
614
  children: "Actual — by market value"
570
- }), z.length > 0 ? /* @__PURE__ */ j(f, {
571
- data: z,
572
- centerValue: ie(O, D),
615
+ }), H.length > 0 ? /* @__PURE__ */ j(p, {
616
+ data: H,
617
+ centerValue: y(k, O),
573
618
  centerLabel: "Market value",
574
- valueFormatter: (e) => v(e, D)
619
+ valueFormatter: (e) => b(e, O)
575
620
  }) : /* @__PURE__ */ j("p", {
576
621
  className: "py-8 text-center text-sm text-text-secondary",
577
622
  children: "Add holdings to see the live allocation."
@@ -581,7 +626,7 @@ function Ve({ portfolioId: e, onOpenChange: t }) {
581
626
  children: [/* @__PURE__ */ j("p", {
582
627
  className: "text-xs font-medium uppercase tracking-wide text-text-secondary",
583
628
  children: "Target — vs live actual"
584
- }), me.length > 0 ? /* @__PURE__ */ j(_, { data: me }) : /* @__PURE__ */ j("p", {
629
+ }), W.length > 0 ? /* @__PURE__ */ j(ee, { data: W }) : /* @__PURE__ */ j("p", {
585
630
  className: "py-8 text-center text-sm text-text-secondary",
586
631
  children: "No target allocation set for this portfolio."
587
632
  })]
@@ -591,26 +636,26 @@ function Ve({ portfolioId: e, onOpenChange: t }) {
591
636
  }),
592
637
  /* @__PURE__ */ j(F, { children: /* @__PURE__ */ j(I, {
593
638
  className: "p-4",
594
- children: /* @__PURE__ */ j(w, {
639
+ children: /* @__PURE__ */ j(ae, {
595
640
  entityType: "brainyrich-portfolio",
596
- entityId: n.id
641
+ entityId: r.id
597
642
  })
598
643
  }) }),
599
- /* @__PURE__ */ M(F, { children: [/* @__PURE__ */ M(de, {
644
+ /* @__PURE__ */ M(F, { children: [/* @__PURE__ */ M(R, {
600
645
  className: "flex flex-row items-center justify-between",
601
- children: [/* @__PURE__ */ M("div", { children: [/* @__PURE__ */ j(fe, {
646
+ children: [/* @__PURE__ */ M("div", { children: [/* @__PURE__ */ j(z, {
602
647
  className: "text-base",
603
648
  children: "Holdings"
604
- }), /* @__PURE__ */ j(ue, { children: "Positions held in this portfolio" })] }), /* @__PURE__ */ M(P, {
649
+ }), /* @__PURE__ */ j(L, { children: "Positions held in this portfolio" })] }), /* @__PURE__ */ M(P, {
605
650
  size: "sm",
606
- onClick: H,
607
- children: [/* @__PURE__ */ j(A, {
651
+ onClick: K,
652
+ children: [/* @__PURE__ */ j(le, {
608
653
  className: "size-4",
609
654
  "aria-hidden": "true"
610
655
  }), "Add holding"]
611
656
  })]
612
- }), /* @__PURE__ */ j(I, { children: C.length === 0 ? /* @__PURE__ */ j(ee, {
613
- icon: /* @__PURE__ */ j(k, {
657
+ }), /* @__PURE__ */ j(I, { children: T.length === 0 ? /* @__PURE__ */ j(te, {
658
+ icon: /* @__PURE__ */ j(A, {
614
659
  className: "size-6",
615
660
  "aria-hidden": "true"
616
661
  }),
@@ -618,15 +663,15 @@ function Ve({ portfolioId: e, onOpenChange: t }) {
618
663
  description: "Add positions to start tracking this portfolio.",
619
664
  action: /* @__PURE__ */ M(P, {
620
665
  size: "sm",
621
- onClick: H,
622
- children: [/* @__PURE__ */ j(A, {
666
+ onClick: K,
667
+ children: [/* @__PURE__ */ j(le, {
623
668
  className: "size-4",
624
669
  "aria-hidden": "true"
625
670
  }), "Add holding"]
626
671
  })
627
672
  }) : /* @__PURE__ */ j("div", {
628
673
  className: "overflow-x-auto",
629
- children: /* @__PURE__ */ M(Te, { children: [/* @__PURE__ */ j(De, { children: /* @__PURE__ */ M(Oe, { children: [
674
+ children: /* @__PURE__ */ M(De, { children: [/* @__PURE__ */ j(ke, { children: /* @__PURE__ */ M(Ae, { children: [
630
675
  /* @__PURE__ */ j(X, { children: "Symbol" }),
631
676
  /* @__PURE__ */ j(X, { children: "Class" }),
632
677
  /* @__PURE__ */ j(X, {
@@ -646,9 +691,9 @@ function Ve({ portfolioId: e, onOpenChange: t }) {
646
691
  children: "Gain"
647
692
  }),
648
693
  /* @__PURE__ */ j(X, { className: "w-10" })
649
- ] }) }), /* @__PURE__ */ j(Ee, { children: C.map((e) => {
694
+ ] }) }), /* @__PURE__ */ j(Oe, { children: T.map((e) => {
650
695
  let t = e.marketValue - e.costBasis, n = e.costBasis > 0 ? t / e.costBasis * 100 : 0;
651
- return /* @__PURE__ */ M(Oe, {
696
+ return /* @__PURE__ */ M(Ae, {
652
697
  className: "transition-colors motion-safe:hover:bg-bg-sunken/60",
653
698
  children: [
654
699
  /* @__PURE__ */ M(Y, { children: [/* @__PURE__ */ j("div", {
@@ -668,53 +713,53 @@ function Ve({ portfolioId: e, onOpenChange: t }) {
668
713
  }),
669
714
  /* @__PURE__ */ j(Y, {
670
715
  className: "text-right tabular-nums",
671
- children: v(e.lastPrice, e.currency)
716
+ children: b(e.lastPrice, e.currency)
672
717
  }),
673
718
  /* @__PURE__ */ j(Y, {
674
719
  className: "text-right font-medium tabular-nums",
675
- children: v(e.marketValue, e.currency)
720
+ children: b(e.marketValue, e.currency)
676
721
  }),
677
722
  /* @__PURE__ */ M(Y, {
678
723
  className: "text-right tabular-nums",
679
- children: [/* @__PURE__ */ j(Ie, {
724
+ children: [/* @__PURE__ */ j(Ve, {
680
725
  value: t,
681
726
  currency: e.currency
682
727
  }), e.costBasis > 0 ? /* @__PURE__ */ M("div", {
683
728
  className: "text-xs text-text-secondary",
684
- children: [t > 0 ? "+" : "", y(n)]
729
+ children: [t > 0 ? "+" : "", x(n)]
685
730
  }) : null]
686
731
  }),
687
732
  /* @__PURE__ */ j(Y, {
688
733
  className: "text-right",
689
- children: /* @__PURE__ */ M(he, { children: [/* @__PURE__ */ j(ye, {
734
+ children: /* @__PURE__ */ M(pe, { children: [/* @__PURE__ */ j(_e, {
690
735
  asChild: !0,
691
736
  children: /* @__PURE__ */ j(P, {
692
737
  variant: "ghost",
693
738
  size: "icon",
694
739
  className: "size-10",
695
740
  "aria-label": `Actions for ${e.symbol}`,
696
- children: /* @__PURE__ */ j(oe, {
741
+ children: /* @__PURE__ */ j(se, {
697
742
  className: "size-4",
698
743
  "aria-hidden": "true"
699
744
  })
700
745
  })
701
- }), /* @__PURE__ */ M(ge, {
746
+ }), /* @__PURE__ */ M(me, {
702
747
  align: "end",
703
748
  children: [
704
- /* @__PURE__ */ j(_e, { children: e.symbol }),
705
- /* @__PURE__ */ j(ve, {}),
706
- /* @__PURE__ */ M(V, {
749
+ /* @__PURE__ */ j(he, { children: e.symbol }),
750
+ /* @__PURE__ */ j(ge, {}),
751
+ /* @__PURE__ */ M(G, {
707
752
  className: "gap-2",
708
- onClick: () => U(e),
709
- children: [/* @__PURE__ */ j(se, {
753
+ onClick: () => q(e),
754
+ children: [/* @__PURE__ */ j(ce, {
710
755
  className: "size-4",
711
756
  "aria-hidden": "true"
712
757
  }), "Edit"]
713
758
  }),
714
- /* @__PURE__ */ M(V, {
759
+ /* @__PURE__ */ M(G, {
715
760
  className: "gap-2 text-status-error-text focus:text-status-error-text",
716
- onClick: () => S(e),
717
- children: [/* @__PURE__ */ j(ce, {
761
+ onClick: () => w(e),
762
+ children: [/* @__PURE__ */ j(ue, {
718
763
  className: "size-4",
719
764
  "aria-hidden": "true"
720
765
  }), "Delete"]
@@ -726,51 +771,51 @@ function Ve({ portfolioId: e, onOpenChange: t }) {
726
771
  }, e.id);
727
772
  }) })] })
728
773
  }) })] }),
729
- /* @__PURE__ */ M(F, { children: [/* @__PURE__ */ M(de, {
774
+ /* @__PURE__ */ M(F, { children: [/* @__PURE__ */ M(R, {
730
775
  className: "pb-3",
731
- children: [/* @__PURE__ */ j(fe, {
776
+ children: [/* @__PURE__ */ j(z, {
732
777
  className: "text-sm",
733
778
  children: "Tags"
734
- }), /* @__PURE__ */ j(ue, { children: "Organize and filter this portfolio." })]
735
- }), /* @__PURE__ */ j(I, { children: /* @__PURE__ */ j(w, {
779
+ }), /* @__PURE__ */ j(L, { children: "Organize and filter this portfolio." })]
780
+ }), /* @__PURE__ */ j(I, { children: /* @__PURE__ */ j(ae, {
736
781
  entityType: "brainyrich-portfolio",
737
- entityId: n.id,
782
+ entityId: r.id,
738
783
  hideLabel: !0
739
784
  }) })] }),
740
785
  /* @__PURE__ */ j(F, { children: /* @__PURE__ */ j(I, {
741
786
  className: "pt-6",
742
- children: /* @__PURE__ */ j(ae, {
787
+ children: /* @__PURE__ */ j(oe, {
743
788
  entityType: "brainyrich-portfolio",
744
- entityId: n.id
789
+ entityId: r.id
745
790
  })
746
791
  }) })
747
792
  ]
748
793
  }),
749
- /* @__PURE__ */ j(Be, {
750
- open: l,
751
- onOpenChange: u,
752
- portfolioId: n.id,
753
- editing: g
794
+ /* @__PURE__ */ j(Ge, {
795
+ open: d,
796
+ onOpenChange: _,
797
+ portfolioId: r.id,
798
+ editing: ie
754
799
  }),
755
- /* @__PURE__ */ j(d, {
756
- open: x !== null,
800
+ /* @__PURE__ */ j(f, {
801
+ open: C !== null,
757
802
  onOpenChange: (e) => {
758
- e || S(null);
803
+ e || w(null);
759
804
  },
760
805
  title: "Delete holding?",
761
- description: x ? `Remove ${x.symbol} from this portfolio. This cannot be undone.` : void 0,
806
+ description: C ? `Remove ${C.symbol} from this portfolio. This cannot be undone.` : void 0,
762
807
  confirmLabel: "Delete",
763
808
  pendingLabel: "Deleting…",
764
809
  destructive: !0,
765
- pending: c.isPending,
810
+ pending: u.isPending,
766
811
  onConfirm: () => {
767
- x && c.mutate(x.id, { onSuccess: () => S(null) });
812
+ C && u.mutate(C.id, { onSuccess: () => w(null) });
768
813
  }
769
814
  })
770
815
  ] }) : /* @__PURE__ */ j("div", {
771
816
  className: "p-6",
772
- children: /* @__PURE__ */ j(ee, {
773
- icon: /* @__PURE__ */ j(k, {
817
+ children: /* @__PURE__ */ j(te, {
818
+ icon: /* @__PURE__ */ j(A, {
774
819
  className: "size-6",
775
820
  "aria-hidden": "true"
776
821
  }),
@@ -781,15 +826,47 @@ function Ve({ portfolioId: e, onOpenChange: t }) {
781
826
  })
782
827
  });
783
828
  }
784
- function He({ portfolio: e, index: t, onView: n, onEdit: r, onArchive: i }) {
785
- let a = T(() => Fe(e.targetAllocation), [e.targetAllocation]), o = a[0], s = e.tags ?? [];
786
- return /* @__PURE__ */ j(p, {
787
- index: t,
829
+ function qe({ driftPct: e, thresholdPct: t, assetClass: n }) {
830
+ let r = Math.abs(e), i = t > 0 && r > t, a = !i && t > 0 && r >= t * .75, o = t > 0 ? Math.min(100, r / t * 100) : 0, s = i ? "bg-status-error-bg" : a ? "bg-status-warning-bg" : "bg-accent-teal", c = i ? "text-status-error-text" : a ? "text-status-warning-text" : "text-text-secondary", l = n ? `Widest drift: ${Q(n)} ${e > 0 ? "over" : "under"}-weight by ${x(r)}` : `Widest drift ${x(r)}`;
831
+ return /* @__PURE__ */ M("div", {
832
+ className: "space-y-1",
833
+ children: [/* @__PURE__ */ M("div", {
834
+ className: "flex items-center justify-between gap-2 text-xs",
835
+ children: [/* @__PURE__ */ j("span", {
836
+ className: "text-text-secondary",
837
+ children: "Drift"
838
+ }), /* @__PURE__ */ M("span", {
839
+ className: `font-medium tabular-nums ${c}`,
840
+ children: [
841
+ i ? "⚠ " : "",
842
+ e > 0 ? "+" : "",
843
+ x(e)
844
+ ]
845
+ })]
846
+ }), /* @__PURE__ */ j("div", {
847
+ className: "h-1.5 w-full overflow-hidden rounded-full bg-bg-sunken",
848
+ role: "progressbar",
849
+ "aria-valuenow": Math.round(o),
850
+ "aria-valuemin": 0,
851
+ "aria-valuemax": 100,
852
+ "aria-label": l,
853
+ title: l,
854
+ children: /* @__PURE__ */ j("div", {
855
+ className: `h-full rounded-full ${s}`,
856
+ style: { width: `${o}%` }
857
+ })
858
+ })]
859
+ });
860
+ }
861
+ function Je({ portfolio: e, valuation: t, valuationError: n, index: r, onView: i, onEdit: a, onArchive: o }) {
862
+ let s = E(() => Re(e.targetAllocation), [e.targetAllocation]), c = s[0], l = e.tags ?? [];
863
+ return /* @__PURE__ */ j(m, {
864
+ index: r,
788
865
  as: "div",
789
866
  className: "h-full",
790
867
  children: /* @__PURE__ */ M(F, {
791
868
  className: "flex h-full flex-col transition-shadow motion-safe:hover:shadow-[var(--shadow-pop-hover,var(--shadow-elevation-2))]",
792
- children: [/* @__PURE__ */ M(de, {
869
+ children: [/* @__PURE__ */ M(R, {
793
870
  className: "pb-3",
794
871
  children: [/* @__PURE__ */ M("div", {
795
872
  className: "flex items-start justify-between gap-2",
@@ -798,154 +875,230 @@ function He({ portfolio: e, index: t, onView: n, onEdit: r, onArchive: i }) {
798
875
  children: [
799
876
  /* @__PURE__ */ j("span", {
800
877
  className: "flex size-8 shrink-0 items-center justify-center rounded-lg bg-[var(--color-action-primary-bg)]/12 text-[var(--color-action-primary-text)]",
801
- children: /* @__PURE__ */ j(k, {
878
+ children: /* @__PURE__ */ j(A, {
802
879
  className: "size-4",
803
880
  "aria-hidden": "true"
804
881
  })
805
882
  }),
806
- /* @__PURE__ */ j(fe, {
883
+ /* @__PURE__ */ j(z, {
807
884
  className: "truncate text-base",
808
885
  children: e.name
809
886
  }),
810
887
  /* @__PURE__ */ j(N, {
811
- variant: b(e.status),
888
+ variant: S(e.status),
812
889
  children: Q(e.status)
813
890
  })
814
891
  ]
815
- }), /* @__PURE__ */ M(he, { children: [/* @__PURE__ */ j(ye, {
892
+ }), /* @__PURE__ */ M(pe, { children: [/* @__PURE__ */ j(_e, {
816
893
  asChild: !0,
817
894
  children: /* @__PURE__ */ j(P, {
818
895
  variant: "ghost",
819
896
  size: "icon",
820
897
  className: "size-9 shrink-0",
821
898
  "aria-label": `Actions for ${e.name}`,
822
- children: /* @__PURE__ */ j(oe, {
899
+ children: /* @__PURE__ */ j(se, {
823
900
  className: "size-4",
824
901
  "aria-hidden": "true"
825
902
  })
826
903
  })
827
- }), /* @__PURE__ */ M(ge, {
904
+ }), /* @__PURE__ */ M(me, {
828
905
  align: "end",
829
906
  children: [
830
- /* @__PURE__ */ j(_e, { children: e.name }),
831
- /* @__PURE__ */ j(ve, {}),
832
- /* @__PURE__ */ M(V, {
907
+ /* @__PURE__ */ j(he, { children: e.name }),
908
+ /* @__PURE__ */ j(ge, {}),
909
+ /* @__PURE__ */ M(G, {
833
910
  className: "gap-2",
834
- onClick: r,
835
- children: [/* @__PURE__ */ j(se, {
911
+ onClick: a,
912
+ children: [/* @__PURE__ */ j(ce, {
836
913
  className: "size-4",
837
914
  "aria-hidden": "true"
838
915
  }), "Edit"]
839
916
  }),
840
- /* @__PURE__ */ M(V, {
917
+ /* @__PURE__ */ M(G, {
841
918
  className: "gap-2 text-status-error-text focus:text-status-error-text",
842
919
  disabled: e.status === "ARCHIVED",
843
- onClick: i,
844
- children: [/* @__PURE__ */ j(ce, {
920
+ onClick: o,
921
+ children: [/* @__PURE__ */ j(ue, {
845
922
  className: "size-4",
846
923
  "aria-hidden": "true"
847
924
  }), "Archive"]
848
925
  })
849
926
  ]
850
927
  })] })]
851
- }), e.description?.trim() ? /* @__PURE__ */ j(ue, {
928
+ }), e.description?.trim() ? /* @__PURE__ */ j(L, {
852
929
  className: "line-clamp-2",
853
930
  children: e.description
854
931
  }) : null]
855
932
  }), /* @__PURE__ */ M(I, {
856
933
  className: "flex flex-1 flex-col justify-between gap-4",
857
- children: [/* @__PURE__ */ M("div", {
858
- className: "grid grid-cols-[auto_1fr] items-center gap-4",
859
- children: [a.length > 0 ? /* @__PURE__ */ j("div", {
860
- className: "w-28 shrink-0",
861
- children: /* @__PURE__ */ j(f, {
862
- data: a,
863
- legend: !1,
864
- height: 112,
865
- centerValue: o ? y(o.value, 0) : void 0,
866
- centerLabel: o?.label,
867
- valueFormatter: (e) => y(e, 0)
868
- })
934
+ children: [
935
+ n ? /* @__PURE__ */ j("p", {
936
+ className: "text-sm text-text-secondary",
937
+ children: "Valuation unavailable — positions could not be loaded."
938
+ }) : t ? t.holdingCount > 0 ? /* @__PURE__ */ M("div", {
939
+ className: "space-y-2",
940
+ children: [/* @__PURE__ */ M("div", {
941
+ className: "flex flex-wrap items-baseline gap-x-3 gap-y-1",
942
+ children: [
943
+ /* @__PURE__ */ j("span", {
944
+ className: "text-2xl font-semibold tabular-nums text-text-primary",
945
+ children: y(t.marketValue, e.baseCurrency)
946
+ }),
947
+ t.gainPct === null ? null : /* @__PURE__ */ M("span", {
948
+ className: `inline-flex items-center gap-1 text-sm font-medium tabular-nums ${v(t.unrealizedGain)}`,
949
+ children: [
950
+ t.unrealizedGain > 0 ? /* @__PURE__ */ j(k, {
951
+ className: "size-3.5",
952
+ "aria-hidden": "true"
953
+ }) : t.unrealizedGain < 0 ? /* @__PURE__ */ j(O, {
954
+ className: "size-3.5",
955
+ "aria-hidden": "true"
956
+ }) : null,
957
+ t.unrealizedGain > 0 ? "+" : "",
958
+ x(t.gainPct)
959
+ ]
960
+ }),
961
+ /* @__PURE__ */ M("span", {
962
+ className: "text-xs text-text-secondary",
963
+ children: [
964
+ t.holdingCount,
965
+ " holding",
966
+ t.holdingCount === 1 ? "" : "s"
967
+ ]
968
+ })
969
+ ]
970
+ }), t.maxDriftPct === null ? /* @__PURE__ */ j("p", {
971
+ className: "text-xs text-text-secondary",
972
+ children: "Drift needs a target allocation on this portfolio."
973
+ }) : /* @__PURE__ */ j(qe, {
974
+ driftPct: t.maxDriftPct,
975
+ thresholdPct: e.driftThresholdPct,
976
+ assetClass: t.driftAssetClass
977
+ })]
978
+ }) : /* @__PURE__ */ j("p", {
979
+ className: "text-sm text-text-secondary",
980
+ children: "No holdings yet — add positions to value this portfolio."
869
981
  }) : /* @__PURE__ */ M("div", {
870
- className: "flex size-28 shrink-0 items-center justify-center rounded-full border border-dashed border-border-subtle text-center text-[10px] leading-tight text-text-secondary",
871
- children: [
872
- "No target",
873
- /* @__PURE__ */ j("br", {}),
874
- "allocation"
875
- ]
876
- }), /* @__PURE__ */ M("div", {
877
- className: "min-w-0 space-y-2",
878
- children: [
879
- /* @__PURE__ */ M("div", {
880
- className: "flex flex-wrap items-center gap-1.5",
881
- children: [/* @__PURE__ */ j(N, {
882
- variant: "outline",
883
- children: e.baseCurrency
884
- }), /* @__PURE__ */ M(N, {
885
- variant: "secondary",
886
- children: ["Drift ≤ ", y(e.driftThresholdPct)]
887
- })]
888
- }),
889
- a.length > 0 ? /* @__PURE__ */ j("ul", {
890
- className: "space-y-1",
891
- "aria-label": "Target allocation",
892
- children: a.slice(0, 3).map((e) => /* @__PURE__ */ M("li", {
893
- className: "flex items-center gap-1.5 text-xs",
894
- children: [/* @__PURE__ */ j("span", {
895
- className: "truncate text-text-secondary",
896
- children: e.label
897
- }), /* @__PURE__ */ j("span", {
898
- className: "ml-auto font-medium tabular-nums text-text-primary",
899
- children: y(e.value, 0)
982
+ className: "space-y-2",
983
+ "aria-busy": "true",
984
+ children: [/* @__PURE__ */ j("div", { className: "h-7 w-32 animate-pulse rounded bg-bg-sunken" }), /* @__PURE__ */ j("div", { className: "h-1.5 w-full animate-pulse rounded-full bg-bg-sunken" })]
985
+ }),
986
+ /* @__PURE__ */ M("div", {
987
+ className: "grid grid-cols-[auto_1fr] items-center gap-4",
988
+ children: [s.length > 0 ? /* @__PURE__ */ j("div", {
989
+ className: "w-28 shrink-0",
990
+ children: /* @__PURE__ */ j(p, {
991
+ data: s,
992
+ legend: !1,
993
+ height: 112,
994
+ centerValue: c ? x(c.value, 0) : void 0,
995
+ centerLabel: c?.label,
996
+ valueFormatter: (e) => x(e, 0)
997
+ })
998
+ }) : /* @__PURE__ */ M("div", {
999
+ className: "flex size-28 shrink-0 items-center justify-center rounded-full border border-dashed border-border-subtle text-center text-[10px] leading-tight text-text-secondary",
1000
+ children: [
1001
+ "No target",
1002
+ /* @__PURE__ */ j("br", {}),
1003
+ "allocation"
1004
+ ]
1005
+ }), /* @__PURE__ */ M("div", {
1006
+ className: "min-w-0 space-y-2",
1007
+ children: [
1008
+ /* @__PURE__ */ M("div", {
1009
+ className: "flex flex-wrap items-center gap-1.5",
1010
+ children: [/* @__PURE__ */ j(N, {
1011
+ variant: "outline",
1012
+ children: e.baseCurrency
1013
+ }), /* @__PURE__ */ M(N, {
1014
+ variant: "secondary",
1015
+ children: ["Drift ≤ ", x(e.driftThresholdPct)]
900
1016
  })]
901
- }, e.label))
902
- }) : null,
903
- s.length > 0 ? /* @__PURE__ */ j("div", {
904
- className: "flex flex-wrap gap-1",
905
- children: s.slice(0, 3).map((e) => /* @__PURE__ */ j(N, {
906
- variant: "outline",
907
- className: "text-[10px]",
908
- children: e
909
- }, e))
910
- }) : null
911
- ]
912
- })]
913
- }), /* @__PURE__ */ j(P, {
914
- variant: "outline",
915
- size: "sm",
916
- className: "w-full",
917
- onClick: n,
918
- children: "View holdings"
919
- })]
1017
+ }),
1018
+ s.length > 0 ? /* @__PURE__ */ j("ul", {
1019
+ className: "space-y-1",
1020
+ "aria-label": "Target allocation",
1021
+ children: s.slice(0, 3).map((e) => /* @__PURE__ */ M("li", {
1022
+ className: "flex items-center gap-1.5 text-xs",
1023
+ children: [/* @__PURE__ */ j("span", {
1024
+ className: "truncate text-text-secondary",
1025
+ children: e.label
1026
+ }), /* @__PURE__ */ j("span", {
1027
+ className: "ml-auto font-medium tabular-nums text-text-primary",
1028
+ children: x(e.value, 0)
1029
+ })]
1030
+ }, e.label))
1031
+ }) : null,
1032
+ l.length > 0 ? /* @__PURE__ */ j("div", {
1033
+ className: "flex flex-wrap gap-1",
1034
+ children: l.slice(0, 3).map((e) => /* @__PURE__ */ j(N, {
1035
+ variant: "outline",
1036
+ className: "text-[10px]",
1037
+ children: e
1038
+ }, e))
1039
+ }) : null
1040
+ ]
1041
+ })]
1042
+ }),
1043
+ /* @__PURE__ */ j(P, {
1044
+ variant: "outline",
1045
+ size: "sm",
1046
+ className: "w-full",
1047
+ onClick: i,
1048
+ children: "View holdings"
1049
+ })
1050
+ ]
920
1051
  })]
921
1052
  })
922
1053
  });
923
1054
  }
924
- function Ue() {
925
- C("brainyrich.portfolios.viewed");
926
- let { items: t, hasMore: n, loadMore: r, isLoading: i, isFetchingNextPage: a, isError: s, refetch: c } = o(), l = e(), [f, m] = E(!1), [g, _] = E(null), [ie, v] = E(null), [b, w] = E(null), ae = t.filter((e) => e.status === "ACTIVE").length, T = t.filter((e) => e.status === "DRAFT").length, D = t.length > 0 ? t.reduce((e, t) => e + t.driftThresholdPct, 0) / t.length : 0, O = () => {
927
- _(null), m(!0);
928
- }, oe = (e) => {
929
- _(e), m(!0);
1055
+ function Ye() {
1056
+ T("brainyrich.portfolios.viewed");
1057
+ let { items: n, hasMore: r, loadMore: i, isLoading: a, isFetchingNextPage: o, isError: c, refetch: l } = s(), u = t(), p = e(), h = E(() => {
1058
+ let e = /* @__PURE__ */ new Map();
1059
+ for (let t of p.data) {
1060
+ if (!t.portfolioId) continue;
1061
+ let n = e.get(t.portfolioId);
1062
+ n ? n.push(t) : e.set(t.portfolioId, [t]);
1063
+ }
1064
+ return e;
1065
+ }, [p.data]), _ = E(() => {
1066
+ let e = /* @__PURE__ */ new Map();
1067
+ for (let t of n) e.set(t.id, Be(h.get(t.id) ?? [], t.targetAllocation));
1068
+ return e;
1069
+ }, [n, h]), [ee, v] = D(!1), [b, S] = D(null), [ae, oe] = D(null), [O, k] = D(null), se = n.filter((e) => e.status === "ACTIVE").length, ce = n.filter((e) => e.status === "DRAFT").length, ue = n.length > 0 ? n.reduce((e, t) => e + t.driftThresholdPct, 0) / n.length : 0, N = E(() => {
1070
+ let e = /* @__PURE__ */ new Map();
1071
+ for (let t of n) {
1072
+ let n = _.get(t.id);
1073
+ !n || n.holdingCount === 0 || e.set(t.baseCurrency, (e.get(t.baseCurrency) ?? 0) + n.marketValue);
1074
+ }
1075
+ return e;
1076
+ }, [n, _]), F = Array.from(N.keys()).sort(), I = F.length === 1 ? F[0] : void 0, L = n.filter((e) => {
1077
+ let t = _.get(e.id)?.maxDriftPct;
1078
+ return t == null || e.driftThresholdPct <= 0 ? !1 : Math.abs(t) > e.driftThresholdPct;
1079
+ }).length, R = () => {
1080
+ S(null), v(!0);
1081
+ }, z = (e) => {
1082
+ S(e), v(!0);
930
1083
  };
931
1084
  return /* @__PURE__ */ j("div", {
932
1085
  "data-tour": "brainyrich-page-portfolios",
933
1086
  className: "contents",
934
- children: /* @__PURE__ */ M(re, {
1087
+ children: /* @__PURE__ */ M(ie, {
935
1088
  title: "Portfolios",
936
1089
  description: "Organize holdings into strategies and keep allocations on target.",
937
- badges: t.length > 0 ? [`${t.length} total`] : [],
1090
+ badges: n.length > 0 ? [`${n.length} total`] : [],
938
1091
  actions: /* @__PURE__ */ M(P, {
939
1092
  size: "sm",
940
- onClick: O,
941
- children: [/* @__PURE__ */ j(A, {
1093
+ onClick: R,
1094
+ children: [/* @__PURE__ */ j(le, {
942
1095
  className: "size-4",
943
1096
  "aria-hidden": "true"
944
1097
  }), "New portfolio"]
945
1098
  }),
946
1099
  children: [
947
- i ? /* @__PURE__ */ j(ne, { rows: 4 }) : s ? /* @__PURE__ */ j(te, { onRetry: () => c() }) : t.length === 0 ? /* @__PURE__ */ j(ee, {
948
- icon: /* @__PURE__ */ j(k, {
1100
+ a ? /* @__PURE__ */ j(re, { rows: 4 }) : c ? /* @__PURE__ */ j(ne, { onRetry: () => l() }) : n.length === 0 ? /* @__PURE__ */ j(te, {
1101
+ icon: /* @__PURE__ */ j(A, {
949
1102
  className: "size-6",
950
1103
  "aria-hidden": "true"
951
1104
  }),
@@ -953,76 +1106,100 @@ function Ue() {
953
1106
  description: "Create your first portfolio to start organizing holdings and tracking drift.",
954
1107
  action: /* @__PURE__ */ M(P, {
955
1108
  size: "sm",
956
- onClick: O,
957
- children: [/* @__PURE__ */ j(A, {
1109
+ onClick: R,
1110
+ children: [/* @__PURE__ */ j(le, {
958
1111
  className: "size-4",
959
1112
  "aria-hidden": "true"
960
1113
  }), "New portfolio"]
961
1114
  })
962
- }) : /* @__PURE__ */ M(le, { children: [
963
- /* @__PURE__ */ M(p, {
964
- className: "grid grid-cols-2 gap-3 lg:grid-cols-4",
1115
+ }) : /* @__PURE__ */ M(de, { children: [
1116
+ /* @__PURE__ */ M(m, {
1117
+ className: "grid grid-cols-2 gap-3 lg:grid-cols-5",
965
1118
  children: [
966
- /* @__PURE__ */ j(h, {
1119
+ /* @__PURE__ */ j(g, {
967
1120
  label: "Portfolios",
968
- value: String(t.length),
1121
+ value: String(n.length),
969
1122
  glow: !0
970
1123
  }),
971
- /* @__PURE__ */ j(h, {
1124
+ /* @__PURE__ */ j(g, {
1125
+ label: I ? `Total value (${I})` : "Total value",
1126
+ value: p.isPending ? "…" : p.isError ? "—" : I ? y(N.get(I) ?? 0, I) : F.length === 0 ? "—" : `${F.length} currencies`
1127
+ }),
1128
+ /* @__PURE__ */ j(g, {
972
1129
  label: "Active",
973
- value: String(ae)
1130
+ value: String(se)
974
1131
  }),
975
- /* @__PURE__ */ j(h, {
1132
+ /* @__PURE__ */ j(g, {
976
1133
  label: "Drafts",
977
- value: String(T)
1134
+ value: String(ce)
978
1135
  }),
979
- /* @__PURE__ */ j(h, {
980
- label: "Avg drift threshold",
981
- value: y(D)
1136
+ /* @__PURE__ */ j(g, {
1137
+ label: "Past drift threshold",
1138
+ value: p.isPending ? "…" : p.isError ? "—" : String(L)
982
1139
  })
983
1140
  ]
984
1141
  }),
1142
+ !p.isPending && !p.isError && F.length > 1 ? /* @__PURE__ */ M("p", {
1143
+ className: "text-xs text-text-secondary",
1144
+ children: [
1145
+ "Market value is not FX-converted:",
1146
+ " ",
1147
+ F.map((e) => y(N.get(e) ?? 0, e)).join(" · "),
1148
+ ". Average drift threshold ",
1149
+ x(ue),
1150
+ "."
1151
+ ]
1152
+ }) : /* @__PURE__ */ M("p", {
1153
+ className: "text-xs text-text-secondary",
1154
+ children: [
1155
+ "Average drift threshold across these portfolios: ",
1156
+ x(ue),
1157
+ "."
1158
+ ]
1159
+ }),
985
1160
  /* @__PURE__ */ j("div", {
986
1161
  className: "grid gap-4 md:grid-cols-2 xl:grid-cols-3",
987
- children: t.map((e, t) => /* @__PURE__ */ j(He, {
1162
+ children: n.map((e, t) => /* @__PURE__ */ j(Je, {
988
1163
  portfolio: e,
1164
+ valuation: p.isPending ? void 0 : _.get(e.id),
1165
+ valuationError: p.isError,
989
1166
  index: t,
990
- onView: () => v(e.id),
991
- onEdit: () => oe(e),
992
- onArchive: () => w(e)
1167
+ onView: () => oe(e.id),
1168
+ onEdit: () => z(e),
1169
+ onArchive: () => k(e)
993
1170
  }, e.id))
994
1171
  }),
995
- /* @__PURE__ */ j(u, {
996
- hasMore: n,
997
- onClick: r,
998
- loading: a
1172
+ /* @__PURE__ */ j(d, {
1173
+ hasMore: r,
1174
+ onClick: i,
1175
+ loading: o
999
1176
  })
1000
1177
  ] }),
1001
- /* @__PURE__ */ j(Re, {
1002
- open: f,
1003
- onOpenChange: m,
1004
- editing: g
1178
+ /* @__PURE__ */ j(Ue, {
1179
+ open: ee,
1180
+ onOpenChange: v,
1181
+ editing: b
1005
1182
  }),
1006
- /* @__PURE__ */ j(Ve, {
1007
- portfolioId: ie,
1183
+ /* @__PURE__ */ j(Ke, {
1184
+ portfolioId: ae,
1008
1185
  onOpenChange: (e) => {
1009
- e || v(null);
1186
+ e || oe(null);
1010
1187
  }
1011
1188
  }),
1012
- /* @__PURE__ */ j(d, {
1013
- open: b !== null,
1189
+ /* @__PURE__ */ j(f, {
1190
+ open: O !== null,
1014
1191
  onOpenChange: (e) => {
1015
- e || w(null);
1192
+ e || k(null);
1016
1193
  },
1017
1194
  title: "Archive portfolio?",
1018
- description: b ? `Archive “${b.name}”. It will move to archived status and stop appearing in active views.` : void 0,
1195
+ description: O ? `Archive “${O.name}”. It will move to archived status and stop appearing in active views.` : void 0,
1019
1196
  confirmLabel: "Archive",
1020
1197
  pendingLabel: "Archiving…",
1021
1198
  destructive: !0,
1022
- pending: l.isPending,
1199
+ pending: u.isPending,
1023
1200
  onConfirm: () => {
1024
- b && l.mutate(b.id, { onSuccess: () => {
1025
- x(), S("Portfolio archived"), w(null);
1201
+ O && u.mutate(O.id, { onSuccess: () => {
1202
+ C(), w("Portfolio archived"), k(null);
1026
1203
  } });
1027
1204
  }
1028
1205
  })
@@ -1031,6 +1208,6 @@ function Ue() {
1031
1208
  });
1032
1209
  }
1033
1210
  //#endregion
1034
- export { Ue as PortfoliosPage };
1211
+ export { Ye as PortfoliosPage };
1035
1212
 
1036
1213
  //# sourceMappingURL=PortfoliosPage.js.map