@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.
- package/dist/brainyrich/BrainyRichRoot.js +55 -90
- package/dist/brainyrich/BrainyRichRoot.js.map +1 -1
- package/dist/brainyrich/BrainyRichRoutes.js +15 -35
- package/dist/brainyrich/BrainyRichRoutes.js.map +1 -1
- package/dist/brainyrich/components/ActorName.js +38 -0
- package/dist/brainyrich/components/ActorName.js.map +1 -0
- package/dist/brainyrich/components/ConfirmDialog.js +25 -0
- package/dist/brainyrich/components/ConfirmDialog.js.map +1 -0
- package/dist/brainyrich/components/LoadMore.js +24 -0
- package/dist/brainyrich/components/LoadMore.js.map +1 -0
- package/dist/brainyrich/components/index.js +5 -0
- package/dist/brainyrich/components/notify.js +38 -0
- package/dist/brainyrich/components/notify.js.map +1 -0
- package/dist/brainyrich/components/pickers.js +232 -0
- package/dist/brainyrich/components/pickers.js.map +1 -0
- package/dist/brainyrich/components/reuse/CommentThread.js +208 -0
- package/dist/brainyrich/components/reuse/CommentThread.js.map +1 -0
- package/dist/brainyrich/components/reuse/DocumentsPanel.js +237 -0
- package/dist/brainyrich/components/reuse/DocumentsPanel.js.map +1 -0
- package/dist/brainyrich/components/reuse/TagField.js +206 -0
- package/dist/brainyrich/components/reuse/TagField.js.map +1 -0
- package/dist/brainyrich/components/reuse/transport.js +24 -0
- package/dist/brainyrich/components/reuse/transport.js.map +1 -0
- package/dist/brainyrich/hooks/useBrainyRichApi.js +815 -0
- package/dist/brainyrich/hooks/useBrainyRichApi.js.map +1 -0
- package/dist/brainyrich/index.js +0 -1
- package/dist/brainyrich/pages/AccountsPage.js +743 -160
- package/dist/brainyrich/pages/AccountsPage.js.map +1 -1
- package/dist/brainyrich/pages/AiAssistantPage.js +556 -363
- package/dist/brainyrich/pages/AiAssistantPage.js.map +1 -1
- package/dist/brainyrich/pages/AnalyticsPage.js +601 -268
- package/dist/brainyrich/pages/AnalyticsPage.js.map +1 -1
- package/dist/brainyrich/pages/DashboardPage.js +375 -231
- package/dist/brainyrich/pages/DashboardPage.js.map +1 -1
- package/dist/brainyrich/pages/FamilyPage.js +599 -337
- package/dist/brainyrich/pages/FamilyPage.js.map +1 -1
- package/dist/brainyrich/pages/GoalsPage.js +810 -141
- package/dist/brainyrich/pages/GoalsPage.js.map +1 -1
- package/dist/brainyrich/pages/InvestmentsPage.js +410 -311
- package/dist/brainyrich/pages/InvestmentsPage.js.map +1 -1
- package/dist/brainyrich/pages/PortfoliosPage.js +867 -156
- package/dist/brainyrich/pages/PortfoliosPage.js.map +1 -1
- package/dist/brainyrich/pages/ReportsPage.js +421 -251
- package/dist/brainyrich/pages/ReportsPage.js.map +1 -1
- package/dist/brainyrich/pages/RiskPage.js +557 -194
- package/dist/brainyrich/pages/RiskPage.js.map +1 -1
- package/dist/brainyrich/pages/TaxPage.js +655 -221
- package/dist/brainyrich/pages/TaxPage.js.map +1 -1
- package/dist/brainyrich/pages/_shared.js +222 -41
- package/dist/brainyrich/pages/_shared.js.map +1 -1
- package/dist/index.js +2 -3
- package/dist/node_modules/sonner/dist/index.js +163 -0
- package/dist/node_modules/sonner/dist/index.js.map +1 -0
- package/package.json +3 -2
- package/dist/brainyrich/pages/AdvisorsPage.js +0 -375
- package/dist/brainyrich/pages/AdvisorsPage.js.map +0 -1
- package/dist/brainyrich/pages/AssistantPage.js +0 -332
- package/dist/brainyrich/pages/AssistantPage.js.map +0 -1
- package/dist/brainyrich/pages/EstatePage.js +0 -269
- package/dist/brainyrich/pages/EstatePage.js.map +0 -1
- package/dist/brainyrich/pages/InsurancePage.js +0 -181
- package/dist/brainyrich/pages/InsurancePage.js.map +0 -1
- package/dist/brainyrich/pages/MarketplacePage.js +0 -450
- package/dist/brainyrich/pages/MarketplacePage.js.map +0 -1
- package/dist/brainyrich/store/brainyrichStore.js +0 -272
- package/dist/brainyrich/store/brainyrichStore.js.map +0 -1
|
@@ -1,316 +1,649 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { KpiGrid as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { useAccounts as e, useAllTransactions as t, useHoldings as n, useNetWorthSummary as r, useRecordTransaction as i } from "../hooks/useBrainyRichApi.js";
|
|
2
|
+
import { AllocationBars as a, EmptyState as o, ErrorState as ee, KpiGrid as te, LoadingState as s, SectionShell as ne, formatDate as re, formatMoney as c, formatPct as ie } from "./_shared.js";
|
|
3
|
+
import { useMemo as l, useState as ae } from "react";
|
|
4
|
+
import { ArrowDownRight as oe, ArrowUpRight as se, BarChart3 as u, Minus as d, PieChart as ce, Plus as le, Wallet as f } from "lucide-react";
|
|
5
|
+
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
6
|
+
import { Badge as ue, Button as h, Card as g, CardContent as _, CardDescription as v, CardHeader as y, CardTitle as b, Dialog as de, DialogContent as fe, DialogDescription as pe, DialogFooter as me, DialogHeader as he, DialogTitle as ge, DialogTrigger as _e, Input as x, Label as S, Select as C, SelectContent as w, SelectItem as T, SelectTrigger as E, SelectValue as D, Table as O, TableBody as k, TableCell as A, TableHead as j, TableHeader as M, TableRow as N, Tabs as ve, TabsContent as P, TabsList as ye, TabsTrigger as F, Textarea as be } from "@burdenoff/fe-libs/ui";
|
|
6
7
|
//#region src/brainyrich/pages/AnalyticsPage.tsx
|
|
7
|
-
var
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
8
|
+
var I = (e) => e.toLowerCase().split("_").map((e) => e && e[0].toUpperCase() + e.slice(1)).join(" "), L = [
|
|
9
|
+
"DEPOSIT",
|
|
10
|
+
"DIVIDEND",
|
|
11
|
+
"INTEREST",
|
|
12
|
+
"SELL"
|
|
13
|
+
], R = [
|
|
14
|
+
"WITHDRAWAL",
|
|
15
|
+
"FEE",
|
|
16
|
+
"BUY"
|
|
17
|
+
], z = (e) => L.includes(e) ? "in" : R.includes(e) ? "out" : "neutral", xe = (e) => {
|
|
18
|
+
let t = new Date(e);
|
|
19
|
+
return Number.isNaN(t.getTime()) ? null : {
|
|
20
|
+
key: `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, "0")}`,
|
|
21
|
+
label: new Intl.DateTimeFormat("en-US", {
|
|
22
|
+
month: "short",
|
|
23
|
+
year: "numeric"
|
|
24
|
+
}).format(t)
|
|
25
|
+
};
|
|
26
|
+
}, Se = (e) => {
|
|
27
|
+
let t = /* @__PURE__ */ new Map();
|
|
28
|
+
for (let n of e) {
|
|
29
|
+
let e = xe(n.tradeDate);
|
|
30
|
+
if (!e) continue;
|
|
31
|
+
let r = z(n.type);
|
|
32
|
+
if (r === "neutral") continue;
|
|
33
|
+
let i = Math.abs(n.amount), a = t.get(e.key) ?? {
|
|
34
|
+
key: e.key,
|
|
35
|
+
label: e.label,
|
|
36
|
+
inflow: 0,
|
|
37
|
+
outflow: 0
|
|
38
|
+
};
|
|
39
|
+
r === "in" ? a.inflow += i : a.outflow += i, t.set(e.key, a);
|
|
37
40
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
41
|
+
return Array.from(t.values()).sort((e, t) => e.key.localeCompare(t.key));
|
|
42
|
+
}, Ce = (e) => {
|
|
43
|
+
let t = /* @__PURE__ */ new Map();
|
|
44
|
+
for (let n of e) t.set(n.type, (t.get(n.type) ?? 0) + Math.abs(n.amount));
|
|
45
|
+
return Array.from(t.entries()).map(([e, t]) => ({
|
|
46
|
+
type: e,
|
|
47
|
+
total: t,
|
|
48
|
+
dir: z(e)
|
|
49
|
+
})).sort((e, t) => t.total - e.total);
|
|
50
|
+
};
|
|
51
|
+
function we({ value: e, currency: t }) {
|
|
52
|
+
let n = e > 0, r = e < 0, i = n ? se : r ? oe : d, a = n ? "text-status-success-text" : r ? "text-status-error-text" : "text-text-secondary", o = n ? "+" : r ? "-" : "";
|
|
53
|
+
return /* @__PURE__ */ m("span", {
|
|
54
|
+
className: `inline-flex items-center justify-end gap-1 font-medium ${a}`,
|
|
55
|
+
children: [
|
|
56
|
+
/* @__PURE__ */ p(i, {
|
|
57
|
+
className: "size-3.5",
|
|
58
|
+
"aria-hidden": "true"
|
|
59
|
+
}),
|
|
60
|
+
o,
|
|
61
|
+
c(Math.abs(e), t)
|
|
62
|
+
]
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
var Te = {
|
|
66
|
+
accountId: "",
|
|
67
|
+
type: "DEPOSIT",
|
|
68
|
+
amount: "",
|
|
69
|
+
symbol: "",
|
|
70
|
+
tradeDate: "",
|
|
71
|
+
notes: ""
|
|
72
|
+
}, Ee = [
|
|
73
|
+
"DEPOSIT",
|
|
74
|
+
"WITHDRAWAL",
|
|
75
|
+
"DIVIDEND",
|
|
76
|
+
"INTEREST",
|
|
77
|
+
"FEE",
|
|
78
|
+
"BUY",
|
|
79
|
+
"SELL",
|
|
80
|
+
"TRANSFER"
|
|
81
|
+
];
|
|
82
|
+
function B() {
|
|
83
|
+
let d = r(), L = t(), R = e(), [z, xe] = ae(void 0), B = R.data, De = z ?? B[0]?.id, V = n({ accountId: De }), H = i(), [Oe, U] = ae(!1), [W, G] = ae(Te), K = d.data, q = K?.currency ?? "USD", J = L.data, ke = l(() => !K || K.totalMarketValue <= 0 ? [] : K.byAssetClass.filter((e) => e.marketValue !== 0).map((e) => ({
|
|
84
|
+
label: I(e.assetClass),
|
|
85
|
+
value: e.marketValue / K.totalMarketValue * 100,
|
|
86
|
+
caption: c(e.marketValue, q),
|
|
87
|
+
tone: "accent"
|
|
88
|
+
})).sort((e, t) => t.value - e.value), [K, q]), Ae = l(() => {
|
|
89
|
+
if (!K) return [];
|
|
90
|
+
let e = K.totalMarketValue + K.totalCash;
|
|
91
|
+
return e <= 0 ? [] : [{
|
|
92
|
+
label: "Invested (Market Value)",
|
|
93
|
+
value: K.totalMarketValue / e * 100,
|
|
94
|
+
caption: c(K.totalMarketValue, q),
|
|
95
|
+
tone: "default"
|
|
96
|
+
}, {
|
|
97
|
+
label: "Cash",
|
|
98
|
+
value: K.totalCash / e * 100,
|
|
99
|
+
caption: c(K.totalCash, q),
|
|
100
|
+
tone: "warning"
|
|
101
|
+
}];
|
|
102
|
+
}, [K, q]), Y = l(() => Se(J), [J]), je = l(() => Ce(J), [J]), X = l(() => {
|
|
103
|
+
let e = 0, t = 0;
|
|
104
|
+
for (let n of Y) e += n.inflow, t += n.outflow;
|
|
105
|
+
return {
|
|
106
|
+
inflow: e,
|
|
107
|
+
outflow: t,
|
|
108
|
+
net: e - t
|
|
109
|
+
};
|
|
110
|
+
}, [Y]), Z = l(() => Math.max(1, ...Y.map((e) => Math.max(e.inflow, e.outflow))), [Y]), Me = V.data, Q = l(() => {
|
|
111
|
+
let e = Me.map((e) => ({
|
|
112
|
+
holding: e,
|
|
113
|
+
unrealized: e.marketValue - e.costBasis
|
|
114
|
+
})).sort((e, t) => t.unrealized - e.unrealized);
|
|
115
|
+
return {
|
|
116
|
+
rows: e,
|
|
117
|
+
totalUnrealized: e.reduce((e, t) => e + t.unrealized, 0),
|
|
118
|
+
totalCost: Me.reduce((e, t) => e + t.costBasis, 0)
|
|
119
|
+
};
|
|
120
|
+
}, [Me]);
|
|
121
|
+
if (d.isLoading) return /* @__PURE__ */ p(ne, {
|
|
122
|
+
title: "Wealth Analytics",
|
|
123
|
+
description: "Allocation, cash flow, and holdings performance derived from your real accounts.",
|
|
124
|
+
children: /* @__PURE__ */ p(s, { rows: 5 })
|
|
125
|
+
});
|
|
126
|
+
if (d.isError || !K) return /* @__PURE__ */ p(ne, {
|
|
127
|
+
title: "Wealth Analytics",
|
|
128
|
+
description: "Allocation, cash flow, and holdings performance derived from your real accounts.",
|
|
129
|
+
children: /* @__PURE__ */ p(ee, {
|
|
130
|
+
title: "Could not load analytics",
|
|
131
|
+
description: "We couldn't reach the wealth service. Please retry.",
|
|
132
|
+
onRetry: () => d.refetch()
|
|
133
|
+
})
|
|
134
|
+
});
|
|
135
|
+
let $ = Number(W.amount), Ne = !!W.accountId && !!W.tradeDate && W.amount.trim() !== "" && Number.isFinite($) && $ > 0 && !H.isPending, Pe = /* @__PURE__ */ m(de, {
|
|
136
|
+
open: Oe,
|
|
137
|
+
onOpenChange: (e) => {
|
|
138
|
+
U(e), e || G(Te);
|
|
139
|
+
},
|
|
140
|
+
children: [/* @__PURE__ */ p(_e, {
|
|
141
|
+
asChild: !0,
|
|
142
|
+
children: /* @__PURE__ */ m(h, {
|
|
143
|
+
size: "sm",
|
|
144
|
+
children: [/* @__PURE__ */ p(le, {
|
|
145
|
+
className: "mr-1 size-4",
|
|
146
|
+
"aria-hidden": "true"
|
|
147
|
+
}), "Record Transaction"]
|
|
148
|
+
})
|
|
149
|
+
}), /* @__PURE__ */ m(fe, { children: [
|
|
150
|
+
/* @__PURE__ */ m(he, { children: [/* @__PURE__ */ p(ge, { children: "Record Transaction" }), /* @__PURE__ */ p(pe, { children: "Log a real cash flow or trade. It updates your cash-flow analytics immediately." })] }),
|
|
151
|
+
B.length === 0 ? /* @__PURE__ */ p(o, {
|
|
152
|
+
icon: /* @__PURE__ */ p(f, {
|
|
153
|
+
className: "size-6",
|
|
154
|
+
"aria-hidden": "true"
|
|
155
|
+
}),
|
|
156
|
+
title: "Create an account first",
|
|
157
|
+
description: "You need at least one account before you can record a transaction. Open the Accounts page to add one, then come back here."
|
|
158
|
+
}) : /* @__PURE__ */ m("div", {
|
|
159
|
+
className: "space-y-4",
|
|
160
|
+
children: [
|
|
161
|
+
/* @__PURE__ */ m("div", {
|
|
162
|
+
className: "space-y-1.5",
|
|
163
|
+
children: [/* @__PURE__ */ p(S, {
|
|
164
|
+
htmlFor: "tx-account",
|
|
165
|
+
children: "Account"
|
|
166
|
+
}), /* @__PURE__ */ m(C, {
|
|
167
|
+
value: W.accountId,
|
|
168
|
+
onValueChange: (e) => G((t) => ({
|
|
169
|
+
...t,
|
|
170
|
+
accountId: e
|
|
171
|
+
})),
|
|
172
|
+
children: [/* @__PURE__ */ p(E, {
|
|
173
|
+
id: "tx-account",
|
|
174
|
+
children: /* @__PURE__ */ p(D, { placeholder: "Select an account" })
|
|
175
|
+
}), /* @__PURE__ */ p(w, { children: B.map((e) => /* @__PURE__ */ p(T, {
|
|
176
|
+
value: e.id,
|
|
177
|
+
children: e.name
|
|
178
|
+
}, e.id)) })]
|
|
179
|
+
})]
|
|
180
|
+
}),
|
|
181
|
+
/* @__PURE__ */ m("div", {
|
|
182
|
+
className: "grid grid-cols-2 gap-4",
|
|
183
|
+
children: [/* @__PURE__ */ m("div", {
|
|
184
|
+
className: "space-y-1.5",
|
|
185
|
+
children: [/* @__PURE__ */ p(S, {
|
|
186
|
+
htmlFor: "tx-type",
|
|
187
|
+
children: "Type"
|
|
188
|
+
}), /* @__PURE__ */ m(C, {
|
|
189
|
+
value: W.type,
|
|
190
|
+
onValueChange: (e) => G((t) => ({
|
|
191
|
+
...t,
|
|
192
|
+
type: e
|
|
193
|
+
})),
|
|
194
|
+
children: [/* @__PURE__ */ p(E, {
|
|
195
|
+
id: "tx-type",
|
|
196
|
+
children: /* @__PURE__ */ p(D, {})
|
|
197
|
+
}), /* @__PURE__ */ p(w, { children: Ee.map((e) => /* @__PURE__ */ p(T, {
|
|
198
|
+
value: e,
|
|
199
|
+
children: I(e)
|
|
200
|
+
}, e)) })]
|
|
201
|
+
})]
|
|
202
|
+
}), /* @__PURE__ */ m("div", {
|
|
203
|
+
className: "space-y-1.5",
|
|
204
|
+
children: [/* @__PURE__ */ m(S, {
|
|
205
|
+
htmlFor: "tx-amount",
|
|
206
|
+
children: [
|
|
207
|
+
"Amount (",
|
|
208
|
+
q,
|
|
209
|
+
")"
|
|
210
|
+
]
|
|
211
|
+
}), /* @__PURE__ */ p(x, {
|
|
212
|
+
id: "tx-amount",
|
|
213
|
+
type: "number",
|
|
214
|
+
min: "0",
|
|
215
|
+
step: "0.01",
|
|
216
|
+
inputMode: "decimal",
|
|
217
|
+
placeholder: "0.00",
|
|
218
|
+
value: W.amount,
|
|
219
|
+
onChange: (e) => G((t) => ({
|
|
220
|
+
...t,
|
|
221
|
+
amount: e.target.value
|
|
222
|
+
}))
|
|
223
|
+
})]
|
|
224
|
+
})]
|
|
225
|
+
}),
|
|
226
|
+
/* @__PURE__ */ m("div", {
|
|
227
|
+
className: "grid grid-cols-2 gap-4",
|
|
228
|
+
children: [/* @__PURE__ */ m("div", {
|
|
229
|
+
className: "space-y-1.5",
|
|
230
|
+
children: [/* @__PURE__ */ p(S, {
|
|
231
|
+
htmlFor: "tx-date",
|
|
232
|
+
children: "Trade date"
|
|
233
|
+
}), /* @__PURE__ */ p(x, {
|
|
234
|
+
id: "tx-date",
|
|
235
|
+
type: "date",
|
|
236
|
+
value: W.tradeDate,
|
|
237
|
+
onChange: (e) => G((t) => ({
|
|
238
|
+
...t,
|
|
239
|
+
tradeDate: e.target.value
|
|
240
|
+
}))
|
|
241
|
+
})]
|
|
242
|
+
}), /* @__PURE__ */ m("div", {
|
|
243
|
+
className: "space-y-1.5",
|
|
244
|
+
children: [/* @__PURE__ */ p(S, {
|
|
245
|
+
htmlFor: "tx-symbol",
|
|
246
|
+
children: "Symbol (optional)"
|
|
247
|
+
}), /* @__PURE__ */ p(x, {
|
|
248
|
+
id: "tx-symbol",
|
|
249
|
+
placeholder: "e.g. AAPL",
|
|
250
|
+
value: W.symbol,
|
|
251
|
+
onChange: (e) => G((t) => ({
|
|
252
|
+
...t,
|
|
253
|
+
symbol: e.target.value
|
|
254
|
+
}))
|
|
255
|
+
})]
|
|
256
|
+
})]
|
|
257
|
+
}),
|
|
258
|
+
/* @__PURE__ */ m("div", {
|
|
259
|
+
className: "space-y-1.5",
|
|
260
|
+
children: [/* @__PURE__ */ p(S, {
|
|
261
|
+
htmlFor: "tx-notes",
|
|
262
|
+
children: "Notes (optional)"
|
|
263
|
+
}), /* @__PURE__ */ p(be, {
|
|
264
|
+
id: "tx-notes",
|
|
265
|
+
rows: 2,
|
|
266
|
+
placeholder: "Context for this transaction",
|
|
267
|
+
value: W.notes,
|
|
268
|
+
onChange: (e) => G((t) => ({
|
|
269
|
+
...t,
|
|
270
|
+
notes: e.target.value
|
|
271
|
+
}))
|
|
272
|
+
})]
|
|
273
|
+
}),
|
|
274
|
+
H.isError ? /* @__PURE__ */ p("p", {
|
|
275
|
+
className: "text-sm text-status-error-text",
|
|
276
|
+
children: H.error instanceof Error ? H.error.message : "Could not record transaction."
|
|
277
|
+
}) : null
|
|
278
|
+
]
|
|
279
|
+
}),
|
|
280
|
+
/* @__PURE__ */ m(me, { children: [/* @__PURE__ */ p(h, {
|
|
281
|
+
variant: "outline",
|
|
282
|
+
onClick: () => U(!1),
|
|
283
|
+
children: B.length === 0 ? "Close" : "Cancel"
|
|
284
|
+
}), B.length > 0 ? /* @__PURE__ */ p(h, {
|
|
285
|
+
onClick: () => {
|
|
286
|
+
Ne && H.mutate({
|
|
287
|
+
accountId: W.accountId,
|
|
288
|
+
type: W.type,
|
|
289
|
+
amount: $,
|
|
290
|
+
symbol: W.symbol.trim() ? W.symbol.trim() : void 0,
|
|
291
|
+
tradeDate: new Date(W.tradeDate).toISOString(),
|
|
292
|
+
notes: W.notes.trim() ? W.notes.trim() : void 0
|
|
293
|
+
}, { onSuccess: () => {
|
|
294
|
+
U(!1), G(Te);
|
|
295
|
+
} });
|
|
296
|
+
},
|
|
297
|
+
disabled: !Ne,
|
|
298
|
+
children: H.isPending ? "Recording…" : "Record"
|
|
299
|
+
}) : null] })
|
|
300
|
+
] })]
|
|
301
|
+
});
|
|
302
|
+
return /* @__PURE__ */ m(ne, {
|
|
79
303
|
title: "Wealth Analytics",
|
|
80
|
-
description: "
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
children: [/* @__PURE__ */
|
|
304
|
+
description: "Allocation, cash flow, and holdings performance derived from your real accounts.",
|
|
305
|
+
badges: [`${K.accountCount} accounts`],
|
|
306
|
+
actions: Pe,
|
|
307
|
+
children: [/* @__PURE__ */ p(te, { items: [
|
|
84
308
|
{
|
|
85
|
-
label: "
|
|
86
|
-
value:
|
|
87
|
-
trend: "+2.3% vs last month"
|
|
309
|
+
label: "Net Worth",
|
|
310
|
+
value: c(K.totalNetWorth, q)
|
|
88
311
|
},
|
|
89
312
|
{
|
|
90
|
-
label: "
|
|
91
|
-
value:
|
|
92
|
-
trend: "+$85K YTD"
|
|
313
|
+
label: "Invested Value",
|
|
314
|
+
value: c(K.totalMarketValue, q)
|
|
93
315
|
},
|
|
94
316
|
{
|
|
95
|
-
label: "
|
|
96
|
-
value:
|
|
97
|
-
trend: "51% savings rate"
|
|
317
|
+
label: "Cash",
|
|
318
|
+
value: c(K.totalCash, q)
|
|
98
319
|
},
|
|
99
320
|
{
|
|
100
|
-
label: "
|
|
101
|
-
value:
|
|
102
|
-
|
|
321
|
+
label: "Net Cash Flow",
|
|
322
|
+
value: c(X.net, q),
|
|
323
|
+
deltaTone: X.net > 0 ? "positive" : X.net < 0 ? "negative" : "neutral",
|
|
324
|
+
trend: J.length > 0 ? `${c(X.inflow, q)} in · ${c(X.outflow, q)} out` : "No transactions yet"
|
|
103
325
|
}
|
|
104
|
-
] }), /* @__PURE__ */
|
|
105
|
-
defaultValue: "
|
|
326
|
+
] }), /* @__PURE__ */ m(ve, {
|
|
327
|
+
defaultValue: "allocation",
|
|
106
328
|
className: "space-y-4",
|
|
107
329
|
children: [
|
|
108
|
-
/* @__PURE__ */
|
|
330
|
+
/* @__PURE__ */ m(ye, {
|
|
109
331
|
className: "grid w-full grid-cols-3",
|
|
110
332
|
children: [
|
|
111
|
-
/* @__PURE__ */
|
|
112
|
-
value: "performance",
|
|
113
|
-
children: "Performance"
|
|
114
|
-
}),
|
|
115
|
-
/* @__PURE__ */ o(_, {
|
|
333
|
+
/* @__PURE__ */ p(F, {
|
|
116
334
|
value: "allocation",
|
|
117
335
|
children: "Allocation"
|
|
118
336
|
}),
|
|
119
|
-
/* @__PURE__ */
|
|
337
|
+
/* @__PURE__ */ p(F, {
|
|
120
338
|
value: "cashflow",
|
|
121
339
|
children: "Cash Flow"
|
|
340
|
+
}),
|
|
341
|
+
/* @__PURE__ */ p(F, {
|
|
342
|
+
value: "performance",
|
|
343
|
+
children: "Performance"
|
|
122
344
|
})
|
|
123
345
|
]
|
|
124
346
|
}),
|
|
125
|
-
/* @__PURE__ */
|
|
126
|
-
value: "
|
|
347
|
+
/* @__PURE__ */ m(P, {
|
|
348
|
+
value: "allocation",
|
|
349
|
+
className: "space-y-4",
|
|
350
|
+
children: [/* @__PURE__ */ m(g, { children: [/* @__PURE__ */ m(y, { children: [/* @__PURE__ */ m(b, {
|
|
351
|
+
className: "flex items-center gap-2",
|
|
352
|
+
children: [/* @__PURE__ */ p(ce, {
|
|
353
|
+
className: "size-5",
|
|
354
|
+
"aria-hidden": "true"
|
|
355
|
+
}), "Asset Allocation"]
|
|
356
|
+
}), /* @__PURE__ */ p(v, { children: "Share of invested value by asset class, from your holdings." })] }), /* @__PURE__ */ p(_, { children: ke.length === 0 ? /* @__PURE__ */ p(o, {
|
|
357
|
+
icon: /* @__PURE__ */ p(ce, {
|
|
358
|
+
className: "size-6",
|
|
359
|
+
"aria-hidden": "true"
|
|
360
|
+
}),
|
|
361
|
+
title: "No invested holdings yet",
|
|
362
|
+
description: "Add holdings to your accounts to see an asset-class breakdown here."
|
|
363
|
+
}) : /* @__PURE__ */ m("div", {
|
|
364
|
+
className: "space-y-4",
|
|
365
|
+
children: [/* @__PURE__ */ p(a, { data: ke }), /* @__PURE__ */ m(O, { children: [/* @__PURE__ */ p(M, { children: /* @__PURE__ */ m(N, { children: [
|
|
366
|
+
/* @__PURE__ */ p(j, { children: "Asset class" }),
|
|
367
|
+
/* @__PURE__ */ p(j, {
|
|
368
|
+
className: "text-right",
|
|
369
|
+
children: "Market value"
|
|
370
|
+
}),
|
|
371
|
+
/* @__PURE__ */ p(j, {
|
|
372
|
+
className: "text-right",
|
|
373
|
+
children: "Weight"
|
|
374
|
+
})
|
|
375
|
+
] }) }), /* @__PURE__ */ p(k, { children: ke.map((e) => /* @__PURE__ */ m(N, { children: [
|
|
376
|
+
/* @__PURE__ */ p(A, {
|
|
377
|
+
className: "font-medium text-text-primary",
|
|
378
|
+
children: e.label
|
|
379
|
+
}),
|
|
380
|
+
/* @__PURE__ */ p(A, {
|
|
381
|
+
className: "text-right",
|
|
382
|
+
children: e.caption
|
|
383
|
+
}),
|
|
384
|
+
/* @__PURE__ */ p(A, {
|
|
385
|
+
className: "text-right text-text-secondary",
|
|
386
|
+
children: ie(e.value)
|
|
387
|
+
})
|
|
388
|
+
] }, e.label)) })] })]
|
|
389
|
+
}) })] }), /* @__PURE__ */ m(g, { children: [/* @__PURE__ */ m(y, { children: [/* @__PURE__ */ m(b, {
|
|
390
|
+
className: "flex items-center gap-2",
|
|
391
|
+
children: [/* @__PURE__ */ p(f, {
|
|
392
|
+
className: "size-5",
|
|
393
|
+
"aria-hidden": "true"
|
|
394
|
+
}), "Net Worth Composition"]
|
|
395
|
+
}), /* @__PURE__ */ p(v, { children: "Invested value versus liquid cash." })] }), /* @__PURE__ */ p(_, { children: Ae.length === 0 ? /* @__PURE__ */ p(o, {
|
|
396
|
+
icon: /* @__PURE__ */ p(f, {
|
|
397
|
+
className: "size-6",
|
|
398
|
+
"aria-hidden": "true"
|
|
399
|
+
}),
|
|
400
|
+
title: "No balances yet",
|
|
401
|
+
description: "Add accounts with balances or holdings to see your composition."
|
|
402
|
+
}) : /* @__PURE__ */ p(a, { data: Ae }) })] })]
|
|
403
|
+
}),
|
|
404
|
+
/* @__PURE__ */ m(P, {
|
|
405
|
+
value: "cashflow",
|
|
127
406
|
className: "space-y-4",
|
|
128
|
-
children: [/* @__PURE__ */
|
|
129
|
-
className: "flex
|
|
130
|
-
children: [/* @__PURE__ */
|
|
131
|
-
|
|
407
|
+
children: [/* @__PURE__ */ m(g, { children: [/* @__PURE__ */ m(y, { children: [/* @__PURE__ */ m(b, {
|
|
408
|
+
className: "flex items-center gap-2",
|
|
409
|
+
children: [/* @__PURE__ */ p(u, {
|
|
410
|
+
className: "size-5",
|
|
411
|
+
"aria-hidden": "true"
|
|
412
|
+
}), "Inflows vs Outflows"]
|
|
413
|
+
}), /* @__PURE__ */ m(v, { children: ["Monthly cash flow aggregated from your recorded transactions.", J.length > 0 ? /* @__PURE__ */ m("span", {
|
|
414
|
+
className: "mt-0.5 block text-xs text-text-secondary",
|
|
415
|
+
children: [
|
|
416
|
+
"Based on ",
|
|
417
|
+
J.length.toLocaleString(),
|
|
418
|
+
" ",
|
|
419
|
+
J.length === 1 ? "transaction" : "transactions",
|
|
420
|
+
"."
|
|
421
|
+
]
|
|
422
|
+
}) : null] })] }), /* @__PURE__ */ p(_, { children: L.isLoading ? /* @__PURE__ */ p(s, { rows: 4 }) : L.isError ? /* @__PURE__ */ p(ee, { onRetry: () => L.refetch() }) : Y.length === 0 ? /* @__PURE__ */ p(o, {
|
|
423
|
+
icon: /* @__PURE__ */ p(u, {
|
|
424
|
+
className: "size-6",
|
|
425
|
+
"aria-hidden": "true"
|
|
426
|
+
}),
|
|
427
|
+
title: "No cash flow to analyze yet",
|
|
428
|
+
description: "Record deposits, withdrawals, or trades to build a cash-flow history.",
|
|
429
|
+
action: /* @__PURE__ */ m(h, {
|
|
132
430
|
size: "sm",
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
children: e.month
|
|
144
|
-
}), /* @__PURE__ */ s("span", { children: [
|
|
145
|
-
"Portfolio: ",
|
|
146
|
-
r(e.portfolio),
|
|
147
|
-
" | Benchmark: ",
|
|
148
|
-
r(e.benchmark)
|
|
149
|
-
] })]
|
|
150
|
-
}), /* @__PURE__ */ s("div", {
|
|
151
|
-
className: "relative h-5 bg-muted rounded overflow-hidden",
|
|
152
|
-
children: [/* @__PURE__ */ o("div", {
|
|
153
|
-
className: "absolute h-5 bg-blue-400/60 rounded",
|
|
154
|
-
style: { width: `${e.benchmark / b * 100}%` }
|
|
155
|
-
}), /* @__PURE__ */ o("div", {
|
|
156
|
-
className: "absolute h-5 bg-blue-600 rounded",
|
|
157
|
-
style: {
|
|
158
|
-
width: `${e.portfolio / b * 100}%`,
|
|
159
|
-
opacity: .8
|
|
160
|
-
}
|
|
161
|
-
})]
|
|
162
|
-
})]
|
|
163
|
-
}, e.month)), /* @__PURE__ */ s("div", {
|
|
164
|
-
className: "flex gap-4 text-xs pt-2",
|
|
165
|
-
children: [/* @__PURE__ */ s("span", {
|
|
166
|
-
className: "flex items-center gap-1",
|
|
167
|
-
children: [/* @__PURE__ */ o("span", { className: "h-2 w-4 bg-blue-600 rounded inline-block" }), " Portfolio"]
|
|
168
|
-
}), /* @__PURE__ */ s("span", {
|
|
169
|
-
className: "flex items-center gap-1",
|
|
170
|
-
children: [/* @__PURE__ */ o("span", { className: "h-2 w-4 bg-blue-400/60 rounded inline-block" }), " Benchmark"]
|
|
171
|
-
})]
|
|
172
|
-
})]
|
|
173
|
-
})] }), /* @__PURE__ */ s(l, { children: [/* @__PURE__ */ s(f, { children: [/* @__PURE__ */ o(p, { children: "Net Worth Trend" }), /* @__PURE__ */ o(d, { children: "Growth trajectory over the past 6 months" })] }), /* @__PURE__ */ o(u, {
|
|
174
|
-
className: "space-y-2",
|
|
175
|
-
children: v.map((e) => /* @__PURE__ */ s("div", {
|
|
176
|
-
className: "flex items-center gap-3",
|
|
431
|
+
onClick: () => U(!0),
|
|
432
|
+
children: [/* @__PURE__ */ p(le, {
|
|
433
|
+
className: "mr-1 size-4",
|
|
434
|
+
"aria-hidden": "true"
|
|
435
|
+
}), "Record Transaction"]
|
|
436
|
+
})
|
|
437
|
+
}) : /* @__PURE__ */ m("div", {
|
|
438
|
+
className: "space-y-4",
|
|
439
|
+
children: [Y.map((e) => /* @__PURE__ */ m("div", {
|
|
440
|
+
className: "space-y-1.5",
|
|
177
441
|
children: [
|
|
178
|
-
/* @__PURE__ */
|
|
179
|
-
className: "
|
|
180
|
-
children:
|
|
442
|
+
/* @__PURE__ */ m("div", {
|
|
443
|
+
className: "flex items-center justify-between text-xs",
|
|
444
|
+
children: [/* @__PURE__ */ p("span", {
|
|
445
|
+
className: "font-medium text-text-primary",
|
|
446
|
+
children: e.label
|
|
447
|
+
}), /* @__PURE__ */ m("span", {
|
|
448
|
+
className: "flex gap-3",
|
|
449
|
+
children: [/* @__PURE__ */ m("span", {
|
|
450
|
+
className: "text-status-success-text",
|
|
451
|
+
children: [/* @__PURE__ */ p(se, {
|
|
452
|
+
className: "mr-0.5 inline size-3",
|
|
453
|
+
"aria-hidden": "true"
|
|
454
|
+
}), c(e.inflow, q)]
|
|
455
|
+
}), /* @__PURE__ */ m("span", {
|
|
456
|
+
className: "text-status-error-text",
|
|
457
|
+
children: [/* @__PURE__ */ p(oe, {
|
|
458
|
+
className: "mr-0.5 inline size-3",
|
|
459
|
+
"aria-hidden": "true"
|
|
460
|
+
}), c(e.outflow, q)]
|
|
461
|
+
})]
|
|
462
|
+
})]
|
|
181
463
|
}),
|
|
182
|
-
/* @__PURE__ */
|
|
183
|
-
className: "
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
464
|
+
/* @__PURE__ */ p("div", {
|
|
465
|
+
className: "h-2 w-full overflow-hidden rounded-full bg-bg-sunken",
|
|
466
|
+
role: "progressbar",
|
|
467
|
+
"aria-label": `${e.label} inflow`,
|
|
468
|
+
"aria-valuenow": Math.round(e.inflow / Z * 100),
|
|
469
|
+
"aria-valuemin": 0,
|
|
470
|
+
"aria-valuemax": 100,
|
|
471
|
+
children: /* @__PURE__ */ p("div", {
|
|
472
|
+
className: "h-full rounded-full bg-status-success-bg motion-safe:transition-[width] motion-safe:duration-200",
|
|
473
|
+
style: { width: `${e.inflow / Z * 100}%` }
|
|
187
474
|
})
|
|
188
475
|
}),
|
|
189
|
-
/* @__PURE__ */
|
|
190
|
-
className: "
|
|
191
|
-
|
|
476
|
+
/* @__PURE__ */ p("div", {
|
|
477
|
+
className: "h-2 w-full overflow-hidden rounded-full bg-bg-sunken",
|
|
478
|
+
role: "progressbar",
|
|
479
|
+
"aria-label": `${e.label} outflow`,
|
|
480
|
+
"aria-valuenow": Math.round(e.outflow / Z * 100),
|
|
481
|
+
"aria-valuemin": 0,
|
|
482
|
+
"aria-valuemax": 100,
|
|
483
|
+
children: /* @__PURE__ */ p("div", {
|
|
484
|
+
className: "h-full rounded-full bg-status-error-bg motion-safe:transition-[width] motion-safe:duration-200",
|
|
485
|
+
style: { width: `${e.outflow / Z * 100}%` }
|
|
486
|
+
})
|
|
192
487
|
})
|
|
193
488
|
]
|
|
194
|
-
}, e.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
children: S.map((e) => {
|
|
203
|
-
let t = Math.round(e.value / w * 100);
|
|
204
|
-
return /* @__PURE__ */ s("div", {
|
|
205
|
-
className: "space-y-1",
|
|
206
|
-
children: [/* @__PURE__ */ s("div", {
|
|
207
|
-
className: "flex justify-between text-sm",
|
|
208
|
-
children: [/* @__PURE__ */ o("span", {
|
|
209
|
-
className: "font-medium",
|
|
210
|
-
children: e.name
|
|
211
|
-
}), /* @__PURE__ */ s("span", { children: [
|
|
212
|
-
r(e.value),
|
|
213
|
-
" (",
|
|
214
|
-
t,
|
|
215
|
-
"%)"
|
|
216
|
-
] })]
|
|
217
|
-
}), /* @__PURE__ */ o("div", {
|
|
218
|
-
className: "h-4 rounded bg-muted overflow-hidden",
|
|
219
|
-
children: /* @__PURE__ */ o("div", {
|
|
220
|
-
className: "h-4 rounded bg-primary",
|
|
221
|
-
style: { width: `${t}%` }
|
|
222
|
-
})
|
|
223
|
-
})]
|
|
224
|
-
}, e.id);
|
|
225
|
-
})
|
|
226
|
-
})] }), /* @__PURE__ */ s(l, { children: [/* @__PURE__ */ s(f, { children: [/* @__PURE__ */ o(p, { children: "Sector Exposure" }), /* @__PURE__ */ o(d, { children: "Breakdown by sector from holdings" })] }), /* @__PURE__ */ o(u, { children: /* @__PURE__ */ o("div", {
|
|
227
|
-
className: "grid gap-3 md:grid-cols-2",
|
|
228
|
-
children: C.map((e) => /* @__PURE__ */ s("div", {
|
|
229
|
-
className: "flex items-center justify-between rounded-lg border p-3",
|
|
230
|
-
children: [/* @__PURE__ */ s("div", { children: [/* @__PURE__ */ o("p", {
|
|
231
|
-
className: "text-sm font-medium",
|
|
232
|
-
children: e.symbol
|
|
233
|
-
}), /* @__PURE__ */ o("p", {
|
|
234
|
-
className: "text-xs text-muted-foreground",
|
|
235
|
-
children: e.sector
|
|
236
|
-
})] }), /* @__PURE__ */ o("span", {
|
|
237
|
-
className: "text-sm font-semibold",
|
|
238
|
-
children: r(e.marketValue)
|
|
489
|
+
}, e.key)), /* @__PURE__ */ m("div", {
|
|
490
|
+
className: "flex flex-wrap gap-4 pt-1 text-xs text-text-secondary",
|
|
491
|
+
children: [/* @__PURE__ */ m("span", {
|
|
492
|
+
className: "inline-flex items-center gap-1.5",
|
|
493
|
+
children: [/* @__PURE__ */ p("span", { className: "inline-block size-2.5 rounded-full bg-status-success-bg" }), "Inflow"]
|
|
494
|
+
}), /* @__PURE__ */ m("span", {
|
|
495
|
+
className: "inline-flex items-center gap-1.5",
|
|
496
|
+
children: [/* @__PURE__ */ p("span", { className: "inline-block size-2.5 rounded-full bg-status-error-bg" }), "Outflow"]
|
|
239
497
|
})]
|
|
240
|
-
}
|
|
241
|
-
}) })] })]
|
|
498
|
+
})]
|
|
499
|
+
}) })] }), je.length > 0 ? /* @__PURE__ */ m(g, { children: [/* @__PURE__ */ m(y, { children: [/* @__PURE__ */ p(b, { children: "By Transaction Type" }), /* @__PURE__ */ p(v, { children: "Total value moved per transaction type." })] }), /* @__PURE__ */ p(_, { children: /* @__PURE__ */ m(O, { children: [/* @__PURE__ */ p(M, { children: /* @__PURE__ */ m(N, { children: [
|
|
500
|
+
/* @__PURE__ */ p(j, { children: "Type" }),
|
|
501
|
+
/* @__PURE__ */ p(j, { children: "Direction" }),
|
|
502
|
+
/* @__PURE__ */ p(j, {
|
|
503
|
+
className: "text-right",
|
|
504
|
+
children: "Total"
|
|
505
|
+
})
|
|
506
|
+
] }) }), /* @__PURE__ */ p(k, { children: je.map((e) => /* @__PURE__ */ m(N, { children: [
|
|
507
|
+
/* @__PURE__ */ p(A, {
|
|
508
|
+
className: "font-medium text-text-primary",
|
|
509
|
+
children: I(e.type)
|
|
510
|
+
}),
|
|
511
|
+
/* @__PURE__ */ p(A, { children: /* @__PURE__ */ p(ue, {
|
|
512
|
+
variant: e.dir === "in" ? "default" : e.dir === "out" ? "destructive" : "secondary",
|
|
513
|
+
children: e.dir === "in" ? "Inflow" : e.dir === "out" ? "Outflow" : "Neutral"
|
|
514
|
+
}) }),
|
|
515
|
+
/* @__PURE__ */ p(A, {
|
|
516
|
+
className: "text-right font-medium",
|
|
517
|
+
children: c(e.total, q)
|
|
518
|
+
})
|
|
519
|
+
] }, e.type)) })] }) })] }) : null]
|
|
242
520
|
}),
|
|
243
|
-
/* @__PURE__ */
|
|
244
|
-
value: "
|
|
521
|
+
/* @__PURE__ */ p(P, {
|
|
522
|
+
value: "performance",
|
|
245
523
|
className: "space-y-4",
|
|
246
|
-
children: /* @__PURE__ */
|
|
247
|
-
className: "flex
|
|
248
|
-
children: [/* @__PURE__ */
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
})
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
/* @__PURE__ */ s("span", {
|
|
265
|
-
className: "text-red-500",
|
|
266
|
-
children: ["Expenses: ", r(e.expenses)]
|
|
267
|
-
}),
|
|
268
|
-
/* @__PURE__ */ s("span", {
|
|
269
|
-
className: "text-blue-600",
|
|
270
|
-
children: ["Saved: ", r(e.savings)]
|
|
271
|
-
})
|
|
272
|
-
]
|
|
273
|
-
}), /* @__PURE__ */ s("div", {
|
|
274
|
-
className: "flex gap-1",
|
|
275
|
-
children: [
|
|
276
|
-
/* @__PURE__ */ o("div", {
|
|
277
|
-
className: "h-3 rounded bg-emerald-500",
|
|
278
|
-
style: { width: `${e.income / x * 50}%` }
|
|
279
|
-
}),
|
|
280
|
-
/* @__PURE__ */ o("div", {
|
|
281
|
-
className: "h-3 rounded bg-red-400",
|
|
282
|
-
style: { width: `${e.expenses / x * 50}%` }
|
|
283
|
-
}),
|
|
284
|
-
/* @__PURE__ */ o("div", {
|
|
285
|
-
className: "h-3 rounded bg-blue-500",
|
|
286
|
-
style: { width: `${e.savings / x * 50}%` }
|
|
287
|
-
})
|
|
288
|
-
]
|
|
524
|
+
children: /* @__PURE__ */ m(g, { children: [/* @__PURE__ */ m(y, {
|
|
525
|
+
className: "flex flex-col gap-3 md:flex-row md:items-start md:justify-between",
|
|
526
|
+
children: [/* @__PURE__ */ m("div", { children: [/* @__PURE__ */ p(b, { children: "Holdings Performance" }), /* @__PURE__ */ p(v, { children: "Unrealized gain or loss — market value versus cost basis." })] }), B.length > 0 ? /* @__PURE__ */ m("div", {
|
|
527
|
+
className: "w-full md:w-56",
|
|
528
|
+
children: [/* @__PURE__ */ p(S, {
|
|
529
|
+
htmlFor: "perf-account",
|
|
530
|
+
className: "sr-only",
|
|
531
|
+
children: "Account"
|
|
532
|
+
}), /* @__PURE__ */ m(C, {
|
|
533
|
+
value: De ?? "",
|
|
534
|
+
onValueChange: (e) => xe(e),
|
|
535
|
+
children: [/* @__PURE__ */ p(E, {
|
|
536
|
+
id: "perf-account",
|
|
537
|
+
children: /* @__PURE__ */ p(D, { placeholder: "Select account" })
|
|
538
|
+
}), /* @__PURE__ */ p(w, { children: B.map((e) => /* @__PURE__ */ p(T, {
|
|
539
|
+
value: e.id,
|
|
540
|
+
children: e.name
|
|
541
|
+
}, e.id)) })]
|
|
289
542
|
})]
|
|
290
|
-
}
|
|
291
|
-
|
|
543
|
+
}) : null]
|
|
544
|
+
}), /* @__PURE__ */ p(_, { children: R.isLoading ? /* @__PURE__ */ p(s, { rows: 3 }) : B.length === 0 ? /* @__PURE__ */ p(o, {
|
|
545
|
+
icon: /* @__PURE__ */ p(f, {
|
|
546
|
+
className: "size-6",
|
|
547
|
+
"aria-hidden": "true"
|
|
548
|
+
}),
|
|
549
|
+
title: "No accounts yet",
|
|
550
|
+
description: "Create an account and add holdings to analyze performance."
|
|
551
|
+
}) : V.isLoading ? /* @__PURE__ */ p(s, { rows: 3 }) : V.isError ? /* @__PURE__ */ p(ee, { onRetry: () => V.refetch() }) : Q.rows.length === 0 ? /* @__PURE__ */ p(o, {
|
|
552
|
+
icon: /* @__PURE__ */ p(u, {
|
|
553
|
+
className: "size-6",
|
|
554
|
+
"aria-hidden": "true"
|
|
555
|
+
}),
|
|
556
|
+
title: "No holdings in this account",
|
|
557
|
+
description: "Add holdings to this account to see unrealized gains and losses."
|
|
558
|
+
}) : /* @__PURE__ */ m("div", {
|
|
559
|
+
className: "space-y-4",
|
|
560
|
+
children: [/* @__PURE__ */ m("div", {
|
|
561
|
+
className: "grid gap-4 sm:grid-cols-3",
|
|
292
562
|
children: [
|
|
293
|
-
/* @__PURE__ */
|
|
294
|
-
className: "
|
|
295
|
-
children: [/* @__PURE__ */
|
|
563
|
+
/* @__PURE__ */ m("div", {
|
|
564
|
+
className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
|
|
565
|
+
children: [/* @__PURE__ */ p("p", {
|
|
566
|
+
className: "text-xs text-text-secondary",
|
|
567
|
+
children: "Total unrealized"
|
|
568
|
+
}), /* @__PURE__ */ p("p", {
|
|
569
|
+
className: "mt-1 text-xl font-semibold",
|
|
570
|
+
children: /* @__PURE__ */ p(we, {
|
|
571
|
+
value: Q.totalUnrealized,
|
|
572
|
+
currency: q
|
|
573
|
+
})
|
|
574
|
+
})]
|
|
296
575
|
}),
|
|
297
|
-
/* @__PURE__ */
|
|
298
|
-
className: "
|
|
299
|
-
children: [/* @__PURE__ */
|
|
576
|
+
/* @__PURE__ */ m("div", {
|
|
577
|
+
className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
|
|
578
|
+
children: [/* @__PURE__ */ p("p", {
|
|
579
|
+
className: "text-xs text-text-secondary",
|
|
580
|
+
children: "Cost basis"
|
|
581
|
+
}), /* @__PURE__ */ p("p", {
|
|
582
|
+
className: "mt-1 text-xl font-semibold text-text-primary",
|
|
583
|
+
children: c(Q.totalCost, q)
|
|
584
|
+
})]
|
|
300
585
|
}),
|
|
301
|
-
/* @__PURE__ */
|
|
302
|
-
className: "
|
|
303
|
-
children: [/* @__PURE__ */
|
|
586
|
+
/* @__PURE__ */ m("div", {
|
|
587
|
+
className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
|
|
588
|
+
children: [/* @__PURE__ */ p("p", {
|
|
589
|
+
className: "text-xs text-text-secondary",
|
|
590
|
+
children: "Return on cost"
|
|
591
|
+
}), /* @__PURE__ */ p("p", {
|
|
592
|
+
className: "mt-1 text-xl font-semibold text-text-primary",
|
|
593
|
+
children: ie(Q.totalCost > 0 ? Q.totalUnrealized / Q.totalCost * 100 : null)
|
|
594
|
+
})]
|
|
304
595
|
})
|
|
305
596
|
]
|
|
306
|
-
})
|
|
307
|
-
|
|
597
|
+
}), /* @__PURE__ */ m(O, { children: [/* @__PURE__ */ p(M, { children: /* @__PURE__ */ m(N, { children: [
|
|
598
|
+
/* @__PURE__ */ p(j, { children: "Holding" }),
|
|
599
|
+
/* @__PURE__ */ p(j, {
|
|
600
|
+
className: "text-right",
|
|
601
|
+
children: "Market value"
|
|
602
|
+
}),
|
|
603
|
+
/* @__PURE__ */ p(j, {
|
|
604
|
+
className: "text-right",
|
|
605
|
+
children: "Cost basis"
|
|
606
|
+
}),
|
|
607
|
+
/* @__PURE__ */ p(j, {
|
|
608
|
+
className: "text-right",
|
|
609
|
+
children: "Unrealized"
|
|
610
|
+
})
|
|
611
|
+
] }) }), /* @__PURE__ */ p(k, { children: Q.rows.map(({ holding: e, unrealized: t }) => /* @__PURE__ */ m(N, { children: [
|
|
612
|
+
/* @__PURE__ */ m(A, { children: [/* @__PURE__ */ p("div", {
|
|
613
|
+
className: "font-medium text-text-primary",
|
|
614
|
+
children: e.symbol
|
|
615
|
+
}), /* @__PURE__ */ m("div", {
|
|
616
|
+
className: "text-xs text-text-secondary",
|
|
617
|
+
children: [
|
|
618
|
+
e.name ?? I(e.assetClass),
|
|
619
|
+
" · as of",
|
|
620
|
+
" ",
|
|
621
|
+
re(e.asOf)
|
|
622
|
+
]
|
|
623
|
+
})] }),
|
|
624
|
+
/* @__PURE__ */ p(A, {
|
|
625
|
+
className: "text-right",
|
|
626
|
+
children: c(e.marketValue, e.currency)
|
|
627
|
+
}),
|
|
628
|
+
/* @__PURE__ */ p(A, {
|
|
629
|
+
className: "text-right text-text-secondary",
|
|
630
|
+
children: c(e.costBasis, e.currency)
|
|
631
|
+
}),
|
|
632
|
+
/* @__PURE__ */ p(A, {
|
|
633
|
+
className: "text-right",
|
|
634
|
+
children: /* @__PURE__ */ p(we, {
|
|
635
|
+
value: t,
|
|
636
|
+
currency: e.currency
|
|
637
|
+
})
|
|
638
|
+
})
|
|
639
|
+
] }, e.id)) })] })]
|
|
640
|
+
}) })] })
|
|
308
641
|
})
|
|
309
642
|
]
|
|
310
643
|
})]
|
|
311
644
|
});
|
|
312
645
|
}
|
|
313
646
|
//#endregion
|
|
314
|
-
export {
|
|
647
|
+
export { B as AnalyticsPage };
|
|
315
648
|
|
|
316
649
|
//# sourceMappingURL=AnalyticsPage.js.map
|