@burdenoff/microfe-housingvista 2026.703.13 → 2026.709.2

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.
Files changed (163) hide show
  1. package/dist/generated/global-operations.d.ts +2 -0
  2. package/dist/generated/global-operations.d.ts.map +1 -0
  3. package/dist/generated/global-types.d.ts +23527 -0
  4. package/dist/generated/global-types.d.ts.map +1 -0
  5. package/dist/generated/wspace-operations.d.ts +267 -0
  6. package/dist/generated/wspace-operations.d.ts.map +1 -0
  7. package/dist/generated/wspace-operations.js +67 -0
  8. package/dist/generated/wspace-operations.js.map +1 -0
  9. package/dist/generated/wspace-types.d.ts +57868 -0
  10. package/dist/generated/wspace-types.d.ts.map +1 -0
  11. package/dist/housingvista/HousingVistaRoot.d.ts +5 -0
  12. package/dist/housingvista/HousingVistaRoot.d.ts.map +1 -0
  13. package/dist/housingvista/HousingVistaRoutes.d.ts +7 -0
  14. package/dist/housingvista/HousingVistaRoutes.d.ts.map +1 -0
  15. package/dist/housingvista/components/Breadcrumbs.d.ts +13 -0
  16. package/dist/housingvista/components/Breadcrumbs.d.ts.map +1 -0
  17. package/dist/housingvista/components/ChartCard.d.ts +12 -0
  18. package/dist/housingvista/components/ChartCard.d.ts.map +1 -0
  19. package/dist/housingvista/components/ContactOwnerDialog.d.ts +33 -0
  20. package/dist/housingvista/components/ContactOwnerDialog.d.ts.map +1 -0
  21. package/dist/housingvista/components/DataTable.d.ts +42 -0
  22. package/dist/housingvista/components/DataTable.d.ts.map +1 -0
  23. package/dist/housingvista/components/EmptyState.d.ts +19 -0
  24. package/dist/housingvista/components/EmptyState.d.ts.map +1 -0
  25. package/dist/housingvista/components/ErrorBoundary.d.ts +19 -0
  26. package/dist/housingvista/components/ErrorBoundary.d.ts.map +1 -0
  27. package/dist/housingvista/components/FileUploader.d.ts +16 -0
  28. package/dist/housingvista/components/FileUploader.d.ts.map +1 -0
  29. package/dist/housingvista/components/FilterBar.d.ts +13 -0
  30. package/dist/housingvista/components/FilterBar.d.ts.map +1 -0
  31. package/dist/housingvista/components/LoadingSkeleton.d.ts +10 -0
  32. package/dist/housingvista/components/LoadingSkeleton.d.ts.map +1 -0
  33. package/dist/housingvista/components/PageLayout.d.ts +18 -0
  34. package/dist/housingvista/components/PageLayout.d.ts.map +1 -0
  35. package/dist/housingvista/components/PropertyCard.d.ts +26 -0
  36. package/dist/housingvista/components/PropertyCard.d.ts.map +1 -0
  37. package/dist/housingvista/components/ReviewsSection.d.ts +12 -0
  38. package/dist/housingvista/components/ReviewsSection.d.ts.map +1 -0
  39. package/dist/housingvista/components/StatCard.d.ts +18 -0
  40. package/dist/housingvista/components/StatCard.d.ts.map +1 -0
  41. package/dist/housingvista/components/StatusBadge.d.ts +12 -0
  42. package/dist/housingvista/components/StatusBadge.d.ts.map +1 -0
  43. package/dist/housingvista/components/index.d.ts +17 -0
  44. package/dist/housingvista/components/index.d.ts.map +1 -0
  45. package/dist/housingvista/context/HousingVistaContext.d.ts +15 -0
  46. package/dist/housingvista/context/HousingVistaContext.d.ts.map +1 -0
  47. package/dist/housingvista/hooks/index.d.ts +804 -0
  48. package/dist/housingvista/hooks/index.d.ts.map +1 -0
  49. package/dist/housingvista/hooks/index.js +1 -0
  50. package/dist/housingvista/hooks/index.js.map +1 -1
  51. package/dist/housingvista/hooks/messages.d.ts +65 -0
  52. package/dist/housingvista/hooks/messages.d.ts.map +1 -0
  53. package/dist/housingvista/hooks/platform.d.ts +140 -0
  54. package/dist/housingvista/hooks/platform.d.ts.map +1 -0
  55. package/dist/housingvista/hooks/useHousingVistaAnalytics.d.ts +16 -0
  56. package/dist/housingvista/hooks/useHousingVistaAnalytics.d.ts.map +1 -0
  57. package/dist/housingvista/hooks/useHousingVistaAnalytics.js +57 -0
  58. package/dist/housingvista/hooks/useHousingVistaAnalytics.js.map +1 -0
  59. package/dist/housingvista/hooks/useServerPagination.d.ts +12 -0
  60. package/dist/housingvista/hooks/useServerPagination.d.ts.map +1 -0
  61. package/dist/housingvista/index.d.ts +13 -0
  62. package/dist/housingvista/index.d.ts.map +1 -0
  63. package/dist/housingvista/index.js +2 -0
  64. package/dist/housingvista/lib/toast.d.ts +11 -0
  65. package/dist/housingvista/lib/toast.d.ts.map +1 -0
  66. package/dist/housingvista/pages/HomePage.d.ts +7 -0
  67. package/dist/housingvista/pages/HomePage.d.ts.map +1 -0
  68. package/dist/housingvista/pages/HomePage.js +135 -132
  69. package/dist/housingvista/pages/HomePage.js.map +1 -1
  70. package/dist/housingvista/pages/amc/AMCManagementPage.d.ts +2 -0
  71. package/dist/housingvista/pages/amc/AMCManagementPage.d.ts.map +1 -0
  72. package/dist/housingvista/pages/analytics/AnalyticsPage.d.ts +2 -0
  73. package/dist/housingvista/pages/analytics/AnalyticsPage.d.ts.map +1 -0
  74. package/dist/housingvista/pages/analytics/AnalyticsPage.js +136 -134
  75. package/dist/housingvista/pages/analytics/AnalyticsPage.js.map +1 -1
  76. package/dist/housingvista/pages/assets/AssetDetailPage.d.ts +9 -0
  77. package/dist/housingvista/pages/assets/AssetDetailPage.d.ts.map +1 -0
  78. package/dist/housingvista/pages/assets/AssetManagementPage.d.ts +2 -0
  79. package/dist/housingvista/pages/assets/AssetManagementPage.d.ts.map +1 -0
  80. package/dist/housingvista/pages/assets/AssetManagementPage.js.map +1 -1
  81. package/dist/housingvista/pages/chat/ChatPage.d.ts +14 -0
  82. package/dist/housingvista/pages/chat/ChatPage.d.ts.map +1 -0
  83. package/dist/housingvista/pages/finance/HomeLoanDetailPage.d.ts +11 -0
  84. package/dist/housingvista/pages/finance/HomeLoanDetailPage.d.ts.map +1 -0
  85. package/dist/housingvista/pages/finance/HomeLoansPage.d.ts +2 -0
  86. package/dist/housingvista/pages/finance/HomeLoansPage.d.ts.map +1 -0
  87. package/dist/housingvista/pages/investments/InvestmentDetailPage.d.ts +2 -0
  88. package/dist/housingvista/pages/investments/InvestmentDetailPage.d.ts.map +1 -0
  89. package/dist/housingvista/pages/investments/InvestmentsPage.d.ts +2 -0
  90. package/dist/housingvista/pages/investments/InvestmentsPage.d.ts.map +1 -0
  91. package/dist/housingvista/pages/investments/InvestmentsPage.js.map +1 -1
  92. package/dist/housingvista/pages/legal/LegalPage.d.ts +2 -0
  93. package/dist/housingvista/pages/legal/LegalPage.d.ts.map +1 -0
  94. package/dist/housingvista/pages/legal/LegalServiceDetailPage.d.ts +12 -0
  95. package/dist/housingvista/pages/legal/LegalServiceDetailPage.d.ts.map +1 -0
  96. package/dist/housingvista/pages/market/AreaInsightsPage.d.ts +2 -0
  97. package/dist/housingvista/pages/market/AreaInsightsPage.d.ts.map +1 -0
  98. package/dist/housingvista/pages/market/MarketAnalyticsPage.d.ts +2 -0
  99. package/dist/housingvista/pages/market/MarketAnalyticsPage.d.ts.map +1 -0
  100. package/dist/housingvista/pages/marketplace/MarketplacePage.d.ts +2 -0
  101. package/dist/housingvista/pages/marketplace/MarketplacePage.d.ts.map +1 -0
  102. package/dist/housingvista/pages/marketplace/ServiceDetailPage.d.ts +12 -0
  103. package/dist/housingvista/pages/marketplace/ServiceDetailPage.d.ts.map +1 -0
  104. package/dist/housingvista/pages/offers/OffersPage.d.ts +10 -0
  105. package/dist/housingvista/pages/offers/OffersPage.d.ts.map +1 -0
  106. package/dist/housingvista/pages/properties/AddPropertyPage.d.ts +8 -0
  107. package/dist/housingvista/pages/properties/AddPropertyPage.d.ts.map +1 -0
  108. package/dist/housingvista/pages/properties/AddPropertyPage.js +279 -278
  109. package/dist/housingvista/pages/properties/AddPropertyPage.js.map +1 -1
  110. package/dist/housingvista/pages/properties/PropertiesPage.d.ts +7 -0
  111. package/dist/housingvista/pages/properties/PropertiesPage.d.ts.map +1 -0
  112. package/dist/housingvista/pages/properties/PropertiesPage.js +93 -86
  113. package/dist/housingvista/pages/properties/PropertiesPage.js.map +1 -1
  114. package/dist/housingvista/pages/properties/PropertyDetailPage.d.ts +9 -0
  115. package/dist/housingvista/pages/properties/PropertyDetailPage.d.ts.map +1 -0
  116. package/dist/housingvista/pages/properties/PropertyDetailPage.js +514 -511
  117. package/dist/housingvista/pages/properties/PropertyDetailPage.js.map +1 -1
  118. package/dist/housingvista/pages/rental/RentalManagementPage.d.ts +2 -0
  119. package/dist/housingvista/pages/rental/RentalManagementPage.d.ts.map +1 -0
  120. package/dist/housingvista/pages/settings/ProfilePage.d.ts +2 -0
  121. package/dist/housingvista/pages/settings/ProfilePage.d.ts.map +1 -0
  122. package/dist/housingvista/pages/settings/SettingsPage.d.ts +2 -0
  123. package/dist/housingvista/pages/settings/SettingsPage.d.ts.map +1 -0
  124. package/dist/housingvista/pages/shortlist/ShortlistPage.d.ts +8 -0
  125. package/dist/housingvista/pages/shortlist/ShortlistPage.d.ts.map +1 -0
  126. package/dist/housingvista/pages/transactions/TransactionDetailPage.d.ts +8 -0
  127. package/dist/housingvista/pages/transactions/TransactionDetailPage.d.ts.map +1 -0
  128. package/dist/housingvista/pages/transactions/TransactionsPage.d.ts +7 -0
  129. package/dist/housingvista/pages/transactions/TransactionsPage.d.ts.map +1 -0
  130. package/dist/housingvista/pages/transactions/milestones.d.ts +35 -0
  131. package/dist/housingvista/pages/transactions/milestones.d.ts.map +1 -0
  132. package/dist/housingvista/pages/verification/VerificationDetailPage.d.ts +10 -0
  133. package/dist/housingvista/pages/verification/VerificationDetailPage.d.ts.map +1 -0
  134. package/dist/housingvista/pages/verification/VerificationPage.d.ts +2 -0
  135. package/dist/housingvista/pages/verification/VerificationPage.d.ts.map +1 -0
  136. package/dist/housingvista/pages/viewings/ViewingsPage.d.ts +9 -0
  137. package/dist/housingvista/pages/viewings/ViewingsPage.d.ts.map +1 -0
  138. package/dist/housingvista/services/assistantApi.d.ts +90 -0
  139. package/dist/housingvista/services/assistantApi.d.ts.map +1 -0
  140. package/dist/housingvista/services/assistantApi.js +222 -0
  141. package/dist/housingvista/services/assistantApi.js.map +1 -0
  142. package/dist/housingvista/services/createSandboxAssistantTransport.d.ts +42 -0
  143. package/dist/housingvista/services/createSandboxAssistantTransport.d.ts.map +1 -0
  144. package/dist/housingvista/services/createSandboxAssistantTransport.js +120 -0
  145. package/dist/housingvista/services/createSandboxAssistantTransport.js.map +1 -0
  146. package/dist/housingvista/store/housingvistaStore.d.ts +72 -0
  147. package/dist/housingvista/store/housingvistaStore.d.ts.map +1 -0
  148. package/dist/housingvista/types/assistant.d.ts +16 -0
  149. package/dist/housingvista/types/assistant.d.ts.map +1 -0
  150. package/dist/housingvista/types/index.d.ts +1328 -0
  151. package/dist/housingvista/types/index.d.ts.map +1 -0
  152. package/dist/housingvista/utils/helpers.d.ts +25 -0
  153. package/dist/housingvista/utils/helpers.d.ts.map +1 -0
  154. package/dist/housingvista/utils/index.d.ts +2 -0
  155. package/dist/housingvista/utils/index.d.ts.map +1 -0
  156. package/dist/housingvista/utils/pageContext.d.ts +25 -0
  157. package/dist/housingvista/utils/pageContext.d.ts.map +1 -0
  158. package/dist/housingvista/utils/pageContext.js +77 -0
  159. package/dist/housingvista/utils/pageContext.js.map +1 -0
  160. package/dist/index.d.ts +6 -0
  161. package/dist/index.d.ts.map +1 -0
  162. package/dist/index.js +5 -3
  163. package/package.json +6 -2
