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