@burdenoff/microfe-housingvista 2026.709.2 → 2026.709.3
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/housingvista/HousingVistaRoutes.d.ts.map +1 -1
- package/dist/housingvista/HousingVistaRoutes.js +136 -37
- package/dist/housingvista/HousingVistaRoutes.js.map +1 -1
- package/dist/housingvista/hooks/useHousingVistaAnalytics.d.ts +1 -1
- package/dist/housingvista/hooks/useHousingVistaAnalytics.d.ts.map +1 -1
- package/dist/housingvista/hooks/useHousingVistaAnalytics.js +4 -4
- package/dist/housingvista/hooks/useHousingVistaAnalytics.js.map +1 -1
- package/dist/housingvista/pages/amc/AMCManagementPage.d.ts.map +1 -1
- package/dist/housingvista/pages/amc/AMCManagementPage.js +62 -60
- package/dist/housingvista/pages/amc/AMCManagementPage.js.map +1 -1
- package/dist/housingvista/pages/assets/AssetDetailPage.d.ts.map +1 -1
- package/dist/housingvista/pages/assets/AssetDetailPage.js +141 -138
- package/dist/housingvista/pages/assets/AssetDetailPage.js.map +1 -1
- package/dist/housingvista/pages/assets/AssetManagementPage.d.ts.map +1 -1
- package/dist/housingvista/pages/assets/AssetManagementPage.js +193 -191
- package/dist/housingvista/pages/assets/AssetManagementPage.js.map +1 -1
- package/dist/housingvista/pages/chat/ChatPage.d.ts.map +1 -1
- package/dist/housingvista/pages/chat/ChatPage.js +115 -113
- package/dist/housingvista/pages/chat/ChatPage.js.map +1 -1
- package/dist/housingvista/pages/finance/HomeLoanDetailPage.d.ts.map +1 -1
- package/dist/housingvista/pages/finance/HomeLoanDetailPage.js +152 -149
- package/dist/housingvista/pages/finance/HomeLoanDetailPage.js.map +1 -1
- package/dist/housingvista/pages/finance/HomeLoansPage.d.ts.map +1 -1
- package/dist/housingvista/pages/finance/HomeLoansPage.js +141 -139
- package/dist/housingvista/pages/finance/HomeLoansPage.js.map +1 -1
- package/dist/housingvista/pages/investments/InvestmentDetailPage.d.ts.map +1 -1
- package/dist/housingvista/pages/investments/InvestmentDetailPage.js +290 -287
- package/dist/housingvista/pages/investments/InvestmentDetailPage.js.map +1 -1
- package/dist/housingvista/pages/investments/InvestmentsPage.d.ts.map +1 -1
- package/dist/housingvista/pages/investments/InvestmentsPage.js +64 -62
- package/dist/housingvista/pages/investments/InvestmentsPage.js.map +1 -1
- package/dist/housingvista/pages/legal/LegalPage.d.ts.map +1 -1
- package/dist/housingvista/pages/legal/LegalPage.js +95 -93
- package/dist/housingvista/pages/legal/LegalPage.js.map +1 -1
- package/dist/housingvista/pages/legal/LegalServiceDetailPage.d.ts.map +1 -1
- package/dist/housingvista/pages/legal/LegalServiceDetailPage.js +129 -126
- package/dist/housingvista/pages/legal/LegalServiceDetailPage.js.map +1 -1
- package/dist/housingvista/pages/market/AreaInsightsPage.d.ts.map +1 -1
- package/dist/housingvista/pages/market/AreaInsightsPage.js +99 -97
- package/dist/housingvista/pages/market/AreaInsightsPage.js.map +1 -1
- package/dist/housingvista/pages/market/MarketAnalyticsPage.d.ts.map +1 -1
- package/dist/housingvista/pages/market/MarketAnalyticsPage.js +138 -136
- package/dist/housingvista/pages/market/MarketAnalyticsPage.js.map +1 -1
- package/dist/housingvista/pages/marketplace/MarketplacePage.d.ts.map +1 -1
- package/dist/housingvista/pages/marketplace/MarketplacePage.js +99 -97
- package/dist/housingvista/pages/marketplace/MarketplacePage.js.map +1 -1
- package/dist/housingvista/pages/marketplace/ServiceDetailPage.d.ts.map +1 -1
- package/dist/housingvista/pages/marketplace/ServiceDetailPage.js +137 -134
- package/dist/housingvista/pages/marketplace/ServiceDetailPage.js.map +1 -1
- package/dist/housingvista/pages/offers/OffersPage.d.ts.map +1 -1
- package/dist/housingvista/pages/offers/OffersPage.js +94 -92
- package/dist/housingvista/pages/offers/OffersPage.js.map +1 -1
- package/dist/housingvista/pages/properties/AddPropertyPage.d.ts.map +1 -1
- package/dist/housingvista/pages/properties/AddPropertyPage.js +280 -279
- package/dist/housingvista/pages/properties/AddPropertyPage.js.map +1 -1
- package/dist/housingvista/pages/rental/RentalManagementPage.d.ts.map +1 -1
- package/dist/housingvista/pages/rental/RentalManagementPage.js +153 -151
- package/dist/housingvista/pages/rental/RentalManagementPage.js.map +1 -1
- package/dist/housingvista/pages/settings/ProfilePage.d.ts.map +1 -1
- package/dist/housingvista/pages/settings/ProfilePage.js +52 -50
- package/dist/housingvista/pages/settings/ProfilePage.js.map +1 -1
- package/dist/housingvista/pages/settings/SettingsPage.d.ts.map +1 -1
- package/dist/housingvista/pages/settings/SettingsPage.js +54 -52
- package/dist/housingvista/pages/settings/SettingsPage.js.map +1 -1
- package/dist/housingvista/pages/shortlist/ShortlistPage.d.ts.map +1 -1
- package/dist/housingvista/pages/shortlist/ShortlistPage.js +43 -41
- package/dist/housingvista/pages/shortlist/ShortlistPage.js.map +1 -1
- package/dist/housingvista/pages/transactions/TransactionDetailPage.d.ts.map +1 -1
- package/dist/housingvista/pages/transactions/TransactionDetailPage.js +211 -208
- package/dist/housingvista/pages/transactions/TransactionDetailPage.js.map +1 -1
- package/dist/housingvista/pages/transactions/TransactionsPage.d.ts.map +1 -1
- package/dist/housingvista/pages/transactions/TransactionsPage.js +85 -83
- package/dist/housingvista/pages/transactions/TransactionsPage.js.map +1 -1
- package/dist/housingvista/pages/verification/VerificationDetailPage.d.ts.map +1 -1
- package/dist/housingvista/pages/verification/VerificationDetailPage.js +25 -22
- package/dist/housingvista/pages/verification/VerificationDetailPage.js.map +1 -1
- package/dist/housingvista/pages/verification/VerificationPage.d.ts.map +1 -1
- package/dist/housingvista/pages/verification/VerificationPage.js +123 -121
- package/dist/housingvista/pages/verification/VerificationPage.js.map +1 -1
- package/dist/housingvista/pages/viewings/ViewingsPage.d.ts.map +1 -1
- package/dist/housingvista/pages/viewings/ViewingsPage.js +128 -126
- package/dist/housingvista/pages/viewings/ViewingsPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,22 +4,23 @@ import { StatusBadge as i } from "../../components/StatusBadge.js";
|
|
|
4
4
|
import { EmptyState as a } from "../../components/EmptyState.js";
|
|
5
5
|
import { Breadcrumbs as o } from "../../components/Breadcrumbs.js";
|
|
6
6
|
import { LoadingSkeleton as s } from "../../components/LoadingSkeleton.js";
|
|
7
|
-
import {
|
|
7
|
+
import { useTrackPageView as c } from "../../hooks/useHousingVistaAnalytics.js";
|
|
8
|
+
import { useAsset as l } from "../../hooks/index.js";
|
|
8
9
|
import "../../components/index.js";
|
|
9
|
-
import { Tooltip as
|
|
10
|
-
import { ResponsiveContainer as
|
|
11
|
-
import { Cell as
|
|
12
|
-
import { Bar as
|
|
13
|
-
import { CartesianGrid as
|
|
14
|
-
import { XAxis as
|
|
15
|
-
import { YAxis as
|
|
16
|
-
import { BarChart as
|
|
17
|
-
import { ArrowDownRight as
|
|
18
|
-
import { useNavigate as
|
|
19
|
-
import { jsx as
|
|
20
|
-
import { EmphasisPanel as
|
|
10
|
+
import { Tooltip as u } from "../../../node_modules/recharts/es6/component/Tooltip.js";
|
|
11
|
+
import { ResponsiveContainer as d } from "../../../node_modules/recharts/es6/component/ResponsiveContainer.js";
|
|
12
|
+
import { Cell as f } from "../../../node_modules/recharts/es6/component/Cell.js";
|
|
13
|
+
import { Bar as p } from "../../../node_modules/recharts/es6/cartesian/Bar.js";
|
|
14
|
+
import { CartesianGrid as m } from "../../../node_modules/recharts/es6/cartesian/CartesianGrid.js";
|
|
15
|
+
import { XAxis as h } from "../../../node_modules/recharts/es6/cartesian/XAxis.js";
|
|
16
|
+
import { YAxis as g } from "../../../node_modules/recharts/es6/cartesian/YAxis.js";
|
|
17
|
+
import { BarChart as _ } from "../../../node_modules/recharts/es6/chart/BarChart.js";
|
|
18
|
+
import { ArrowDownRight as v, ArrowLeft as y, ArrowUpRight as b, BarChart3 as x, Building as S, Calendar as C, DollarSign as w, ImageOff as T, MapPin as E, Percent as D, Target as O, TrendingUp as k } from "lucide-react";
|
|
19
|
+
import { useNavigate as A, useParams as j } from "react-router-dom";
|
|
20
|
+
import { jsx as M, jsxs as N } from "react/jsx-runtime";
|
|
21
|
+
import { EmphasisPanel as P, GlassCard as F, NextSteps as I, PagePurpose as L } from "@burdenoff/fe-libs/ui";
|
|
21
22
|
//#region src/housingvista/pages/assets/AssetDetailPage.tsx
|
|
22
|
-
function
|
|
23
|
+
function R(e) {
|
|
23
24
|
switch (e) {
|
|
24
25
|
case "active": return "success";
|
|
25
26
|
case "under_renovation": return "warning";
|
|
@@ -28,213 +29,215 @@ function L(e) {
|
|
|
28
29
|
default: return "muted";
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
|
-
function
|
|
32
|
-
let { id:
|
|
33
|
-
|
|
32
|
+
function z() {
|
|
33
|
+
let { id: z } = j();
|
|
34
|
+
c("housingvista.asset.viewed", z);
|
|
35
|
+
let B = A(), { data: V, loading: H } = l(z);
|
|
36
|
+
if (H) return /* @__PURE__ */ M("div", {
|
|
34
37
|
className: "flex flex-col gap-6 p-6",
|
|
35
|
-
children: /* @__PURE__ */
|
|
38
|
+
children: /* @__PURE__ */ M(s, { variant: "detail" })
|
|
36
39
|
});
|
|
37
|
-
if (!
|
|
40
|
+
if (!V) return /* @__PURE__ */ M("div", {
|
|
38
41
|
className: "p-6",
|
|
39
|
-
children: /* @__PURE__ */
|
|
42
|
+
children: /* @__PURE__ */ M(a, {
|
|
40
43
|
illustration: "empty-search",
|
|
41
|
-
icon: /* @__PURE__ */
|
|
44
|
+
icon: /* @__PURE__ */ M(S, { className: "h-12 w-12" }),
|
|
42
45
|
title: "Asset Not Found",
|
|
43
46
|
description: "The asset you're looking for doesn't exist or has been removed.",
|
|
44
|
-
action: /* @__PURE__ */
|
|
45
|
-
onClick: () =>
|
|
47
|
+
action: /* @__PURE__ */ N("button", {
|
|
48
|
+
onClick: () => B("../assets"),
|
|
46
49
|
className: "inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover",
|
|
47
|
-
children: [/* @__PURE__ */
|
|
50
|
+
children: [/* @__PURE__ */ M(y, { className: "h-4 w-4" }), "Back to Assets"]
|
|
48
51
|
})
|
|
49
52
|
})
|
|
50
53
|
});
|
|
51
|
-
let
|
|
52
|
-
return /* @__PURE__ */
|
|
54
|
+
let U = V.currentValue - V.purchasePrice, W = U >= 0, G = V.purchasePrice > 0 ? U / V.purchasePrice * 100 : 0, K = V.rentalYield ? V.currentValue * V.rentalYield / 100 / 12 : 0;
|
|
55
|
+
return /* @__PURE__ */ N("div", {
|
|
53
56
|
className: "flex flex-col gap-6 p-6",
|
|
54
57
|
children: [
|
|
55
|
-
/* @__PURE__ */
|
|
58
|
+
/* @__PURE__ */ M(o, { items: [{
|
|
56
59
|
label: "Assets",
|
|
57
60
|
href: "../"
|
|
58
|
-
}, { label:
|
|
59
|
-
/* @__PURE__ */
|
|
61
|
+
}, { label: V.title }] }),
|
|
62
|
+
/* @__PURE__ */ N("div", {
|
|
60
63
|
className: "flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between",
|
|
61
|
-
children: [/* @__PURE__ */
|
|
62
|
-
/* @__PURE__ */
|
|
63
|
-
onClick: () =>
|
|
64
|
+
children: [/* @__PURE__ */ N("div", { children: [
|
|
65
|
+
/* @__PURE__ */ N("button", {
|
|
66
|
+
onClick: () => B("../assets"),
|
|
64
67
|
className: "mb-2 inline-flex items-center gap-2 rounded-md px-2 py-1 text-sm text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary",
|
|
65
|
-
children: [/* @__PURE__ */
|
|
68
|
+
children: [/* @__PURE__ */ M(y, { className: "h-4 w-4" }), "Back to Assets"]
|
|
66
69
|
}),
|
|
67
|
-
/* @__PURE__ */
|
|
70
|
+
/* @__PURE__ */ M("h1", {
|
|
68
71
|
className: "text-2xl font-semibold text-text-primary",
|
|
69
|
-
children:
|
|
72
|
+
children: V.title
|
|
70
73
|
}),
|
|
71
|
-
/* @__PURE__ */
|
|
74
|
+
/* @__PURE__ */ N("div", {
|
|
72
75
|
className: "mt-2 flex flex-wrap items-center gap-2",
|
|
73
76
|
children: [
|
|
74
|
-
/* @__PURE__ */
|
|
75
|
-
label:
|
|
76
|
-
variant:
|
|
77
|
+
/* @__PURE__ */ M(i, {
|
|
78
|
+
label: V.status.replace("_", " "),
|
|
79
|
+
variant: R(V.status),
|
|
77
80
|
dot: !0
|
|
78
81
|
}),
|
|
79
|
-
/* @__PURE__ */
|
|
80
|
-
label:
|
|
82
|
+
/* @__PURE__ */ M(i, {
|
|
83
|
+
label: V.type,
|
|
81
84
|
variant: "muted"
|
|
82
85
|
}),
|
|
83
|
-
/* @__PURE__ */
|
|
86
|
+
/* @__PURE__ */ N("span", {
|
|
84
87
|
className: "inline-flex items-center gap-1 text-sm text-text-secondary",
|
|
85
|
-
children: [/* @__PURE__ */
|
|
88
|
+
children: [/* @__PURE__ */ M(E, { className: "h-3.5 w-3.5" }), V.location]
|
|
86
89
|
})
|
|
87
90
|
]
|
|
88
91
|
})
|
|
89
|
-
] }),
|
|
90
|
-
src:
|
|
91
|
-
alt:
|
|
92
|
+
] }), V.imageUrl ? /* @__PURE__ */ M("img", {
|
|
93
|
+
src: V.imageUrl,
|
|
94
|
+
alt: V.title,
|
|
92
95
|
className: "h-24 w-full rounded-lg object-cover sm:w-40 lg:w-48"
|
|
93
|
-
}) : /* @__PURE__ */
|
|
96
|
+
}) : /* @__PURE__ */ M("div", {
|
|
94
97
|
className: "flex h-24 w-full items-center justify-center rounded-lg bg-gradient-to-br from-bg-sunken to-bg-sunken/50 sm:w-40 lg:w-48",
|
|
95
98
|
role: "img",
|
|
96
|
-
"aria-label": `${
|
|
97
|
-
children: /* @__PURE__ */
|
|
99
|
+
"aria-label": `${V.title} — no image`,
|
|
100
|
+
children: /* @__PURE__ */ M(T, { className: "h-8 w-8 text-text-secondary/40" })
|
|
98
101
|
})]
|
|
99
102
|
}),
|
|
100
|
-
/* @__PURE__ */
|
|
103
|
+
/* @__PURE__ */ M(L, {
|
|
101
104
|
className: "max-w-3xl",
|
|
102
105
|
children: "A full performance breakdown for one property you own — what you paid, what it is worth today, how much it has appreciated, and the rental yield it generates. Use it to judge whether to hold, renovate, or sell."
|
|
103
106
|
}),
|
|
104
|
-
/* @__PURE__ */
|
|
107
|
+
/* @__PURE__ */ M(I, {
|
|
105
108
|
storageKey: "housingvista-asset-detail",
|
|
106
109
|
steps: [
|
|
107
110
|
{
|
|
108
111
|
id: "benchmark",
|
|
109
112
|
label: "Benchmark against the market",
|
|
110
113
|
description: "Compare this asset against area and market trends.",
|
|
111
|
-
onClick: () =>
|
|
114
|
+
onClick: () => B("../market-analytics")
|
|
112
115
|
},
|
|
113
116
|
{
|
|
114
117
|
id: "manage-rental",
|
|
115
118
|
label: "Manage the rental",
|
|
116
119
|
description: "Review tenants, leases, and rent collection for your units.",
|
|
117
|
-
onClick: () =>
|
|
120
|
+
onClick: () => B("../rental")
|
|
118
121
|
},
|
|
119
122
|
{
|
|
120
123
|
id: "back",
|
|
121
124
|
label: "Back to all assets",
|
|
122
125
|
description: "Return to your full portfolio view.",
|
|
123
|
-
onClick: () =>
|
|
126
|
+
onClick: () => B("../assets")
|
|
124
127
|
}
|
|
125
128
|
]
|
|
126
129
|
}),
|
|
127
|
-
/* @__PURE__ */
|
|
130
|
+
/* @__PURE__ */ M(P, {
|
|
128
131
|
className: "p-4",
|
|
129
|
-
children: /* @__PURE__ */
|
|
132
|
+
children: /* @__PURE__ */ N("div", {
|
|
130
133
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
|
|
131
134
|
children: [
|
|
132
|
-
/* @__PURE__ */
|
|
135
|
+
/* @__PURE__ */ M(r, {
|
|
133
136
|
label: "Current Value",
|
|
134
|
-
value:
|
|
137
|
+
value: V.currentValue,
|
|
135
138
|
prefix: "$",
|
|
136
|
-
icon: /* @__PURE__ */
|
|
139
|
+
icon: /* @__PURE__ */ M(w, { className: "h-4 w-4" })
|
|
137
140
|
}),
|
|
138
|
-
/* @__PURE__ */
|
|
141
|
+
/* @__PURE__ */ M(r, {
|
|
139
142
|
label: "Appreciation",
|
|
140
|
-
value: `${
|
|
141
|
-
icon: /* @__PURE__ */
|
|
143
|
+
value: `${V.appreciationPercent.toFixed(1)}%`,
|
|
144
|
+
icon: /* @__PURE__ */ M(k, { className: "h-4 w-4" })
|
|
142
145
|
}),
|
|
143
|
-
/* @__PURE__ */
|
|
146
|
+
/* @__PURE__ */ M(r, {
|
|
144
147
|
label: "Overall ROI",
|
|
145
|
-
value: `${
|
|
146
|
-
icon: /* @__PURE__ */
|
|
148
|
+
value: `${G.toFixed(1)}%`,
|
|
149
|
+
icon: /* @__PURE__ */ M(O, { className: "h-4 w-4" })
|
|
147
150
|
}),
|
|
148
|
-
/* @__PURE__ */
|
|
151
|
+
/* @__PURE__ */ M(r, {
|
|
149
152
|
label: "Rental Yield",
|
|
150
|
-
value:
|
|
151
|
-
icon: /* @__PURE__ */
|
|
153
|
+
value: V.rentalYield == null ? "—" : `${V.rentalYield.toFixed(1)}%`,
|
|
154
|
+
icon: /* @__PURE__ */ M(D, { className: "h-4 w-4" })
|
|
152
155
|
})
|
|
153
156
|
]
|
|
154
157
|
})
|
|
155
158
|
}),
|
|
156
|
-
/* @__PURE__ */
|
|
159
|
+
/* @__PURE__ */ N("div", {
|
|
157
160
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
|
|
158
|
-
children: [/* @__PURE__ */
|
|
161
|
+
children: [/* @__PURE__ */ M("div", {
|
|
159
162
|
className: "space-y-6 lg:col-span-2",
|
|
160
|
-
children: /* @__PURE__ */
|
|
163
|
+
children: /* @__PURE__ */ N(F, {
|
|
161
164
|
treatment: "plain",
|
|
162
165
|
className: "border-border-seam p-6",
|
|
163
166
|
children: [
|
|
164
|
-
/* @__PURE__ */
|
|
167
|
+
/* @__PURE__ */ N("h2", {
|
|
165
168
|
className: "mb-4 flex items-center gap-2 text-base font-semibold text-text-primary",
|
|
166
|
-
children: [/* @__PURE__ */
|
|
169
|
+
children: [/* @__PURE__ */ M(x, { className: "h-5 w-5" }), "Value & Performance"]
|
|
167
170
|
}),
|
|
168
|
-
/* @__PURE__ */
|
|
171
|
+
/* @__PURE__ */ N("dl", {
|
|
169
172
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
|
|
170
173
|
children: [
|
|
171
|
-
/* @__PURE__ */
|
|
174
|
+
/* @__PURE__ */ N("div", {
|
|
172
175
|
className: "rounded-lg bg-bg-sunken/50 p-4",
|
|
173
|
-
children: [/* @__PURE__ */
|
|
176
|
+
children: [/* @__PURE__ */ M("dt", {
|
|
174
177
|
className: "text-xs text-text-secondary",
|
|
175
178
|
children: "Purchase Price"
|
|
176
|
-
}), /* @__PURE__ */
|
|
179
|
+
}), /* @__PURE__ */ M("dd", {
|
|
177
180
|
className: "mt-1 text-lg font-semibold text-text-primary",
|
|
178
|
-
children: t(
|
|
181
|
+
children: t(V.purchasePrice)
|
|
179
182
|
})]
|
|
180
183
|
}),
|
|
181
|
-
/* @__PURE__ */
|
|
184
|
+
/* @__PURE__ */ N("div", {
|
|
182
185
|
className: "rounded-lg bg-bg-sunken/50 p-4",
|
|
183
|
-
children: [/* @__PURE__ */
|
|
186
|
+
children: [/* @__PURE__ */ M("dt", {
|
|
184
187
|
className: "text-xs text-text-secondary",
|
|
185
188
|
children: "Current Value"
|
|
186
|
-
}), /* @__PURE__ */
|
|
189
|
+
}), /* @__PURE__ */ M("dd", {
|
|
187
190
|
className: "mt-1 text-lg font-semibold text-text-primary",
|
|
188
|
-
children: t(
|
|
191
|
+
children: t(V.currentValue)
|
|
189
192
|
})]
|
|
190
193
|
}),
|
|
191
|
-
/* @__PURE__ */
|
|
194
|
+
/* @__PURE__ */ N("div", {
|
|
192
195
|
className: "rounded-lg bg-bg-sunken/50 p-4",
|
|
193
|
-
children: [/* @__PURE__ */
|
|
196
|
+
children: [/* @__PURE__ */ M("dt", {
|
|
194
197
|
className: "text-xs text-text-secondary",
|
|
195
198
|
children: "Total Gain / Loss"
|
|
196
|
-
}), /* @__PURE__ */
|
|
197
|
-
className: e("mt-1 flex items-center gap-1 text-lg font-semibold",
|
|
199
|
+
}), /* @__PURE__ */ N("dd", {
|
|
200
|
+
className: e("mt-1 flex items-center gap-1 text-lg font-semibold", W ? "text-status-success-text" : "text-status-error-text"),
|
|
198
201
|
children: [
|
|
199
|
-
|
|
200
|
-
t(Math.abs(
|
|
202
|
+
M(W ? b : v, { className: "h-4 w-4" }),
|
|
203
|
+
t(Math.abs(U)),
|
|
201
204
|
" (",
|
|
202
|
-
|
|
205
|
+
G.toFixed(1),
|
|
203
206
|
"%)"
|
|
204
207
|
]
|
|
205
208
|
})]
|
|
206
209
|
}),
|
|
207
|
-
/* @__PURE__ */
|
|
210
|
+
/* @__PURE__ */ N("div", {
|
|
208
211
|
className: "rounded-lg bg-bg-sunken/50 p-4",
|
|
209
|
-
children: [/* @__PURE__ */
|
|
212
|
+
children: [/* @__PURE__ */ M("dt", {
|
|
210
213
|
className: "text-xs text-text-secondary",
|
|
211
214
|
children: "Est. Monthly Rental Income"
|
|
212
|
-
}), /* @__PURE__ */
|
|
215
|
+
}), /* @__PURE__ */ M("dd", {
|
|
213
216
|
className: "mt-1 text-lg font-semibold text-text-primary",
|
|
214
|
-
children:
|
|
217
|
+
children: V.rentalYield ? t(Math.round(K)) : "—"
|
|
215
218
|
})]
|
|
216
219
|
})
|
|
217
220
|
]
|
|
218
221
|
}),
|
|
219
|
-
/* @__PURE__ */
|
|
222
|
+
/* @__PURE__ */ N("div", {
|
|
220
223
|
className: "mt-6",
|
|
221
|
-
children: [/* @__PURE__ */
|
|
224
|
+
children: [/* @__PURE__ */ M("p", {
|
|
222
225
|
className: "mb-2 text-xs font-medium text-text-secondary",
|
|
223
226
|
children: "Purchase vs current value"
|
|
224
|
-
}), /* @__PURE__ */
|
|
227
|
+
}), /* @__PURE__ */ M("div", {
|
|
225
228
|
className: "h-44 w-full",
|
|
226
|
-
children: /* @__PURE__ */
|
|
229
|
+
children: /* @__PURE__ */ M(d, {
|
|
227
230
|
width: "100%",
|
|
228
231
|
height: "100%",
|
|
229
|
-
children: /* @__PURE__ */
|
|
232
|
+
children: /* @__PURE__ */ N(_, {
|
|
230
233
|
data: [{
|
|
231
234
|
name: "Purchase",
|
|
232
|
-
value:
|
|
235
|
+
value: V.purchasePrice,
|
|
233
236
|
fill: "var(--color-chart-3)"
|
|
234
237
|
}, {
|
|
235
238
|
name: "Current",
|
|
236
|
-
value:
|
|
237
|
-
fill:
|
|
239
|
+
value: V.currentValue,
|
|
240
|
+
fill: W ? "var(--color-chart-2)" : "var(--color-chart-5)"
|
|
238
241
|
}],
|
|
239
242
|
margin: {
|
|
240
243
|
top: 8,
|
|
@@ -243,12 +246,12 @@ function R() {
|
|
|
243
246
|
bottom: 0
|
|
244
247
|
},
|
|
245
248
|
children: [
|
|
246
|
-
/* @__PURE__ */
|
|
249
|
+
/* @__PURE__ */ M(m, {
|
|
247
250
|
strokeDasharray: "3 3",
|
|
248
251
|
stroke: "var(--color-border-subtle)",
|
|
249
252
|
vertical: !1
|
|
250
253
|
}),
|
|
251
|
-
/* @__PURE__ */
|
|
254
|
+
/* @__PURE__ */ M(h, {
|
|
252
255
|
dataKey: "name",
|
|
253
256
|
tick: {
|
|
254
257
|
fontSize: 11,
|
|
@@ -257,7 +260,7 @@ function R() {
|
|
|
257
260
|
tickLine: !1,
|
|
258
261
|
axisLine: !1
|
|
259
262
|
}),
|
|
260
|
-
/* @__PURE__ */
|
|
263
|
+
/* @__PURE__ */ M(g, {
|
|
261
264
|
tick: {
|
|
262
265
|
fontSize: 11,
|
|
263
266
|
fill: "var(--color-text-secondary)"
|
|
@@ -267,7 +270,7 @@ function R() {
|
|
|
267
270
|
width: 56,
|
|
268
271
|
tickFormatter: (e) => t(e)
|
|
269
272
|
}),
|
|
270
|
-
/* @__PURE__ */
|
|
273
|
+
/* @__PURE__ */ M(u, {
|
|
271
274
|
cursor: { fill: "var(--color-bg-sunken)" },
|
|
272
275
|
contentStyle: {
|
|
273
276
|
background: "var(--color-bg-surface)",
|
|
@@ -277,7 +280,7 @@ function R() {
|
|
|
277
280
|
},
|
|
278
281
|
formatter: (e) => [t(e), "Value"]
|
|
279
282
|
}),
|
|
280
|
-
/* @__PURE__ */
|
|
283
|
+
/* @__PURE__ */ N(p, {
|
|
281
284
|
dataKey: "value",
|
|
282
285
|
radius: [
|
|
283
286
|
6,
|
|
@@ -286,7 +289,7 @@ function R() {
|
|
|
286
289
|
0
|
|
287
290
|
],
|
|
288
291
|
maxBarSize: 72,
|
|
289
|
-
children: [/* @__PURE__ */
|
|
292
|
+
children: [/* @__PURE__ */ M(f, { fill: "var(--color-chart-3)" }), /* @__PURE__ */ M(f, { fill: W ? "var(--color-chart-2)" : "var(--color-chart-5)" })]
|
|
290
293
|
})
|
|
291
294
|
]
|
|
292
295
|
})
|
|
@@ -295,75 +298,75 @@ function R() {
|
|
|
295
298
|
})
|
|
296
299
|
]
|
|
297
300
|
})
|
|
298
|
-
}), /* @__PURE__ */
|
|
301
|
+
}), /* @__PURE__ */ M("div", {
|
|
299
302
|
className: "space-y-6",
|
|
300
|
-
children: /* @__PURE__ */
|
|
303
|
+
children: /* @__PURE__ */ N(F, {
|
|
301
304
|
treatment: "plain",
|
|
302
305
|
className: "border-border-seam p-5",
|
|
303
|
-
children: [/* @__PURE__ */
|
|
306
|
+
children: [/* @__PURE__ */ N("h3", {
|
|
304
307
|
className: "mb-4 flex items-center gap-2 text-base font-semibold text-text-primary",
|
|
305
|
-
children: [/* @__PURE__ */
|
|
306
|
-
}), /* @__PURE__ */
|
|
308
|
+
children: [/* @__PURE__ */ M(C, { className: "h-5 w-5" }), "Purchase & Holding"]
|
|
309
|
+
}), /* @__PURE__ */ N("dl", {
|
|
307
310
|
className: "space-y-3 text-sm",
|
|
308
311
|
children: [
|
|
309
|
-
/* @__PURE__ */
|
|
312
|
+
/* @__PURE__ */ N("div", {
|
|
310
313
|
className: "flex items-center justify-between",
|
|
311
|
-
children: [/* @__PURE__ */
|
|
314
|
+
children: [/* @__PURE__ */ M("dt", {
|
|
312
315
|
className: "text-text-secondary",
|
|
313
316
|
children: "Category"
|
|
314
|
-
}), /* @__PURE__ */
|
|
317
|
+
}), /* @__PURE__ */ M("dd", {
|
|
315
318
|
className: "font-medium capitalize text-text-primary",
|
|
316
|
-
children:
|
|
319
|
+
children: V.category
|
|
317
320
|
})]
|
|
318
321
|
}),
|
|
319
|
-
/* @__PURE__ */
|
|
322
|
+
/* @__PURE__ */ N("div", {
|
|
320
323
|
className: "flex items-center justify-between",
|
|
321
|
-
children: [/* @__PURE__ */
|
|
324
|
+
children: [/* @__PURE__ */ M("dt", {
|
|
322
325
|
className: "text-text-secondary",
|
|
323
326
|
children: "Type"
|
|
324
|
-
}), /* @__PURE__ */
|
|
327
|
+
}), /* @__PURE__ */ M("dd", {
|
|
325
328
|
className: "font-medium capitalize text-text-primary",
|
|
326
|
-
children:
|
|
329
|
+
children: V.type.replace("_", " ")
|
|
327
330
|
})]
|
|
328
331
|
}),
|
|
329
|
-
/* @__PURE__ */
|
|
332
|
+
/* @__PURE__ */ N("div", {
|
|
330
333
|
className: "flex items-center justify-between",
|
|
331
|
-
children: [/* @__PURE__ */
|
|
334
|
+
children: [/* @__PURE__ */ M("dt", {
|
|
332
335
|
className: "text-text-secondary",
|
|
333
336
|
children: "Location"
|
|
334
|
-
}), /* @__PURE__ */
|
|
337
|
+
}), /* @__PURE__ */ M("dd", {
|
|
335
338
|
className: "font-medium text-text-primary",
|
|
336
|
-
children:
|
|
339
|
+
children: V.location
|
|
337
340
|
})]
|
|
338
341
|
}),
|
|
339
|
-
/* @__PURE__ */
|
|
342
|
+
/* @__PURE__ */ N("div", {
|
|
340
343
|
className: "flex items-center justify-between",
|
|
341
|
-
children: [/* @__PURE__ */
|
|
344
|
+
children: [/* @__PURE__ */ M("dt", {
|
|
342
345
|
className: "text-text-secondary",
|
|
343
346
|
children: "Purchase Date"
|
|
344
|
-
}), /* @__PURE__ */
|
|
347
|
+
}), /* @__PURE__ */ M("dd", {
|
|
345
348
|
className: "font-medium text-text-primary",
|
|
346
|
-
children:
|
|
349
|
+
children: V.purchaseDate ? n(V.purchaseDate) : "—"
|
|
347
350
|
})]
|
|
348
351
|
}),
|
|
349
|
-
/* @__PURE__ */
|
|
352
|
+
/* @__PURE__ */ N("div", {
|
|
350
353
|
className: "flex items-center justify-between",
|
|
351
|
-
children: [/* @__PURE__ */
|
|
354
|
+
children: [/* @__PURE__ */ M("dt", {
|
|
352
355
|
className: "text-text-secondary",
|
|
353
356
|
children: "Last Valuation"
|
|
354
|
-
}), /* @__PURE__ */
|
|
357
|
+
}), /* @__PURE__ */ M("dd", {
|
|
355
358
|
className: "font-medium text-text-primary",
|
|
356
|
-
children:
|
|
359
|
+
children: V.lastValuationDate ? n(V.lastValuationDate) : "—"
|
|
357
360
|
})]
|
|
358
361
|
}),
|
|
359
|
-
/* @__PURE__ */
|
|
362
|
+
/* @__PURE__ */ N("div", {
|
|
360
363
|
className: "flex items-center justify-between border-t border-border-subtle pt-3",
|
|
361
|
-
children: [/* @__PURE__ */
|
|
364
|
+
children: [/* @__PURE__ */ M("dt", {
|
|
362
365
|
className: "text-text-secondary",
|
|
363
366
|
children: "Status"
|
|
364
|
-
}), /* @__PURE__ */
|
|
365
|
-
label:
|
|
366
|
-
variant:
|
|
367
|
+
}), /* @__PURE__ */ M("dd", { children: /* @__PURE__ */ M(i, {
|
|
368
|
+
label: V.status.replace("_", " "),
|
|
369
|
+
variant: R(V.status)
|
|
367
370
|
}) })]
|
|
368
371
|
})
|
|
369
372
|
]
|
|
@@ -375,6 +378,6 @@ function R() {
|
|
|
375
378
|
});
|
|
376
379
|
}
|
|
377
380
|
//#endregion
|
|
378
|
-
export {
|
|
381
|
+
export { z as AssetDetailPage };
|
|
379
382
|
|
|
380
383
|
//# sourceMappingURL=AssetDetailPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetDetailPage.js","names":[],"sources":["../../../../src/housingvista/pages/assets/AssetDetailPage.tsx"],"sourcesContent":["/**\n * HousingVista Asset Detail Page\n * Full performance view for a single owned asset backed by the single-item\n * `housingvistaAsset(id)` query — current value, appreciation, rental yield,\n * ROI, and purchase history. Read-only: no fabricated actions.\n * @module housingvista\n */\n\nimport { useNavigate, useParams } from 'react-router-dom';\nimport {\n ArrowLeft,\n ArrowUpRight,\n ArrowDownRight,\n Building,\n DollarSign,\n TrendingUp,\n Percent,\n Target,\n MapPin,\n Calendar,\n BarChart3,\n ImageOff,\n} from 'lucide-react';\nimport { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Cell } from 'recharts';\nimport { EmphasisPanel, GlassCard, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { Breadcrumbs, StatCard, StatusBadge, EmptyState, LoadingSkeleton } from '../../components';\nimport type { BreadcrumbItem } from '../../components';\nimport { useAsset } from '../../hooks';\nimport { cn, formatCurrency, formatDate } from '../../utils/helpers';\nimport type { Asset } from '../../types';\n\nfunction getStatusVariant(status: Asset['status']): 'success' | 'warning' | 'info' | 'muted' {\n switch (status) {\n case 'active':\n return 'success';\n case 'under_renovation':\n return 'warning';\n case 'pending_sale':\n return 'info';\n case 'sold':\n return 'muted';\n default:\n return 'muted';\n }\n}\n\nexport function AssetDetailPage() {\n const { id } = useParams<{ id: string }>();\n const navigate = useNavigate();\n const { data: asset, loading } = useAsset(id);\n\n if (loading) {\n return (\n <div className=\"flex flex-col gap-6 p-6\">\n <LoadingSkeleton variant=\"detail\" />\n </div>\n );\n }\n\n if (!asset) {\n return (\n <div className=\"p-6\">\n <EmptyState\n illustration=\"empty-search\"\n icon={<Building className=\"h-12 w-12\" />}\n title=\"Asset Not Found\"\n description=\"The asset you're looking for doesn't exist or has been removed.\"\n action={\n <button\n onClick={() => navigate('../assets')}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Assets\n </button>\n }\n />\n </div>\n );\n }\n\n const gain = asset.currentValue - asset.purchasePrice;\n const isPositive = gain >= 0;\n const roi = asset.purchasePrice > 0 ? (gain / asset.purchasePrice) * 100 : 0;\n const monthlyRentalIncome = asset.rentalYield ? (asset.currentValue * asset.rentalYield) / 100 / 12 : 0;\n\n const breadcrumbs: BreadcrumbItem[] = [{ label: 'Assets', href: '../' }, { label: asset.title }];\n\n return (\n <div className=\"flex flex-col gap-6 p-6\">\n <Breadcrumbs items={breadcrumbs} />\n\n {/* Header */}\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n <div>\n <button\n onClick={() => navigate('../assets')}\n className=\"mb-2 inline-flex items-center gap-2 rounded-md px-2 py-1 text-sm text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Assets\n </button>\n <h1 className=\"text-2xl font-semibold text-text-primary\">{asset.title}</h1>\n <div className=\"mt-2 flex flex-wrap items-center gap-2\">\n <StatusBadge label={asset.status.replace('_', ' ')} variant={getStatusVariant(asset.status)} dot />\n <StatusBadge label={asset.type} variant=\"muted\" />\n <span className=\"inline-flex items-center gap-1 text-sm text-text-secondary\">\n <MapPin className=\"h-3.5 w-3.5\" />\n {asset.location}\n </span>\n </div>\n </div>\n {asset.imageUrl ? (\n <img src={asset.imageUrl} alt={asset.title} className=\"h-24 w-full rounded-lg object-cover sm:w-40 lg:w-48\" />\n ) : (\n <div\n className=\"flex h-24 w-full items-center justify-center rounded-lg bg-gradient-to-br from-bg-sunken to-bg-sunken/50 sm:w-40 lg:w-48\"\n role=\"img\"\n aria-label={`${asset.title} — no image`}\n >\n <ImageOff className=\"h-8 w-8 text-text-secondary/40\" />\n </div>\n )}\n </div>\n\n <PagePurpose className=\"max-w-3xl\">\n A full performance breakdown for one property you own — what you paid, what it is worth today, how much it has\n appreciated, and the rental yield it generates. Use it to judge whether to hold, renovate, or sell.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"housingvista-asset-detail\"\n steps={[\n {\n id: 'benchmark',\n label: 'Benchmark against the market',\n description: 'Compare this asset against area and market trends.',\n onClick: () => navigate('../market-analytics'),\n },\n {\n id: 'manage-rental',\n label: 'Manage the rental',\n description: 'Review tenants, leases, and rent collection for your units.',\n onClick: () => navigate('../rental'),\n },\n {\n id: 'back',\n label: 'Back to all assets',\n description: 'Return to your full portfolio view.',\n onClick: () => navigate('../assets'),\n },\n ]}\n />\n\n {/* Performance metrics — primary insight zone (one EmphasisPanel per page) */}\n <EmphasisPanel className=\"p-4\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n label=\"Current Value\"\n value={asset.currentValue}\n prefix=\"$\"\n icon={<DollarSign className=\"h-4 w-4\" />}\n />\n <StatCard\n label=\"Appreciation\"\n value={`${asset.appreciationPercent.toFixed(1)}%`}\n icon={<TrendingUp className=\"h-4 w-4\" />}\n />\n <StatCard label=\"Overall ROI\" value={`${roi.toFixed(1)}%`} icon={<Target className=\"h-4 w-4\" />} />\n <StatCard\n label=\"Rental Yield\"\n value={asset.rentalYield != null ? `${asset.rentalYield.toFixed(1)}%` : '—'}\n icon={<Percent className=\"h-4 w-4\" />}\n />\n </div>\n </EmphasisPanel>\n\n {/* Detail grid */}\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Value & performance */}\n <div className=\"space-y-6 lg:col-span-2\">\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-6\">\n <h2 className=\"mb-4 flex items-center gap-2 text-base font-semibold text-text-primary\">\n <BarChart3 className=\"h-5 w-5\" />\n Value & Performance\n </h2>\n <dl className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <dt className=\"text-xs text-text-secondary\">Purchase Price</dt>\n <dd className=\"mt-1 text-lg font-semibold text-text-primary\">{formatCurrency(asset.purchasePrice)}</dd>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <dt className=\"text-xs text-text-secondary\">Current Value</dt>\n <dd className=\"mt-1 text-lg font-semibold text-text-primary\">{formatCurrency(asset.currentValue)}</dd>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <dt className=\"text-xs text-text-secondary\">Total Gain / Loss</dt>\n <dd\n className={cn(\n 'mt-1 flex items-center gap-1 text-lg font-semibold',\n isPositive ? 'text-status-success-text' : 'text-status-error-text'\n )}\n >\n {isPositive ? <ArrowUpRight className=\"h-4 w-4\" /> : <ArrowDownRight className=\"h-4 w-4\" />}\n {formatCurrency(Math.abs(gain))} ({roi.toFixed(1)}%)\n </dd>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <dt className=\"text-xs text-text-secondary\">Est. Monthly Rental Income</dt>\n <dd className=\"mt-1 text-lg font-semibold text-text-primary\">\n {asset.rentalYield ? formatCurrency(Math.round(monthlyRentalIncome)) : '—'}\n </dd>\n </div>\n </dl>\n\n {/* Purchase vs current value — real two-point comparison */}\n <div className=\"mt-6\">\n <p className=\"mb-2 text-xs font-medium text-text-secondary\">Purchase vs current value</p>\n <div className=\"h-44 w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart\n data={[\n { name: 'Purchase', value: asset.purchasePrice, fill: 'var(--color-chart-3)' },\n {\n name: 'Current',\n value: asset.currentValue,\n fill: isPositive ? 'var(--color-chart-2)' : 'var(--color-chart-5)',\n },\n ]}\n margin={{ top: 8, right: 8, left: 0, bottom: 0 }}\n >\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"var(--color-border-subtle)\" vertical={false} />\n <XAxis\n dataKey=\"name\"\n tick={{ fontSize: 11, fill: 'var(--color-text-secondary)' }}\n tickLine={false}\n axisLine={false}\n />\n <YAxis\n tick={{ fontSize: 11, fill: 'var(--color-text-secondary)' }}\n tickLine={false}\n axisLine={false}\n width={56}\n tickFormatter={(v: number) => formatCurrency(v)}\n />\n <Tooltip\n cursor={{ fill: 'var(--color-bg-sunken)' }}\n contentStyle={{\n background: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border-subtle)',\n borderRadius: 10,\n fontSize: 12,\n }}\n formatter={(value: number) => [formatCurrency(value), 'Value']}\n />\n <Bar dataKey=\"value\" radius={[6, 6, 0, 0]} maxBarSize={72}>\n <Cell fill=\"var(--color-chart-3)\" />\n <Cell fill={isPositive ? 'var(--color-chart-2)' : 'var(--color-chart-5)'} />\n </Bar>\n </BarChart>\n </ResponsiveContainer>\n </div>\n </div>\n </GlassCard>\n </div>\n\n {/* Purchase & holding info */}\n <div className=\"space-y-6\">\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5\">\n <h3 className=\"mb-4 flex items-center gap-2 text-base font-semibold text-text-primary\">\n <Calendar className=\"h-5 w-5\" />\n Purchase & Holding\n </h3>\n <dl className=\"space-y-3 text-sm\">\n <div className=\"flex items-center justify-between\">\n <dt className=\"text-text-secondary\">Category</dt>\n <dd className=\"font-medium capitalize text-text-primary\">{asset.category}</dd>\n </div>\n <div className=\"flex items-center justify-between\">\n <dt className=\"text-text-secondary\">Type</dt>\n <dd className=\"font-medium capitalize text-text-primary\">{asset.type.replace('_', ' ')}</dd>\n </div>\n <div className=\"flex items-center justify-between\">\n <dt className=\"text-text-secondary\">Location</dt>\n <dd className=\"font-medium text-text-primary\">{asset.location}</dd>\n </div>\n <div className=\"flex items-center justify-between\">\n <dt className=\"text-text-secondary\">Purchase Date</dt>\n <dd className=\"font-medium text-text-primary\">\n {asset.purchaseDate ? formatDate(asset.purchaseDate) : '—'}\n </dd>\n </div>\n <div className=\"flex items-center justify-between\">\n <dt className=\"text-text-secondary\">Last Valuation</dt>\n <dd className=\"font-medium text-text-primary\">\n {asset.lastValuationDate ? formatDate(asset.lastValuationDate) : '—'}\n </dd>\n </div>\n <div className=\"flex items-center justify-between border-t border-border-subtle pt-3\">\n <dt className=\"text-text-secondary\">Status</dt>\n <dd>\n <StatusBadge label={asset.status.replace('_', ' ')} variant={getStatusVariant(asset.status)} />\n </dd>\n </div>\n </dl>\n </GlassCard>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AssetDetailPage.js","names":[],"sources":["../../../../src/housingvista/pages/assets/AssetDetailPage.tsx"],"sourcesContent":["/**\n * HousingVista Asset Detail Page\n * Full performance view for a single owned asset backed by the single-item\n * `housingvistaAsset(id)` query — current value, appreciation, rental yield,\n * ROI, and purchase history. Read-only: no fabricated actions.\n * @module housingvista\n */\n\nimport { useNavigate, useParams } from 'react-router-dom';\nimport {\n ArrowLeft,\n ArrowUpRight,\n ArrowDownRight,\n Building,\n DollarSign,\n TrendingUp,\n Percent,\n Target,\n MapPin,\n Calendar,\n BarChart3,\n ImageOff,\n} from 'lucide-react';\nimport { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Cell } from 'recharts';\nimport { EmphasisPanel, GlassCard, PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { Breadcrumbs, StatCard, StatusBadge, EmptyState, LoadingSkeleton } from '../../components';\nimport type { BreadcrumbItem } from '../../components';\nimport { useAsset } from '../../hooks';\nimport { cn, formatCurrency, formatDate } from '../../utils/helpers';\nimport type { Asset } from '../../types';\nimport { useTrackPageView } from '../../hooks/useHousingVistaAnalytics';\n\nfunction getStatusVariant(status: Asset['status']): 'success' | 'warning' | 'info' | 'muted' {\n switch (status) {\n case 'active':\n return 'success';\n case 'under_renovation':\n return 'warning';\n case 'pending_sale':\n return 'info';\n case 'sold':\n return 'muted';\n default:\n return 'muted';\n }\n}\n\nexport function AssetDetailPage() {\n const { id } = useParams<{ id: string }>();\n\n useTrackPageView('housingvista.asset.viewed', id);\n const navigate = useNavigate();\n const { data: asset, loading } = useAsset(id);\n\n if (loading) {\n return (\n <div className=\"flex flex-col gap-6 p-6\">\n <LoadingSkeleton variant=\"detail\" />\n </div>\n );\n }\n\n if (!asset) {\n return (\n <div className=\"p-6\">\n <EmptyState\n illustration=\"empty-search\"\n icon={<Building className=\"h-12 w-12\" />}\n title=\"Asset Not Found\"\n description=\"The asset you're looking for doesn't exist or has been removed.\"\n action={\n <button\n onClick={() => navigate('../assets')}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg-hover\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Assets\n </button>\n }\n />\n </div>\n );\n }\n\n const gain = asset.currentValue - asset.purchasePrice;\n const isPositive = gain >= 0;\n const roi = asset.purchasePrice > 0 ? (gain / asset.purchasePrice) * 100 : 0;\n const monthlyRentalIncome = asset.rentalYield ? (asset.currentValue * asset.rentalYield) / 100 / 12 : 0;\n\n const breadcrumbs: BreadcrumbItem[] = [{ label: 'Assets', href: '../' }, { label: asset.title }];\n\n return (\n <div className=\"flex flex-col gap-6 p-6\">\n <Breadcrumbs items={breadcrumbs} />\n\n {/* Header */}\n <div className=\"flex flex-col gap-4 lg:flex-row lg:items-center lg:justify-between\">\n <div>\n <button\n onClick={() => navigate('../assets')}\n className=\"mb-2 inline-flex items-center gap-2 rounded-md px-2 py-1 text-sm text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary\"\n >\n <ArrowLeft className=\"h-4 w-4\" />\n Back to Assets\n </button>\n <h1 className=\"text-2xl font-semibold text-text-primary\">{asset.title}</h1>\n <div className=\"mt-2 flex flex-wrap items-center gap-2\">\n <StatusBadge label={asset.status.replace('_', ' ')} variant={getStatusVariant(asset.status)} dot />\n <StatusBadge label={asset.type} variant=\"muted\" />\n <span className=\"inline-flex items-center gap-1 text-sm text-text-secondary\">\n <MapPin className=\"h-3.5 w-3.5\" />\n {asset.location}\n </span>\n </div>\n </div>\n {asset.imageUrl ? (\n <img src={asset.imageUrl} alt={asset.title} className=\"h-24 w-full rounded-lg object-cover sm:w-40 lg:w-48\" />\n ) : (\n <div\n className=\"flex h-24 w-full items-center justify-center rounded-lg bg-gradient-to-br from-bg-sunken to-bg-sunken/50 sm:w-40 lg:w-48\"\n role=\"img\"\n aria-label={`${asset.title} — no image`}\n >\n <ImageOff className=\"h-8 w-8 text-text-secondary/40\" />\n </div>\n )}\n </div>\n\n <PagePurpose className=\"max-w-3xl\">\n A full performance breakdown for one property you own — what you paid, what it is worth today, how much it has\n appreciated, and the rental yield it generates. Use it to judge whether to hold, renovate, or sell.\n </PagePurpose>\n\n <NextSteps\n storageKey=\"housingvista-asset-detail\"\n steps={[\n {\n id: 'benchmark',\n label: 'Benchmark against the market',\n description: 'Compare this asset against area and market trends.',\n onClick: () => navigate('../market-analytics'),\n },\n {\n id: 'manage-rental',\n label: 'Manage the rental',\n description: 'Review tenants, leases, and rent collection for your units.',\n onClick: () => navigate('../rental'),\n },\n {\n id: 'back',\n label: 'Back to all assets',\n description: 'Return to your full portfolio view.',\n onClick: () => navigate('../assets'),\n },\n ]}\n />\n\n {/* Performance metrics — primary insight zone (one EmphasisPanel per page) */}\n <EmphasisPanel className=\"p-4\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard\n label=\"Current Value\"\n value={asset.currentValue}\n prefix=\"$\"\n icon={<DollarSign className=\"h-4 w-4\" />}\n />\n <StatCard\n label=\"Appreciation\"\n value={`${asset.appreciationPercent.toFixed(1)}%`}\n icon={<TrendingUp className=\"h-4 w-4\" />}\n />\n <StatCard label=\"Overall ROI\" value={`${roi.toFixed(1)}%`} icon={<Target className=\"h-4 w-4\" />} />\n <StatCard\n label=\"Rental Yield\"\n value={asset.rentalYield != null ? `${asset.rentalYield.toFixed(1)}%` : '—'}\n icon={<Percent className=\"h-4 w-4\" />}\n />\n </div>\n </EmphasisPanel>\n\n {/* Detail grid */}\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Value & performance */}\n <div className=\"space-y-6 lg:col-span-2\">\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-6\">\n <h2 className=\"mb-4 flex items-center gap-2 text-base font-semibold text-text-primary\">\n <BarChart3 className=\"h-5 w-5\" />\n Value & Performance\n </h2>\n <dl className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <dt className=\"text-xs text-text-secondary\">Purchase Price</dt>\n <dd className=\"mt-1 text-lg font-semibold text-text-primary\">{formatCurrency(asset.purchasePrice)}</dd>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <dt className=\"text-xs text-text-secondary\">Current Value</dt>\n <dd className=\"mt-1 text-lg font-semibold text-text-primary\">{formatCurrency(asset.currentValue)}</dd>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <dt className=\"text-xs text-text-secondary\">Total Gain / Loss</dt>\n <dd\n className={cn(\n 'mt-1 flex items-center gap-1 text-lg font-semibold',\n isPositive ? 'text-status-success-text' : 'text-status-error-text'\n )}\n >\n {isPositive ? <ArrowUpRight className=\"h-4 w-4\" /> : <ArrowDownRight className=\"h-4 w-4\" />}\n {formatCurrency(Math.abs(gain))} ({roi.toFixed(1)}%)\n </dd>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <dt className=\"text-xs text-text-secondary\">Est. Monthly Rental Income</dt>\n <dd className=\"mt-1 text-lg font-semibold text-text-primary\">\n {asset.rentalYield ? formatCurrency(Math.round(monthlyRentalIncome)) : '—'}\n </dd>\n </div>\n </dl>\n\n {/* Purchase vs current value — real two-point comparison */}\n <div className=\"mt-6\">\n <p className=\"mb-2 text-xs font-medium text-text-secondary\">Purchase vs current value</p>\n <div className=\"h-44 w-full\">\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart\n data={[\n { name: 'Purchase', value: asset.purchasePrice, fill: 'var(--color-chart-3)' },\n {\n name: 'Current',\n value: asset.currentValue,\n fill: isPositive ? 'var(--color-chart-2)' : 'var(--color-chart-5)',\n },\n ]}\n margin={{ top: 8, right: 8, left: 0, bottom: 0 }}\n >\n <CartesianGrid strokeDasharray=\"3 3\" stroke=\"var(--color-border-subtle)\" vertical={false} />\n <XAxis\n dataKey=\"name\"\n tick={{ fontSize: 11, fill: 'var(--color-text-secondary)' }}\n tickLine={false}\n axisLine={false}\n />\n <YAxis\n tick={{ fontSize: 11, fill: 'var(--color-text-secondary)' }}\n tickLine={false}\n axisLine={false}\n width={56}\n tickFormatter={(v: number) => formatCurrency(v)}\n />\n <Tooltip\n cursor={{ fill: 'var(--color-bg-sunken)' }}\n contentStyle={{\n background: 'var(--color-bg-surface)',\n border: '1px solid var(--color-border-subtle)',\n borderRadius: 10,\n fontSize: 12,\n }}\n formatter={(value: number) => [formatCurrency(value), 'Value']}\n />\n <Bar dataKey=\"value\" radius={[6, 6, 0, 0]} maxBarSize={72}>\n <Cell fill=\"var(--color-chart-3)\" />\n <Cell fill={isPositive ? 'var(--color-chart-2)' : 'var(--color-chart-5)'} />\n </Bar>\n </BarChart>\n </ResponsiveContainer>\n </div>\n </div>\n </GlassCard>\n </div>\n\n {/* Purchase & holding info */}\n <div className=\"space-y-6\">\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5\">\n <h3 className=\"mb-4 flex items-center gap-2 text-base font-semibold text-text-primary\">\n <Calendar className=\"h-5 w-5\" />\n Purchase & Holding\n </h3>\n <dl className=\"space-y-3 text-sm\">\n <div className=\"flex items-center justify-between\">\n <dt className=\"text-text-secondary\">Category</dt>\n <dd className=\"font-medium capitalize text-text-primary\">{asset.category}</dd>\n </div>\n <div className=\"flex items-center justify-between\">\n <dt className=\"text-text-secondary\">Type</dt>\n <dd className=\"font-medium capitalize text-text-primary\">{asset.type.replace('_', ' ')}</dd>\n </div>\n <div className=\"flex items-center justify-between\">\n <dt className=\"text-text-secondary\">Location</dt>\n <dd className=\"font-medium text-text-primary\">{asset.location}</dd>\n </div>\n <div className=\"flex items-center justify-between\">\n <dt className=\"text-text-secondary\">Purchase Date</dt>\n <dd className=\"font-medium text-text-primary\">\n {asset.purchaseDate ? formatDate(asset.purchaseDate) : '—'}\n </dd>\n </div>\n <div className=\"flex items-center justify-between\">\n <dt className=\"text-text-secondary\">Last Valuation</dt>\n <dd className=\"font-medium text-text-primary\">\n {asset.lastValuationDate ? formatDate(asset.lastValuationDate) : '—'}\n </dd>\n </div>\n <div className=\"flex items-center justify-between border-t border-border-subtle pt-3\">\n <dt className=\"text-text-secondary\">Status</dt>\n <dd>\n <StatusBadge label={asset.status.replace('_', ' ')} variant={getStatusVariant(asset.status)} />\n </dd>\n </div>\n </dl>\n </GlassCard>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AssetManagementPage.d.ts","sourceRoot":"","sources":["../../../../src/housingvista/pages/assets/AssetManagementPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AssetManagementPage.d.ts","sourceRoot":"","sources":["../../../../src/housingvista/pages/assets/AssetManagementPage.tsx"],"names":[],"mappings":"AAsHA,wBAAgB,mBAAmB,gCAkpBlC"}
|