@burdenoff/microfe-housingvista 2026.709.2 → 2026.709.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/housingvista/HousingVistaRoutes.d.ts.map +1 -1
  2. package/dist/housingvista/HousingVistaRoutes.js +136 -37
  3. package/dist/housingvista/HousingVistaRoutes.js.map +1 -1
  4. package/dist/housingvista/hooks/useHousingVistaAnalytics.d.ts +1 -1
  5. package/dist/housingvista/hooks/useHousingVistaAnalytics.d.ts.map +1 -1
  6. package/dist/housingvista/hooks/useHousingVistaAnalytics.js +4 -4
  7. package/dist/housingvista/hooks/useHousingVistaAnalytics.js.map +1 -1
  8. package/dist/housingvista/pages/amc/AMCManagementPage.d.ts.map +1 -1
  9. package/dist/housingvista/pages/amc/AMCManagementPage.js +62 -60
  10. package/dist/housingvista/pages/amc/AMCManagementPage.js.map +1 -1
  11. package/dist/housingvista/pages/assets/AssetDetailPage.d.ts.map +1 -1
  12. package/dist/housingvista/pages/assets/AssetDetailPage.js +141 -138
  13. package/dist/housingvista/pages/assets/AssetDetailPage.js.map +1 -1
  14. package/dist/housingvista/pages/assets/AssetManagementPage.d.ts.map +1 -1
  15. package/dist/housingvista/pages/assets/AssetManagementPage.js +193 -191
  16. package/dist/housingvista/pages/assets/AssetManagementPage.js.map +1 -1
  17. package/dist/housingvista/pages/chat/ChatPage.d.ts.map +1 -1
  18. package/dist/housingvista/pages/chat/ChatPage.js +115 -113
  19. package/dist/housingvista/pages/chat/ChatPage.js.map +1 -1
  20. package/dist/housingvista/pages/finance/HomeLoanDetailPage.d.ts.map +1 -1
  21. package/dist/housingvista/pages/finance/HomeLoanDetailPage.js +152 -149
  22. package/dist/housingvista/pages/finance/HomeLoanDetailPage.js.map +1 -1
  23. package/dist/housingvista/pages/finance/HomeLoansPage.d.ts.map +1 -1
  24. package/dist/housingvista/pages/finance/HomeLoansPage.js +141 -139
  25. package/dist/housingvista/pages/finance/HomeLoansPage.js.map +1 -1
  26. package/dist/housingvista/pages/investments/InvestmentDetailPage.d.ts.map +1 -1
  27. package/dist/housingvista/pages/investments/InvestmentDetailPage.js +290 -287
  28. package/dist/housingvista/pages/investments/InvestmentDetailPage.js.map +1 -1
  29. package/dist/housingvista/pages/investments/InvestmentsPage.d.ts.map +1 -1
  30. package/dist/housingvista/pages/investments/InvestmentsPage.js +64 -62
  31. package/dist/housingvista/pages/investments/InvestmentsPage.js.map +1 -1
  32. package/dist/housingvista/pages/legal/LegalPage.d.ts.map +1 -1
  33. package/dist/housingvista/pages/legal/LegalPage.js +95 -93
  34. package/dist/housingvista/pages/legal/LegalPage.js.map +1 -1
  35. package/dist/housingvista/pages/legal/LegalServiceDetailPage.d.ts.map +1 -1
  36. package/dist/housingvista/pages/legal/LegalServiceDetailPage.js +129 -126
  37. package/dist/housingvista/pages/legal/LegalServiceDetailPage.js.map +1 -1
  38. package/dist/housingvista/pages/market/AreaInsightsPage.d.ts.map +1 -1
  39. package/dist/housingvista/pages/market/AreaInsightsPage.js +99 -97
  40. package/dist/housingvista/pages/market/AreaInsightsPage.js.map +1 -1
  41. package/dist/housingvista/pages/market/MarketAnalyticsPage.d.ts.map +1 -1
  42. package/dist/housingvista/pages/market/MarketAnalyticsPage.js +138 -136
  43. package/dist/housingvista/pages/market/MarketAnalyticsPage.js.map +1 -1
  44. package/dist/housingvista/pages/marketplace/MarketplacePage.d.ts.map +1 -1
  45. package/dist/housingvista/pages/marketplace/MarketplacePage.js +99 -97
  46. package/dist/housingvista/pages/marketplace/MarketplacePage.js.map +1 -1
  47. package/dist/housingvista/pages/marketplace/ServiceDetailPage.d.ts.map +1 -1
  48. package/dist/housingvista/pages/marketplace/ServiceDetailPage.js +137 -134
  49. package/dist/housingvista/pages/marketplace/ServiceDetailPage.js.map +1 -1
  50. package/dist/housingvista/pages/offers/OffersPage.d.ts.map +1 -1
  51. package/dist/housingvista/pages/offers/OffersPage.js +94 -92
  52. package/dist/housingvista/pages/offers/OffersPage.js.map +1 -1
  53. package/dist/housingvista/pages/properties/AddPropertyPage.d.ts.map +1 -1
  54. package/dist/housingvista/pages/properties/AddPropertyPage.js +280 -279
  55. package/dist/housingvista/pages/properties/AddPropertyPage.js.map +1 -1
  56. package/dist/housingvista/pages/rental/RentalManagementPage.d.ts.map +1 -1
  57. package/dist/housingvista/pages/rental/RentalManagementPage.js +153 -151
  58. package/dist/housingvista/pages/rental/RentalManagementPage.js.map +1 -1
  59. package/dist/housingvista/pages/settings/ProfilePage.d.ts.map +1 -1
  60. package/dist/housingvista/pages/settings/ProfilePage.js +52 -50
  61. package/dist/housingvista/pages/settings/ProfilePage.js.map +1 -1
  62. package/dist/housingvista/pages/settings/SettingsPage.d.ts.map +1 -1
  63. package/dist/housingvista/pages/settings/SettingsPage.js +54 -52
  64. package/dist/housingvista/pages/settings/SettingsPage.js.map +1 -1
  65. package/dist/housingvista/pages/shortlist/ShortlistPage.d.ts.map +1 -1
  66. package/dist/housingvista/pages/shortlist/ShortlistPage.js +43 -41
  67. package/dist/housingvista/pages/shortlist/ShortlistPage.js.map +1 -1
  68. package/dist/housingvista/pages/transactions/TransactionDetailPage.d.ts.map +1 -1
  69. package/dist/housingvista/pages/transactions/TransactionDetailPage.js +211 -208
  70. package/dist/housingvista/pages/transactions/TransactionDetailPage.js.map +1 -1
  71. package/dist/housingvista/pages/transactions/TransactionsPage.d.ts.map +1 -1
  72. package/dist/housingvista/pages/transactions/TransactionsPage.js +85 -83
  73. package/dist/housingvista/pages/transactions/TransactionsPage.js.map +1 -1
  74. package/dist/housingvista/pages/verification/VerificationDetailPage.d.ts.map +1 -1
  75. package/dist/housingvista/pages/verification/VerificationDetailPage.js +25 -22
  76. package/dist/housingvista/pages/verification/VerificationDetailPage.js.map +1 -1
  77. package/dist/housingvista/pages/verification/VerificationPage.d.ts.map +1 -1
  78. package/dist/housingvista/pages/verification/VerificationPage.js +123 -121
  79. package/dist/housingvista/pages/verification/VerificationPage.js.map +1 -1
  80. package/dist/housingvista/pages/viewings/ViewingsPage.d.ts.map +1 -1
  81. package/dist/housingvista/pages/viewings/ViewingsPage.js +128 -126
  82. package/dist/housingvista/pages/viewings/ViewingsPage.js.map +1 -1
  83. package/package.json +1 -1
