@burdenoff/microfe-housingvista 2026.703.10 → 2026.703.11
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/pages/finance/HomeLoanDetailPage.js +73 -71
- package/dist/housingvista/pages/finance/HomeLoanDetailPage.js.map +1 -1
- package/dist/housingvista/pages/legal/LegalServiceDetailPage.js +71 -68
- package/dist/housingvista/pages/legal/LegalServiceDetailPage.js.map +1 -1
- package/dist/housingvista/pages/marketplace/ServiceDetailPage.js +85 -82
- package/dist/housingvista/pages/marketplace/ServiceDetailPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -10,30 +10,30 @@ import { useMemo as c, useState as l } from "react";
|
|
|
10
10
|
import { ArrowLeft as u, Building2 as d, Calculator as f, CalendarClock as p, CheckCircle as m, Gift as h, Percent as g, Star as _, Wallet as v } from "lucide-react";
|
|
11
11
|
import { useLocation as y, useNavigate as b, useParams as x } from "react-router-dom";
|
|
12
12
|
import { jsx as S, jsxs as C } from "react/jsx-runtime";
|
|
13
|
-
import {
|
|
13
|
+
import { Button as w, EmphasisPanel as T, GlassCard as E, PagePurpose as D } from "@burdenoff/fe-libs/ui";
|
|
14
14
|
//#region src/housingvista/pages/finance/HomeLoanDetailPage.tsx
|
|
15
|
-
function
|
|
15
|
+
function O(e, t, n) {
|
|
16
16
|
if (e <= 0 || t <= 0 || n <= 0) return 0;
|
|
17
17
|
let r = t / 12 / 100, i = n * 12, a = e * r * (1 + r) ** +i / ((1 + r) ** +i - 1);
|
|
18
18
|
return Math.round(a);
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function k({ rating: t }) {
|
|
21
21
|
return /* @__PURE__ */ S("div", {
|
|
22
22
|
className: "flex items-center gap-0.5",
|
|
23
23
|
children: Array.from({ length: 5 }).map((n, r) => /* @__PURE__ */ S(_, { className: e("h-4 w-4", r < Math.floor(t) ? "fill-status-warning text-status-warning" : "text-text-secondary/30") }, r))
|
|
24
24
|
});
|
|
25
25
|
}
|
|
26
|
-
function
|
|
27
|
-
let { id: _ } = x(),
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
]),
|
|
32
|
-
if (
|
|
26
|
+
function A() {
|
|
27
|
+
let { id: _ } = x(), A = b(), j = y(), { data: M, loading: N } = o(_), [P, F] = l(5e5), [I, L] = l(20), [R, z] = l(!1), B = M?.interestRate ?? 0, V = c(() => O(P, B, I), [
|
|
28
|
+
P,
|
|
29
|
+
B,
|
|
30
|
+
I
|
|
31
|
+
]), H = V * I * 12, U = H - P;
|
|
32
|
+
if (N) return /* @__PURE__ */ S("div", {
|
|
33
33
|
className: "p-6",
|
|
34
34
|
children: /* @__PURE__ */ S(a, { variant: "detail" })
|
|
35
35
|
});
|
|
36
|
-
if (!
|
|
36
|
+
if (!M) return /* @__PURE__ */ S("div", {
|
|
37
37
|
className: "p-6",
|
|
38
38
|
children: /* @__PURE__ */ S(r, {
|
|
39
39
|
illustration: "empty-data",
|
|
@@ -41,20 +41,20 @@ function k() {
|
|
|
41
41
|
title: "Loan Offer Not Found",
|
|
42
42
|
description: "The loan offer you're looking for doesn't exist or is no longer available.",
|
|
43
43
|
action: /* @__PURE__ */ C("button", {
|
|
44
|
-
onClick: () =>
|
|
44
|
+
onClick: () => A("../home-loans"),
|
|
45
45
|
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",
|
|
46
46
|
children: [/* @__PURE__ */ S(u, { className: "h-4 w-4" }), "Back to Home Loans"]
|
|
47
47
|
})
|
|
48
48
|
})
|
|
49
49
|
});
|
|
50
|
-
let
|
|
50
|
+
let W = M.features ?? [];
|
|
51
51
|
return /* @__PURE__ */ C("div", {
|
|
52
52
|
className: "flex flex-col gap-6 p-6",
|
|
53
53
|
children: [
|
|
54
54
|
/* @__PURE__ */ S(i, { items: [{
|
|
55
55
|
label: "Home Loans",
|
|
56
56
|
href: "../"
|
|
57
|
-
}, { label:
|
|
57
|
+
}, { label: M.bankName }] }),
|
|
58
58
|
/* @__PURE__ */ C("div", {
|
|
59
59
|
className: "flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between",
|
|
60
60
|
children: [/* @__PURE__ */ C("div", {
|
|
@@ -64,52 +64,48 @@ function k() {
|
|
|
64
64
|
children: /* @__PURE__ */ S(d, { className: "h-6 w-6" })
|
|
65
65
|
}), /* @__PURE__ */ C("div", { children: [
|
|
66
66
|
/* @__PURE__ */ C("button", {
|
|
67
|
-
onClick: () =>
|
|
67
|
+
onClick: () => A("../home-loans"),
|
|
68
68
|
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",
|
|
69
69
|
children: [/* @__PURE__ */ S(u, { className: "h-4 w-4" }), "Back to Home Loans"]
|
|
70
70
|
}),
|
|
71
71
|
/* @__PURE__ */ S("h1", {
|
|
72
72
|
className: "text-2xl font-semibold text-text-primary",
|
|
73
|
-
children:
|
|
73
|
+
children: M.bankName
|
|
74
74
|
}),
|
|
75
75
|
/* @__PURE__ */ C("div", {
|
|
76
76
|
className: "mt-2 flex flex-wrap items-center gap-2",
|
|
77
|
-
children: [
|
|
77
|
+
children: [M.rating != null && /* @__PURE__ */ C("span", {
|
|
78
78
|
className: "inline-flex items-center gap-1.5",
|
|
79
|
-
children: [/* @__PURE__ */ S(
|
|
79
|
+
children: [/* @__PURE__ */ S(k, { rating: M.rating }), /* @__PURE__ */ S("span", {
|
|
80
80
|
className: "text-sm text-text-secondary",
|
|
81
|
-
children:
|
|
81
|
+
children: M.rating
|
|
82
82
|
})]
|
|
83
|
-
}),
|
|
83
|
+
}), M.specialOffer && /* @__PURE__ */ S(n, {
|
|
84
84
|
label: "Special Offer",
|
|
85
85
|
variant: "warning"
|
|
86
86
|
})]
|
|
87
87
|
})
|
|
88
88
|
] })]
|
|
89
|
-
}), /* @__PURE__ */ S(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
heading: `Apply with ${j.bankName}`,
|
|
95
|
-
description: `Start your application with ${j.bankName}. Messages are saved and delivered in your inbox.`,
|
|
96
|
-
triggerVariant: "default",
|
|
97
|
-
triggerContent: "Apply Now"
|
|
89
|
+
}), /* @__PURE__ */ S(w, {
|
|
90
|
+
type: "button",
|
|
91
|
+
variant: "default",
|
|
92
|
+
onClick: () => z(!0),
|
|
93
|
+
children: "Apply Now"
|
|
98
94
|
})]
|
|
99
95
|
}),
|
|
100
|
-
/* @__PURE__ */ C(
|
|
96
|
+
/* @__PURE__ */ C(D, {
|
|
101
97
|
className: "max-w-3xl",
|
|
102
98
|
children: [
|
|
103
99
|
"The full terms of this offer with a live EMI estimate at the bank's headline rate. Model your loan amount and tenure to see the real monthly cost, then apply to connect with ",
|
|
104
|
-
|
|
100
|
+
M.bankName,
|
|
105
101
|
" through Messages."
|
|
106
102
|
]
|
|
107
103
|
}),
|
|
108
|
-
|
|
104
|
+
M.specialOffer && /* @__PURE__ */ C("div", {
|
|
109
105
|
className: "flex items-center gap-2 rounded-lg bg-status-warning-bg-subtle p-3 text-sm text-status-warning-text",
|
|
110
|
-
children: [/* @__PURE__ */ S(h, { className: "h-4 w-4 shrink-0" }),
|
|
106
|
+
children: [/* @__PURE__ */ S(h, { className: "h-4 w-4 shrink-0" }), M.specialOffer]
|
|
111
107
|
}),
|
|
112
|
-
/* @__PURE__ */ C(
|
|
108
|
+
/* @__PURE__ */ C(T, {
|
|
113
109
|
className: "p-5",
|
|
114
110
|
children: [/* @__PURE__ */ C("div", {
|
|
115
111
|
className: "mb-4 flex items-center gap-2",
|
|
@@ -117,7 +113,7 @@ function k() {
|
|
|
117
113
|
className: "text-lg font-semibold text-text-primary",
|
|
118
114
|
children: [
|
|
119
115
|
"EMI Estimate at ",
|
|
120
|
-
|
|
116
|
+
M.interestRate,
|
|
121
117
|
"%"
|
|
122
118
|
]
|
|
123
119
|
})]
|
|
@@ -133,21 +129,21 @@ function k() {
|
|
|
133
129
|
children: "Loan Amount"
|
|
134
130
|
}), /* @__PURE__ */ S("span", {
|
|
135
131
|
className: "text-sm font-semibold text-text-primary",
|
|
136
|
-
children: t(
|
|
132
|
+
children: t(P)
|
|
137
133
|
})]
|
|
138
134
|
}),
|
|
139
135
|
/* @__PURE__ */ S("input", {
|
|
140
136
|
type: "range",
|
|
141
137
|
min: 5e4,
|
|
142
|
-
max: Math.max(
|
|
138
|
+
max: Math.max(M.maxAmount, 1e5),
|
|
143
139
|
step: 1e4,
|
|
144
|
-
value: Math.min(
|
|
145
|
-
onChange: (e) =>
|
|
140
|
+
value: Math.min(P, M.maxAmount),
|
|
141
|
+
onChange: (e) => F(Number(e.target.value)),
|
|
146
142
|
className: "w-full accent-foreground"
|
|
147
143
|
}),
|
|
148
144
|
/* @__PURE__ */ C("div", {
|
|
149
145
|
className: "mt-1 flex justify-between text-xs text-text-secondary",
|
|
150
|
-
children: [/* @__PURE__ */ S("span", { children: "$50K" }), /* @__PURE__ */ C("span", { children: ["Max ", t(
|
|
146
|
+
children: [/* @__PURE__ */ S("span", { children: "$50K" }), /* @__PURE__ */ C("span", { children: ["Max ", t(M.maxAmount)] })]
|
|
151
147
|
})
|
|
152
148
|
] }), /* @__PURE__ */ C("div", { children: [
|
|
153
149
|
/* @__PURE__ */ C("div", {
|
|
@@ -157,23 +153,23 @@ function k() {
|
|
|
157
153
|
children: "Tenure (years)"
|
|
158
154
|
}), /* @__PURE__ */ C("span", {
|
|
159
155
|
className: "text-sm font-semibold text-text-primary",
|
|
160
|
-
children: [
|
|
156
|
+
children: [I, " years"]
|
|
161
157
|
})]
|
|
162
158
|
}),
|
|
163
159
|
/* @__PURE__ */ S("input", {
|
|
164
160
|
type: "range",
|
|
165
161
|
min: 1,
|
|
166
|
-
max:
|
|
162
|
+
max: M.maxTenure,
|
|
167
163
|
step: 1,
|
|
168
|
-
value: Math.min(
|
|
169
|
-
onChange: (e) =>
|
|
164
|
+
value: Math.min(I, M.maxTenure),
|
|
165
|
+
onChange: (e) => L(Number(e.target.value)),
|
|
170
166
|
className: "w-full accent-foreground"
|
|
171
167
|
}),
|
|
172
168
|
/* @__PURE__ */ C("div", {
|
|
173
169
|
className: "mt-1 flex justify-between text-xs text-text-secondary",
|
|
174
170
|
children: [/* @__PURE__ */ S("span", { children: "1 yr" }), /* @__PURE__ */ C("span", { children: [
|
|
175
171
|
"Max ",
|
|
176
|
-
|
|
172
|
+
M.maxTenure,
|
|
177
173
|
" yrs"
|
|
178
174
|
] })]
|
|
179
175
|
})
|
|
@@ -187,7 +183,7 @@ function k() {
|
|
|
187
183
|
}),
|
|
188
184
|
/* @__PURE__ */ S("p", {
|
|
189
185
|
className: "my-2 text-4xl font-bold text-text-primary",
|
|
190
|
-
children: t(
|
|
186
|
+
children: t(V)
|
|
191
187
|
}),
|
|
192
188
|
/* @__PURE__ */ C("div", {
|
|
193
189
|
className: "mt-4 grid w-full grid-cols-2 gap-4",
|
|
@@ -198,7 +194,7 @@ function k() {
|
|
|
198
194
|
children: "Total Payment"
|
|
199
195
|
}), /* @__PURE__ */ S("p", {
|
|
200
196
|
className: "text-sm font-semibold text-text-primary",
|
|
201
|
-
children: t(
|
|
197
|
+
children: t(H)
|
|
202
198
|
})]
|
|
203
199
|
}), /* @__PURE__ */ C("div", {
|
|
204
200
|
className: "text-center",
|
|
@@ -207,7 +203,7 @@ function k() {
|
|
|
207
203
|
children: "Total Interest"
|
|
208
204
|
}), /* @__PURE__ */ S("p", {
|
|
209
205
|
className: "text-sm font-semibold text-status-error-text",
|
|
210
|
-
children: t(
|
|
206
|
+
children: t(U)
|
|
211
207
|
})]
|
|
212
208
|
})]
|
|
213
209
|
})
|
|
@@ -219,7 +215,7 @@ function k() {
|
|
|
219
215
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
|
|
220
216
|
children: [/* @__PURE__ */ C("div", {
|
|
221
217
|
className: "space-y-6 lg:col-span-2",
|
|
222
|
-
children: [/* @__PURE__ */ C(
|
|
218
|
+
children: [/* @__PURE__ */ C(E, {
|
|
223
219
|
treatment: "plain",
|
|
224
220
|
className: "border-border-seam p-6",
|
|
225
221
|
children: [/* @__PURE__ */ S("h2", {
|
|
@@ -235,7 +231,7 @@ function k() {
|
|
|
235
231
|
children: [/* @__PURE__ */ S(g, { className: "h-3.5 w-3.5" }), "Interest Rate"]
|
|
236
232
|
}), /* @__PURE__ */ C("div", {
|
|
237
233
|
className: "mt-1 text-lg font-bold text-text-primary",
|
|
238
|
-
children: [
|
|
234
|
+
children: [M.interestRate, "%"]
|
|
239
235
|
})]
|
|
240
236
|
}),
|
|
241
237
|
/* @__PURE__ */ C("div", {
|
|
@@ -245,7 +241,7 @@ function k() {
|
|
|
245
241
|
children: [/* @__PURE__ */ S(v, { className: "h-3.5 w-3.5" }), "EMI / Lakh"]
|
|
246
242
|
}), /* @__PURE__ */ S("div", {
|
|
247
243
|
className: "mt-1 text-lg font-bold text-text-primary",
|
|
248
|
-
children:
|
|
244
|
+
children: M.emiPerLakh == null ? "—" : `$${M.emiPerLakh}`
|
|
249
245
|
})]
|
|
250
246
|
}),
|
|
251
247
|
/* @__PURE__ */ C("div", {
|
|
@@ -255,7 +251,7 @@ function k() {
|
|
|
255
251
|
children: [/* @__PURE__ */ S(p, { className: "h-3.5 w-3.5" }), "Max Tenure"]
|
|
256
252
|
}), /* @__PURE__ */ C("div", {
|
|
257
253
|
className: "mt-1 text-lg font-bold text-text-primary",
|
|
258
|
-
children: [
|
|
254
|
+
children: [M.maxTenure, " yrs"]
|
|
259
255
|
})]
|
|
260
256
|
}),
|
|
261
257
|
/* @__PURE__ */ C("div", {
|
|
@@ -265,7 +261,7 @@ function k() {
|
|
|
265
261
|
children: "Max Amount"
|
|
266
262
|
}), /* @__PURE__ */ S("div", {
|
|
267
263
|
className: "mt-1 text-sm font-semibold text-text-primary",
|
|
268
|
-
children: t(
|
|
264
|
+
children: t(M.maxAmount)
|
|
269
265
|
})]
|
|
270
266
|
}),
|
|
271
267
|
/* @__PURE__ */ C("div", {
|
|
@@ -275,7 +271,7 @@ function k() {
|
|
|
275
271
|
children: "Processing Fee"
|
|
276
272
|
}), /* @__PURE__ */ S("div", {
|
|
277
273
|
className: "mt-1 text-sm font-semibold text-text-primary",
|
|
278
|
-
children:
|
|
274
|
+
children: M.processingFee ?? "—"
|
|
279
275
|
})]
|
|
280
276
|
}),
|
|
281
277
|
/* @__PURE__ */ C("div", {
|
|
@@ -284,13 +280,13 @@ function k() {
|
|
|
284
280
|
className: "text-xs text-text-secondary",
|
|
285
281
|
children: "Prepayment"
|
|
286
282
|
}), /* @__PURE__ */ S("div", {
|
|
287
|
-
className: e("mt-1 text-sm font-semibold",
|
|
288
|
-
children:
|
|
283
|
+
className: e("mt-1 text-sm font-semibold", M.prepaymentCharges === "None" ? "text-status-success-text" : "text-text-primary"),
|
|
284
|
+
children: M.prepaymentCharges ?? "—"
|
|
289
285
|
})]
|
|
290
286
|
})
|
|
291
287
|
]
|
|
292
288
|
})]
|
|
293
|
-
}),
|
|
289
|
+
}), W.length > 0 && /* @__PURE__ */ C(E, {
|
|
294
290
|
treatment: "plain",
|
|
295
291
|
className: "border-border-seam p-6",
|
|
296
292
|
children: [/* @__PURE__ */ S("h2", {
|
|
@@ -298,7 +294,7 @@ function k() {
|
|
|
298
294
|
children: "Features"
|
|
299
295
|
}), /* @__PURE__ */ S("ul", {
|
|
300
296
|
className: "grid grid-cols-1 gap-2 sm:grid-cols-2",
|
|
301
|
-
children:
|
|
297
|
+
children: W.map((e, t) => /* @__PURE__ */ C("li", {
|
|
302
298
|
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
303
299
|
children: [/* @__PURE__ */ S(m, { className: "h-4 w-4 shrink-0 text-status-success-text" }), e]
|
|
304
300
|
}, t))
|
|
@@ -306,7 +302,7 @@ function k() {
|
|
|
306
302
|
})]
|
|
307
303
|
}), /* @__PURE__ */ S("div", {
|
|
308
304
|
className: "space-y-6",
|
|
309
|
-
children: /* @__PURE__ */ C(
|
|
305
|
+
children: /* @__PURE__ */ C(E, {
|
|
310
306
|
treatment: "plain",
|
|
311
307
|
className: "border-border-seam p-5",
|
|
312
308
|
children: [
|
|
@@ -318,29 +314,35 @@ function k() {
|
|
|
318
314
|
className: "mb-4 text-sm text-text-secondary",
|
|
319
315
|
children: [
|
|
320
316
|
"Applications are handled directly with ",
|
|
321
|
-
|
|
317
|
+
M.bankName,
|
|
322
318
|
" through HousingVista Messages. Start an enquiry and the bank will guide you through eligibility and paperwork."
|
|
323
319
|
]
|
|
324
320
|
}),
|
|
325
|
-
/* @__PURE__ */ S(
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
description: `Start your application with ${j.bankName}. Messages are saved and delivered in your inbox.`,
|
|
332
|
-
triggerVariant: "default",
|
|
333
|
-
triggerClassName: "w-full justify-center",
|
|
334
|
-
triggerContent: "Apply Now"
|
|
321
|
+
/* @__PURE__ */ S(w, {
|
|
322
|
+
type: "button",
|
|
323
|
+
variant: "default",
|
|
324
|
+
className: "w-full justify-center",
|
|
325
|
+
onClick: () => z(!0),
|
|
326
|
+
children: "Apply Now"
|
|
335
327
|
})
|
|
336
328
|
]
|
|
337
329
|
})
|
|
338
330
|
})]
|
|
331
|
+
}),
|
|
332
|
+
/* @__PURE__ */ S(s, {
|
|
333
|
+
open: R,
|
|
334
|
+
onOpenChange: z,
|
|
335
|
+
entityId: M.id,
|
|
336
|
+
entityType: "housingvista-home-loan",
|
|
337
|
+
title: M.bankName,
|
|
338
|
+
pagePath: j.pathname,
|
|
339
|
+
heading: `Apply with ${M.bankName}`,
|
|
340
|
+
description: `Start your application with ${M.bankName}. Messages are saved and delivered in your inbox.`
|
|
339
341
|
})
|
|
340
342
|
]
|
|
341
343
|
});
|
|
342
344
|
}
|
|
343
345
|
//#endregion
|
|
344
|
-
export {
|
|
346
|
+
export { A as HomeLoanDetailPage };
|
|
345
347
|
|
|
346
348
|
//# sourceMappingURL=HomeLoanDetailPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HomeLoanDetailPage.js","names":[],"sources":["../../../../src/housingvista/pages/finance/HomeLoanDetailPage.tsx"],"sourcesContent":["/**\n * HousingVista Home Loan Detail / Apply Page\n * Single loan offer backed by `housingvistaHomeLoanOffer(id)` — full terms plus\n * a live EMI summary for the offer's headline rate.\n *\n * \"Apply\" opens the real `ContactOwnerDialog` — a persisted conversation with\n * the bank. No fabricated approval; the EMI calculator stays for modelling.\n * @module housingvista\n */\n\nimport { useMemo, useState } from 'react';\nimport { useNavigate, useParams, useLocation } from 'react-router-dom';\nimport {\n ArrowLeft,\n Building2,\n Star,\n CheckCircle,\n Gift,\n Calculator,\n Percent,\n Wallet,\n CalendarClock,\n} from 'lucide-react';\nimport { EmphasisPanel, GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { Breadcrumbs, StatusBadge, EmptyState, LoadingSkeleton, ContactOwnerDialog } from '../../components';\nimport type { BreadcrumbItem } from '../../components';\nimport { useHomeLoanOffer } from '../../hooks';\nimport { cn, formatCurrency } from '../../utils/helpers';\n\nfunction calculateEMI(principal: number, annualRate: number, tenureYears: number): number {\n if (principal <= 0 || annualRate <= 0 || tenureYears <= 0) return 0;\n const monthlyRate = annualRate / 12 / 100;\n const months = tenureYears * 12;\n const emi = (principal * monthlyRate * Math.pow(1 + monthlyRate, months)) / (Math.pow(1 + monthlyRate, months) - 1);\n return Math.round(emi);\n}\n\nfunction RatingStars({ rating }: { rating: number }) {\n return (\n <div className=\"flex items-center gap-0.5\">\n {Array.from({ length: 5 }).map((_, i) => (\n <Star\n key={i}\n className={cn(\n 'h-4 w-4',\n i < Math.floor(rating) ? 'fill-status-warning text-status-warning' : 'text-text-secondary/30'\n )}\n />\n ))}\n </div>\n );\n}\n\nexport function HomeLoanDetailPage() {\n const { id } = useParams<{ id: string }>();\n const navigate = useNavigate();\n const location = useLocation();\n const { data: loan, loading } = useHomeLoanOffer(id);\n\n // Model a representative loan against the offer's headline rate so the borrower\n // can see the real monthly cost before enquiring.\n const [amount, setAmount] = useState(500000);\n const [tenure, setTenure] = useState(20);\n\n const rate = loan?.interestRate ?? 0;\n const emi = useMemo(() => calculateEMI(amount, rate, tenure), [amount, rate, tenure]);\n const totalPayment = emi * tenure * 12;\n const totalInterest = totalPayment - amount;\n\n if (loading) {\n return (\n <div className=\"p-6\">\n <LoadingSkeleton variant=\"detail\" />\n </div>\n );\n }\n\n if (!loan) {\n return (\n <div className=\"p-6\">\n <EmptyState\n illustration=\"empty-data\"\n icon={<Building2 className=\"h-12 w-12\" />}\n title=\"Loan Offer Not Found\"\n description=\"The loan offer you're looking for doesn't exist or is no longer available.\"\n action={\n <button\n onClick={() => navigate('../home-loans')}\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 Home Loans\n </button>\n }\n />\n </div>\n );\n }\n\n const features = loan.features ?? [];\n const breadcrumbs: BreadcrumbItem[] = [{ label: 'Home Loans', href: '../' }, { label: loan.bankName }];\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-start lg:justify-between\">\n <div className=\"flex items-start gap-4\">\n <div className=\"flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n <Building2 className=\"h-6 w-6\" />\n </div>\n <div>\n <button\n onClick={() => navigate('../home-loans')}\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 Home Loans\n </button>\n <h1 className=\"text-2xl font-semibold text-text-primary\">{loan.bankName}</h1>\n <div className=\"mt-2 flex flex-wrap items-center gap-2\">\n {loan.rating != null && (\n <span className=\"inline-flex items-center gap-1.5\">\n <RatingStars rating={loan.rating} />\n <span className=\"text-sm text-text-secondary\">{loan.rating}</span>\n </span>\n )}\n {loan.specialOffer && <StatusBadge label=\"Special Offer\" variant=\"warning\" />}\n </div>\n </div>\n </div>\n <ContactOwnerDialog\n entityId={loan.id}\n entityType=\"housingvista-home-loan\"\n title={loan.bankName}\n pagePath={location.pathname}\n heading={`Apply with ${loan.bankName}`}\n description={`Start your application with ${loan.bankName}. Messages are saved and delivered in your inbox.`}\n triggerVariant=\"default\"\n triggerContent=\"Apply Now\"\n />\n </div>\n\n <PagePurpose className=\"max-w-3xl\">\n The full terms of this offer with a live EMI estimate at the bank's headline rate. Model your loan amount and\n tenure to see the real monthly cost, then apply to connect with {loan.bankName} through Messages.\n </PagePurpose>\n\n {loan.specialOffer && (\n <div className=\"flex items-center gap-2 rounded-lg bg-status-warning-bg-subtle p-3 text-sm text-status-warning-text\">\n <Gift className=\"h-4 w-4 shrink-0\" />\n {loan.specialOffer}\n </div>\n )}\n\n {/* EMI summary — primary emphasis zone (one per page) */}\n <EmphasisPanel className=\"p-5\">\n <div className=\"mb-4 flex items-center gap-2\">\n <Calculator className=\"h-5 w-5 text-text-secondary\" />\n <h2 className=\"text-lg font-semibold text-text-primary\">EMI Estimate at {loan.interestRate}%</h2>\n </div>\n <div className=\"grid gap-6 md:grid-cols-2\">\n <div className=\"space-y-5\">\n <div>\n <div className=\"mb-2 flex items-center justify-between\">\n <label className=\"text-sm font-medium text-text-primary\">Loan Amount</label>\n <span className=\"text-sm font-semibold text-text-primary\">{formatCurrency(amount)}</span>\n </div>\n <input\n type=\"range\"\n min={50000}\n max={Math.max(loan.maxAmount, 100000)}\n step={10000}\n value={Math.min(amount, loan.maxAmount)}\n onChange={(e) => setAmount(Number(e.target.value))}\n className=\"w-full accent-foreground\"\n />\n <div className=\"mt-1 flex justify-between text-xs text-text-secondary\">\n <span>$50K</span>\n <span>Max {formatCurrency(loan.maxAmount)}</span>\n </div>\n </div>\n <div>\n <div className=\"mb-2 flex items-center justify-between\">\n <label className=\"text-sm font-medium text-text-primary\">Tenure (years)</label>\n <span className=\"text-sm font-semibold text-text-primary\">{tenure} years</span>\n </div>\n <input\n type=\"range\"\n min={1}\n max={loan.maxTenure}\n step={1}\n value={Math.min(tenure, loan.maxTenure)}\n onChange={(e) => setTenure(Number(e.target.value))}\n className=\"w-full accent-foreground\"\n />\n <div className=\"mt-1 flex justify-between text-xs text-text-secondary\">\n <span>1 yr</span>\n <span>Max {loan.maxTenure} yrs</span>\n </div>\n </div>\n </div>\n <div className=\"flex flex-col items-center justify-center rounded-lg bg-bg-sunken/50 p-6\">\n <p className=\"text-sm text-text-secondary\">Monthly EMI</p>\n <p className=\"my-2 text-4xl font-bold text-text-primary\">{formatCurrency(emi)}</p>\n <div className=\"mt-4 grid w-full grid-cols-2 gap-4\">\n <div className=\"text-center\">\n <p className=\"text-xs text-text-secondary\">Total Payment</p>\n <p className=\"text-sm font-semibold text-text-primary\">{formatCurrency(totalPayment)}</p>\n </div>\n <div className=\"text-center\">\n <p className=\"text-xs text-text-secondary\">Total Interest</p>\n <p className=\"text-sm font-semibold text-status-error-text\">{formatCurrency(totalInterest)}</p>\n </div>\n </div>\n </div>\n </div>\n </EmphasisPanel>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Terms */}\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 text-base font-semibold text-text-primary\">Loan Terms</h2>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <div className=\"flex items-center gap-1.5 text-xs text-text-secondary\">\n <Percent className=\"h-3.5 w-3.5\" />\n Interest Rate\n </div>\n <div className=\"mt-1 text-lg font-bold text-text-primary\">{loan.interestRate}%</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <div className=\"flex items-center gap-1.5 text-xs text-text-secondary\">\n <Wallet className=\"h-3.5 w-3.5\" />\n EMI / Lakh\n </div>\n <div className=\"mt-1 text-lg font-bold text-text-primary\">\n {loan.emiPerLakh != null ? `$${loan.emiPerLakh}` : '—'}\n </div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <div className=\"flex items-center gap-1.5 text-xs text-text-secondary\">\n <CalendarClock className=\"h-3.5 w-3.5\" />\n Max Tenure\n </div>\n <div className=\"mt-1 text-lg font-bold text-text-primary\">{loan.maxTenure} yrs</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <div className=\"text-xs text-text-secondary\">Max Amount</div>\n <div className=\"mt-1 text-sm font-semibold text-text-primary\">{formatCurrency(loan.maxAmount)}</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <div className=\"text-xs text-text-secondary\">Processing Fee</div>\n <div className=\"mt-1 text-sm font-semibold text-text-primary\">{loan.processingFee ?? '—'}</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <div className=\"text-xs text-text-secondary\">Prepayment</div>\n <div\n className={cn(\n 'mt-1 text-sm font-semibold',\n loan.prepaymentCharges === 'None' ? 'text-status-success-text' : 'text-text-primary'\n )}\n >\n {loan.prepaymentCharges ?? '—'}\n </div>\n </div>\n </div>\n </GlassCard>\n\n {features.length > 0 && (\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-6\">\n <h2 className=\"mb-4 text-base font-semibold text-text-primary\">Features</h2>\n <ul className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n {features.map((feature, i) => (\n <li key={i} className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <CheckCircle className=\"h-4 w-4 shrink-0 text-status-success-text\" />\n {feature}\n </li>\n ))}\n </ul>\n </GlassCard>\n )}\n </div>\n\n {/* Apply card */}\n <div className=\"space-y-6\">\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5\">\n <h3 className=\"mb-2 text-base font-semibold text-text-primary\">Ready to apply?</h3>\n <p className=\"mb-4 text-sm text-text-secondary\">\n Applications are handled directly with {loan.bankName} through HousingVista Messages. Start an enquiry and\n the bank will guide you through eligibility and paperwork.\n </p>\n <ContactOwnerDialog\n entityId={loan.id}\n entityType=\"housingvista-home-loan\"\n title={loan.bankName}\n pagePath={location.pathname}\n heading={`Apply with ${loan.bankName}`}\n description={`Start your application with ${loan.bankName}. Messages are saved and delivered in your inbox.`}\n triggerVariant=\"default\"\n triggerClassName=\"w-full justify-center\"\n triggerContent=\"Apply Now\"\n />\n </GlassCard>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"HomeLoanDetailPage.js","names":[],"sources":["../../../../src/housingvista/pages/finance/HomeLoanDetailPage.tsx"],"sourcesContent":["/**\n * HousingVista Home Loan Detail / Apply Page\n * Single loan offer backed by `housingvistaHomeLoanOffer(id)` — full terms plus\n * a live EMI summary for the offer's headline rate.\n *\n * \"Apply\" opens the real `ContactOwnerDialog` — a persisted conversation with\n * the bank. No fabricated approval; the EMI calculator stays for modelling.\n * @module housingvista\n */\n\nimport { useMemo, useState } from 'react';\nimport { useNavigate, useParams, useLocation } from 'react-router-dom';\nimport {\n ArrowLeft,\n Building2,\n Star,\n CheckCircle,\n Gift,\n Calculator,\n Percent,\n Wallet,\n CalendarClock,\n} from 'lucide-react';\nimport { Button, EmphasisPanel, GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { Breadcrumbs, StatusBadge, EmptyState, LoadingSkeleton, ContactOwnerDialog } from '../../components';\nimport type { BreadcrumbItem } from '../../components';\nimport { useHomeLoanOffer } from '../../hooks';\nimport { cn, formatCurrency } from '../../utils/helpers';\n\nfunction calculateEMI(principal: number, annualRate: number, tenureYears: number): number {\n if (principal <= 0 || annualRate <= 0 || tenureYears <= 0) return 0;\n const monthlyRate = annualRate / 12 / 100;\n const months = tenureYears * 12;\n const emi = (principal * monthlyRate * Math.pow(1 + monthlyRate, months)) / (Math.pow(1 + monthlyRate, months) - 1);\n return Math.round(emi);\n}\n\nfunction RatingStars({ rating }: { rating: number }) {\n return (\n <div className=\"flex items-center gap-0.5\">\n {Array.from({ length: 5 }).map((_, i) => (\n <Star\n key={i}\n className={cn(\n 'h-4 w-4',\n i < Math.floor(rating) ? 'fill-status-warning text-status-warning' : 'text-text-secondary/30'\n )}\n />\n ))}\n </div>\n );\n}\n\nexport function HomeLoanDetailPage() {\n const { id } = useParams<{ id: string }>();\n const navigate = useNavigate();\n const location = useLocation();\n const { data: loan, loading } = useHomeLoanOffer(id);\n\n // Model a representative loan against the offer's headline rate so the borrower\n // can see the real monthly cost before enquiring.\n const [amount, setAmount] = useState(500000);\n const [tenure, setTenure] = useState(20);\n const [contactOpen, setContactOpen] = useState(false);\n\n const rate = loan?.interestRate ?? 0;\n const emi = useMemo(() => calculateEMI(amount, rate, tenure), [amount, rate, tenure]);\n const totalPayment = emi * tenure * 12;\n const totalInterest = totalPayment - amount;\n\n if (loading) {\n return (\n <div className=\"p-6\">\n <LoadingSkeleton variant=\"detail\" />\n </div>\n );\n }\n\n if (!loan) {\n return (\n <div className=\"p-6\">\n <EmptyState\n illustration=\"empty-data\"\n icon={<Building2 className=\"h-12 w-12\" />}\n title=\"Loan Offer Not Found\"\n description=\"The loan offer you're looking for doesn't exist or is no longer available.\"\n action={\n <button\n onClick={() => navigate('../home-loans')}\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 Home Loans\n </button>\n }\n />\n </div>\n );\n }\n\n const features = loan.features ?? [];\n const breadcrumbs: BreadcrumbItem[] = [{ label: 'Home Loans', href: '../' }, { label: loan.bankName }];\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-start lg:justify-between\">\n <div className=\"flex items-start gap-4\">\n <div className=\"flex h-12 w-12 shrink-0 items-center justify-center rounded-lg bg-bg-sunken text-text-secondary\">\n <Building2 className=\"h-6 w-6\" />\n </div>\n <div>\n <button\n onClick={() => navigate('../home-loans')}\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 Home Loans\n </button>\n <h1 className=\"text-2xl font-semibold text-text-primary\">{loan.bankName}</h1>\n <div className=\"mt-2 flex flex-wrap items-center gap-2\">\n {loan.rating != null && (\n <span className=\"inline-flex items-center gap-1.5\">\n <RatingStars rating={loan.rating} />\n <span className=\"text-sm text-text-secondary\">{loan.rating}</span>\n </span>\n )}\n {loan.specialOffer && <StatusBadge label=\"Special Offer\" variant=\"warning\" />}\n </div>\n </div>\n </div>\n <Button type=\"button\" variant=\"default\" onClick={() => setContactOpen(true)}>\n Apply Now\n </Button>\n </div>\n\n <PagePurpose className=\"max-w-3xl\">\n The full terms of this offer with a live EMI estimate at the bank's headline rate. Model your loan amount and\n tenure to see the real monthly cost, then apply to connect with {loan.bankName} through Messages.\n </PagePurpose>\n\n {loan.specialOffer && (\n <div className=\"flex items-center gap-2 rounded-lg bg-status-warning-bg-subtle p-3 text-sm text-status-warning-text\">\n <Gift className=\"h-4 w-4 shrink-0\" />\n {loan.specialOffer}\n </div>\n )}\n\n {/* EMI summary — primary emphasis zone (one per page) */}\n <EmphasisPanel className=\"p-5\">\n <div className=\"mb-4 flex items-center gap-2\">\n <Calculator className=\"h-5 w-5 text-text-secondary\" />\n <h2 className=\"text-lg font-semibold text-text-primary\">EMI Estimate at {loan.interestRate}%</h2>\n </div>\n <div className=\"grid gap-6 md:grid-cols-2\">\n <div className=\"space-y-5\">\n <div>\n <div className=\"mb-2 flex items-center justify-between\">\n <label className=\"text-sm font-medium text-text-primary\">Loan Amount</label>\n <span className=\"text-sm font-semibold text-text-primary\">{formatCurrency(amount)}</span>\n </div>\n <input\n type=\"range\"\n min={50000}\n max={Math.max(loan.maxAmount, 100000)}\n step={10000}\n value={Math.min(amount, loan.maxAmount)}\n onChange={(e) => setAmount(Number(e.target.value))}\n className=\"w-full accent-foreground\"\n />\n <div className=\"mt-1 flex justify-between text-xs text-text-secondary\">\n <span>$50K</span>\n <span>Max {formatCurrency(loan.maxAmount)}</span>\n </div>\n </div>\n <div>\n <div className=\"mb-2 flex items-center justify-between\">\n <label className=\"text-sm font-medium text-text-primary\">Tenure (years)</label>\n <span className=\"text-sm font-semibold text-text-primary\">{tenure} years</span>\n </div>\n <input\n type=\"range\"\n min={1}\n max={loan.maxTenure}\n step={1}\n value={Math.min(tenure, loan.maxTenure)}\n onChange={(e) => setTenure(Number(e.target.value))}\n className=\"w-full accent-foreground\"\n />\n <div className=\"mt-1 flex justify-between text-xs text-text-secondary\">\n <span>1 yr</span>\n <span>Max {loan.maxTenure} yrs</span>\n </div>\n </div>\n </div>\n <div className=\"flex flex-col items-center justify-center rounded-lg bg-bg-sunken/50 p-6\">\n <p className=\"text-sm text-text-secondary\">Monthly EMI</p>\n <p className=\"my-2 text-4xl font-bold text-text-primary\">{formatCurrency(emi)}</p>\n <div className=\"mt-4 grid w-full grid-cols-2 gap-4\">\n <div className=\"text-center\">\n <p className=\"text-xs text-text-secondary\">Total Payment</p>\n <p className=\"text-sm font-semibold text-text-primary\">{formatCurrency(totalPayment)}</p>\n </div>\n <div className=\"text-center\">\n <p className=\"text-xs text-text-secondary\">Total Interest</p>\n <p className=\"text-sm font-semibold text-status-error-text\">{formatCurrency(totalInterest)}</p>\n </div>\n </div>\n </div>\n </div>\n </EmphasisPanel>\n\n <div className=\"grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Terms */}\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 text-base font-semibold text-text-primary\">Loan Terms</h2>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3\">\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <div className=\"flex items-center gap-1.5 text-xs text-text-secondary\">\n <Percent className=\"h-3.5 w-3.5\" />\n Interest Rate\n </div>\n <div className=\"mt-1 text-lg font-bold text-text-primary\">{loan.interestRate}%</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <div className=\"flex items-center gap-1.5 text-xs text-text-secondary\">\n <Wallet className=\"h-3.5 w-3.5\" />\n EMI / Lakh\n </div>\n <div className=\"mt-1 text-lg font-bold text-text-primary\">\n {loan.emiPerLakh != null ? `$${loan.emiPerLakh}` : '—'}\n </div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <div className=\"flex items-center gap-1.5 text-xs text-text-secondary\">\n <CalendarClock className=\"h-3.5 w-3.5\" />\n Max Tenure\n </div>\n <div className=\"mt-1 text-lg font-bold text-text-primary\">{loan.maxTenure} yrs</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <div className=\"text-xs text-text-secondary\">Max Amount</div>\n <div className=\"mt-1 text-sm font-semibold text-text-primary\">{formatCurrency(loan.maxAmount)}</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <div className=\"text-xs text-text-secondary\">Processing Fee</div>\n <div className=\"mt-1 text-sm font-semibold text-text-primary\">{loan.processingFee ?? '—'}</div>\n </div>\n <div className=\"rounded-lg bg-bg-sunken/50 p-4\">\n <div className=\"text-xs text-text-secondary\">Prepayment</div>\n <div\n className={cn(\n 'mt-1 text-sm font-semibold',\n loan.prepaymentCharges === 'None' ? 'text-status-success-text' : 'text-text-primary'\n )}\n >\n {loan.prepaymentCharges ?? '—'}\n </div>\n </div>\n </div>\n </GlassCard>\n\n {features.length > 0 && (\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-6\">\n <h2 className=\"mb-4 text-base font-semibold text-text-primary\">Features</h2>\n <ul className=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n {features.map((feature, i) => (\n <li key={i} className=\"flex items-center gap-2 text-sm text-text-secondary\">\n <CheckCircle className=\"h-4 w-4 shrink-0 text-status-success-text\" />\n {feature}\n </li>\n ))}\n </ul>\n </GlassCard>\n )}\n </div>\n\n {/* Apply card */}\n <div className=\"space-y-6\">\n <GlassCard treatment=\"plain\" className=\"border-border-seam p-5\">\n <h3 className=\"mb-2 text-base font-semibold text-text-primary\">Ready to apply?</h3>\n <p className=\"mb-4 text-sm text-text-secondary\">\n Applications are handled directly with {loan.bankName} through HousingVista Messages. Start an enquiry and\n the bank will guide you through eligibility and paperwork.\n </p>\n <Button\n type=\"button\"\n variant=\"default\"\n className=\"w-full justify-center\"\n onClick={() => setContactOpen(true)}\n >\n Apply Now\n </Button>\n </GlassCard>\n </div>\n </div>\n\n <ContactOwnerDialog\n open={contactOpen}\n onOpenChange={setContactOpen}\n entityId={loan.id}\n entityType=\"housingvista-home-loan\"\n title={loan.bankName}\n pagePath={location.pathname}\n heading={`Apply with ${loan.bankName}`}\n description={`Start your application with ${loan.bankName}. Messages are saved and delivered in your inbox.`}\n />\n </div>\n );\n}\n"],"mappings":"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"}
|