@burdenoff/microfe-housingvista 2026.703.7 → 2026.703.9
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/components/ContactOwnerDialog.js +45 -43
- package/dist/housingvista/components/ContactOwnerDialog.js.map +1 -1
- package/dist/housingvista/pages/finance/HomeLoanDetailPage.js +67 -71
- package/dist/housingvista/pages/finance/HomeLoanDetailPage.js.map +1 -1
- package/dist/housingvista/pages/legal/LegalServiceDetailPage.js +97 -101
- package/dist/housingvista/pages/legal/LegalServiceDetailPage.js.map +1 -1
- package/dist/housingvista/pages/marketplace/ServiceDetailPage.js +94 -98
- package/dist/housingvista/pages/marketplace/ServiceDetailPage.js.map +1 -1
- package/dist/housingvista/pages/properties/PropertyDetailPage.js +376 -379
- package/dist/housingvista/pages/properties/PropertyDetailPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -7,65 +7,67 @@ import { useEffect as o, useRef as s, useState as c } from "react";
|
|
|
7
7
|
import { Send as l } from "lucide-react";
|
|
8
8
|
import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
9
9
|
import { Button as p, ResponsiveDialog as m, ResponsiveDialogContent as h, ResponsiveDialogDescription as g, ResponsiveDialogHeader as _, ResponsiveDialogTitle as v } from "@burdenoff/fe-libs/ui";
|
|
10
|
+
import { createPortal as y } from "react-dom";
|
|
10
11
|
//#region src/housingvista/components/ContactOwnerDialog.tsx
|
|
11
|
-
var
|
|
12
|
-
let { currentUser:
|
|
12
|
+
var b = ({ entityId: b, entityType: x, title: S, pagePath: C, triggerContent: w, triggerVariant: T = "outline", triggerClassName: E, heading: D = "Contact", description: O }) => {
|
|
13
|
+
let { currentUser: k } = e(), { openConversation: A, loading: j } = n(), { sendMessage: M, loading: N } = i(), [P, F] = c(!1), [I, L] = c(), [R, z] = c(""), { data: B, loading: V } = r(I), H = s(null);
|
|
13
14
|
o(() => {
|
|
14
|
-
if (!
|
|
15
|
+
if (!P || I) return;
|
|
15
16
|
let e = !1;
|
|
16
|
-
return
|
|
17
|
-
entityId:
|
|
18
|
-
entityType:
|
|
19
|
-
title:
|
|
20
|
-
contextHref:
|
|
21
|
-
pagePath:
|
|
17
|
+
return A({
|
|
18
|
+
entityId: b,
|
|
19
|
+
entityType: x,
|
|
20
|
+
title: S,
|
|
21
|
+
contextHref: C,
|
|
22
|
+
pagePath: C
|
|
22
23
|
}).then((t) => {
|
|
23
|
-
e ||
|
|
24
|
+
e || L(t.id);
|
|
24
25
|
}).catch((e) => a.error("Could not open the conversation", e.message)), () => {
|
|
25
26
|
e = !0;
|
|
26
27
|
};
|
|
27
28
|
}, [
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
y,
|
|
29
|
+
P,
|
|
30
|
+
I,
|
|
31
|
+
A,
|
|
32
32
|
b,
|
|
33
33
|
x,
|
|
34
|
-
S
|
|
34
|
+
S,
|
|
35
|
+
C
|
|
35
36
|
]), o(() => {
|
|
36
|
-
|
|
37
|
-
}, [
|
|
38
|
-
let
|
|
39
|
-
let e =
|
|
40
|
-
if (!(!e || !
|
|
41
|
-
await
|
|
37
|
+
H.current?.scrollTo({ top: H.current.scrollHeight });
|
|
38
|
+
}, [B]);
|
|
39
|
+
let U = async () => {
|
|
40
|
+
let e = R.trim();
|
|
41
|
+
if (!(!e || !I)) try {
|
|
42
|
+
await M(I, e), z("");
|
|
42
43
|
} catch (e) {
|
|
43
44
|
a.error("Message not sent", e.message);
|
|
44
45
|
}
|
|
45
|
-
},
|
|
46
|
-
return /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
}, W = k?.id ?? "";
|
|
47
|
+
return /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d(p, {
|
|
48
|
+
type: "button",
|
|
49
|
+
variant: T,
|
|
50
|
+
className: E,
|
|
51
|
+
onClick: () => F(!0),
|
|
52
|
+
children: w
|
|
53
|
+
}), y(/* @__PURE__ */ d(m, {
|
|
54
|
+
open: P,
|
|
55
|
+
onOpenChange: F,
|
|
54
56
|
children: /* @__PURE__ */ f(h, {
|
|
55
57
|
className: "sm:max-w-lg",
|
|
56
58
|
children: [
|
|
57
|
-
/* @__PURE__ */ f(_, { children: [/* @__PURE__ */ d(v, { children:
|
|
59
|
+
/* @__PURE__ */ f(_, { children: [/* @__PURE__ */ d(v, { children: D }), /* @__PURE__ */ d(g, { children: O ?? `Start a conversation about ${S}. Messages are saved and delivered in your inbox.` })] }),
|
|
58
60
|
/* @__PURE__ */ d("div", {
|
|
59
|
-
ref:
|
|
61
|
+
ref: H,
|
|
60
62
|
className: "max-h-72 min-h-40 space-y-2 overflow-y-auto rounded-md border border-border-subtle bg-bg-sunken p-3",
|
|
61
|
-
children:
|
|
63
|
+
children: j || V ? /* @__PURE__ */ d("p", {
|
|
62
64
|
className: "py-8 text-center text-sm text-text-secondary",
|
|
63
65
|
children: "Loading conversation…"
|
|
64
|
-
}) :
|
|
66
|
+
}) : B.length === 0 ? /* @__PURE__ */ d("p", {
|
|
65
67
|
className: "py-8 text-center text-sm text-text-secondary",
|
|
66
68
|
children: "No messages yet. Say hello to get the conversation started."
|
|
67
|
-
}) :
|
|
68
|
-
let n = e.authorId ===
|
|
69
|
+
}) : B.map((e) => {
|
|
70
|
+
let n = e.authorId === W;
|
|
69
71
|
return /* @__PURE__ */ d("div", {
|
|
70
72
|
className: t("flex", n ? "justify-end" : "justify-start"),
|
|
71
73
|
children: /* @__PURE__ */ d("div", {
|
|
@@ -78,18 +80,18 @@ var y = ({ entityId: y, entityType: b, title: x, pagePath: S, trigger: C, headin
|
|
|
78
80
|
/* @__PURE__ */ f("div", {
|
|
79
81
|
className: "mt-3 flex items-end gap-2",
|
|
80
82
|
children: [/* @__PURE__ */ d("textarea", {
|
|
81
|
-
value:
|
|
82
|
-
onChange: (e) =>
|
|
83
|
+
value: R,
|
|
84
|
+
onChange: (e) => z(e.target.value),
|
|
83
85
|
onKeyDown: (e) => {
|
|
84
|
-
e.key === "Enter" && !e.shiftKey && (e.preventDefault(),
|
|
86
|
+
e.key === "Enter" && !e.shiftKey && (e.preventDefault(), U());
|
|
85
87
|
},
|
|
86
88
|
rows: 2,
|
|
87
89
|
placeholder: "Write a message…",
|
|
88
90
|
className: "min-h-10 flex-1 resize-none rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]"
|
|
89
91
|
}), /* @__PURE__ */ f(p, {
|
|
90
92
|
type: "button",
|
|
91
|
-
onClick:
|
|
92
|
-
disabled: !
|
|
93
|
+
onClick: U,
|
|
94
|
+
disabled: !R.trim() || !I || N,
|
|
93
95
|
children: [/* @__PURE__ */ d(l, { className: "h-4 w-4" }), /* @__PURE__ */ d("span", {
|
|
94
96
|
className: "ml-1",
|
|
95
97
|
children: "Send"
|
|
@@ -98,9 +100,9 @@ var y = ({ entityId: y, entityType: b, title: x, pagePath: S, trigger: C, headin
|
|
|
98
100
|
})
|
|
99
101
|
]
|
|
100
102
|
})
|
|
101
|
-
})] });
|
|
103
|
+
}), document.body)] });
|
|
102
104
|
};
|
|
103
105
|
//#endregion
|
|
104
|
-
export {
|
|
106
|
+
export { b as ContactOwnerDialog };
|
|
105
107
|
|
|
106
108
|
//# sourceMappingURL=ContactOwnerDialog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContactOwnerDialog.js","names":[],"sources":["../../../src/housingvista/components/ContactOwnerDialog.tsx"],"sourcesContent":["/**\n * Real messaging surface backed by wspace-conversations-svc. Any \"Contact /\n * Message / Apply / Contact Owner\" CTA renders this: it resolves (get-or-create)\n * the entity's conversation, shows the persisted thread, and posts messages via\n * `sendMessage`. No stub, no dead-end — everything is persisted server-side.\n * @module housingvista\n */\n\nimport { useEffect, useRef, useState, type FC, type ReactNode } from 'react';\nimport { Send } from 'lucide-react';\nimport {\n Button,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n} from '@burdenoff/fe-libs/ui';\nimport { useContactConversation, useConversationMessages, useSendMessage } from '../hooks';\nimport { useHousingVista } from '../context/HousingVistaContext';\nimport { notify } from '../lib/toast';\nimport { cn } from '../utils/helpers';\n\ninterface ContactOwnerDialogProps {\n /** Stable id of the thing being discussed (property/service/listing id). */\n entityId: string;\n /** e.g. `housingvista-property`, `housingvista-marketplace-service`. */\n entityType: string;\n /** Title used when the conversation is first created. */\n title: string;\n /** Router path back into this surface (deep link). */\n pagePath: string;\n /**
|
|
1
|
+
{"version":3,"file":"ContactOwnerDialog.js","names":[],"sources":["../../../src/housingvista/components/ContactOwnerDialog.tsx"],"sourcesContent":["/**\n * Real messaging surface backed by wspace-conversations-svc. Any \"Contact /\n * Message / Apply / Contact Owner\" CTA renders this: it resolves (get-or-create)\n * the entity's conversation, shows the persisted thread, and posts messages via\n * `sendMessage`. No stub, no dead-end — everything is persisted server-side.\n * @module housingvista\n */\n\nimport { useEffect, useRef, useState, type FC, type ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport { Send } from 'lucide-react';\nimport {\n Button,\n type ButtonProps,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n} from '@burdenoff/fe-libs/ui';\nimport { useContactConversation, useConversationMessages, useSendMessage } from '../hooks';\nimport { useHousingVista } from '../context/HousingVistaContext';\nimport { notify } from '../lib/toast';\nimport { cn } from '../utils/helpers';\n\ninterface ContactOwnerDialogProps {\n /** Stable id of the thing being discussed (property/service/listing id). */\n entityId: string;\n /** e.g. `housingvista-property`, `housingvista-marketplace-service`. */\n entityType: string;\n /** Title used when the conversation is first created. */\n title: string;\n /** Router path back into this surface (deep link). */\n pagePath: string;\n /** Inner content of the trigger button (icon + label). */\n triggerContent: ReactNode;\n /** Trigger button variant (defaults to `outline`). */\n triggerVariant?: ButtonProps['variant'];\n /** Extra classes for the trigger button. */\n triggerClassName?: string;\n /** Dialog heading, defaults to \"Contact\". */\n heading?: string;\n description?: string;\n}\n\nexport const ContactOwnerDialog: FC<ContactOwnerDialogProps> = ({\n entityId,\n entityType,\n title,\n pagePath,\n triggerContent,\n triggerVariant = 'outline',\n triggerClassName,\n heading = 'Contact',\n description,\n}) => {\n const { currentUser } = useHousingVista();\n const { openConversation, loading: opening } = useContactConversation();\n const { sendMessage, loading: sending } = useSendMessage();\n const [open, setOpen] = useState(false);\n const [conversationId, setConversationId] = useState<string | undefined>();\n const [draft, setDraft] = useState('');\n const { data: messages, loading: loadingMessages } = useConversationMessages(conversationId);\n const scrollRef = useRef<HTMLDivElement>(null);\n\n // Resolve the conversation the first time the dialog opens.\n useEffect(() => {\n if (!open || conversationId) return;\n let cancelled = false;\n openConversation({\n entityId,\n entityType,\n title,\n contextHref: pagePath,\n pagePath,\n })\n .then((res) => {\n if (!cancelled) setConversationId(res.id);\n })\n .catch((err: Error) => notify.error('Could not open the conversation', err.message));\n return () => {\n cancelled = true;\n };\n }, [open, conversationId, openConversation, entityId, entityType, title, pagePath]);\n\n useEffect(() => {\n scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight });\n }, [messages]);\n\n const handleSend = async () => {\n const text = draft.trim();\n if (!text || !conversationId) return;\n try {\n await sendMessage(conversationId, text);\n setDraft('');\n } catch (err) {\n notify.error('Message not sent', (err as Error).message);\n }\n };\n\n const currentUserId = currentUser?.id ?? '';\n\n // Render the trigger as a real Button with a direct onClick — the exact\n // controlled-open pattern the in-page dialogs (e.g. Make Offer) use. Passing a\n // pre-built element through ResponsiveDialogTrigger asChild / cloneElement /\n // a display:contents wrapper all failed to forward the click in production.\n return (\n <>\n <Button type=\"button\" variant={triggerVariant} className={triggerClassName} onClick={() => setOpen(true)}>\n {triggerContent}\n </Button>\n {createPortal(\n <ResponsiveDialog open={open} onOpenChange={setOpen}>\n <ResponsiveDialogContent className=\"sm:max-w-lg\">\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>{heading}</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {description ?? `Start a conversation about ${title}. Messages are saved and delivered in your inbox.`}\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div\n ref={scrollRef}\n className=\"max-h-72 min-h-40 space-y-2 overflow-y-auto rounded-md border border-border-subtle bg-bg-sunken p-3\"\n >\n {opening || loadingMessages ? (\n <p className=\"py-8 text-center text-sm text-text-secondary\">Loading conversation…</p>\n ) : messages.length === 0 ? (\n <p className=\"py-8 text-center text-sm text-text-secondary\">\n No messages yet. Say hello to get the conversation started.\n </p>\n ) : (\n messages.map((message) => {\n const mine = message.authorId === currentUserId;\n return (\n <div key={message.id} className={cn('flex', mine ? 'justify-end' : 'justify-start')}>\n <div\n className={cn(\n 'max-w-[80%] rounded-lg px-3 py-2 text-sm',\n mine\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-surface text-text-primary border border-border-subtle'\n )}\n >\n {message.text}\n </div>\n </div>\n );\n })\n )}\n </div>\n\n <div className=\"mt-3 flex items-end gap-2\">\n <textarea\n value={draft}\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n void handleSend();\n }\n }}\n rows={2}\n placeholder=\"Write a message…\"\n className=\"min-h-10 flex-1 resize-none rounded-md border border-border-subtle bg-bg-surface px-3 py-2 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n />\n <Button type=\"button\" onClick={handleSend} disabled={!draft.trim() || !conversationId || sending}>\n <Send className=\"h-4 w-4\" />\n <span className=\"ml-1\">Send</span>\n </Button>\n </div>\n </ResponsiveDialogContent>\n </ResponsiveDialog>,\n document.body\n )}\n </>\n );\n};\n"],"mappings":"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"}
|
|
@@ -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 { EmphasisPanel as w, GlassCard as T, PagePurpose as E } from "@burdenoff/fe-libs/ui";
|
|
14
14
|
//#region src/housingvista/pages/finance/HomeLoanDetailPage.tsx
|
|
15
|
-
function
|
|
15
|
+
function D(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 O({ 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 k() {
|
|
27
|
+
let { id: _ } = x(), k = b(), A = y(), { data: j, loading: M } = o(_), [N, P] = l(5e5), [F, I] = l(20), L = j?.interestRate ?? 0, R = c(() => D(N, L, F), [
|
|
28
|
+
N,
|
|
29
|
+
L,
|
|
30
|
+
F
|
|
31
|
+
]), z = R * F * 12, B = z - N;
|
|
32
|
+
if (M) return /* @__PURE__ */ S("div", {
|
|
33
33
|
className: "p-6",
|
|
34
34
|
children: /* @__PURE__ */ S(a, { variant: "detail" })
|
|
35
35
|
});
|
|
36
|
-
if (!
|
|
36
|
+
if (!j) 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 A() {
|
|
|
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: () => k("../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 V = j.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: j.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,54 +64,52 @@ function A() {
|
|
|
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: () => k("../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: j.bankName
|
|
74
74
|
}),
|
|
75
75
|
/* @__PURE__ */ C("div", {
|
|
76
76
|
className: "mt-2 flex flex-wrap items-center gap-2",
|
|
77
|
-
children: [
|
|
77
|
+
children: [j.rating != null && /* @__PURE__ */ C("span", {
|
|
78
78
|
className: "inline-flex items-center gap-1.5",
|
|
79
|
-
children: [/* @__PURE__ */ S(
|
|
79
|
+
children: [/* @__PURE__ */ S(O, { rating: j.rating }), /* @__PURE__ */ S("span", {
|
|
80
80
|
className: "text-sm text-text-secondary",
|
|
81
|
-
children:
|
|
81
|
+
children: j.rating
|
|
82
82
|
})]
|
|
83
|
-
}),
|
|
83
|
+
}), j.specialOffer && /* @__PURE__ */ S(n, {
|
|
84
84
|
label: "Special Offer",
|
|
85
85
|
variant: "warning"
|
|
86
86
|
})]
|
|
87
87
|
})
|
|
88
88
|
] })]
|
|
89
89
|
}), /* @__PURE__ */ S(s, {
|
|
90
|
-
entityId:
|
|
90
|
+
entityId: j.id,
|
|
91
91
|
entityType: "housingvista-home-loan",
|
|
92
|
-
title:
|
|
93
|
-
pagePath:
|
|
94
|
-
heading: `Apply with ${
|
|
95
|
-
description: `Start your application with ${
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
children: "Apply Now"
|
|
99
|
-
})
|
|
92
|
+
title: j.bankName,
|
|
93
|
+
pagePath: A.pathname,
|
|
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"
|
|
100
98
|
})]
|
|
101
99
|
}),
|
|
102
|
-
/* @__PURE__ */ C(
|
|
100
|
+
/* @__PURE__ */ C(E, {
|
|
103
101
|
className: "max-w-3xl",
|
|
104
102
|
children: [
|
|
105
103
|
"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 ",
|
|
106
|
-
|
|
104
|
+
j.bankName,
|
|
107
105
|
" through Messages."
|
|
108
106
|
]
|
|
109
107
|
}),
|
|
110
|
-
|
|
108
|
+
j.specialOffer && /* @__PURE__ */ C("div", {
|
|
111
109
|
className: "flex items-center gap-2 rounded-lg bg-status-warning-bg-subtle p-3 text-sm text-status-warning-text",
|
|
112
|
-
children: [/* @__PURE__ */ S(h, { className: "h-4 w-4 shrink-0" }),
|
|
110
|
+
children: [/* @__PURE__ */ S(h, { className: "h-4 w-4 shrink-0" }), j.specialOffer]
|
|
113
111
|
}),
|
|
114
|
-
/* @__PURE__ */ C(
|
|
112
|
+
/* @__PURE__ */ C(w, {
|
|
115
113
|
className: "p-5",
|
|
116
114
|
children: [/* @__PURE__ */ C("div", {
|
|
117
115
|
className: "mb-4 flex items-center gap-2",
|
|
@@ -119,7 +117,7 @@ function A() {
|
|
|
119
117
|
className: "text-lg font-semibold text-text-primary",
|
|
120
118
|
children: [
|
|
121
119
|
"EMI Estimate at ",
|
|
122
|
-
|
|
120
|
+
j.interestRate,
|
|
123
121
|
"%"
|
|
124
122
|
]
|
|
125
123
|
})]
|
|
@@ -135,21 +133,21 @@ function A() {
|
|
|
135
133
|
children: "Loan Amount"
|
|
136
134
|
}), /* @__PURE__ */ S("span", {
|
|
137
135
|
className: "text-sm font-semibold text-text-primary",
|
|
138
|
-
children: t(
|
|
136
|
+
children: t(N)
|
|
139
137
|
})]
|
|
140
138
|
}),
|
|
141
139
|
/* @__PURE__ */ S("input", {
|
|
142
140
|
type: "range",
|
|
143
141
|
min: 5e4,
|
|
144
|
-
max: Math.max(
|
|
142
|
+
max: Math.max(j.maxAmount, 1e5),
|
|
145
143
|
step: 1e4,
|
|
146
|
-
value: Math.min(
|
|
147
|
-
onChange: (e) =>
|
|
144
|
+
value: Math.min(N, j.maxAmount),
|
|
145
|
+
onChange: (e) => P(Number(e.target.value)),
|
|
148
146
|
className: "w-full accent-foreground"
|
|
149
147
|
}),
|
|
150
148
|
/* @__PURE__ */ C("div", {
|
|
151
149
|
className: "mt-1 flex justify-between text-xs text-text-secondary",
|
|
152
|
-
children: [/* @__PURE__ */ S("span", { children: "$50K" }), /* @__PURE__ */ C("span", { children: ["Max ", t(
|
|
150
|
+
children: [/* @__PURE__ */ S("span", { children: "$50K" }), /* @__PURE__ */ C("span", { children: ["Max ", t(j.maxAmount)] })]
|
|
153
151
|
})
|
|
154
152
|
] }), /* @__PURE__ */ C("div", { children: [
|
|
155
153
|
/* @__PURE__ */ C("div", {
|
|
@@ -159,23 +157,23 @@ function A() {
|
|
|
159
157
|
children: "Tenure (years)"
|
|
160
158
|
}), /* @__PURE__ */ C("span", {
|
|
161
159
|
className: "text-sm font-semibold text-text-primary",
|
|
162
|
-
children: [
|
|
160
|
+
children: [F, " years"]
|
|
163
161
|
})]
|
|
164
162
|
}),
|
|
165
163
|
/* @__PURE__ */ S("input", {
|
|
166
164
|
type: "range",
|
|
167
165
|
min: 1,
|
|
168
|
-
max:
|
|
166
|
+
max: j.maxTenure,
|
|
169
167
|
step: 1,
|
|
170
|
-
value: Math.min(
|
|
171
|
-
onChange: (e) =>
|
|
168
|
+
value: Math.min(F, j.maxTenure),
|
|
169
|
+
onChange: (e) => I(Number(e.target.value)),
|
|
172
170
|
className: "w-full accent-foreground"
|
|
173
171
|
}),
|
|
174
172
|
/* @__PURE__ */ C("div", {
|
|
175
173
|
className: "mt-1 flex justify-between text-xs text-text-secondary",
|
|
176
174
|
children: [/* @__PURE__ */ S("span", { children: "1 yr" }), /* @__PURE__ */ C("span", { children: [
|
|
177
175
|
"Max ",
|
|
178
|
-
|
|
176
|
+
j.maxTenure,
|
|
179
177
|
" yrs"
|
|
180
178
|
] })]
|
|
181
179
|
})
|
|
@@ -189,7 +187,7 @@ function A() {
|
|
|
189
187
|
}),
|
|
190
188
|
/* @__PURE__ */ S("p", {
|
|
191
189
|
className: "my-2 text-4xl font-bold text-text-primary",
|
|
192
|
-
children: t(
|
|
190
|
+
children: t(R)
|
|
193
191
|
}),
|
|
194
192
|
/* @__PURE__ */ C("div", {
|
|
195
193
|
className: "mt-4 grid w-full grid-cols-2 gap-4",
|
|
@@ -200,7 +198,7 @@ function A() {
|
|
|
200
198
|
children: "Total Payment"
|
|
201
199
|
}), /* @__PURE__ */ S("p", {
|
|
202
200
|
className: "text-sm font-semibold text-text-primary",
|
|
203
|
-
children: t(
|
|
201
|
+
children: t(z)
|
|
204
202
|
})]
|
|
205
203
|
}), /* @__PURE__ */ C("div", {
|
|
206
204
|
className: "text-center",
|
|
@@ -209,7 +207,7 @@ function A() {
|
|
|
209
207
|
children: "Total Interest"
|
|
210
208
|
}), /* @__PURE__ */ S("p", {
|
|
211
209
|
className: "text-sm font-semibold text-status-error-text",
|
|
212
|
-
children: t(
|
|
210
|
+
children: t(B)
|
|
213
211
|
})]
|
|
214
212
|
})]
|
|
215
213
|
})
|
|
@@ -221,7 +219,7 @@ function A() {
|
|
|
221
219
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-3",
|
|
222
220
|
children: [/* @__PURE__ */ C("div", {
|
|
223
221
|
className: "space-y-6 lg:col-span-2",
|
|
224
|
-
children: [/* @__PURE__ */ C(
|
|
222
|
+
children: [/* @__PURE__ */ C(T, {
|
|
225
223
|
treatment: "plain",
|
|
226
224
|
className: "border-border-seam p-6",
|
|
227
225
|
children: [/* @__PURE__ */ S("h2", {
|
|
@@ -237,7 +235,7 @@ function A() {
|
|
|
237
235
|
children: [/* @__PURE__ */ S(g, { className: "h-3.5 w-3.5" }), "Interest Rate"]
|
|
238
236
|
}), /* @__PURE__ */ C("div", {
|
|
239
237
|
className: "mt-1 text-lg font-bold text-text-primary",
|
|
240
|
-
children: [
|
|
238
|
+
children: [j.interestRate, "%"]
|
|
241
239
|
})]
|
|
242
240
|
}),
|
|
243
241
|
/* @__PURE__ */ C("div", {
|
|
@@ -247,7 +245,7 @@ function A() {
|
|
|
247
245
|
children: [/* @__PURE__ */ S(v, { className: "h-3.5 w-3.5" }), "EMI / Lakh"]
|
|
248
246
|
}), /* @__PURE__ */ S("div", {
|
|
249
247
|
className: "mt-1 text-lg font-bold text-text-primary",
|
|
250
|
-
children:
|
|
248
|
+
children: j.emiPerLakh == null ? "—" : `$${j.emiPerLakh}`
|
|
251
249
|
})]
|
|
252
250
|
}),
|
|
253
251
|
/* @__PURE__ */ C("div", {
|
|
@@ -257,7 +255,7 @@ function A() {
|
|
|
257
255
|
children: [/* @__PURE__ */ S(p, { className: "h-3.5 w-3.5" }), "Max Tenure"]
|
|
258
256
|
}), /* @__PURE__ */ C("div", {
|
|
259
257
|
className: "mt-1 text-lg font-bold text-text-primary",
|
|
260
|
-
children: [
|
|
258
|
+
children: [j.maxTenure, " yrs"]
|
|
261
259
|
})]
|
|
262
260
|
}),
|
|
263
261
|
/* @__PURE__ */ C("div", {
|
|
@@ -267,7 +265,7 @@ function A() {
|
|
|
267
265
|
children: "Max Amount"
|
|
268
266
|
}), /* @__PURE__ */ S("div", {
|
|
269
267
|
className: "mt-1 text-sm font-semibold text-text-primary",
|
|
270
|
-
children: t(
|
|
268
|
+
children: t(j.maxAmount)
|
|
271
269
|
})]
|
|
272
270
|
}),
|
|
273
271
|
/* @__PURE__ */ C("div", {
|
|
@@ -277,7 +275,7 @@ function A() {
|
|
|
277
275
|
children: "Processing Fee"
|
|
278
276
|
}), /* @__PURE__ */ S("div", {
|
|
279
277
|
className: "mt-1 text-sm font-semibold text-text-primary",
|
|
280
|
-
children:
|
|
278
|
+
children: j.processingFee ?? "—"
|
|
281
279
|
})]
|
|
282
280
|
}),
|
|
283
281
|
/* @__PURE__ */ C("div", {
|
|
@@ -286,13 +284,13 @@ function A() {
|
|
|
286
284
|
className: "text-xs text-text-secondary",
|
|
287
285
|
children: "Prepayment"
|
|
288
286
|
}), /* @__PURE__ */ S("div", {
|
|
289
|
-
className: e("mt-1 text-sm font-semibold",
|
|
290
|
-
children:
|
|
287
|
+
className: e("mt-1 text-sm font-semibold", j.prepaymentCharges === "None" ? "text-status-success-text" : "text-text-primary"),
|
|
288
|
+
children: j.prepaymentCharges ?? "—"
|
|
291
289
|
})]
|
|
292
290
|
})
|
|
293
291
|
]
|
|
294
292
|
})]
|
|
295
|
-
}),
|
|
293
|
+
}), V.length > 0 && /* @__PURE__ */ C(T, {
|
|
296
294
|
treatment: "plain",
|
|
297
295
|
className: "border-border-seam p-6",
|
|
298
296
|
children: [/* @__PURE__ */ S("h2", {
|
|
@@ -300,7 +298,7 @@ function A() {
|
|
|
300
298
|
children: "Features"
|
|
301
299
|
}), /* @__PURE__ */ S("ul", {
|
|
302
300
|
className: "grid grid-cols-1 gap-2 sm:grid-cols-2",
|
|
303
|
-
children:
|
|
301
|
+
children: V.map((e, t) => /* @__PURE__ */ C("li", {
|
|
304
302
|
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
305
303
|
children: [/* @__PURE__ */ S(m, { className: "h-4 w-4 shrink-0 text-status-success-text" }), e]
|
|
306
304
|
}, t))
|
|
@@ -308,7 +306,7 @@ function A() {
|
|
|
308
306
|
})]
|
|
309
307
|
}), /* @__PURE__ */ S("div", {
|
|
310
308
|
className: "space-y-6",
|
|
311
|
-
children: /* @__PURE__ */ C(
|
|
309
|
+
children: /* @__PURE__ */ C(T, {
|
|
312
310
|
treatment: "plain",
|
|
313
311
|
className: "border-border-seam p-5",
|
|
314
312
|
children: [
|
|
@@ -320,22 +318,20 @@ function A() {
|
|
|
320
318
|
className: "mb-4 text-sm text-text-secondary",
|
|
321
319
|
children: [
|
|
322
320
|
"Applications are handled directly with ",
|
|
323
|
-
|
|
321
|
+
j.bankName,
|
|
324
322
|
" through HousingVista Messages. Start an enquiry and the bank will guide you through eligibility and paperwork."
|
|
325
323
|
]
|
|
326
324
|
}),
|
|
327
325
|
/* @__PURE__ */ S(s, {
|
|
328
|
-
entityId:
|
|
326
|
+
entityId: j.id,
|
|
329
327
|
entityType: "housingvista-home-loan",
|
|
330
|
-
title:
|
|
331
|
-
pagePath:
|
|
332
|
-
heading: `Apply with ${
|
|
333
|
-
description: `Start your application with ${
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
children: "Apply Now"
|
|
338
|
-
})
|
|
328
|
+
title: j.bankName,
|
|
329
|
+
pagePath: A.pathname,
|
|
330
|
+
heading: `Apply with ${j.bankName}`,
|
|
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"
|
|
339
335
|
})
|
|
340
336
|
]
|
|
341
337
|
})
|
|
@@ -345,6 +341,6 @@ function A() {
|
|
|
345
341
|
});
|
|
346
342
|
}
|
|
347
343
|
//#endregion
|
|
348
|
-
export {
|
|
344
|
+
export { k as HomeLoanDetailPage };
|
|
349
345
|
|
|
350
346
|
//# sourceMappingURL=HomeLoanDetailPage.js.map
|