@@ -3,24 +3,27 @@ import { PageLayout as t } from "../../components/PageLayout.js";
3
3
  import { StatCard as n } from "../../components/StatCard.js";
4
4
  import { EmptyState as r } from "../../components/EmptyState.js";
5
5
  import { FilterBar as ee } from "../../components/FilterBar.js";
6
- import { LoadingSkeleton as te } from "../../components/LoadingSkeleton.js";
7
- import { PropertyCard as ne } from "../../components/PropertyCard.js";
8
- import { useDashboardStats as re, useProperties as ie, useRemoveShortlist as i, useSaveShortlist as a, useShortlists as ae } from "../../hooks/index.js";
9
- import { notify as o } from "../../lib/toast.js";
6
+ import { LoadingSkeleton as i } from "../../components/LoadingSkeleton.js";
7
+ import { PropertyCard as a } from "../../components/PropertyCard.js";
8
+ import { useHousingVistaAnalytics as o, useTrackPageView as s } from "../../hooks/useHousingVistaAnalytics.js";
9
+ import { useDashboardStats as te, useProperties as ne, useRemoveShortlist as re, useSaveShortlist as ie, useShortlists as ae } from "../../hooks/index.js";
10
+ import { notify as c } from "../../lib/toast.js";
10
11
  import "../../components/index.js";
11
12
  import { useServerPagination as oe } from "../../hooks/useServerPagination.js";
12
- import { useEffect as s, useMemo as c, useState as l } from "react";
13
- import { Building as u, Grid as se, List as ce, Plus as d, SlidersHorizontal as f, X as p } from "lucide-react";
14
- import { useNavigate as m } from "react-router-dom";
15
- import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
16
- import { useI18n as v } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
17
- import { EmphasisPanel as y, Pagination as le } from "@burdenoff/fe-libs/ui";
13
+ import { useEffect as l, useMemo as u, useState as d } from "react";
14
+ import { Building as f, Grid as p, List as m, Plus as h, SlidersHorizontal as g, X as _ } from "lucide-react";
15
+ import { useNavigate as se } from "react-router-dom";
16
+ import { Fragment as ce, jsx as v, jsxs as y } from "react/jsx-runtime";
17
+ import { useI18n as le } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
18
+ import { EmphasisPanel as ue, Pagination as de } from "@burdenoff/fe-libs/ui";
18
19
  //#region src/housingvista/pages/properties/PropertiesPage.tsx