@@ -3,17 +3,18 @@ import { PageLayout as r } from "../../components/PageLayout.js";
3
3
  import { StatCard as i } from "../../components/StatCard.js";
4
4
  import { StatusBadge as a } from "../../components/StatusBadge.js";
5
5
  import { EmptyState as o } from "../../components/EmptyState.js";
6
- import { useOffers as s, useRespondOffer as c, useWithdrawOffer as l } from "../../hooks/index.js";
7
- import { notify as u } from "../../lib/toast.js";
6
+ import { useTrackPageView as s } from "../../hooks/useHousingVistaAnalytics.js";
7
+ import { useOffers as c, useRespondOffer as l, useWithdrawOffer as u } from "../../hooks/index.js";
8
+ import { notify as d } from "../../lib/toast.js";
8
9
  import "../../components/index.js";
9
- import { useServerPagination as d } from "../../hooks/useServerPagination.js";
10
- import { useState as f } from "react";
11
- import { ArrowRight as p, Check as m, Home as h, MapPin as g, Repeat as _, Tag as v, Undo2 as y, X as b } from "lucide-react";
10
+ import { useServerPagination as f } from "../../hooks/useServerPagination.js";
11
+ import { useState as p } from "react";
12
+ import { ArrowRight as m, Check as h, Home as g, MapPin as _, Repeat as v, Tag as y, Undo2 as b, X as ee } from "lucide-react";
12
13
  import { useNavigate as x } from "react-router-dom";
13
14
  import { jsx as S, jsxs as C } from "react/jsx-runtime";
14
- import { Button as w, EmphasisPanel as T, GlassCard as E, Pagination as D, ResponsiveDialog as O, ResponsiveDialogContent as ee, ResponsiveDialogDescription as te, ResponsiveDialogFooter as ne, ResponsiveDialogHeader as k, ResponsiveDialogTitle as A } from "@burdenoff/fe-libs/ui";
15
+ import { Button as w, EmphasisPanel as T, GlassCard as te, Pagination as ne, ResponsiveDialog as re, ResponsiveDialogContent as ie, ResponsiveDialogDescription as E, ResponsiveDialogFooter as D, ResponsiveDialogHeader as O, ResponsiveDialogTitle as k } from "@burdenoff/fe-libs/ui";
15
16
  //#region src/housingvista/pages/offers/OffersPage.tsx
