@burdenoff/microfe-housingvista 2026.703.5 → 2026.703.6

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.
@@ -3,93 +3,94 @@ import { cn as t } from "../utils/helpers.js";
3
3
  import { useContactConversation as n, useConversationMessages as r, useSendMessage as i } from "../hooks/platform.js";
4
4
  import "../hooks/index.js";
5
5
  import { notify as a } from "../lib/toast.js";
6
- import { cloneElement as o, isValidElement as s, useEffect as c, useRef as l, useState as u } from "react";
7
- import { Send as d } from "lucide-react";
8
- import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
9
- import { Button as h, ResponsiveDialog as g, ResponsiveDialogContent as _, ResponsiveDialogDescription as v, ResponsiveDialogHeader as y, ResponsiveDialogTitle as b } from "@burdenoff/fe-libs/ui";
6
+ import { useEffect as o, useRef as s, useState as c } from "react";
7
+ import { Send as l } from "lucide-react";
8
+ import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
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
10
  //#region src/housingvista/components/ContactOwnerDialog.tsx
11
- var x = ({ entityId: x, entityType: S, title: C, pagePath: w, trigger: T, heading: E = "Contact", description: D }) => {
12
- let { currentUser: O } = e(), { openConversation: k, loading: A } = n(), { sendMessage: j, loading: M } = i(), [N, P] = u(!1), [F, I] = u(), [L, R] = u(""), { data: z, loading: B } = r(F), V = l(null);
13
- c(() => {
14
- if (!N || F) return;
11
+ var y = ({ entityId: y, entityType: b, title: x, pagePath: S, trigger: C, heading: w = "Contact", description: T }) => {
12
+ let { currentUser: E } = e(), { openConversation: D, loading: O } = n(), { sendMessage: k, loading: A } = i(), [j, M] = c(!1), [N, P] = c(), [F, I] = c(""), { data: L, loading: R } = r(N), z = s(null);
13
+ o(() => {
14
+ if (!j || N) return;
15
15
  let e = !1;
16
- return k({
17
- entityId: x,
18
- entityType: S,
19
- title: C,
20
- contextHref: w,
21
- pagePath: w
16
+ return D({
17
+ entityId: y,
18
+ entityType: b,
19
+ title: x,
20
+ contextHref: S,
21
+ pagePath: S
22
22
  }).then((t) => {
23
- e || I(t.id);
23
+ e || P(t.id);
24
24
  }).catch((e) => a.error("Could not open the conversation", e.message)), () => {
25
25
  e = !0;
26
26
  };
27
27
  }, [
28
+ j,
28
29
  N,
29
- F,
30
- k,
30
+ D,
31
+ y,
32
+ b,
31
33
  x,
32
- S,
33
- C,
34
- w
35
- ]), c(() => {
36
- V.current?.scrollTo({ top: V.current.scrollHeight });
37
- }, [z]);
38
- let H = async () => {
39
- let e = L.trim();
40
- if (!(!e || !F)) try {
41
- await j(F, e), R("");
34
+ S
35
+ ]), o(() => {
36
+ z.current?.scrollTo({ top: z.current.scrollHeight });
37
+ }, [L]);
38
+ let B = async () => {
39
+ let e = F.trim();
40
+ if (!(!e || !N)) try {
41
+ await k(N, e), I("");
42
42
  } catch (e) {
43
43
  a.error("Message not sent", e.message);
44
44
  }
45
- }, U = O?.id ?? "";
46
- return /* @__PURE__ */ m(f, { children: [s(T) ? o(T, { onClick: () => P(!0) }) : /* @__PURE__ */ p("button", {
47
- type: "button",
48
- onClick: () => P(!0),
49
- children: T
50
- }), /* @__PURE__ */ p(g, {
51
- open: N,
52
- onOpenChange: P,
53
- children: /* @__PURE__ */ m(_, {
45
+ }, V = E?.id ?? "";
46
+ return /* @__PURE__ */ f(u, { children: [/* @__PURE__ */ d("span", {
47
+ className: "contents",
48
+ role: "presentation",
49
+ onClick: () => M(!0),
50
+ children: C
51
+ }), /* @__PURE__ */ d(m, {
52
+ open: j,
53
+ onOpenChange: M,
54
+ children: /* @__PURE__ */ f(h, {
54
55
  className: "sm:max-w-lg",
55
56
  children: [
56
- /* @__PURE__ */ m(y, { children: [/* @__PURE__ */ p(b, { children: E }), /* @__PURE__ */ p(v, { children: D ?? `Start a conversation about ${C}. Messages are saved and delivered in your inbox.` })] }),
57
- /* @__PURE__ */ p("div", {
58
- ref: V,
57
+ /* @__PURE__ */ f(_, { children: [/* @__PURE__ */ d(v, { children: w }), /* @__PURE__ */ d(g, { children: T ?? `Start a conversation about ${x}. Messages are saved and delivered in your inbox.` })] }),
58
+ /* @__PURE__ */ d("div", {
59
+ ref: z,
59
60
  className: "max-h-72 min-h-40 space-y-2 overflow-y-auto rounded-md border border-border-subtle bg-bg-sunken p-3",
60
- children: A || B ? /* @__PURE__ */ p("p", {
61
+ children: O || R ? /* @__PURE__ */ d("p", {
61
62
  className: "py-8 text-center text-sm text-text-secondary",
62
63
  children: "Loading conversation…"
63
- }) : z.length === 0 ? /* @__PURE__ */ p("p", {
64
+ }) : L.length === 0 ? /* @__PURE__ */ d("p", {
64
65
  className: "py-8 text-center text-sm text-text-secondary",
65
66
  children: "No messages yet. Say hello to get the conversation started."
66
- }) : z.map((e) => {
67
- let n = e.authorId === U;
68
- return /* @__PURE__ */ p("div", {
67
+ }) : L.map((e) => {
68
+ let n = e.authorId === V;
69
+ return /* @__PURE__ */ d("div", {
69
70
  className: t("flex", n ? "justify-end" : "justify-start"),
70
- children: /* @__PURE__ */ p("div", {
71
+ children: /* @__PURE__ */ d("div", {
71
72
  className: t("max-w-[80%] rounded-lg px-3 py-2 text-sm", n ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-surface text-text-primary border border-border-subtle"),
72
73
  children: e.text
73
74
  })
74
75
  }, e.id);
75
76
  })
76
77
  }),
77
- /* @__PURE__ */ m("div", {
78
+ /* @__PURE__ */ f("div", {
78
79
  className: "mt-3 flex items-end gap-2",
79
- children: [/* @__PURE__ */ p("textarea", {
80
- value: L,
81
- onChange: (e) => R(e.target.value),
80
+ children: [/* @__PURE__ */ d("textarea", {
81
+ value: F,
82
+ onChange: (e) => I(e.target.value),
82
83
  onKeyDown: (e) => {
83
- e.key === "Enter" && !e.shiftKey && (e.preventDefault(), H());
84
+ e.key === "Enter" && !e.shiftKey && (e.preventDefault(), B());
84
85
  },
85
86
  rows: 2,
86
87
  placeholder: "Write a message…",
87
88
  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)]"
88
- }), /* @__PURE__ */ m(h, {
89
+ }), /* @__PURE__ */ f(p, {
89
90
  type: "button",
90
- onClick: H,
91
- disabled: !L.trim() || !F || M,
92
- children: [/* @__PURE__ */ p(d, { className: "h-4 w-4" }), /* @__PURE__ */ p("span", {
91
+ onClick: B,
92
+ disabled: !F.trim() || !N || A,
93
+ children: [/* @__PURE__ */ d(l, { className: "h-4 w-4" }), /* @__PURE__ */ d("span", {
93
94
  className: "ml-1",
94
95
  children: "Send"
95
96
  })]
@@ -100,6 +101,6 @@ var x = ({ entityId: x, entityType: S, title: C, pagePath: w, trigger: T, headin
100
101
  })] });
101
102
  };
102
103
  //#endregion
103
- export { x as ContactOwnerDialog };
104
+ export { y as ContactOwnerDialog };
104
105
 
105
106
  //# 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 {\n cloneElement,\n isValidElement,\n useEffect,\n useRef,\n useState,\n type FC,\n type MouseEventHandler,\n type ReactElement,\n type ReactNode,\n} 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 /** Clickable trigger element (button/link). */\n trigger: ReactNode;\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 trigger,\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 caller's trigger with an injected open handler. We clone rather\n // than rely on ResponsiveDialogTrigger's asChild slot (which did not forward\n // the click through the fe-libs Button in production).\n const openTrigger = isValidElement(trigger) ? (\n cloneElement(trigger as ReactElement<{ onClick?: MouseEventHandler }>, { onClick: () => setOpen(true) })\n ) : (\n <button type=\"button\" onClick={() => setOpen(true)}>\n {trigger}\n </button>\n );\n\n return (\n <>\n {openTrigger}\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 </>\n );\n};\n"],"mappings":"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"}
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 /** Clickable trigger element (button/link). */\n trigger: ReactNode;\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 trigger,\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 caller's trigger inside a display:contents wrapper that opens the\n // dialog on click. A DOM-level onClick on the wrapper reliably catches the\n // bubbled click from the inner button — neither ResponsiveDialogTrigger's\n // asChild slot nor cloneElement forwarded the click through the fe-libs Button\n // in production.\n const openTrigger = (\n <span className=\"contents\" role=\"presentation\" onClick={() => setOpen(true)}>\n {trigger}\n </span>\n );\n\n return (\n <>\n {openTrigger}\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 </>\n );\n};\n"],"mappings":";;;;;;;;;;AAuCA,IAAa,KAAmD,EAC9D,aACA,eACA,UACA,aACA,YACA,aAAU,WACV,qBACI;CACJ,IAAM,EAAE,mBAAgB,GAAiB,EACnC,EAAE,qBAAkB,SAAS,MAAY,GAAwB,EACjE,EAAE,gBAAa,SAAS,MAAY,GAAgB,EACpD,CAAC,GAAM,KAAW,EAAS,GAAM,EACjC,CAAC,GAAgB,KAAqB,GAA8B,EACpE,CAAC,GAAO,KAAY,EAAS,GAAG,EAChC,EAAE,MAAM,GAAU,SAAS,MAAoB,EAAwB,EAAe,EACtF,IAAY,EAAuB,KAAK;AAsB9C,CAnBA,QAAgB;AACd,MAAI,CAAC,KAAQ,EAAgB;EAC7B,IAAI,IAAY;AAYhB,SAXA,EAAiB;GACf;GACA;GACA;GACA,aAAa;GACb;GACD,CAAC,CACC,MAAM,MAAQ;AACb,GAAK,KAAW,EAAkB,EAAI,GAAG;IACzC,CACD,OAAO,MAAe,EAAO,MAAM,mCAAmC,EAAI,QAAQ,CAAC,QACzE;AACX,OAAY;;IAEb;EAAC;EAAM;EAAgB;EAAkB;EAAU;EAAY;EAAO;EAAS,CAAC,EAEnF,QAAgB;AACd,IAAU,SAAS,SAAS,EAAE,KAAK,EAAU,QAAQ,cAAc,CAAC;IACnE,CAAC,EAAS,CAAC;CAEd,IAAM,IAAa,YAAY;EAC7B,IAAM,IAAO,EAAM,MAAM;AACrB,SAAC,KAAQ,CAAC,GACd,KAAI;AAEF,GADA,MAAM,EAAY,GAAgB,EAAK,EACvC,EAAS,GAAG;WACL,GAAK;AACZ,KAAO,MAAM,oBAAqB,EAAc,QAAQ;;IAItD,IAAgB,GAAa,MAAM;AAazC,QACE,kBAAA,GAAA,EAAA,UAAA,CANA,kBAAC,QAAD;EAAM,WAAU;EAAW,MAAK;EAAe,eAAe,EAAQ,GAAK;YACxE;EACI,CAAA,EAML,kBAAC,GAAD;EAAwB;EAAM,cAAc;YAC1C,kBAAC,GAAD;GAAyB,WAAU;aAAnC;IACE,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UAAwB,GAAgC,CAAA,EACxD,kBAAC,GAAD,EAAA,UACG,KAAe,8BAA8B,EAAM,oDACxB,CAAA,CACP,EAAA,CAAA;IAEzB,kBAAC,OAAD;KACE,KAAK;KACL,WAAU;eAET,KAAW,IACV,kBAAC,KAAD;MAAG,WAAU;gBAA+C;MAAyB,CAAA,GACnF,EAAS,WAAW,IACtB,kBAAC,KAAD;MAAG,WAAU;gBAA+C;MAExD,CAAA,GAEJ,EAAS,KAAK,MAAY;MACxB,IAAM,IAAO,EAAQ,aAAa;AAClC,aACE,kBAAC,OAAD;OAAsB,WAAW,EAAG,QAAQ,IAAO,gBAAgB,gBAAgB;iBACjF,kBAAC,OAAD;QACE,WAAW,EACT,4CACA,IACI,kDACA,8DACL;kBAEA,EAAQ;QACL,CAAA;OACF,EAXI,EAAQ,GAWZ;OAER;KAEA,CAAA;IAEN,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,YAAD;MACE,OAAO;MACP,WAAW,MAAU,EAAS,EAAM,OAAO,MAAM;MACjD,YAAY,MAAU;AACpB,OAAI,EAAM,QAAQ,WAAW,CAAC,EAAM,aAClC,EAAM,gBAAgB,EACjB,GAAY;;MAGrB,MAAM;MACN,aAAY;MACZ,WAAU;MACV,CAAA,EACF,kBAAC,GAAD;MAAQ,MAAK;MAAS,SAAS;MAAY,UAAU,CAAC,EAAM,MAAM,IAAI,CAAC,KAAkB;gBAAzF,CACE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAC5B,kBAAC,QAAD;OAAM,WAAU;iBAAO;OAAW,CAAA,CAC3B;QACL;;IACkB;;EACT,CAAA,CAClB,EAAA,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-housingvista",
3
- "version": "2026.703.5",
3
+ "version": "2026.703.6",
4
4
  "description": "Burdenoff HousingVista Microfrontend - Comprehensive real estate platform for property management, investment, and transactions",
5
5
  "type": "module",
6
6
  "files": [