19
- var ue = 9, b = () => {
20
- let b = m(), { t: de } = v(), x = (e, t) => {
21
- let n = de(e);
20
+ var fe = 9, b = () => {
21
+ let b = se(), { t: pe } = le(), { emit: me, emitResource: he, emitSearch: ge } = o();
22
+ s("housingvista.property.viewed");
23
+ let x = (e, t) => {
24
+ let n = pe(e);
22
25
  return n === e ? t : n;
23
- }, fe = [
26
+ }, _e = [
24
27
  {
25
28
  value: "all",
26
29
  label: x("housingvista.properties.filters.propertyTypes.all", "All Types")
@@ -45,7 +48,7 @@ var ue = 9, b = () => {
45
48
  value: "mixed_use",
46
49
  label: x("housingvista.properties.filters.propertyTypes.mixedUse", "Mixed Use")
47
50
  }
48
- ], pe = [
51
+ ], ve = [
49
52
  {
50
53
  value: "all",
51
54
  label: x("housingvista.properties.filters.propertyStatuses.all", "All Status")
@@ -74,7 +77,7 @@ var ue = 9, b = () => {
74
77
  value: "off_market",
75
78
  label: x("housingvista.properties.filters.propertyStatuses.offMarket", "Off Market")
76
79
  }
77
- ], me = [
80
+ ], ye = [
78
81
  {
79
82
  value: "all",
80
83
  label: x("housingvista.properties.filters.propertyCategories.all", "All Categories")
@@ -142,7 +145,7 @@ var ue = 9, b = () => {
142
145
  min: 1e6,
143
146
  max: Infinity
144
147
  }
145
- ], he = [
148
+ ], be = [
146
149
  {
147
150
  value: "all",
148
151
  label: x("housingvista.properties.filters.bedrooms.all", "Any Bedrooms")
@@ -167,12 +170,14 @@ var ue = 9, b = () => {
167
170
  value: "5",
168
171
  label: "5+"
169
172
  }
170
- ], [C, w] = l(""), [T, E] = l("all"), [D, O] = l("all"), [k, A] = l("all"), [j, M] = l("all"), [N, P] = l("all"), [F, I] = l("grid"), [L, ge] = l(!1), R = S.find((e) => e.value === j) ?? S[0], z = N === "all" ? 0 : Number(N), [B, _e] = l("");
171
- s(() => {
172
- let e = setTimeout(() => _e(C), 300);
173
+ ], [C, w] = d(""), [T, E] = d("all"), [D, O] = d("all"), [k, A] = d("all"), [j, M] = d("all"), [N, P] = d("all"), [F, I] = d("grid"), [L, xe] = d(!1), R = S.find((e) => e.value === j) ?? S[0], z = N === "all" ? 0 : Number(N), [B, Se] = d("");
174
+ l(() => {
175
+ let e = setTimeout(() => Se(C), 300);
173
176
  return () => clearTimeout(e);
174
- }, [C]);
175
- let { page: V, pageSize: H, pagination: ve, setPage: U, setPageSize: ye } = oe(ue), W = c(() => {
177
+ }, [C]), l(() => {
178
+ B.trim() && ge("properties");
179
+ }, [B]);
180
+ let { page: V, pageSize: H, pagination: Ce, setPage: U, setPageSize: we } = oe(fe), W = u(() => {
176
181
  let e = {};
177
182
  return B.trim() && (e.search = B.trim()), D !== "all" && (e.status = D), T !== "all" && (e.type = T), Object.keys(e).length > 0 ? e : void 0;
178
183
  }, [
@@ -180,19 +185,19 @@ var ue = 9, b = () => {
180
185
  D,
181
186
  T
182
187
  ]);
183
- s(() => {
188
+ l(() => {
184
189
  U(1);
185
190
  }, [W, U]);
186
- let { data: G, loading: K } = ie({
191
+ let { data: G, loading: K } = ne({
187
192
  filter: W,
188
- pagination: ve
189
- }), { data: q } = re(), { data: J } = ae(), { saveShortlist: be } = a(), { removeShortlist: Y } = i(), X = c(() => new Set(J.map((e) => e.propertyId)), [J]), xe = async (e) => {
193
+ pagination: Ce
194
+ }), { data: q } = te(), { data: J } = ae(), { saveShortlist: Te } = ie(), { removeShortlist: Ee } = re(), Y = u(() => new Set(J.map((e) => e.propertyId)), [J]), X = async (e) => {
190
195
  try {
191
- X.has(e) ? (await Y(e), o.success("Removed from shortlist")) : (await be(e), o.success("Saved to shortlist"));
196
+ Y.has(e) ? (await Ee(e), c.success("Removed from shortlist")) : (await Te(e), he("housingvista.shortlist.property_added", e), c.success("Saved to shortlist"));
192
197
  } catch (e) {
193
- o.error("Could not update shortlist", e.message);
198
+ c.error("Could not update shortlist", e.message);
194
199
  }
195
- }, Z = c(() => G.filter((e) => {
200
+ }, Z = u(() => G.filter((e) => {
196
201
  let t = k === "all" || e.category === k, n = e.price.amount >= R.min && e.price.amount <= R.max, r = (e.specifications.bedrooms ?? 0) >= z;
197
202
  return t && n && r;
198
203
  }), [
@@ -200,40 +205,42 @@ var ue = 9, b = () => {
200
205
  k,
201
206
  R,
202
207
  z
203
- ]), Se = G.length >= H, Q = C || T !== "all" || D !== "all" || k !== "all" || j !== "all" || N !== "all", $ = () => {
208
+ ]), De = G.length >= H, Q = C || T !== "all" || D !== "all" || k !== "all" || j !== "all" || N !== "all", $ = () => {
204
209
  w(""), E("all"), O("all"), A("all"), M("all"), P("all");
205
210
  };
206
- return /* @__PURE__ */ _(t, {
211
+ return /* @__PURE__ */ y(t, {
207
212
  title: x("housingvista.properties.title", "Properties"),
208
213
  description: x("housingvista.properties.description", "Discover your perfect property from our comprehensive listings"),
209
214
  purpose: x("housingvista.properties.purpose", "Browse, search, and filter every property in your portfolio or on the market. Use the filters to narrow by type, status, price, and bedrooms, then open any listing to see full details, schedule viewings, or start a transaction."),
210
- actions: /* @__PURE__ */ _("button", {
211
- onClick: () => b("new"),
215
+ actions: /* @__PURE__ */ y("button", {
216
+ onClick: () => {
217
+ me("housingvista.property.create_clicked"), b("new");
218
+ },
212
219
  className: "inline-flex items-center gap-2 rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90",
213
- children: [/* @__PURE__ */ g(d, { className: "h-4 w-4" }), x("housingvista.properties.actions.addProperty", "Add Property")]
220
+ children: [/* @__PURE__ */ v(h, { className: "h-4 w-4" }), x("housingvista.properties.actions.addProperty", "Add Property")]
214
221
  }),
215
222
  children: [
216
- /* @__PURE__ */ g(y, {
223
+ /* @__PURE__ */ v(ue, {
217
224
  className: "p-4",
218
- children: /* @__PURE__ */ _("div", {
225
+ children: /* @__PURE__ */ y("div", {
219
226
  className: "grid grid-cols-2 gap-4 lg:grid-cols-4",
220
227
  children: [
221
- /* @__PURE__ */ g(n, {
228
+ /* @__PURE__ */ v(n, {
222
229
  label: x("housingvista.properties.stats.totalProperties", "Total Properties"),
223
230
  value: q.totalProperties,
224
- icon: /* @__PURE__ */ g(u, { className: "h-5 w-5" })
231
+ icon: /* @__PURE__ */ v(f, { className: "h-5 w-5" })
225
232
  }),
226
- /* @__PURE__ */ g(n, {
233
+ /* @__PURE__ */ v(n, {
227
234
  label: x("housingvista.properties.stats.portfolioValue", "Portfolio Value"),
228
235
  value: q.totalValue,
229
236
  prefix: "$"
230
237
  }),
231
- /* @__PURE__ */ g(n, {
238
+ /* @__PURE__ */ v(n, {
232
239
  label: x("housingvista.properties.stats.occupancyRate", "Occupancy Rate"),
233
240
  value: q.occupancyRate,
234
241
  unit: "%"
235
242
  }),
236
- /* @__PURE__ */ g(n, {
243
+ /* @__PURE__ */ v(n, {
237
244
  label: x("housingvista.properties.stats.monthlyRevenue", "Monthly Revenue"),
238
245
  value: q.monthlyRevenue,
239
246
  prefix: "$"
@@ -241,106 +248,106 @@ var ue = 9, b = () => {
241
248
  ]
242
249
  })
243
250
  }),
244
- /* @__PURE__ */ g(ee, {
251
+ /* @__PURE__ */ v(ee, {
245
252
  searchValue: C,
246
253
  onSearchChange: w,
247
254
  searchPlaceholder: x("housingvista.properties.search.placeholder", "Search properties by name, city, or neighborhood..."),
248
- filters: /* @__PURE__ */ _("button", {
249
- onClick: () => ge((e) => !e),
255
+ filters: /* @__PURE__ */ y("button", {
256
+ onClick: () => xe((e) => !e),
250
257
  className: e("inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium transition-colors", L ? "bg-foreground text-background" : "text-text-primary hover:bg-bg-sunken"),
251
258
  children: [
252
- /* @__PURE__ */ g(f, { className: "h-4 w-4" }),
259
+ /* @__PURE__ */ v(g, { className: "h-4 w-4" }),
253
260
  x("housingvista.properties.filters.toggle", "Filters"),
254
- Q && /* @__PURE__ */ g("span", {
261
+ Q && /* @__PURE__ */ v("span", {
255
262
  className: "flex h-5 w-5 items-center justify-center rounded-full bg-action-primary-bg text-[10px] font-bold text-action-primary-text",
256
263
  children: "!"
257
264
  })
258
265
  ]
259
266
  }),
260
- actions: /* @__PURE__ */ _("div", {
267
+ actions: /* @__PURE__ */ y("div", {
261
268
  className: "flex items-center gap-1",
262
- children: [/* @__PURE__ */ g("button", {
269
+ children: [/* @__PURE__ */ v("button", {
263
270
  onClick: () => I("grid"),
264
271
  className: e("rounded-md p-2 transition-colors", F === "grid" ? "bg-foreground text-background" : "text-text-secondary hover:text-text-primary hover:bg-bg-sunken"),
265
- children: /* @__PURE__ */ g(se, { className: "h-4 w-4" })
266
- }), /* @__PURE__ */ g("button", {
272
+ children: /* @__PURE__ */ v(p, { className: "h-4 w-4" })
273
+ }), /* @__PURE__ */ v("button", {
267
274
  onClick: () => I("list"),
268
275
  className: e("rounded-md p-2 transition-colors", F === "list" ? "bg-foreground text-background" : "text-text-secondary hover:text-text-primary hover:bg-bg-sunken"),
269
- children: /* @__PURE__ */ g(ce, { className: "h-4 w-4" })
276
+ children: /* @__PURE__ */ v(m, { className: "h-4 w-4" })
270
277
  })]
271
278
  })
272
279
  }),
273
- L && /* @__PURE__ */ _("div", {
280
+ L && /* @__PURE__ */ y("div", {
274
281
  className: "rounded-lg border border-border-subtle bg-bg-surface p-4",
275
- children: [/* @__PURE__ */ _("div", {
282
+ children: [/* @__PURE__ */ y("div", {
276
283
  className: "flex items-center justify-between mb-4",
277
- children: [/* @__PURE__ */ g("h3", {
284
+ children: [/* @__PURE__ */ v("h3", {
278
285
  className: "text-sm font-medium text-text-primary",
279
286
  children: x("housingvista.properties.filters.title", "Filters")
280
- }), Q && /* @__PURE__ */ _("button", {
287
+ }), Q && /* @__PURE__ */ y("button", {
281
288
  onClick: $,
282
289
  className: "inline-flex items-center gap-1 text-xs text-text-secondary hover:text-text-primary",
283
- children: [/* @__PURE__ */ g(p, { className: "h-3 w-3" }), x("housingvista.properties.filters.clearAll", "Clear All")]
290
+ children: [/* @__PURE__ */ v(_, { className: "h-3 w-3" }), x("housingvista.properties.filters.clearAll", "Clear All")]
284
291
  })]
285
- }), /* @__PURE__ */ _("div", {
292
+ }), /* @__PURE__ */ y("div", {
286
293
  className: "grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-5",
287
294
  children: [
288
- /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
295
+ /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
289
296
  className: "mb-1.5 block text-xs font-medium text-text-secondary",
290
297
  children: x("housingvista.properties.filters.labels.propertyType", "Property Type")
291
- }), /* @__PURE__ */ g("select", {
298
+ }), /* @__PURE__ */ v("select", {
292
299
  value: T,
293
300
  onChange: (e) => E(e.target.value),
294
301
  className: "h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
295
- children: fe.map((e) => /* @__PURE__ */ g("option", {
302
+ children: _e.map((e) => /* @__PURE__ */ v("option", {
296
303
  value: e.value,
297
304
  children: e.label
298
305
  }, e.value))
299
306
  })] }),
300
- /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
307
+ /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
301
308
  className: "mb-1.5 block text-xs font-medium text-text-secondary",
302
309
  children: x("housingvista.properties.filters.labels.status", "Status")
303
- }), /* @__PURE__ */ g("select", {
310
+ }), /* @__PURE__ */ v("select", {
304
311
  value: D,
305
312
  onChange: (e) => O(e.target.value),
306
313
  className: "h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
307
- children: pe.map((e) => /* @__PURE__ */ g("option", {
314
+ children: ve.map((e) => /* @__PURE__ */ v("option", {
308
315
  value: e.value,
309
316
  children: e.label
310
317
  }, e.value))
311
318
  })] }),
312
- /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
319
+ /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
313
320
  className: "mb-1.5 block text-xs font-medium text-text-secondary",
314
321
  children: x("housingvista.properties.filters.labels.category", "Category")
315
- }), /* @__PURE__ */ g("select", {
322
+ }), /* @__PURE__ */ v("select", {
316
323
  value: k,
317
324
  onChange: (e) => A(e.target.value),
318
325
  className: "h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
319
- children: me.map((e) => /* @__PURE__ */ g("option", {
326
+ children: ye.map((e) => /* @__PURE__ */ v("option", {
320
327
  value: e.value,
321
328
  children: e.label
322
329
  }, e.value))
323
330
  })] }),
324
- /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
331
+ /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
325
332
  className: "mb-1.5 block text-xs font-medium text-text-secondary",
326
333
  children: x("housingvista.properties.filters.labels.priceRange", "Price Range")
327
- }), /* @__PURE__ */ g("select", {
334
+ }), /* @__PURE__ */ v("select", {
328
335
  value: j,
329
336
  onChange: (e) => M(e.target.value),
330
337
  className: "h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
331
- children: S.map((e) => /* @__PURE__ */ g("option", {
338
+ children: S.map((e) => /* @__PURE__ */ v("option", {
332
339
  value: e.value,
333
340
  children: e.label
334
341
  }, e.value))
335
342
  })] }),
336
- /* @__PURE__ */ _("div", { children: [/* @__PURE__ */ g("label", {
343
+ /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
337
344
  className: "mb-1.5 block text-xs font-medium text-text-secondary",
338
345
  children: x("housingvista.properties.filters.labels.bedrooms", "Bedrooms")
339
- }), /* @__PURE__ */ g("select", {
346
+ }), /* @__PURE__ */ v("select", {
340
347
  value: N,
341
348
  onChange: (e) => P(e.target.value),
342
349
  className: "h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]",
343
- children: he.map((e) => /* @__PURE__ */ g("option", {
350
+ children: be.map((e) => /* @__PURE__ */ v("option", {
344
351
  value: e.value,
345
352
  children: e.label
346
353
  }, e.value))
@@ -348,9 +355,9 @@ var ue = 9, b = () => {
348
355
  ]
349
356
  })]
350
357
  }),
351
- /* @__PURE__ */ _("div", {
358
+ /* @__PURE__ */ y("div", {
352
359
  className: "flex items-center justify-between",
353
- children: [/* @__PURE__ */ _("p", {
360
+ children: [/* @__PURE__ */ y("p", {
354
361
  className: "text-sm text-text-secondary",
355
362
  children: [
356
363
  x("housingvista.properties.results.showing", "Showing"),
@@ -360,18 +367,18 @@ var ue = 9, b = () => {
360
367
  x("housingvista.properties.results.properties", "properties"),
361
368
  V > 1 ? ` · page ${V}` : ""
362
369
  ]
363
- }), Q && /* @__PURE__ */ g("button", {
370
+ }), Q && /* @__PURE__ */ v("button", {
364
371
  onClick: $,
365
372
  className: "text-sm text-text-secondary hover:text-text-primary",
366
373
  children: x("housingvista.properties.results.clearFilters", "Clear Filters")
367
374
  })]
368
375
  }),
369
- K ? /* @__PURE__ */ g(te, {
376
+ K ? /* @__PURE__ */ v(i, {
370
377
  variant: "card",
371
378
  count: 6
372
- }) : Z.length > 0 ? /* @__PURE__ */ _(h, { children: [/* @__PURE__ */ g("div", {
379
+ }) : Z.length > 0 ? /* @__PURE__ */ y(ce, { children: [/* @__PURE__ */ v("div", {
373
380
  className: e(F === "grid" ? "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3" : "space-y-4"),
374
- children: Z.map((e) => /* @__PURE__ */ g(ne, {
381
+ children: Z.map((e) => /* @__PURE__ */ v(a, {
375
382
  id: e.id,
376
383
  title: e.title,
377
384
  price: e.price.amount,
@@ -386,23 +393,23 @@ var ue = 9, b = () => {
386
393
  status: e.status.replace("_", " "),
387
394
  type: e.category,
388
395
  onClick: () => b(e.id),
389
- isShortlisted: X.has(e.id),
390
- onToggleShortlist: () => xe(e.id)
396
+ isShortlisted: Y.has(e.id),
397
+ onToggleShortlist: () => X(e.id)
391
398
  }, e.id))
392
- }), /* @__PURE__ */ g(le, {
399
+ }), /* @__PURE__ */ v(de, {
393
400
  page: V,
394
401
  pageSize: H,
395
- hasNextPage: Se,
402
+ hasNextPage: De,
396
403
  hasPreviousPage: V > 1,
397
404
  loading: K,
398
405
  onPageChange: U,
399
- onPageSizeChange: ye
400
- })] }) : /* @__PURE__ */ g(r, {
406
+ onPageSizeChange: we
407
+ })] }) : /* @__PURE__ */ v(r, {
401
408
  illustration: "empty-search",
402
- icon: /* @__PURE__ */ g(u, { className: "h-12 w-12" }),
409
+ icon: /* @__PURE__ */ v(f, { className: "h-12 w-12" }),
403
410
  title: x("housingvista.properties.empty.title", "No properties found"),
404
411
  description: x("housingvista.properties.empty.description", "Try adjusting your search criteria or filters to find more properties."),
405
- action: /* @__PURE__ */ g("button", {
412
+ action: /* @__PURE__ */ v("button", {
406
413
  onClick: $,
407
414
  className: "rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90",
408
415
  children: x("housingvista.properties.empty.clearAllFilters", "Clear All Filters")
@@ -1 +1 @@
1
- {"version":3,"file":"PropertiesPage.js","names":[],"sources":["../../../../src/housingvista/pages/properties/PropertiesPage.tsx"],"sourcesContent":["/**\n * HousingVista Properties Listing Page\n * Migrated from legacy housingvista-frontend properties.tsx\n * @module housingvista\n */\n\nimport { useState, useMemo, useEffect } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Plus, Grid, List, Building, SlidersHorizontal, X } from 'lucide-react';\nimport { EmphasisPanel, Pagination } from '@burdenoff/fe-libs/ui';\nimport { PageLayout, FilterBar, PropertyCard, EmptyState, StatCard, LoadingSkeleton } from '../../components';\nimport {\n useProperties,\n useShortlists,\n useSaveShortlist,\n useRemoveShortlist,\n useDashboardStats,\n type PropertyFilterInput,\n} from '../../hooks';\nimport { useServerPagination } from '../../hooks/useServerPagination';\nimport { notify } from '../../lib/toast';\nimport { cn } from '../../utils/helpers';\nimport type { PropertyType, PropertyStatus, PropertyCategory } from '../../types';\n\nconst PAGE_SIZE = 9;\n\nexport const PropertiesPage = () => {\n const navigate = useNavigate();\n const { t } = useI18n();\n\n const tr = (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const propertyTypes: { value: PropertyType | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.propertyTypes.all', 'All Types') },\n { value: 'residential', label: tr('housingvista.properties.filters.propertyTypes.residential', 'Residential') },\n { value: 'commercial', label: tr('housingvista.properties.filters.propertyTypes.commercial', 'Commercial') },\n { value: 'industrial', label: tr('housingvista.properties.filters.propertyTypes.industrial', 'Industrial') },\n { value: 'agricultural', label: tr('housingvista.properties.filters.propertyTypes.agricultural', 'Agricultural') },\n { value: 'mixed_use', label: tr('housingvista.properties.filters.propertyTypes.mixedUse', 'Mixed Use') },\n ];\n\n const propertyStatuses: { value: PropertyStatus | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.propertyStatuses.all', 'All Status') },\n { value: 'for_sale', label: tr('housingvista.properties.filters.propertyStatuses.forSale', 'For Sale') },\n { value: 'for_rent', label: tr('housingvista.properties.filters.propertyStatuses.forRent', 'For Rent') },\n { value: 'sold', label: tr('housingvista.properties.filters.propertyStatuses.sold', 'Sold') },\n { value: 'rented', label: tr('housingvista.properties.filters.propertyStatuses.rented', 'Rented') },\n {\n value: 'under_contract',\n label: tr('housingvista.properties.filters.propertyStatuses.underContract', 'Under Contract'),\n },\n { value: 'off_market', label: tr('housingvista.properties.filters.propertyStatuses.offMarket', 'Off Market') },\n ];\n\n const propertyCategories: { value: PropertyCategory | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.propertyCategories.all', 'All Categories') },\n { value: 'apartment', label: tr('housingvista.properties.filters.propertyCategories.apartment', 'Apartment') },\n { value: 'house', label: tr('housingvista.properties.filters.propertyCategories.house', 'House') },\n { value: 'villa', label: tr('housingvista.properties.filters.propertyCategories.villa', 'Villa') },\n { value: 'office', label: tr('housingvista.properties.filters.propertyCategories.office', 'Office') },\n { value: 'retail', label: tr('housingvista.properties.filters.propertyCategories.retail', 'Retail') },\n { value: 'warehouse', label: tr('housingvista.properties.filters.propertyCategories.warehouse', 'Warehouse') },\n { value: 'land', label: tr('housingvista.properties.filters.propertyCategories.land', 'Land') },\n { value: 'plot', label: tr('housingvista.properties.filters.propertyCategories.plot', 'Plot') },\n ];\n\n const priceRanges = [\n { value: 'all', label: tr('housingvista.properties.filters.priceRanges.all', 'Any Price'), min: 0, max: Infinity },\n {\n value: 'under_100k',\n label: tr('housingvista.properties.filters.priceRanges.under100k', 'Under $100K'),\n min: 0,\n max: 100000,\n },\n {\n value: '100k_500k',\n label: tr('housingvista.properties.filters.priceRanges.100kTo500k', '$100K - $500K'),\n min: 100000,\n max: 500000,\n },\n {\n value: '500k_1m',\n label: tr('housingvista.properties.filters.priceRanges.500kTo1m', '$500K - $1M'),\n min: 500000,\n max: 1000000,\n },\n {\n value: 'over_1m',\n label: tr('housingvista.properties.filters.priceRanges.over1m', 'Over $1M'),\n min: 1000000,\n max: Infinity,\n },\n ];\n\n const bedroomOptions = [\n { value: 'all', label: tr('housingvista.properties.filters.bedrooms.all', 'Any Bedrooms') },\n { value: '1', label: '1+' },\n { value: '2', label: '2+' },\n { value: '3', label: '3+' },\n { value: '4', label: '4+' },\n { value: '5', label: '5+' },\n ];\n\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedType, setSelectedType] = useState<PropertyType | 'all'>('all');\n const [selectedStatus, setSelectedStatus] = useState<PropertyStatus | 'all'>('all');\n const [selectedCategory, setSelectedCategory] = useState<PropertyCategory | 'all'>('all');\n const [selectedPriceRange, setSelectedPriceRange] = useState('all');\n const [selectedBedrooms, setSelectedBedrooms] = useState('all');\n const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');\n const [showFilters, setShowFilters] = useState(false);\n\n const priceRange = priceRanges.find((r) => r.value === selectedPriceRange) ?? priceRanges[0];\n const minBedrooms = selectedBedrooms === 'all' ? 0 : Number(selectedBedrooms);\n\n // Debounce the search box so we don't refetch on every keystroke.\n const [debouncedSearch, setDebouncedSearch] = useState('');\n useEffect(() => {\n const timer = setTimeout(() => setDebouncedSearch(searchQuery), 300);\n return () => clearTimeout(timer);\n }, [searchQuery]);\n\n const { page, pageSize, pagination, setPage, setPageSize } = useServerPagination(PAGE_SIZE);\n\n // Server-side filter uses the schema-supported fields (search/status/type).\n const serverFilter = useMemo<PropertyFilterInput | undefined>(() => {\n const filter: PropertyFilterInput = {};\n if (debouncedSearch.trim()) filter.search = debouncedSearch.trim();\n if (selectedStatus !== 'all') filter.status = selectedStatus;\n if (selectedType !== 'all') filter.type = selectedType;\n return Object.keys(filter).length > 0 ? filter : undefined;\n }, [debouncedSearch, selectedStatus, selectedType]);\n\n // Reset to first page whenever the server-side filter changes.\n useEffect(() => {\n setPage(1);\n }, [serverFilter, setPage]);\n\n const { data: properties, loading } = useProperties({ filter: serverFilter, pagination });\n // Portfolio-wide totals for the stats zone — independent of the current page slice.\n const { data: dashboardStats } = useDashboardStats();\n const { data: shortlists } = useShortlists();\n const { saveShortlist } = useSaveShortlist();\n const { removeShortlist } = useRemoveShortlist();\n\n const shortlistedIds = useMemo(() => new Set(shortlists.map((s) => s.propertyId)), [shortlists]);\n\n const toggleShortlist = async (propertyId: string) => {\n try {\n if (shortlistedIds.has(propertyId)) {\n await removeShortlist(propertyId);\n notify.success('Removed from shortlist');\n } else {\n await saveShortlist(propertyId);\n notify.success('Saved to shortlist');\n }\n } catch (err) {\n notify.error('Could not update shortlist', (err as Error).message);\n }\n };\n\n // Category, price range, and bedrooms are refined on the client (the subgraph\n // filter input does not model them).\n const filteredProperties = useMemo(() => {\n return properties.filter((property) => {\n const matchesCategory = selectedCategory === 'all' || property.category === selectedCategory;\n const matchesPrice = property.price.amount >= priceRange.min && property.price.amount <= priceRange.max;\n const matchesBedrooms = (property.specifications.bedrooms ?? 0) >= minBedrooms;\n return matchesCategory && matchesPrice && matchesBedrooms;\n });\n }, [properties, selectedCategory, priceRange, minBedrooms]);\n\n const hasNextPage = properties.length >= pageSize;\n\n const hasActiveFilters =\n searchQuery ||\n selectedType !== 'all' ||\n selectedStatus !== 'all' ||\n selectedCategory !== 'all' ||\n selectedPriceRange !== 'all' ||\n selectedBedrooms !== 'all';\n\n const clearFilters = () => {\n setSearchQuery('');\n setSelectedType('all');\n setSelectedStatus('all');\n setSelectedCategory('all');\n setSelectedPriceRange('all');\n setSelectedBedrooms('all');\n };\n\n return (\n <PageLayout\n title={tr('housingvista.properties.title', 'Properties')}\n description={tr(\n 'housingvista.properties.description',\n 'Discover your perfect property from our comprehensive listings'\n )}\n purpose={tr(\n 'housingvista.properties.purpose',\n 'Browse, search, and filter every property in your portfolio or on the market. Use the filters to narrow by type, status, price, and bedrooms, then open any listing to see full details, schedule viewings, or start a transaction.'\n )}\n actions={\n <button\n onClick={() => navigate('new')}\n className=\"inline-flex items-center gap-2 rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90\"\n >\n <Plus className=\"h-4 w-4\" />\n {tr('housingvista.properties.actions.addProperty', 'Add Property')}\n </button>\n }\n >\n {/* Stats — primary insight zone (one EmphasisPanel per page) */}\n <EmphasisPanel className=\"p-4\">\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n <StatCard\n label={tr('housingvista.properties.stats.totalProperties', 'Total Properties')}\n value={dashboardStats.totalProperties}\n icon={<Building className=\"h-5 w-5\" />}\n />\n <StatCard\n label={tr('housingvista.properties.stats.portfolioValue', 'Portfolio Value')}\n value={dashboardStats.totalValue}\n prefix=\"$\"\n />\n <StatCard\n label={tr('housingvista.properties.stats.occupancyRate', 'Occupancy Rate')}\n value={dashboardStats.occupancyRate}\n unit=\"%\"\n />\n <StatCard\n label={tr('housingvista.properties.stats.monthlyRevenue', 'Monthly Revenue')}\n value={dashboardStats.monthlyRevenue}\n prefix=\"$\"\n />\n </div>\n </EmphasisPanel>\n\n {/* Search + View Toggle */}\n <FilterBar\n searchValue={searchQuery}\n onSearchChange={setSearchQuery}\n searchPlaceholder={tr(\n 'housingvista.properties.search.placeholder',\n 'Search properties by name, city, or neighborhood...'\n )}\n filters={\n <button\n onClick={() => setShowFilters((prev) => !prev)}\n className={cn(\n 'inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium transition-colors',\n showFilters ? 'bg-foreground text-background' : 'text-text-primary hover:bg-bg-sunken'\n )}\n >\n <SlidersHorizontal className=\"h-4 w-4\" />\n {tr('housingvista.properties.filters.toggle', 'Filters')}\n {hasActiveFilters && (\n <span className=\"flex h-5 w-5 items-center justify-center rounded-full bg-action-primary-bg text-[10px] font-bold text-action-primary-text\">\n !\n </span>\n )}\n </button>\n }\n actions={\n <div className=\"flex items-center gap-1\">\n <button\n onClick={() => setViewMode('grid')}\n className={cn(\n 'rounded-md p-2 transition-colors',\n viewMode === 'grid'\n ? 'bg-foreground text-background'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-sunken'\n )}\n >\n <Grid className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setViewMode('list')}\n className={cn(\n 'rounded-md p-2 transition-colors',\n viewMode === 'list'\n ? 'bg-foreground text-background'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-sunken'\n )}\n >\n <List className=\"h-4 w-4\" />\n </button>\n </div>\n }\n />\n\n {/* Filter Dropdowns */}\n {showFilters && (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-sm font-medium text-text-primary\">\n {tr('housingvista.properties.filters.title', 'Filters')}\n </h3>\n {hasActiveFilters && (\n <button\n onClick={clearFilters}\n className=\"inline-flex items-center gap-1 text-xs text-text-secondary hover:text-text-primary\"\n >\n <X className=\"h-3 w-3\" />\n {tr('housingvista.properties.filters.clearAll', 'Clear All')}\n </button>\n )}\n </div>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-5\">\n {/* Type */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.propertyType', 'Property Type')}\n </label>\n <select\n value={selectedType}\n onChange={(e) => setSelectedType(e.target.value as PropertyType | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {propertyTypes.map((t) => (\n <option key={t.value} value={t.value}>\n {t.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Status */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.status', 'Status')}\n </label>\n <select\n value={selectedStatus}\n onChange={(e) => setSelectedStatus(e.target.value as PropertyStatus | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {propertyStatuses.map((s) => (\n <option key={s.value} value={s.value}>\n {s.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Category */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.category', 'Category')}\n </label>\n <select\n value={selectedCategory}\n onChange={(e) => setSelectedCategory(e.target.value as PropertyCategory | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {propertyCategories.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Price Range */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.priceRange', 'Price Range')}\n </label>\n <select\n value={selectedPriceRange}\n onChange={(e) => setSelectedPriceRange(e.target.value)}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {priceRanges.map((r) => (\n <option key={r.value} value={r.value}>\n {r.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Bedrooms */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.bedrooms', 'Bedrooms')}\n </label>\n <select\n value={selectedBedrooms}\n onChange={(e) => setSelectedBedrooms(e.target.value)}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {bedroomOptions.map((b) => (\n <option key={b.value} value={b.value}>\n {b.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n </div>\n )}\n\n {/* Results Count */}\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {tr('housingvista.properties.results.showing', 'Showing')} {filteredProperties.length}{' '}\n {tr('housingvista.properties.results.properties', 'properties')}\n {page > 1 ? ` · page ${page}` : ''}\n </p>\n {hasActiveFilters && (\n <button onClick={clearFilters} className=\"text-sm text-text-secondary hover:text-text-primary\">\n {tr('housingvista.properties.results.clearFilters', 'Clear Filters')}\n </button>\n )}\n </div>\n\n {/* Property Grid / List */}\n {loading ? (\n <LoadingSkeleton variant=\"card\" count={6} />\n ) : filteredProperties.length > 0 ? (\n <>\n <div\n className={cn(viewMode === 'grid' ? 'grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3' : 'space-y-4')}\n >\n {filteredProperties.map((property) => (\n <PropertyCard\n key={property.id}\n id={property.id}\n title={property.title}\n price={property.price.amount}\n priceType={property.price.type === 'rent' ? 'rent' : 'sale'}\n pricePeriod={property.price.period}\n currency={property.price.currency}\n location={[property.location.neighborhood, property.location.city].filter(Boolean).join(', ')}\n bedrooms={property.specifications.bedrooms}\n bathrooms={property.specifications.bathrooms}\n area={property.specifications.totalArea}\n imageUrl={property.images[0]?.url}\n status={property.status.replace('_', ' ')}\n type={property.category}\n onClick={() => navigate(property.id)}\n isShortlisted={shortlistedIds.has(property.id)}\n onToggleShortlist={() => toggleShortlist(property.id)}\n />\n ))}\n </div>\n\n {/* Pagination (server-side): working prev/next + page-size, no silent truncation */}\n <Pagination\n page={page}\n pageSize={pageSize}\n hasNextPage={hasNextPage}\n hasPreviousPage={page > 1}\n loading={loading}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n </>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n icon={<Building className=\"h-12 w-12\" />}\n title={tr('housingvista.properties.empty.title', 'No properties found')}\n description={tr(\n 'housingvista.properties.empty.description',\n 'Try adjusting your search criteria or filters to find more properties.'\n )}\n action={\n <button\n onClick={clearFilters}\n className=\"rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90\"\n >\n {tr('housingvista.properties.empty.clearAllFilters', 'Clear All Filters')}\n </button>\n }\n />\n )}\n </PageLayout>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAyBA,IAAM,KAAY,GAEL,UAAuB;CAClC,IAAM,IAAW,GAAa,EACxB,EAAE,UAAM,GAAS,EAEjB,KAAM,GAAa,MAAqB;EAC5C,IAAM,IAAa,GAAE,EAAI;AACzB,SAAO,MAAe,IAAM,IAAW;IAGnC,KAAkE;EACtE;GAAE,OAAO;GAAO,OAAO,EAAG,qDAAqD,YAAY;GAAE;EAC7F;GAAE,OAAO;GAAe,OAAO,EAAG,6DAA6D,cAAc;GAAE;EAC/G;GAAE,OAAO;GAAc,OAAO,EAAG,4DAA4D,aAAa;GAAE;EAC5G;GAAE,OAAO;GAAc,OAAO,EAAG,4DAA4D,aAAa;GAAE;EAC5G;GAAE,OAAO;GAAgB,OAAO,EAAG,8DAA8D,eAAe;GAAE;EAClH;GAAE,OAAO;GAAa,OAAO,EAAG,0DAA0D,YAAY;GAAE;EACzG,EAEK,KAAuE;EAC3E;GAAE,OAAO;GAAO,OAAO,EAAG,wDAAwD,aAAa;GAAE;EACjG;GAAE,OAAO;GAAY,OAAO,EAAG,4DAA4D,WAAW;GAAE;EACxG;GAAE,OAAO;GAAY,OAAO,EAAG,4DAA4D,WAAW;GAAE;EACxG;GAAE,OAAO;GAAQ,OAAO,EAAG,yDAAyD,OAAO;GAAE;EAC7F;GAAE,OAAO;GAAU,OAAO,EAAG,2DAA2D,SAAS;GAAE;EACnG;GACE,OAAO;GACP,OAAO,EAAG,kEAAkE,iBAAiB;GAC9F;EACD;GAAE,OAAO;GAAc,OAAO,EAAG,8DAA8D,aAAa;GAAE;EAC/G,EAEK,KAA2E;EAC/E;GAAE,OAAO;GAAO,OAAO,EAAG,0DAA0D,iBAAiB;GAAE;EACvG;GAAE,OAAO;GAAa,OAAO,EAAG,gEAAgE,YAAY;GAAE;EAC9G;GAAE,OAAO;GAAS,OAAO,EAAG,4DAA4D,QAAQ;GAAE;EAClG;GAAE,OAAO;GAAS,OAAO,EAAG,4DAA4D,QAAQ;GAAE;EAClG;GAAE,OAAO;GAAU,OAAO,EAAG,6DAA6D,SAAS;GAAE;EACrG;GAAE,OAAO;GAAU,OAAO,EAAG,6DAA6D,SAAS;GAAE;EACrG;GAAE,OAAO;GAAa,OAAO,EAAG,gEAAgE,YAAY;GAAE;EAC9G;GAAE,OAAO;GAAQ,OAAO,EAAG,2DAA2D,OAAO;GAAE;EAC/F;GAAE,OAAO;GAAQ,OAAO,EAAG,2DAA2D,OAAO;GAAE;EAChG,EAEK,IAAc;EAClB;GAAE,OAAO;GAAO,OAAO,EAAG,mDAAmD,YAAY;GAAE,KAAK;GAAG,KAAK;GAAU;EAClH;GACE,OAAO;GACP,OAAO,EAAG,yDAAyD,cAAc;GACjF,KAAK;GACL,KAAK;GACN;EACD;GACE,OAAO;GACP,OAAO,EAAG,0DAA0D,gBAAgB;GACpF,KAAK;GACL,KAAK;GACN;EACD;GACE,OAAO;GACP,OAAO,EAAG,wDAAwD,cAAc;GAChF,KAAK;GACL,KAAK;GACN;EACD;GACE,OAAO;GACP,OAAO,EAAG,sDAAsD,WAAW;GAC3E,KAAK;GACL,KAAK;GACN;EACF,EAEK,KAAiB;EACrB;GAAE,OAAO;GAAO,OAAO,EAAG,gDAAgD,eAAe;GAAE;EAC3F;GAAE,OAAO;GAAK,OAAO;GAAM;EAC3B;GAAE,OAAO;GAAK,OAAO;GAAM;EAC3B;GAAE,OAAO;GAAK,OAAO;GAAM;EAC3B;GAAE,OAAO;GAAK,OAAO;GAAM;EAC3B;GAAE,OAAO;GAAK,OAAO;GAAM;EAC5B,EAEK,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAc,KAAmB,EAA+B,MAAM,EACvE,CAAC,GAAgB,KAAqB,EAAiC,MAAM,EAC7E,CAAC,GAAkB,KAAuB,EAAmC,MAAM,EACnF,CAAC,GAAoB,KAAyB,EAAS,MAAM,EAC7D,CAAC,GAAkB,KAAuB,EAAS,MAAM,EACzD,CAAC,GAAU,KAAe,EAA0B,OAAO,EAC3D,CAAC,GAAa,MAAkB,EAAS,GAAM,EAE/C,IAAa,EAAY,MAAM,MAAM,EAAE,UAAU,EAAmB,IAAI,EAAY,IACpF,IAAc,MAAqB,QAAQ,IAAI,OAAO,EAAiB,EAGvE,CAAC,GAAiB,MAAsB,EAAS,GAAG;AAC1D,SAAgB;EACd,IAAM,IAAQ,iBAAiB,GAAmB,EAAY,EAAE,IAAI;AACpE,eAAa,aAAa,EAAM;IAC/B,CAAC,EAAY,CAAC;CAEjB,IAAM,EAAE,SAAM,aAAU,gBAAY,YAAS,oBAAgB,GAAoB,GAAU,EAGrF,IAAe,QAA+C;EAClE,IAAM,IAA8B,EAAE;AAItC,SAHI,EAAgB,MAAM,KAAE,EAAO,SAAS,EAAgB,MAAM,GAC9D,MAAmB,UAAO,EAAO,SAAS,IAC1C,MAAiB,UAAO,EAAO,OAAO,IACnC,OAAO,KAAK,EAAO,CAAC,SAAS,IAAI,IAAS,KAAA;IAChD;EAAC;EAAiB;EAAgB;EAAa,CAAC;AAGnD,SAAgB;AACd,IAAQ,EAAE;IACT,CAAC,GAAc,EAAQ,CAAC;CAE3B,IAAM,EAAE,MAAM,GAAY,eAAY,GAAc;EAAE,QAAQ;EAAc;EAAY,CAAC,EAEnF,EAAE,MAAM,MAAmB,IAAmB,EAC9C,EAAE,MAAM,MAAe,IAAe,EACtC,EAAE,sBAAkB,GAAkB,EACtC,EAAE,uBAAoB,GAAoB,EAE1C,IAAiB,QAAc,IAAI,IAAI,EAAW,KAAK,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC,EAAW,CAAC,EAE1F,KAAkB,OAAO,MAAuB;AACpD,MAAI;AACF,GAAI,EAAe,IAAI,EAAW,IAChC,MAAM,EAAgB,EAAW,EACjC,EAAO,QAAQ,yBAAyB,KAExC,MAAM,GAAc,EAAW,EAC/B,EAAO,QAAQ,qBAAqB;WAE/B,GAAK;AACZ,KAAO,MAAM,8BAA+B,EAAc,QAAQ;;IAMhE,IAAqB,QAClB,EAAW,QAAQ,MAAa;EACrC,IAAM,IAAkB,MAAqB,SAAS,EAAS,aAAa,GACtE,IAAe,EAAS,MAAM,UAAU,EAAW,OAAO,EAAS,MAAM,UAAU,EAAW,KAC9F,KAAmB,EAAS,eAAe,YAAY,MAAM;AACnE,SAAO,KAAmB,KAAgB;GAC1C,EACD;EAAC;EAAY;EAAkB;EAAY;EAAY,CAAC,EAErD,KAAc,EAAW,UAAU,GAEnC,IACJ,KACA,MAAiB,SACjB,MAAmB,SACnB,MAAqB,SACrB,MAAuB,SACvB,MAAqB,OAEjB,UAAqB;AAMzB,EALA,EAAe,GAAG,EAClB,EAAgB,MAAM,EACtB,EAAkB,MAAM,EACxB,EAAoB,MAAM,EAC1B,EAAsB,MAAM,EAC5B,EAAoB,MAAM;;AAG5B,QACE,kBAAC,GAAD;EACE,OAAO,EAAG,iCAAiC,aAAa;EACxD,aAAa,EACX,uCACA,iEACD;EACD,SAAS,EACP,mCACA,sOACD;EACD,SACE,kBAAC,UAAD;GACE,eAAe,EAAS,MAAM;GAC9B,WAAU;aAFZ,CAIE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAC3B,EAAG,+CAA+C,eAAe,CAC3D;;YAjBb;GAqBE,kBAAC,GAAD;IAAe,WAAU;cACvB,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,GAAD;OACE,OAAO,EAAG,iDAAiD,mBAAmB;OAC9E,OAAO,EAAe;OACtB,MAAM,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;OACtC,CAAA;MACF,kBAAC,GAAD;OACE,OAAO,EAAG,gDAAgD,kBAAkB;OAC5E,OAAO,EAAe;OACtB,QAAO;OACP,CAAA;MACF,kBAAC,GAAD;OACE,OAAO,EAAG,+CAA+C,iBAAiB;OAC1E,OAAO,EAAe;OACtB,MAAK;OACL,CAAA;MACF,kBAAC,GAAD;OACE,OAAO,EAAG,gDAAgD,kBAAkB;OAC5E,OAAO,EAAe;OACtB,QAAO;OACP,CAAA;MACE;;IACQ,CAAA;GAGhB,kBAAC,IAAD;IACE,aAAa;IACb,gBAAgB;IAChB,mBAAmB,EACjB,8CACA,sDACD;IACD,SACE,kBAAC,UAAD;KACE,eAAe,IAAgB,MAAS,CAAC,EAAK;KAC9C,WAAW,EACT,yHACA,IAAc,kCAAkC,uCACjD;eALH;MAOE,kBAAC,GAAD,EAAmB,WAAU,WAAY,CAAA;MACxC,EAAG,0CAA0C,UAAU;MACvD,KACC,kBAAC,QAAD;OAAM,WAAU;iBAA4H;OAErI,CAAA;MAEF;;IAEX,SACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,UAAD;MACE,eAAe,EAAY,OAAO;MAClC,WAAW,EACT,oCACA,MAAa,SACT,kCACA,iEACL;gBAED,kBAAC,IAAD,EAAM,WAAU,WAAY,CAAA;MACrB,CAAA,EACT,kBAAC,UAAD;MACE,eAAe,EAAY,OAAO;MAClC,WAAW,EACT,oCACA,MAAa,SACT,kCACA,iEACL;gBAED,kBAAC,IAAD,EAAM,WAAU,WAAY,CAAA;MACrB,CAAA,CACL;;IAER,CAAA;GAGD,KACC,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBACX,EAAG,yCAAyC,UAAU;MACpD,CAAA,EACJ,KACC,kBAAC,UAAD;MACE,SAAS;MACT,WAAU;gBAFZ,CAIE,kBAAC,GAAD,EAAG,WAAU,WAAY,CAAA,EACxB,EAAG,4CAA4C,YAAY,CACrD;QAEP;QACN,kBAAC,OAAD;KAAK,WAAU;eAAf;MAEE,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBACd,EAAG,uDAAuD,gBAAgB;OACrE,CAAA,EACR,kBAAC,UAAD;OACE,OAAO;OACP,WAAW,MAAM,EAAgB,EAAE,OAAO,MAA8B;OACxE,WAAU;iBAET,GAAc,KAAK,MAClB,kBAAC,UAAD;QAAsB,OAAO,EAAE;kBAC5B,EAAE;QACI,EAFI,EAAE,MAEN,CACT;OACK,CAAA,CACL,EAAA,CAAA;MAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBACd,EAAG,iDAAiD,SAAS;OACxD,CAAA,EACR,kBAAC,UAAD;OACE,OAAO;OACP,WAAW,MAAM,EAAkB,EAAE,OAAO,MAAgC;OAC5E,WAAU;iBAET,GAAiB,KAAK,MACrB,kBAAC,UAAD;QAAsB,OAAO,EAAE;kBAC5B,EAAE;QACI,EAFI,EAAE,MAEN,CACT;OACK,CAAA,CACL,EAAA,CAAA;MAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBACd,EAAG,mDAAmD,WAAW;OAC5D,CAAA,EACR,kBAAC,UAAD;OACE,OAAO;OACP,WAAW,MAAM,EAAoB,EAAE,OAAO,MAAkC;OAChF,WAAU;iBAET,GAAmB,KAAK,MACvB,kBAAC,UAAD;QAAsB,OAAO,EAAE;kBAC5B,EAAE;QACI,EAFI,EAAE,MAEN,CACT;OACK,CAAA,CACL,EAAA,CAAA;MAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBACd,EAAG,qDAAqD,cAAc;OACjE,CAAA,EACR,kBAAC,UAAD;OACE,OAAO;OACP,WAAW,MAAM,EAAsB,EAAE,OAAO,MAAM;OACtD,WAAU;iBAET,EAAY,KAAK,MAChB,kBAAC,UAAD;QAAsB,OAAO,EAAE;kBAC5B,EAAE;QACI,EAFI,EAAE,MAEN,CACT;OACK,CAAA,CACL,EAAA,CAAA;MAGN,kBAAC,OAAD,EAAA,UAAA,CACE,kBAAC,SAAD;OAAO,WAAU;iBACd,EAAG,mDAAmD,WAAW;OAC5D,CAAA,EACR,kBAAC,UAAD;OACE,OAAO;OACP,WAAW,MAAM,EAAoB,EAAE,OAAO,MAAM;OACpD,WAAU;iBAET,GAAe,KAAK,MACnB,kBAAC,UAAD;QAAsB,OAAO,EAAE;kBAC5B,EAAE;QACI,EAFI,EAAE,MAEN,CACT;OACK,CAAA,CACL,EAAA,CAAA;MACF;OACF;;GAIR,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KAAG,WAAU;eAAb;MACG,EAAG,2CAA2C,UAAU;MAAC;MAAE,EAAmB;MAAQ;MACtF,EAAG,8CAA8C,aAAa;MAC9D,IAAO,IAAI,WAAW,MAAS;MAC9B;QACH,KACC,kBAAC,UAAD;KAAQ,SAAS;KAAc,WAAU;eACtC,EAAG,gDAAgD,gBAAgB;KAC7D,CAAA,CAEP;;GAGL,IACC,kBAAC,IAAD;IAAiB,SAAQ;IAAO,OAAO;IAAK,CAAA,GAC1C,EAAmB,SAAS,IAC9B,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;IACE,WAAW,EAAG,MAAa,SAAS,yDAAyD,YAAY;cAExG,EAAmB,KAAK,MACvB,kBAAC,IAAD;KAEE,IAAI,EAAS;KACb,OAAO,EAAS;KAChB,OAAO,EAAS,MAAM;KACtB,WAAW,EAAS,MAAM,SAAS,SAAS,SAAS;KACrD,aAAa,EAAS,MAAM;KAC5B,UAAU,EAAS,MAAM;KACzB,UAAU,CAAC,EAAS,SAAS,cAAc,EAAS,SAAS,KAAK,CAAC,OAAO,QAAQ,CAAC,KAAK,KAAK;KAC7F,UAAU,EAAS,eAAe;KAClC,WAAW,EAAS,eAAe;KACnC,MAAM,EAAS,eAAe;KAC9B,UAAU,EAAS,OAAO,IAAI;KAC9B,QAAQ,EAAS,OAAO,QAAQ,KAAK,IAAI;KACzC,MAAM,EAAS;KACf,eAAe,EAAS,EAAS,GAAG;KACpC,eAAe,EAAe,IAAI,EAAS,GAAG;KAC9C,yBAAyB,GAAgB,EAAS,GAAG;KACrD,EAjBK,EAAS,GAiBd,CACF;IACE,CAAA,EAGN,kBAAC,IAAD;IACQ;IACI;IACG;IACb,iBAAiB,IAAO;IACf;IACT,cAAc;IACd,kBAAkB;IAClB,CAAA,CACD,EAAA,CAAA,GAEH,kBAAC,GAAD;IACE,cAAa;IACb,MAAM,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA;IACxC,OAAO,EAAG,uCAAuC,sBAAsB;IACvE,aAAa,EACX,6CACA,yEACD;IACD,QACE,kBAAC,UAAD;KACE,SAAS;KACT,WAAU;eAET,EAAG,iDAAiD,oBAAoB;KAClE,CAAA;IAEX,CAAA;GAEO"}
1
+ {"version":3,"file":"PropertiesPage.js","names":[],"sources":["../../../../src/housingvista/pages/properties/PropertiesPage.tsx"],"sourcesContent":["/**\n * HousingVista Properties Listing Page\n * Migrated from legacy housingvista-frontend properties.tsx\n * @module housingvista\n */\n\nimport { useState, useMemo, useEffect } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { Plus, Grid, List, Building, SlidersHorizontal, X } from 'lucide-react';\nimport { EmphasisPanel, Pagination } from '@burdenoff/fe-libs/ui';\nimport { PageLayout, FilterBar, PropertyCard, EmptyState, StatCard, LoadingSkeleton } from '../../components';\nimport {\n useProperties,\n useShortlists,\n useSaveShortlist,\n useRemoveShortlist,\n useDashboardStats,\n type PropertyFilterInput,\n} from '../../hooks';\nimport { useServerPagination } from '../../hooks/useServerPagination';\nimport { useHousingVistaAnalytics, useTrackPageView } from '../../hooks/useHousingVistaAnalytics';\nimport { notify } from '../../lib/toast';\nimport { cn } from '../../utils/helpers';\nimport type { PropertyType, PropertyStatus, PropertyCategory } from '../../types';\n\nconst PAGE_SIZE = 9;\n\nexport const PropertiesPage = () => {\n const navigate = useNavigate();\n const { t } = useI18n();\n const { emit, emitResource, emitSearch } = useHousingVistaAnalytics();\n useTrackPageView('housingvista.property.viewed');\n\n const tr = (key: string, fallback: string) => {\n const translated = t(key);\n return translated === key ? fallback : translated;\n };\n\n const propertyTypes: { value: PropertyType | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.propertyTypes.all', 'All Types') },\n { value: 'residential', label: tr('housingvista.properties.filters.propertyTypes.residential', 'Residential') },\n { value: 'commercial', label: tr('housingvista.properties.filters.propertyTypes.commercial', 'Commercial') },\n { value: 'industrial', label: tr('housingvista.properties.filters.propertyTypes.industrial', 'Industrial') },\n { value: 'agricultural', label: tr('housingvista.properties.filters.propertyTypes.agricultural', 'Agricultural') },\n { value: 'mixed_use', label: tr('housingvista.properties.filters.propertyTypes.mixedUse', 'Mixed Use') },\n ];\n\n const propertyStatuses: { value: PropertyStatus | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.propertyStatuses.all', 'All Status') },\n { value: 'for_sale', label: tr('housingvista.properties.filters.propertyStatuses.forSale', 'For Sale') },\n { value: 'for_rent', label: tr('housingvista.properties.filters.propertyStatuses.forRent', 'For Rent') },\n { value: 'sold', label: tr('housingvista.properties.filters.propertyStatuses.sold', 'Sold') },\n { value: 'rented', label: tr('housingvista.properties.filters.propertyStatuses.rented', 'Rented') },\n {\n value: 'under_contract',\n label: tr('housingvista.properties.filters.propertyStatuses.underContract', 'Under Contract'),\n },\n { value: 'off_market', label: tr('housingvista.properties.filters.propertyStatuses.offMarket', 'Off Market') },\n ];\n\n const propertyCategories: { value: PropertyCategory | 'all'; label: string }[] = [\n { value: 'all', label: tr('housingvista.properties.filters.propertyCategories.all', 'All Categories') },\n { value: 'apartment', label: tr('housingvista.properties.filters.propertyCategories.apartment', 'Apartment') },\n { value: 'house', label: tr('housingvista.properties.filters.propertyCategories.house', 'House') },\n { value: 'villa', label: tr('housingvista.properties.filters.propertyCategories.villa', 'Villa') },\n { value: 'office', label: tr('housingvista.properties.filters.propertyCategories.office', 'Office') },\n { value: 'retail', label: tr('housingvista.properties.filters.propertyCategories.retail', 'Retail') },\n { value: 'warehouse', label: tr('housingvista.properties.filters.propertyCategories.warehouse', 'Warehouse') },\n { value: 'land', label: tr('housingvista.properties.filters.propertyCategories.land', 'Land') },\n { value: 'plot', label: tr('housingvista.properties.filters.propertyCategories.plot', 'Plot') },\n ];\n\n const priceRanges = [\n { value: 'all', label: tr('housingvista.properties.filters.priceRanges.all', 'Any Price'), min: 0, max: Infinity },\n {\n value: 'under_100k',\n label: tr('housingvista.properties.filters.priceRanges.under100k', 'Under $100K'),\n min: 0,\n max: 100000,\n },\n {\n value: '100k_500k',\n label: tr('housingvista.properties.filters.priceRanges.100kTo500k', '$100K - $500K'),\n min: 100000,\n max: 500000,\n },\n {\n value: '500k_1m',\n label: tr('housingvista.properties.filters.priceRanges.500kTo1m', '$500K - $1M'),\n min: 500000,\n max: 1000000,\n },\n {\n value: 'over_1m',\n label: tr('housingvista.properties.filters.priceRanges.over1m', 'Over $1M'),\n min: 1000000,\n max: Infinity,\n },\n ];\n\n const bedroomOptions = [\n { value: 'all', label: tr('housingvista.properties.filters.bedrooms.all', 'Any Bedrooms') },\n { value: '1', label: '1+' },\n { value: '2', label: '2+' },\n { value: '3', label: '3+' },\n { value: '4', label: '4+' },\n { value: '5', label: '5+' },\n ];\n\n const [searchQuery, setSearchQuery] = useState('');\n const [selectedType, setSelectedType] = useState<PropertyType | 'all'>('all');\n const [selectedStatus, setSelectedStatus] = useState<PropertyStatus | 'all'>('all');\n const [selectedCategory, setSelectedCategory] = useState<PropertyCategory | 'all'>('all');\n const [selectedPriceRange, setSelectedPriceRange] = useState('all');\n const [selectedBedrooms, setSelectedBedrooms] = useState('all');\n const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');\n const [showFilters, setShowFilters] = useState(false);\n\n const priceRange = priceRanges.find((r) => r.value === selectedPriceRange) ?? priceRanges[0];\n const minBedrooms = selectedBedrooms === 'all' ? 0 : Number(selectedBedrooms);\n\n // Debounce the search box so we don't refetch on every keystroke.\n const [debouncedSearch, setDebouncedSearch] = useState('');\n useEffect(() => {\n const timer = setTimeout(() => setDebouncedSearch(searchQuery), 300);\n return () => clearTimeout(timer);\n }, [searchQuery]);\n\n // Analytics: emit search event when a non-empty debounced query is entered.\n useEffect(() => {\n if (debouncedSearch.trim()) {\n emitSearch('properties');\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [debouncedSearch]);\n\n const { page, pageSize, pagination, setPage, setPageSize } = useServerPagination(PAGE_SIZE);\n\n // Server-side filter uses the schema-supported fields (search/status/type).\n const serverFilter = useMemo<PropertyFilterInput | undefined>(() => {\n const filter: PropertyFilterInput = {};\n if (debouncedSearch.trim()) filter.search = debouncedSearch.trim();\n if (selectedStatus !== 'all') filter.status = selectedStatus;\n if (selectedType !== 'all') filter.type = selectedType;\n return Object.keys(filter).length > 0 ? filter : undefined;\n }, [debouncedSearch, selectedStatus, selectedType]);\n\n // Reset to first page whenever the server-side filter changes.\n useEffect(() => {\n setPage(1);\n }, [serverFilter, setPage]);\n\n const { data: properties, loading } = useProperties({ filter: serverFilter, pagination });\n // Portfolio-wide totals for the stats zone — independent of the current page slice.\n const { data: dashboardStats } = useDashboardStats();\n const { data: shortlists } = useShortlists();\n const { saveShortlist } = useSaveShortlist();\n const { removeShortlist } = useRemoveShortlist();\n\n const shortlistedIds = useMemo(() => new Set(shortlists.map((s) => s.propertyId)), [shortlists]);\n\n const toggleShortlist = async (propertyId: string) => {\n try {\n if (shortlistedIds.has(propertyId)) {\n await removeShortlist(propertyId);\n notify.success('Removed from shortlist');\n } else {\n await saveShortlist(propertyId);\n emitResource('housingvista.shortlist.property_added', propertyId);\n notify.success('Saved to shortlist');\n }\n } catch (err) {\n notify.error('Could not update shortlist', (err as Error).message);\n }\n };\n\n // Category, price range, and bedrooms are refined on the client (the subgraph\n // filter input does not model them).\n const filteredProperties = useMemo(() => {\n return properties.filter((property) => {\n const matchesCategory = selectedCategory === 'all' || property.category === selectedCategory;\n const matchesPrice = property.price.amount >= priceRange.min && property.price.amount <= priceRange.max;\n const matchesBedrooms = (property.specifications.bedrooms ?? 0) >= minBedrooms;\n return matchesCategory && matchesPrice && matchesBedrooms;\n });\n }, [properties, selectedCategory, priceRange, minBedrooms]);\n\n const hasNextPage = properties.length >= pageSize;\n\n const hasActiveFilters =\n searchQuery ||\n selectedType !== 'all' ||\n selectedStatus !== 'all' ||\n selectedCategory !== 'all' ||\n selectedPriceRange !== 'all' ||\n selectedBedrooms !== 'all';\n\n const clearFilters = () => {\n setSearchQuery('');\n setSelectedType('all');\n setSelectedStatus('all');\n setSelectedCategory('all');\n setSelectedPriceRange('all');\n setSelectedBedrooms('all');\n };\n\n return (\n <PageLayout\n title={tr('housingvista.properties.title', 'Properties')}\n description={tr(\n 'housingvista.properties.description',\n 'Discover your perfect property from our comprehensive listings'\n )}\n purpose={tr(\n 'housingvista.properties.purpose',\n 'Browse, search, and filter every property in your portfolio or on the market. Use the filters to narrow by type, status, price, and bedrooms, then open any listing to see full details, schedule viewings, or start a transaction.'\n )}\n actions={\n <button\n onClick={() => {\n emit('housingvista.property.create_clicked');\n navigate('new');\n }}\n className=\"inline-flex items-center gap-2 rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90\"\n >\n <Plus className=\"h-4 w-4\" />\n {tr('housingvista.properties.actions.addProperty', 'Add Property')}\n </button>\n }\n >\n {/* Stats — primary insight zone (one EmphasisPanel per page) */}\n <EmphasisPanel className=\"p-4\">\n <div className=\"grid grid-cols-2 gap-4 lg:grid-cols-4\">\n <StatCard\n label={tr('housingvista.properties.stats.totalProperties', 'Total Properties')}\n value={dashboardStats.totalProperties}\n icon={<Building className=\"h-5 w-5\" />}\n />\n <StatCard\n label={tr('housingvista.properties.stats.portfolioValue', 'Portfolio Value')}\n value={dashboardStats.totalValue}\n prefix=\"$\"\n />\n <StatCard\n label={tr('housingvista.properties.stats.occupancyRate', 'Occupancy Rate')}\n value={dashboardStats.occupancyRate}\n unit=\"%\"\n />\n <StatCard\n label={tr('housingvista.properties.stats.monthlyRevenue', 'Monthly Revenue')}\n value={dashboardStats.monthlyRevenue}\n prefix=\"$\"\n />\n </div>\n </EmphasisPanel>\n\n {/* Search + View Toggle */}\n <FilterBar\n searchValue={searchQuery}\n onSearchChange={setSearchQuery}\n searchPlaceholder={tr(\n 'housingvista.properties.search.placeholder',\n 'Search properties by name, city, or neighborhood...'\n )}\n filters={\n <button\n onClick={() => setShowFilters((prev) => !prev)}\n className={cn(\n 'inline-flex items-center gap-2 rounded-md border border-border-subtle px-3 py-2 text-sm font-medium transition-colors',\n showFilters ? 'bg-foreground text-background' : 'text-text-primary hover:bg-bg-sunken'\n )}\n >\n <SlidersHorizontal className=\"h-4 w-4\" />\n {tr('housingvista.properties.filters.toggle', 'Filters')}\n {hasActiveFilters && (\n <span className=\"flex h-5 w-5 items-center justify-center rounded-full bg-action-primary-bg text-[10px] font-bold text-action-primary-text\">\n !\n </span>\n )}\n </button>\n }\n actions={\n <div className=\"flex items-center gap-1\">\n <button\n onClick={() => setViewMode('grid')}\n className={cn(\n 'rounded-md p-2 transition-colors',\n viewMode === 'grid'\n ? 'bg-foreground text-background'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-sunken'\n )}\n >\n <Grid className=\"h-4 w-4\" />\n </button>\n <button\n onClick={() => setViewMode('list')}\n className={cn(\n 'rounded-md p-2 transition-colors',\n viewMode === 'list'\n ? 'bg-foreground text-background'\n : 'text-text-secondary hover:text-text-primary hover:bg-bg-sunken'\n )}\n >\n <List className=\"h-4 w-4\" />\n </button>\n </div>\n }\n />\n\n {/* Filter Dropdowns */}\n {showFilters && (\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-4\">\n <div className=\"flex items-center justify-between mb-4\">\n <h3 className=\"text-sm font-medium text-text-primary\">\n {tr('housingvista.properties.filters.title', 'Filters')}\n </h3>\n {hasActiveFilters && (\n <button\n onClick={clearFilters}\n className=\"inline-flex items-center gap-1 text-xs text-text-secondary hover:text-text-primary\"\n >\n <X className=\"h-3 w-3\" />\n {tr('housingvista.properties.filters.clearAll', 'Clear All')}\n </button>\n )}\n </div>\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-3 lg:grid-cols-5\">\n {/* Type */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.propertyType', 'Property Type')}\n </label>\n <select\n value={selectedType}\n onChange={(e) => setSelectedType(e.target.value as PropertyType | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {propertyTypes.map((t) => (\n <option key={t.value} value={t.value}>\n {t.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Status */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.status', 'Status')}\n </label>\n <select\n value={selectedStatus}\n onChange={(e) => setSelectedStatus(e.target.value as PropertyStatus | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {propertyStatuses.map((s) => (\n <option key={s.value} value={s.value}>\n {s.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Category */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.category', 'Category')}\n </label>\n <select\n value={selectedCategory}\n onChange={(e) => setSelectedCategory(e.target.value as PropertyCategory | 'all')}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {propertyCategories.map((c) => (\n <option key={c.value} value={c.value}>\n {c.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Price Range */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.priceRange', 'Price Range')}\n </label>\n <select\n value={selectedPriceRange}\n onChange={(e) => setSelectedPriceRange(e.target.value)}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {priceRanges.map((r) => (\n <option key={r.value} value={r.value}>\n {r.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* Bedrooms */}\n <div>\n <label className=\"mb-1.5 block text-xs font-medium text-text-secondary\">\n {tr('housingvista.properties.filters.labels.bedrooms', 'Bedrooms')}\n </label>\n <select\n value={selectedBedrooms}\n onChange={(e) => setSelectedBedrooms(e.target.value)}\n className=\"h-9 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]\"\n >\n {bedroomOptions.map((b) => (\n <option key={b.value} value={b.value}>\n {b.label}\n </option>\n ))}\n </select>\n </div>\n </div>\n </div>\n )}\n\n {/* Results Count */}\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-text-secondary\">\n {tr('housingvista.properties.results.showing', 'Showing')} {filteredProperties.length}{' '}\n {tr('housingvista.properties.results.properties', 'properties')}\n {page > 1 ? ` · page ${page}` : ''}\n </p>\n {hasActiveFilters && (\n <button onClick={clearFilters} className=\"text-sm text-text-secondary hover:text-text-primary\">\n {tr('housingvista.properties.results.clearFilters', 'Clear Filters')}\n </button>\n )}\n </div>\n\n {/* Property Grid / List */}\n {loading ? (\n <LoadingSkeleton variant=\"card\" count={6} />\n ) : filteredProperties.length > 0 ? (\n <>\n <div\n className={cn(viewMode === 'grid' ? 'grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3' : 'space-y-4')}\n >\n {filteredProperties.map((property) => (\n <PropertyCard\n key={property.id}\n id={property.id}\n title={property.title}\n price={property.price.amount}\n priceType={property.price.type === 'rent' ? 'rent' : 'sale'}\n pricePeriod={property.price.period}\n currency={property.price.currency}\n location={[property.location.neighborhood, property.location.city].filter(Boolean).join(', ')}\n bedrooms={property.specifications.bedrooms}\n bathrooms={property.specifications.bathrooms}\n area={property.specifications.totalArea}\n imageUrl={property.images[0]?.url}\n status={property.status.replace('_', ' ')}\n type={property.category}\n onClick={() => navigate(property.id)}\n isShortlisted={shortlistedIds.has(property.id)}\n onToggleShortlist={() => toggleShortlist(property.id)}\n />\n ))}\n </div>\n\n {/* Pagination (server-side): working prev/next + page-size, no silent truncation */}\n <Pagination\n page={page}\n pageSize={pageSize}\n hasNextPage={hasNextPage}\n hasPreviousPage={page > 1}\n loading={loading}\n onPageChange={setPage}\n onPageSizeChange={setPageSize}\n />\n </>\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n icon={<Building className=\"h-12 w-12\" />}\n title={tr('housingvista.properties.empty.title', 'No properties found')}\n description={tr(\n 'housingvista.properties.empty.description',\n 'Try adjusting your search criteria or filters to find more properties.'\n )}\n action={\n <button\n onClick={clearFilters}\n className=\"rounded-md bg-foreground px-4 py-2 text-sm font-medium text-background transition-colors hover:bg-foreground/90\"\n >\n {tr('housingvista.properties.empty.clearAllFilters', 'Clear All Filters')}\n </button>\n }\n />\n )}\n </PageLayout>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * HousingVista Property Detail Page
3
+ * Full property detail view backed by the single-item `housingvistaProperty(id)`
4
+ * query, with the core buyer journey wired to real mutations: shortlist, book a
5
+ * viewing, submit an offer, plus owner-side edit and delete.
6
+ * @module housingvista
7
+ */
8
+ export declare const PropertyDetailPage: () => import("react").JSX.Element;
9
+ //# sourceMappingURL=PropertyDetailPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PropertyDetailPage.d.ts","sourceRoot":"","sources":["../../../../src/housingvista/pages/properties/PropertyDetailPage.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA2HH,eAAO,MAAM,kBAAkB,mCA+vC9B,CAAC"}