16
- var j = [
17
+ var A = [
17
18
  {
18
19
  value: "all",
19
20
  label: "All"
@@ -39,7 +40,7 @@ var j = [
39
40
  label: "Withdrawn"
40
41
  }
41
42
  ];
42
- function M(e) {
43
+ function j(e) {
43
44
  switch (e) {
44
45
  case "accepted": return "success";
45
46
  case "countered": return "warning";
@@ -48,14 +49,14 @@ function M(e) {
48
49
  default: return "muted";
49
50
  }
50
51
  }
51
- var N = {
52
+ var M = {
52
53
  success: "bg-status-success",
53
54
  warning: "bg-status-warning",
54
55
  error: "bg-status-error",
55
56
  info: "bg-status-info",
56
57
  muted: "bg-text-secondary"
57
58
  };
58
- function P(e) {
59
+ function N(e) {
59
60
  let t = {
60
61
  label: "Submitted",
61
62
  date: e.createdAt,
@@ -119,8 +120,8 @@ function P(e) {
119
120
  }];
120
121
  }
121
122
  }
122
- function F({ offer: t }) {
123
- let r = P(t);
123
+ function P({ offer: t }) {
124
+ let r = N(t);
124
125
  return /* @__PURE__ */ S("ol", {
125
126
  className: "flex items-start",
126
127
  "aria-label": "Offer status timeline",
@@ -130,7 +131,7 @@ function F({ offer: t }) {
130
131
  className: e("flex flex-col items-center", !a && "flex-1"),
131
132
  children: [/* @__PURE__ */ C("div", {
132
133
  className: "flex w-full items-center",
133
- children: [/* @__PURE__ */ S("span", { className: e("flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-full", t.filled ? N[t.tone] : "border-2 border-border-subtle bg-bg-surface") }), !a && /* @__PURE__ */ S("span", { className: e("mx-1 h-0.5 flex-1 rounded-full", t.filled && o ? N[t.tone] : "bg-border-subtle") })]
134
+ children: [/* @__PURE__ */ S("span", { className: e("flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-full", t.filled ? M[t.tone] : "border-2 border-border-subtle bg-bg-surface") }), !a && /* @__PURE__ */ S("span", { className: e("mx-1 h-0.5 flex-1 rounded-full", t.filled && o ? M[t.tone] : "bg-border-subtle") })]
134
135
  }), /* @__PURE__ */ C("div", {
135
136
  className: e("mt-1.5 text-center", a ? "items-end" : ""),
136
137
  children: [/* @__PURE__ */ S("span", {
@@ -145,42 +146,43 @@ function F({ offer: t }) {
145
146
  })
146
147
  });
147
148
  }
148
- var I = "h-10 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]";
149
- function L() {
150
- let N = x(), P = d(10), [L, R] = f("all"), { data: z, loading: B } = s({
151
- filter: L === "all" ? void 0 : { status: L },
152
- pagination: P.pagination
153
- }), { data: V } = s({ pagination: {
149
+ var F = "h-10 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]";
150
+ function I() {
151
+ s("housingvista.offer.viewed");
152
+ let M = x(), N = f(10), [I, L] = p("all"), { data: R, loading: z } = c({
153
+ filter: I === "all" ? void 0 : { status: I },
154
+ pagination: N.pagination
155
+ }), { data: B } = c({ pagination: {
154
156
  limit: 100,
155
157
  offset: 0
156
- } }), { respondOffer: H, loading: U } = c(), { withdrawOffer: W, loading: G } = l(), [K, q] = f(null), [J, Y] = f("accept"), [X, Z] = f(""), [Q, $] = f(""), re = (e) => {
157
- q(e), Y("accept"), Z(String(e.amount)), $("");
158
- }, ie = async (e) => {
159
- if (e.preventDefault(), K) {
160
- if (J === "counter") {
161
- let e = Number(X);
158
+ } }), { respondOffer: V, loading: H } = l(), { withdrawOffer: U, loading: W } = u(), [G, K] = p(null), [q, J] = p("accept"), [Y, X] = p(""), [Z, Q] = p(""), ae = (e) => {
159
+ K(e), J("accept"), X(String(e.amount)), Q("");
160
+ }, oe = async (e) => {
161
+ if (e.preventDefault(), G) {
162
+ if (q === "counter") {
163
+ let e = Number(Y);
162
164
  if (!Number.isFinite(e) || e <= 0) {
163
- u.warning("Enter a valid counter amount");
165
+ d.warning("Enter a valid counter amount");
164
166
  return;
165
167
  }
166
168
  }
167
169
  try {
168
- await H(K.id, {
169
- action: J,
170
- counterAmount: J === "counter" ? Number(X) : void 0,
171
- notes: Q.trim() || void 0
172
- }), u.success("Response sent", `Offer ${J === "accept" ? "accepted" : J === "reject" ? "rejected" : "countered"}.`), q(null);
170
+ await V(G.id, {
171
+ action: q,
172
+ counterAmount: q === "counter" ? Number(Y) : void 0,
173
+ notes: Z.trim() || void 0
174
+ }), d.success("Response sent", `Offer ${q === "accept" ? "accepted" : q === "reject" ? "rejected" : "countered"}.`), K(null);
173
175
  } catch (e) {
174
- u.error("Could not respond to offer", e.message);
176
+ d.error("Could not respond to offer", e.message);
175
177
  }
176
178
  }
177
- }, ae = async (e) => {
179
+ }, se = async (e) => {
178
180
  try {
179
- await W(e.id), u.success("Offer withdrawn");
181
+ await U(e.id), d.success("Offer withdrawn");
180
182
  } catch (e) {
181
- u.error("Could not withdraw offer", e.message);
183
+ d.error("Could not withdraw offer", e.message);
182
184
  }
183
- }, oe = (e) => e === "all" ? V.length : V.filter((t) => t.status === e).length, se = V.filter((e) => e.status === "submitted" || e.status === "countered").length, ce = V.filter((e) => e.status === "accepted").length;
185
+ }, ce = (e) => e === "all" ? B.length : B.filter((t) => t.status === e).length, le = B.filter((e) => e.status === "submitted" || e.status === "countered").length, $ = B.filter((e) => e.status === "accepted").length;
184
186
  return /* @__PURE__ */ C(r, {
185
187
  title: "Offers",
186
188
  description: "Track the offers you have made and respond to offers on your listings",
@@ -193,29 +195,29 @@ function L() {
193
195
  children: [
194
196
  /* @__PURE__ */ S(i, {
195
197
  label: "Total offers",
196
- value: V.length,
197
- icon: /* @__PURE__ */ S(v, { className: "h-4 w-4" })
198
+ value: B.length,
199
+ icon: /* @__PURE__ */ S(y, { className: "h-4 w-4" })
198
200
  }),
199
201
  /* @__PURE__ */ S(i, {
200
202
  label: "Awaiting action",
201
- value: se,
202
- icon: /* @__PURE__ */ S(_, { className: "h-4 w-4" })
203
+ value: le,
204
+ icon: /* @__PURE__ */ S(v, { className: "h-4 w-4" })
203
205
  }),
204
206
  /* @__PURE__ */ S(i, {
205
207
  label: "Accepted",
206
- value: ce,
207
- icon: /* @__PURE__ */ S(m, { className: "h-4 w-4" })
208
+ value: $,
209
+ icon: /* @__PURE__ */ S(h, { className: "h-4 w-4" })
208
210
  })
209
211
  ]
210
212
  })
211
213
  }),
212
214
  /* @__PURE__ */ S("div", {
213
215
  className: "-mx-1 flex flex-nowrap items-center gap-2 overflow-x-auto px-1 pb-1 sm:flex-wrap sm:overflow-visible",
214
- children: j.map((t) => {
215
- let n = oe(t.value), r = L === t.value;
216
+ children: A.map((t) => {
217
+ let n = ce(t.value), r = I === t.value;
216
218
  return /* @__PURE__ */ C("button", {
217
219
  onClick: () => {
218
- R(t.value), P.setPage(1);
220
+ L(t.value), N.setPage(1);
219
221
  },
220
222
  className: e("inline-flex shrink-0 items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors", r ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
221
223
  children: [t.label, /* @__PURE__ */ S("span", {
@@ -225,22 +227,22 @@ function L() {
225
227
  }, t.value);
226
228
  })
227
229
  }),
228
- z.length === 0 && !B ? /* @__PURE__ */ S(o, {
230
+ R.length === 0 && !z ? /* @__PURE__ */ S(o, {
229
231
  illustration: "empty-search",
230
- icon: /* @__PURE__ */ S(v, { className: "h-12 w-12" }),
232
+ icon: /* @__PURE__ */ S(y, { className: "h-12 w-12" }),
231
233
  title: "No offers here",
232
234
  description: "Offers you submit on properties — and offers made on your listings — will appear here.",
233
235
  action: /* @__PURE__ */ S(w, {
234
- onClick: () => N("../properties"),
236
+ onClick: () => M("../properties"),
235
237
  children: "Browse properties"
236
238
  })
237
239
  }) : /* @__PURE__ */ C("div", {
238
240
  className: "space-y-4",
239
241
  children: [/* @__PURE__ */ S("div", {
240
242
  className: "grid grid-cols-1 gap-4 xl:grid-cols-2",
241
- children: z.map((e) => {
243
+ children: R.map((e) => {
242
244
  let r = e.property?.images.find((e) => e.isPrimary) ?? e.property?.images[0], i = e.status === "submitted" || e.status === "countered";
243
- return /* @__PURE__ */ C(E, {
245
+ return /* @__PURE__ */ C(te, {
244
246
  treatment: i ? "insight" : "plain",
245
247
  glow: i,
246
248
  className: "flex flex-col gap-4 p-5",
@@ -249,7 +251,7 @@ function L() {
249
251
  className: "flex items-start gap-3",
250
252
  children: [/* @__PURE__ */ S("button", {
251
253
  type: "button",
252
- onClick: () => e.property && N(`../properties/${e.property.id}`),
254
+ onClick: () => e.property && M(`../properties/${e.property.id}`),
253
255
  className: "shrink-0",
254
256
  "aria-label": `Open ${e.property?.title ?? "property"}`,
255
257
  children: r ? /* @__PURE__ */ S("img", {
@@ -258,7 +260,7 @@ function L() {
258
260
  className: "h-16 w-16 rounded-lg object-cover"
259
261
  }) : /* @__PURE__ */ S("div", {
260
262
  className: "flex h-16 w-16 items-center justify-center rounded-lg bg-bg-sunken",
261
- children: /* @__PURE__ */ S(h, { className: "h-6 w-6 text-text-secondary" })
263
+ children: /* @__PURE__ */ S(g, { className: "h-6 w-6 text-text-secondary" })
262
264
  })
263
265
  }), /* @__PURE__ */ C("div", {
264
266
  className: "min-w-0 flex-1",
@@ -267,7 +269,7 @@ function L() {
267
269
  className: "flex flex-wrap items-start justify-between gap-2",
268
270
  children: [/* @__PURE__ */ C("button", {
269
271
  type: "button",
270
- onClick: () => e.property && N(`../properties/${e.property.id}`),
272
+ onClick: () => e.property && M(`../properties/${e.property.id}`),
271
273
  className: "text-left",
272
274
  children: [/* @__PURE__ */ S("h3", {
273
275
  className: "font-semibold text-text-primary hover:text-primary",
@@ -275,7 +277,7 @@ function L() {
275
277
  }), e.property && /* @__PURE__ */ C("p", {
276
278
  className: "flex items-center gap-1 text-xs text-text-secondary",
277
279
  children: [
278
- /* @__PURE__ */ S(g, { className: "h-3 w-3" }),
280
+ /* @__PURE__ */ S(_, { className: "h-3 w-3" }),
279
281
  e.property.location.city,
280
282
  ", ",
281
283
  e.property.location.state
@@ -283,7 +285,7 @@ function L() {
283
285
  })]
284
286
  }), /* @__PURE__ */ S(a, {
285
287
  label: e.status,
286
- variant: M(e.status),
288
+ variant: j(e.status),
287
289
  dot: !0
288
290
  })]
289
291
  }),
@@ -313,15 +315,15 @@ function L() {
313
315
  }),
314
316
  /* @__PURE__ */ S("div", {
315
317
  className: "rounded-lg bg-bg-sunken/50 p-3",
316
- children: /* @__PURE__ */ S(F, { offer: e })
318
+ children: /* @__PURE__ */ S(P, { offer: e })
317
319
  }),
318
320
  i && /* @__PURE__ */ C("div", {
319
321
  className: "flex flex-wrap gap-2",
320
322
  children: [
321
323
  /* @__PURE__ */ C(w, {
322
324
  size: "sm",
323
- onClick: () => re(e),
324
- children: [/* @__PURE__ */ S(m, { className: "h-4 w-4" }), /* @__PURE__ */ S("span", {
325
+ onClick: () => ae(e),
326
+ children: [/* @__PURE__ */ S(h, { className: "h-4 w-4" }), /* @__PURE__ */ S("span", {
325
327
  className: "ml-1",
326
328
  children: "Respond"
327
329
  })]
@@ -329,9 +331,9 @@ function L() {
329
331
  /* @__PURE__ */ C(w, {
330
332
  variant: "outline",
331
333
  size: "sm",
332
- disabled: G,
333
- onClick: () => ae(e),
334
- children: [/* @__PURE__ */ S(y, { className: "h-4 w-4" }), /* @__PURE__ */ S("span", {
334
+ disabled: W,
335
+ onClick: () => se(e),
336
+ children: [/* @__PURE__ */ S(b, { className: "h-4 w-4" }), /* @__PURE__ */ S("span", {
335
337
  className: "ml-1",
336
338
  children: "Withdraw"
337
339
  })]
@@ -339,32 +341,32 @@ function L() {
339
341
  e.property && /* @__PURE__ */ C(w, {
340
342
  variant: "ghost",
341
343
  size: "sm",
342
- onClick: () => N(`../properties/${e.property?.id}`),
343
- children: [/* @__PURE__ */ S("span", { children: "View property" }), /* @__PURE__ */ S(p, { className: "ml-1 h-4 w-4" })]
344
+ onClick: () => M(`../properties/${e.property?.id}`),
345
+ children: [/* @__PURE__ */ S("span", { children: "View property" }), /* @__PURE__ */ S(m, { className: "ml-1 h-4 w-4" })]
344
346
  })
345
347
  ]
346
348
  })
347
349
  ]
348
350
  }, e.id);
349
351
  })
350
- }), /* @__PURE__ */ S(D, {
351
- page: P.page,
352
- pageSize: P.pageSize,
353
- hasNextPage: z.length >= P.pageSize,
354
- hasPreviousPage: P.page > 1,
355
- onPageChange: P.setPage,
356
- onPageSizeChange: P.setPageSize
352
+ }), /* @__PURE__ */ S(ne, {
353
+ page: N.page,
354
+ pageSize: N.pageSize,
355
+ hasNextPage: R.length >= N.pageSize,
356
+ hasPreviousPage: N.page > 1,
357
+ onPageChange: N.setPage,
358
+ onPageSizeChange: N.setPageSize
357
359
  })]
358
360
  }),
359
- /* @__PURE__ */ S(O, {
360
- open: K !== null,
361
- onOpenChange: (e) => !e && q(null),
362
- children: /* @__PURE__ */ S(ee, {
361
+ /* @__PURE__ */ S(re, {
362
+ open: G !== null,
363
+ onOpenChange: (e) => !e && K(null),
364
+ children: /* @__PURE__ */ S(ie, {
363
365
  className: "sm:max-w-md",
364
366
  children: /* @__PURE__ */ C("form", {
365
- onSubmit: ie,
367
+ onSubmit: oe,
366
368
  children: [
367
- /* @__PURE__ */ C(k, { children: [/* @__PURE__ */ S(A, { children: "Respond to offer" }), /* @__PURE__ */ S(te, { children: K?.property?.title ? `Offer of ${t(K.amount, K.currency)} on ${K.property.title}.` : "Accept, counter, or reject this offer." })] }),
369
+ /* @__PURE__ */ C(O, { children: [/* @__PURE__ */ S(k, { children: "Respond to offer" }), /* @__PURE__ */ S(E, { children: G?.property?.title ? `Offer of ${t(G.amount, G.currency)} on ${G.property.title}.` : "Accept, counter, or reject this offer." })] }),
368
370
  /* @__PURE__ */ C("div", {
369
371
  className: "space-y-3 py-2",
370
372
  children: [
@@ -376,47 +378,47 @@ function L() {
376
378
  "reject"
377
379
  ].map((t) => /* @__PURE__ */ C("button", {
378
380
  type: "button",
379
- onClick: () => Y(t),
380
- className: e("inline-flex items-center gap-1 rounded-md px-3 py-1.5 text-sm font-medium capitalize transition-colors", J === t ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
381
+ onClick: () => J(t),
382
+ className: e("inline-flex items-center gap-1 rounded-md px-3 py-1.5 text-sm font-medium capitalize transition-colors", q === t ? "bg-action-primary-bg text-action-primary-text" : "bg-bg-sunken text-text-secondary hover:text-text-primary"),
381
383
  children: [
382
- t === "accept" && /* @__PURE__ */ S(m, { className: "h-4 w-4" }),
383
- t === "counter" && /* @__PURE__ */ S(_, { className: "h-4 w-4" }),
384
- t === "reject" && /* @__PURE__ */ S(b, { className: "h-4 w-4" }),
384
+ t === "accept" && /* @__PURE__ */ S(h, { className: "h-4 w-4" }),
385
+ t === "counter" && /* @__PURE__ */ S(v, { className: "h-4 w-4" }),
386
+ t === "reject" && /* @__PURE__ */ S(ee, { className: "h-4 w-4" }),
385
387
  t
386
388
  ]
387
389
  }, t))
388
390
  }),
389
- J === "counter" && /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("label", {
391
+ q === "counter" && /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("label", {
390
392
  className: "mb-1.5 block text-sm font-medium text-text-primary",
391
393
  children: "Counter amount *"
392
394
  }), /* @__PURE__ */ S("input", {
393
395
  type: "number",
394
396
  min: 1,
395
397
  step: "any",
396
- value: X,
397
- onChange: (e) => Z(e.target.value),
398
- className: I
398
+ value: Y,
399
+ onChange: (e) => X(e.target.value),
400
+ className: F
399
401
  })] }),
400
402
  /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("label", {
401
403
  className: "mb-1.5 block text-sm font-medium text-text-primary",
402
404
  children: "Note (optional)"
403
405
  }), /* @__PURE__ */ S("textarea", {
404
- value: Q,
405
- onChange: (e) => $(e.target.value),
406
+ value: Z,
407
+ onChange: (e) => Q(e.target.value),
406
408
  rows: 2,
407
409
  className: "w-full 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)]"
408
410
  })] })
409
411
  ]
410
412
  }),
411
- /* @__PURE__ */ C(ne, { children: [/* @__PURE__ */ S(w, {
413
+ /* @__PURE__ */ C(D, { children: [/* @__PURE__ */ S(w, {
412
414
  type: "button",
413
415
  variant: "outline",
414
- onClick: () => q(null),
416
+ onClick: () => K(null),
415
417
  children: "Cancel"
416
418
  }), /* @__PURE__ */ S(w, {
417
419
  type: "submit",
418
- disabled: U,
419
- children: U ? "Sending…" : "Send response"
420
+ disabled: H,
421
+ children: H ? "Sending…" : "Send response"
420
422
  })] })
421
423
  ]
422
424
  })
@@ -426,6 +428,6 @@ function L() {
426
428
  });
427
429
  }
428
430
  //#endregion
429
- export { L as OffersPage };
431
+ export { I as OffersPage };
430
432
 
431
433
  //# sourceMappingURL=OffersPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"OffersPage.js","names":[],"sources":["../../../../src/housingvista/pages/offers/OffersPage.tsx"],"sourcesContent":["/**\n * Offers — the buyer/owner surface for property offers. Buyers track offers they\n * submitted (status timeline submitted→countered→accepted/rejected/withdrawn)\n * and can withdraw; owners can respond (accept / counter / reject). Server-side\n * status filter + pagination, with live per-status tab counts driven off a real\n * unfiltered read (no fabricated numbers).\n * @module housingvista\n */\n\nimport { useState, type FormEvent } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Tag, Check, X, Repeat, Undo2, MapPin, ArrowRight, Home } from 'lucide-react';\nimport {\n Button,\n Pagination,\n EmphasisPanel,\n GlassCard,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { PageLayout, StatCard, StatusBadge, EmptyState } from '../../components';\nimport { useOffers, useRespondOffer, useWithdrawOffer, type OfferRow } from '../../hooks';\nimport { useServerPagination } from '../../hooks/useServerPagination';\nimport { notify } from '../../lib/toast';\nimport { cn, formatCurrency, formatDate } from '../../utils/helpers';\n\nconst statusTabs: { value: string; label: string }[] = [\n { value: 'all', label: 'All' },\n { value: 'submitted', label: 'Submitted' },\n { value: 'countered', label: 'Countered' },\n { value: 'accepted', label: 'Accepted' },\n { value: 'rejected', label: 'Rejected' },\n { value: 'withdrawn', label: 'Withdrawn' },\n];\n\nfunction statusVariant(status: OfferRow['status']): 'success' | 'warning' | 'error' | 'info' | 'muted' {\n switch (status) {\n case 'accepted':\n return 'success';\n case 'countered':\n return 'warning';\n case 'rejected':\n return 'error';\n case 'submitted':\n return 'info';\n default:\n return 'muted';\n }\n}\n\n// ---- Status timeline (submitted → countered → accepted / rejected / withdrawn) ----\n\ntype NodeTone = 'success' | 'warning' | 'error' | 'info' | 'muted';\ninterface TimelineNode {\n label: string;\n date: string | null;\n tone: NodeTone;\n filled: boolean;\n}\n\nconst toneFill: Record<NodeTone, string> = {\n success: 'bg-status-success',\n warning: 'bg-status-warning',\n error: 'bg-status-error',\n info: 'bg-status-info',\n muted: 'bg-text-secondary',\n};\n\nfunction buildTimeline(offer: OfferRow): TimelineNode[] {\n const submitted: TimelineNode = { label: 'Submitted', date: offer.createdAt, tone: 'info', filled: true };\n const respondedAt = offer.respondedAt;\n switch (offer.status) {\n case 'accepted':\n return [\n { ...submitted, tone: 'success' },\n ...(offer.counterAmount != null\n ? [{ label: 'Countered', date: null, tone: 'success' as NodeTone, filled: true }]\n : []),\n { label: 'Accepted', date: respondedAt, tone: 'success', filled: true },\n ];\n case 'countered':\n return [\n { ...submitted, tone: 'warning' },\n { label: 'Countered', date: respondedAt, tone: 'warning', filled: true },\n { label: 'Accepted', date: null, tone: 'muted', filled: false },\n ];\n case 'rejected':\n return [{ ...submitted }, { label: 'Rejected', date: respondedAt, tone: 'error', filled: true }];\n case 'withdrawn':\n return [{ ...submitted }, { label: 'Withdrawn', date: offer.updatedAt, tone: 'muted', filled: true }];\n default:\n // submitted\n return [{ ...submitted }, { label: 'Accepted', date: null, tone: 'muted', filled: false }];\n }\n}\n\nfunction OfferTimeline({ offer }: { offer: OfferRow }) {\n const nodes = buildTimeline(offer);\n return (\n <ol className=\"flex items-start\" aria-label=\"Offer status timeline\">\n {nodes.map((node, index) => {\n const isLast = index === nodes.length - 1;\n const nextFilled = !isLast && nodes[index + 1].filled;\n return (\n <li key={node.label} className={cn('flex flex-col items-center', !isLast && 'flex-1')}>\n <div className=\"flex w-full items-center\">\n <span\n className={cn(\n 'flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-full',\n node.filled ? toneFill[node.tone] : 'border-2 border-border-subtle bg-bg-surface'\n )}\n />\n {!isLast && (\n <span\n className={cn(\n 'mx-1 h-0.5 flex-1 rounded-full',\n node.filled && nextFilled ? toneFill[node.tone] : 'bg-border-subtle'\n )}\n />\n )}\n </div>\n <div className={cn('mt-1.5 text-center', isLast ? 'items-end' : '')}>\n <span className=\"block text-xs font-medium text-text-primary\">{node.label}</span>\n {node.date && <span className=\"block text-[0.65rem] text-text-secondary\">{formatDate(node.date)}</span>}\n </div>\n </li>\n );\n })}\n </ol>\n );\n}\n\nconst inputClass =\n 'h-10 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\n\nexport function OffersPage() {\n const navigate = useNavigate();\n const pagination = useServerPagination(10);\n const [activeTab, setActiveTab] = useState('all');\n const { data: offers, loading } = useOffers({\n filter: activeTab === 'all' ? undefined : { status: activeTab },\n pagination: pagination.pagination,\n });\n // Unfiltered read powers the live tab counts + summary stats (real data).\n const { data: allOffers } = useOffers({ pagination: { limit: 100, offset: 0 } });\n const { respondOffer, loading: responding } = useRespondOffer();\n const { withdrawOffer, loading: withdrawing } = useWithdrawOffer();\n\n const [respondTarget, setRespondTarget] = useState<OfferRow | null>(null);\n const [action, setAction] = useState<'accept' | 'reject' | 'counter'>('accept');\n const [counterAmount, setCounterAmount] = useState('');\n const [notes, setNotes] = useState('');\n\n const openRespond = (offer: OfferRow) => {\n setRespondTarget(offer);\n setAction('accept');\n setCounterAmount(String(offer.amount));\n setNotes('');\n };\n\n const handleRespond = async (event: FormEvent) => {\n event.preventDefault();\n if (!respondTarget) return;\n if (action === 'counter') {\n const amount = Number(counterAmount);\n if (!Number.isFinite(amount) || amount <= 0) {\n notify.warning('Enter a valid counter amount');\n return;\n }\n }\n try {\n await respondOffer(respondTarget.id, {\n action,\n counterAmount: action === 'counter' ? Number(counterAmount) : undefined,\n notes: notes.trim() || undefined,\n });\n notify.success(\n 'Response sent',\n `Offer ${action === 'accept' ? 'accepted' : action === 'reject' ? 'rejected' : 'countered'}.`\n );\n setRespondTarget(null);\n } catch (err) {\n notify.error('Could not respond to offer', (err as Error).message);\n }\n };\n\n const handleWithdraw = async (offer: OfferRow) => {\n try {\n await withdrawOffer(offer.id);\n notify.success('Offer withdrawn');\n } catch (err) {\n notify.error('Could not withdraw offer', (err as Error).message);\n }\n };\n\n const countFor = (value: string): number =>\n value === 'all' ? allOffers.length : allOffers.filter((o) => o.status === value).length;\n\n const activeCount = allOffers.filter((o) => o.status === 'submitted' || o.status === 'countered').length;\n const acceptedCount = allOffers.filter((o) => o.status === 'accepted').length;\n\n return (\n <PageLayout\n title=\"Offers\"\n description=\"Track the offers you have made and respond to offers on your listings\"\n purpose=\"Every offer in one place: watch its status move from submitted to countered, accepted, or rejected — withdraw one you no longer want, or respond to offers coming in on properties you own.\"\n >\n <EmphasisPanel className=\"p-4\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <StatCard label=\"Total offers\" value={allOffers.length} icon={<Tag className=\"h-4 w-4\" />} />\n <StatCard label=\"Awaiting action\" value={activeCount} icon={<Repeat className=\"h-4 w-4\" />} />\n <StatCard label=\"Accepted\" value={acceptedCount} icon={<Check className=\"h-4 w-4\" />} />\n </div>\n </EmphasisPanel>\n\n <div className=\"-mx-1 flex flex-nowrap items-center gap-2 overflow-x-auto px-1 pb-1 sm:flex-wrap sm:overflow-visible\">\n {statusTabs.map((tab) => {\n const count = countFor(tab.value);\n const isActive = activeTab === tab.value;\n return (\n <button\n key={tab.value}\n onClick={() => {\n setActiveTab(tab.value);\n pagination.setPage(1);\n }}\n className={cn(\n 'inline-flex shrink-0 items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors',\n isActive\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n {tab.label}\n <span\n className={cn(\n 'inline-flex min-w-5 items-center justify-center rounded-full px-1.5 text-[0.65rem] font-semibold tabular-nums',\n isActive ? 'bg-action-primary-text/20 text-action-primary-text' : 'bg-bg-surface text-text-secondary'\n )}\n >\n {count}\n </span>\n </button>\n );\n })}\n </div>\n\n {offers.length === 0 && !loading ? (\n <EmptyState\n illustration=\"empty-search\"\n icon={<Tag className=\"h-12 w-12\" />}\n title=\"No offers here\"\n description=\"Offers you submit on properties — and offers made on your listings — will appear here.\"\n action={<Button onClick={() => navigate('../properties')}>Browse properties</Button>}\n />\n ) : (\n <div className=\"space-y-4\">\n <div className=\"grid grid-cols-1 gap-4 xl:grid-cols-2\">\n {offers.map((offer) => {\n const image = offer.property?.images.find((img) => img.isPrimary) ?? offer.property?.images[0];\n const canAct = offer.status === 'submitted' || offer.status === 'countered';\n return (\n <GlassCard\n key={offer.id}\n treatment={canAct ? 'insight' : 'plain'}\n glow={canAct}\n className=\"flex flex-col gap-4 p-5\"\n >\n <div className=\"flex items-start gap-3\">\n <button\n type=\"button\"\n onClick={() => offer.property && navigate(`../properties/${offer.property.id}`)}\n className=\"shrink-0\"\n aria-label={`Open ${offer.property?.title ?? 'property'}`}\n >\n {image ? (\n <img src={image.url} alt=\"\" className=\"h-16 w-16 rounded-lg object-cover\" />\n ) : (\n <div className=\"flex h-16 w-16 items-center justify-center rounded-lg bg-bg-sunken\">\n <Home className=\"h-6 w-6 text-text-secondary\" />\n </div>\n )}\n </button>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-start justify-between gap-2\">\n <button\n type=\"button\"\n onClick={() => offer.property && navigate(`../properties/${offer.property.id}`)}\n className=\"text-left\"\n >\n <h3 className=\"font-semibold text-text-primary hover:text-primary\">\n {offer.property?.title ?? 'Property'}\n </h3>\n {offer.property && (\n <p className=\"flex items-center gap-1 text-xs text-text-secondary\">\n <MapPin className=\"h-3 w-3\" />\n {offer.property.location.city}, {offer.property.location.state}\n </p>\n )}\n </button>\n <StatusBadge label={offer.status} variant={statusVariant(offer.status)} dot />\n </div>\n <div className=\"mt-2 flex items-baseline gap-3\">\n <span className=\"text-xl font-bold tabular-nums text-text-primary\">\n {formatCurrency(offer.amount, offer.currency)}\n </span>\n {offer.counterAmount != null && (\n <span className=\"text-sm text-text-secondary\">\n Counter{' '}\n <span className=\"font-semibold text-status-warning-text\">\n {formatCurrency(offer.counterAmount, offer.currency)}\n </span>\n </span>\n )}\n </div>\n <p className=\"mt-0.5 text-xs text-text-secondary\">Submitted {formatDate(offer.createdAt)}</p>\n </div>\n </div>\n\n <div className=\"rounded-lg bg-bg-sunken/50 p-3\">\n <OfferTimeline offer={offer} />\n </div>\n\n {canAct && (\n <div className=\"flex flex-wrap gap-2\">\n <Button size=\"sm\" onClick={() => openRespond(offer)}>\n <Check className=\"h-4 w-4\" />\n <span className=\"ml-1\">Respond</span>\n </Button>\n <Button variant=\"outline\" size=\"sm\" disabled={withdrawing} onClick={() => handleWithdraw(offer)}>\n <Undo2 className=\"h-4 w-4\" />\n <span className=\"ml-1\">Withdraw</span>\n </Button>\n {offer.property && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => navigate(`../properties/${offer.property?.id}`)}\n >\n <span>View property</span>\n <ArrowRight className=\"ml-1 h-4 w-4\" />\n </Button>\n )}\n </div>\n )}\n </GlassCard>\n );\n })}\n </div>\n\n <Pagination\n page={pagination.page}\n pageSize={pagination.pageSize}\n hasNextPage={offers.length >= pagination.pageSize}\n hasPreviousPage={pagination.page > 1}\n onPageChange={pagination.setPage}\n onPageSizeChange={pagination.setPageSize}\n />\n </div>\n )}\n\n {/* Respond to offer */}\n <ResponsiveDialog open={respondTarget !== null} onOpenChange={(open) => !open && setRespondTarget(null)}>\n <ResponsiveDialogContent className=\"sm:max-w-md\">\n <form onSubmit={handleRespond}>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Respond to offer</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {respondTarget?.property?.title\n ? `Offer of ${formatCurrency(respondTarget.amount, respondTarget.currency)} on ${respondTarget.property.title}.`\n : 'Accept, counter, or reject this offer.'}\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-3 py-2\">\n <div className=\"flex flex-wrap gap-2\">\n {(['accept', 'counter', 'reject'] as const).map((value) => (\n <button\n key={value}\n type=\"button\"\n onClick={() => setAction(value)}\n className={cn(\n 'inline-flex items-center gap-1 rounded-md px-3 py-1.5 text-sm font-medium capitalize transition-colors',\n action === value\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n {value === 'accept' && <Check className=\"h-4 w-4\" />}\n {value === 'counter' && <Repeat className=\"h-4 w-4\" />}\n {value === 'reject' && <X className=\"h-4 w-4\" />}\n {value}\n </button>\n ))}\n </div>\n {action === 'counter' && (\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Counter amount *</label>\n <input\n type=\"number\"\n min={1}\n step=\"any\"\n value={counterAmount}\n onChange={(event) => setCounterAmount(event.target.value)}\n className={inputClass}\n />\n </div>\n )}\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Note (optional)</label>\n <textarea\n value={notes}\n onChange={(event) => setNotes(event.target.value)}\n rows={2}\n className=\"w-full 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 </div>\n </div>\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setRespondTarget(null)}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={responding}>\n {responding ? 'Sending…' : 'Send response'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"OffersPage.js","names":[],"sources":["../../../../src/housingvista/pages/offers/OffersPage.tsx"],"sourcesContent":["/**\n * Offers — the buyer/owner surface for property offers. Buyers track offers they\n * submitted (status timeline submitted→countered→accepted/rejected/withdrawn)\n * and can withdraw; owners can respond (accept / counter / reject). Server-side\n * status filter + pagination, with live per-status tab counts driven off a real\n * unfiltered read (no fabricated numbers).\n * @module housingvista\n */\n\nimport { useState, type FormEvent } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { Tag, Check, X, Repeat, Undo2, MapPin, ArrowRight, Home } from 'lucide-react';\nimport {\n Button,\n Pagination,\n EmphasisPanel,\n GlassCard,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { PageLayout, StatCard, StatusBadge, EmptyState } from '../../components';\nimport { useOffers, useRespondOffer, useWithdrawOffer, type OfferRow } from '../../hooks';\nimport { useServerPagination } from '../../hooks/useServerPagination';\nimport { notify } from '../../lib/toast';\nimport { cn, formatCurrency, formatDate } from '../../utils/helpers';\nimport { useTrackPageView } from '../../hooks/useHousingVistaAnalytics';\n\nconst statusTabs: { value: string; label: string }[] = [\n { value: 'all', label: 'All' },\n { value: 'submitted', label: 'Submitted' },\n { value: 'countered', label: 'Countered' },\n { value: 'accepted', label: 'Accepted' },\n { value: 'rejected', label: 'Rejected' },\n { value: 'withdrawn', label: 'Withdrawn' },\n];\n\nfunction statusVariant(status: OfferRow['status']): 'success' | 'warning' | 'error' | 'info' | 'muted' {\n switch (status) {\n case 'accepted':\n return 'success';\n case 'countered':\n return 'warning';\n case 'rejected':\n return 'error';\n case 'submitted':\n return 'info';\n default:\n return 'muted';\n }\n}\n\n// ---- Status timeline (submitted → countered → accepted / rejected / withdrawn) ----\n\ntype NodeTone = 'success' | 'warning' | 'error' | 'info' | 'muted';\ninterface TimelineNode {\n label: string;\n date: string | null;\n tone: NodeTone;\n filled: boolean;\n}\n\nconst toneFill: Record<NodeTone, string> = {\n success: 'bg-status-success',\n warning: 'bg-status-warning',\n error: 'bg-status-error',\n info: 'bg-status-info',\n muted: 'bg-text-secondary',\n};\n\nfunction buildTimeline(offer: OfferRow): TimelineNode[] {\n const submitted: TimelineNode = { label: 'Submitted', date: offer.createdAt, tone: 'info', filled: true };\n const respondedAt = offer.respondedAt;\n switch (offer.status) {\n case 'accepted':\n return [\n { ...submitted, tone: 'success' },\n ...(offer.counterAmount != null\n ? [{ label: 'Countered', date: null, tone: 'success' as NodeTone, filled: true }]\n : []),\n { label: 'Accepted', date: respondedAt, tone: 'success', filled: true },\n ];\n case 'countered':\n return [\n { ...submitted, tone: 'warning' },\n { label: 'Countered', date: respondedAt, tone: 'warning', filled: true },\n { label: 'Accepted', date: null, tone: 'muted', filled: false },\n ];\n case 'rejected':\n return [{ ...submitted }, { label: 'Rejected', date: respondedAt, tone: 'error', filled: true }];\n case 'withdrawn':\n return [{ ...submitted }, { label: 'Withdrawn', date: offer.updatedAt, tone: 'muted', filled: true }];\n default:\n // submitted\n return [{ ...submitted }, { label: 'Accepted', date: null, tone: 'muted', filled: false }];\n }\n}\n\nfunction OfferTimeline({ offer }: { offer: OfferRow }) {\n const nodes = buildTimeline(offer);\n return (\n <ol className=\"flex items-start\" aria-label=\"Offer status timeline\">\n {nodes.map((node, index) => {\n const isLast = index === nodes.length - 1;\n const nextFilled = !isLast && nodes[index + 1].filled;\n return (\n <li key={node.label} className={cn('flex flex-col items-center', !isLast && 'flex-1')}>\n <div className=\"flex w-full items-center\">\n <span\n className={cn(\n 'flex h-3.5 w-3.5 shrink-0 items-center justify-center rounded-full',\n node.filled ? toneFill[node.tone] : 'border-2 border-border-subtle bg-bg-surface'\n )}\n />\n {!isLast && (\n <span\n className={cn(\n 'mx-1 h-0.5 flex-1 rounded-full',\n node.filled && nextFilled ? toneFill[node.tone] : 'bg-border-subtle'\n )}\n />\n )}\n </div>\n <div className={cn('mt-1.5 text-center', isLast ? 'items-end' : '')}>\n <span className=\"block text-xs font-medium text-text-primary\">{node.label}</span>\n {node.date && <span className=\"block text-[0.65rem] text-text-secondary\">{formatDate(node.date)}</span>}\n </div>\n </li>\n );\n })}\n </ol>\n );\n}\n\nconst inputClass =\n 'h-10 w-full rounded-md border border-border-subtle bg-bg-surface px-3 text-sm text-text-primary placeholder:text-text-secondary focus:outline-none focus:ring-2 focus:ring-[var(--color-focus-ring)]';\n\nexport function OffersPage() {\n useTrackPageView('housingvista.offer.viewed');\n const navigate = useNavigate();\n const pagination = useServerPagination(10);\n const [activeTab, setActiveTab] = useState('all');\n const { data: offers, loading } = useOffers({\n filter: activeTab === 'all' ? undefined : { status: activeTab },\n pagination: pagination.pagination,\n });\n // Unfiltered read powers the live tab counts + summary stats (real data).\n const { data: allOffers } = useOffers({ pagination: { limit: 100, offset: 0 } });\n const { respondOffer, loading: responding } = useRespondOffer();\n const { withdrawOffer, loading: withdrawing } = useWithdrawOffer();\n\n const [respondTarget, setRespondTarget] = useState<OfferRow | null>(null);\n const [action, setAction] = useState<'accept' | 'reject' | 'counter'>('accept');\n const [counterAmount, setCounterAmount] = useState('');\n const [notes, setNotes] = useState('');\n\n const openRespond = (offer: OfferRow) => {\n setRespondTarget(offer);\n setAction('accept');\n setCounterAmount(String(offer.amount));\n setNotes('');\n };\n\n const handleRespond = async (event: FormEvent) => {\n event.preventDefault();\n if (!respondTarget) return;\n if (action === 'counter') {\n const amount = Number(counterAmount);\n if (!Number.isFinite(amount) || amount <= 0) {\n notify.warning('Enter a valid counter amount');\n return;\n }\n }\n try {\n await respondOffer(respondTarget.id, {\n action,\n counterAmount: action === 'counter' ? Number(counterAmount) : undefined,\n notes: notes.trim() || undefined,\n });\n notify.success(\n 'Response sent',\n `Offer ${action === 'accept' ? 'accepted' : action === 'reject' ? 'rejected' : 'countered'}.`\n );\n setRespondTarget(null);\n } catch (err) {\n notify.error('Could not respond to offer', (err as Error).message);\n }\n };\n\n const handleWithdraw = async (offer: OfferRow) => {\n try {\n await withdrawOffer(offer.id);\n notify.success('Offer withdrawn');\n } catch (err) {\n notify.error('Could not withdraw offer', (err as Error).message);\n }\n };\n\n const countFor = (value: string): number =>\n value === 'all' ? allOffers.length : allOffers.filter((o) => o.status === value).length;\n\n const activeCount = allOffers.filter((o) => o.status === 'submitted' || o.status === 'countered').length;\n const acceptedCount = allOffers.filter((o) => o.status === 'accepted').length;\n\n return (\n <PageLayout\n title=\"Offers\"\n description=\"Track the offers you have made and respond to offers on your listings\"\n purpose=\"Every offer in one place: watch its status move from submitted to countered, accepted, or rejected — withdraw one you no longer want, or respond to offers coming in on properties you own.\"\n >\n <EmphasisPanel className=\"p-4\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <StatCard label=\"Total offers\" value={allOffers.length} icon={<Tag className=\"h-4 w-4\" />} />\n <StatCard label=\"Awaiting action\" value={activeCount} icon={<Repeat className=\"h-4 w-4\" />} />\n <StatCard label=\"Accepted\" value={acceptedCount} icon={<Check className=\"h-4 w-4\" />} />\n </div>\n </EmphasisPanel>\n\n <div className=\"-mx-1 flex flex-nowrap items-center gap-2 overflow-x-auto px-1 pb-1 sm:flex-wrap sm:overflow-visible\">\n {statusTabs.map((tab) => {\n const count = countFor(tab.value);\n const isActive = activeTab === tab.value;\n return (\n <button\n key={tab.value}\n onClick={() => {\n setActiveTab(tab.value);\n pagination.setPage(1);\n }}\n className={cn(\n 'inline-flex shrink-0 items-center gap-1.5 rounded-full px-3 py-1.5 text-sm font-medium transition-colors',\n isActive\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n {tab.label}\n <span\n className={cn(\n 'inline-flex min-w-5 items-center justify-center rounded-full px-1.5 text-[0.65rem] font-semibold tabular-nums',\n isActive ? 'bg-action-primary-text/20 text-action-primary-text' : 'bg-bg-surface text-text-secondary'\n )}\n >\n {count}\n </span>\n </button>\n );\n })}\n </div>\n\n {offers.length === 0 && !loading ? (\n <EmptyState\n illustration=\"empty-search\"\n icon={<Tag className=\"h-12 w-12\" />}\n title=\"No offers here\"\n description=\"Offers you submit on properties — and offers made on your listings — will appear here.\"\n action={<Button onClick={() => navigate('../properties')}>Browse properties</Button>}\n />\n ) : (\n <div className=\"space-y-4\">\n <div className=\"grid grid-cols-1 gap-4 xl:grid-cols-2\">\n {offers.map((offer) => {\n const image = offer.property?.images.find((img) => img.isPrimary) ?? offer.property?.images[0];\n const canAct = offer.status === 'submitted' || offer.status === 'countered';\n return (\n <GlassCard\n key={offer.id}\n treatment={canAct ? 'insight' : 'plain'}\n glow={canAct}\n className=\"flex flex-col gap-4 p-5\"\n >\n <div className=\"flex items-start gap-3\">\n <button\n type=\"button\"\n onClick={() => offer.property && navigate(`../properties/${offer.property.id}`)}\n className=\"shrink-0\"\n aria-label={`Open ${offer.property?.title ?? 'property'}`}\n >\n {image ? (\n <img src={image.url} alt=\"\" className=\"h-16 w-16 rounded-lg object-cover\" />\n ) : (\n <div className=\"flex h-16 w-16 items-center justify-center rounded-lg bg-bg-sunken\">\n <Home className=\"h-6 w-6 text-text-secondary\" />\n </div>\n )}\n </button>\n <div className=\"min-w-0 flex-1\">\n <div className=\"flex flex-wrap items-start justify-between gap-2\">\n <button\n type=\"button\"\n onClick={() => offer.property && navigate(`../properties/${offer.property.id}`)}\n className=\"text-left\"\n >\n <h3 className=\"font-semibold text-text-primary hover:text-primary\">\n {offer.property?.title ?? 'Property'}\n </h3>\n {offer.property && (\n <p className=\"flex items-center gap-1 text-xs text-text-secondary\">\n <MapPin className=\"h-3 w-3\" />\n {offer.property.location.city}, {offer.property.location.state}\n </p>\n )}\n </button>\n <StatusBadge label={offer.status} variant={statusVariant(offer.status)} dot />\n </div>\n <div className=\"mt-2 flex items-baseline gap-3\">\n <span className=\"text-xl font-bold tabular-nums text-text-primary\">\n {formatCurrency(offer.amount, offer.currency)}\n </span>\n {offer.counterAmount != null && (\n <span className=\"text-sm text-text-secondary\">\n Counter{' '}\n <span className=\"font-semibold text-status-warning-text\">\n {formatCurrency(offer.counterAmount, offer.currency)}\n </span>\n </span>\n )}\n </div>\n <p className=\"mt-0.5 text-xs text-text-secondary\">Submitted {formatDate(offer.createdAt)}</p>\n </div>\n </div>\n\n <div className=\"rounded-lg bg-bg-sunken/50 p-3\">\n <OfferTimeline offer={offer} />\n </div>\n\n {canAct && (\n <div className=\"flex flex-wrap gap-2\">\n <Button size=\"sm\" onClick={() => openRespond(offer)}>\n <Check className=\"h-4 w-4\" />\n <span className=\"ml-1\">Respond</span>\n </Button>\n <Button variant=\"outline\" size=\"sm\" disabled={withdrawing} onClick={() => handleWithdraw(offer)}>\n <Undo2 className=\"h-4 w-4\" />\n <span className=\"ml-1\">Withdraw</span>\n </Button>\n {offer.property && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={() => navigate(`../properties/${offer.property?.id}`)}\n >\n <span>View property</span>\n <ArrowRight className=\"ml-1 h-4 w-4\" />\n </Button>\n )}\n </div>\n )}\n </GlassCard>\n );\n })}\n </div>\n\n <Pagination\n page={pagination.page}\n pageSize={pagination.pageSize}\n hasNextPage={offers.length >= pagination.pageSize}\n hasPreviousPage={pagination.page > 1}\n onPageChange={pagination.setPage}\n onPageSizeChange={pagination.setPageSize}\n />\n </div>\n )}\n\n {/* Respond to offer */}\n <ResponsiveDialog open={respondTarget !== null} onOpenChange={(open) => !open && setRespondTarget(null)}>\n <ResponsiveDialogContent className=\"sm:max-w-md\">\n <form onSubmit={handleRespond}>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Respond to offer</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n {respondTarget?.property?.title\n ? `Offer of ${formatCurrency(respondTarget.amount, respondTarget.currency)} on ${respondTarget.property.title}.`\n : 'Accept, counter, or reject this offer.'}\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n <div className=\"space-y-3 py-2\">\n <div className=\"flex flex-wrap gap-2\">\n {(['accept', 'counter', 'reject'] as const).map((value) => (\n <button\n key={value}\n type=\"button\"\n onClick={() => setAction(value)}\n className={cn(\n 'inline-flex items-center gap-1 rounded-md px-3 py-1.5 text-sm font-medium capitalize transition-colors',\n action === value\n ? 'bg-action-primary-bg text-action-primary-text'\n : 'bg-bg-sunken text-text-secondary hover:text-text-primary'\n )}\n >\n {value === 'accept' && <Check className=\"h-4 w-4\" />}\n {value === 'counter' && <Repeat className=\"h-4 w-4\" />}\n {value === 'reject' && <X className=\"h-4 w-4\" />}\n {value}\n </button>\n ))}\n </div>\n {action === 'counter' && (\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Counter amount *</label>\n <input\n type=\"number\"\n min={1}\n step=\"any\"\n value={counterAmount}\n onChange={(event) => setCounterAmount(event.target.value)}\n className={inputClass}\n />\n </div>\n )}\n <div>\n <label className=\"mb-1.5 block text-sm font-medium text-text-primary\">Note (optional)</label>\n <textarea\n value={notes}\n onChange={(event) => setNotes(event.target.value)}\n rows={2}\n className=\"w-full 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 </div>\n </div>\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={() => setRespondTarget(null)}>\n Cancel\n </Button>\n <Button type=\"submit\" disabled={responding}>\n {responding ? 'Sending…' : 'Send response'}\n </Button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AddPropertyPage.d.ts","sourceRoot":"","sources":["../../../../src/housingvista/pages/properties/AddPropertyPage.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsEH,eAAO,MAAM,eAAe,mCAqrB3B,CAAC"}
1
+ {"version":3,"file":"AddPropertyPage.d.ts","sourceRoot":"","sources":["../../../../src/housingvista/pages/properties/AddPropertyPage.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuEH,eAAO,MAAM,eAAe,mCAsrB3B,CAAC"}