@burdenoff/microfe-housingvista 2026.625.2 → 2026.626.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.
@@ -9,10 +9,11 @@ import "../../components/index.js";
9
9
  import { useAMCContracts as l } from "../../hooks/index.js";
10
10
  import { useMemo as u, useState as d } from "react";
11
11
  import { AlertTriangle as f, Calendar as p, Clock as m, DollarSign as h, Download as g, Plus as _, RotateCcw as v, Shield as y, Wrench as b } from "lucide-react";
12
- import { jsx as x, jsxs as S } from "react/jsx-runtime";
13
- import { EmphasisPanel as C } from "@burdenoff/fe-libs/ui";
12
+ import { useNavigate as x } from "react-router-dom";
13
+ import { jsx as S, jsxs as C } from "react/jsx-runtime";
14
+ import { EmphasisPanel as w, NextSteps as T } from "@burdenoff/fe-libs/ui";
14
15
  //#region src/housingvista/pages/amc/AMCManagementPage.tsx
15
- function w(e) {
16
+ function E(e) {
16
17
  switch (e) {
17
18
  case "active": return "success";
18
19
  case "expiring_soon": return "warning";
@@ -21,94 +22,120 @@ function w(e) {
21
22
  default: return "muted";
22
23
  }
23
24
  }
24
- function T() {
25
- let { data: T } = l(), [E, D] = d(""), O = u(() => {
26
- if (!E) return T;
27
- let e = E.toLowerCase();
28
- return T.filter((t) => t.propertyTitle.toLowerCase().includes(e) || t.providerName.toLowerCase().includes(e) || t.packageName.toLowerCase().includes(e));
29
- }, [T, E]), k = u(() => ({
30
- activeContracts: T.filter((e) => e.status === "active" || e.status === "expiring_soon").length,
31
- pendingRenewals: T.filter((e) => e.status === "expiring_soon").length,
32
- totalMonthlySpent: T.filter((e) => e.status === "active" || e.status === "expiring_soon").reduce((e, t) => e + t.monthlyCost, 0),
33
- upcomingServices: T.filter((e) => {
25
+ function D() {
26
+ let D = x(), { data: O } = l(), [k, A] = d(""), j = u(() => {
27
+ if (!k) return O;
28
+ let e = k.toLowerCase();
29
+ return O.filter((t) => t.propertyTitle.toLowerCase().includes(e) || t.providerName.toLowerCase().includes(e) || t.packageName.toLowerCase().includes(e));
30
+ }, [O, k]), M = u(() => ({
31
+ activeContracts: O.filter((e) => e.status === "active" || e.status === "expiring_soon").length,
32
+ pendingRenewals: O.filter((e) => e.status === "expiring_soon").length,
33
+ totalMonthlySpent: O.filter((e) => e.status === "active" || e.status === "expiring_soon").reduce((e, t) => e + t.monthlyCost, 0),
34
+ upcomingServices: O.filter((e) => {
34
35
  if (!e.nextServiceDate) return !1;
35
36
  let t = new Date(e.nextServiceDate), n = /* @__PURE__ */ new Date(), r = (t.getTime() - n.getTime()) / (1e3 * 60 * 60 * 24);
36
37
  return r >= 0 && r <= 30;
37
38
  }).length
38
- }), [T]), A = u(() => T.filter((e) => e.nextServiceDate && (e.status === "active" || e.status === "expiring_soon")).sort((e, t) => new Date(e.nextServiceDate).getTime() - new Date(t.nextServiceDate).getTime()), [T]);
39
- return /* @__PURE__ */ S(r, {
39
+ }), [O]), N = u(() => O.filter((e) => e.nextServiceDate && (e.status === "active" || e.status === "expiring_soon")).sort((e, t) => new Date(e.nextServiceDate).getTime() - new Date(t.nextServiceDate).getTime()), [O]);
40
+ return /* @__PURE__ */ C(r, {
40
41
  title: "AMC Management",
41
42
  description: "Manage Annual Maintenance Contracts and service packages",
42
43
  purpose: "Keep your properties maintained without surprises. Track every Annual Maintenance Contract, see what each covers and costs, get ahead of renewals, and know which services are due in the next 30 days so nothing slips.",
43
- actions: /* @__PURE__ */ S("div", {
44
+ actions: /* @__PURE__ */ C("div", {
44
45
  className: "flex items-center gap-2",
45
- children: [/* @__PURE__ */ S("button", {
46
+ children: [/* @__PURE__ */ C("button", {
46
47
  className: "inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
47
- children: [/* @__PURE__ */ x(g, { className: "h-4 w-4" }), "Export"]
48
- }), /* @__PURE__ */ S("button", {
48
+ children: [/* @__PURE__ */ S(g, { className: "h-4 w-4" }), "Export"]
49
+ }), /* @__PURE__ */ C("button", {
49
50
  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",
50
- children: [/* @__PURE__ */ x(_, { className: "h-4 w-4" }), "New Contract"]
51
+ children: [/* @__PURE__ */ S(_, { className: "h-4 w-4" }), "New Contract"]
51
52
  })]
52
53
  }),
53
54
  children: [
54
- /* @__PURE__ */ x(C, {
55
+ /* @__PURE__ */ S(w, {
55
56
  className: "p-4",
56
- children: /* @__PURE__ */ S("div", {
57
+ children: /* @__PURE__ */ C("div", {
57
58
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
58
59
  children: [
59
- /* @__PURE__ */ x(i, {
60
+ /* @__PURE__ */ S(i, {
60
61
  label: "Active Contracts",
61
- value: k.activeContracts,
62
- icon: /* @__PURE__ */ x(y, { className: "h-4 w-4" })
62
+ value: M.activeContracts,
63
+ icon: /* @__PURE__ */ S(y, { className: "h-4 w-4" })
63
64
  }),
64
- /* @__PURE__ */ x(i, {
65
+ /* @__PURE__ */ S(i, {
65
66
  label: "Pending Renewals",
66
- value: k.pendingRenewals,
67
- icon: /* @__PURE__ */ x(v, { className: "h-4 w-4" }),
68
- trend: k.pendingRenewals > 0 ? "up" : "stable",
69
- change: k.pendingRenewals > 0 ? k.pendingRenewals : 0
67
+ value: M.pendingRenewals,
68
+ icon: /* @__PURE__ */ S(v, { className: "h-4 w-4" }),
69
+ trend: M.pendingRenewals > 0 ? "up" : "stable",
70
+ change: M.pendingRenewals > 0 ? M.pendingRenewals : 0
70
71
  }),
71
- /* @__PURE__ */ x(i, {
72
+ /* @__PURE__ */ S(i, {
72
73
  label: "Total Monthly Spent",
73
- value: k.totalMonthlySpent,
74
+ value: M.totalMonthlySpent,
74
75
  prefix: "$",
75
- icon: /* @__PURE__ */ x(h, { className: "h-4 w-4" })
76
+ icon: /* @__PURE__ */ S(h, { className: "h-4 w-4" })
76
77
  }),
77
- /* @__PURE__ */ x(i, {
78
+ /* @__PURE__ */ S(i, {
78
79
  label: "Upcoming Services",
79
- value: k.upcomingServices,
80
- icon: /* @__PURE__ */ x(p, { className: "h-4 w-4" })
80
+ value: M.upcomingServices,
81
+ icon: /* @__PURE__ */ S(p, { className: "h-4 w-4" })
81
82
  })
82
83
  ]
83
84
  })
84
85
  }),
85
- /* @__PURE__ */ S("div", {
86
+ /* @__PURE__ */ S(T, {
87
+ storageKey: "housingvista-amc",
88
+ steps: [
89
+ {
90
+ id: "pick-property",
91
+ label: "Add coverage for a property",
92
+ description: "Choose a property to set up a new maintenance contract.",
93
+ onClick: () => D("/properties")
94
+ },
95
+ {
96
+ id: "compare-providers",
97
+ label: "Compare your providers",
98
+ description: "Search by provider name to weigh coverage and monthly cost.",
99
+ onClick: () => {
100
+ let e = O[0]?.providerName;
101
+ e && A(e);
102
+ }
103
+ },
104
+ {
105
+ id: "check-legal",
106
+ label: "Review contract paperwork",
107
+ description: "Open the legal hub to manage the underlying documents.",
108
+ onClick: () => D("/legal")
109
+ }
110
+ ]
111
+ }),
112
+ /* @__PURE__ */ C("div", {
86
113
  className: "rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-sm",
87
- children: [/* @__PURE__ */ x("h3", {
114
+ children: [/* @__PURE__ */ S("h3", {
88
115
  className: "mb-4 text-lg font-semibold text-text-primary",
89
116
  children: "Upcoming Service Schedule"
90
- }), A.length === 0 ? /* @__PURE__ */ x(s, {
117
+ }), N.length === 0 ? /* @__PURE__ */ S(s, {
91
118
  illustration: "empty-generic",
92
119
  title: "No services scheduled",
93
120
  description: "Once your active contracts have upcoming service dates, they'll be listed here in order of priority.",
94
121
  className: "border-0 bg-transparent p-6"
95
- }) : /* @__PURE__ */ x("div", {
122
+ }) : /* @__PURE__ */ S("div", {
96
123
  className: "space-y-3",
97
- children: A.map((t) => {
124
+ children: N.map((t) => {
98
125
  let r = new Date(t.nextServiceDate), i = /* @__PURE__ */ new Date(), a = Math.ceil((r.getTime() - i.getTime()) / (1e3 * 60 * 60 * 24)), s = a <= 7, c = a < 0;
99
- return /* @__PURE__ */ S("div", {
126
+ return /* @__PURE__ */ C("div", {
100
127
  className: "flex flex-col gap-3 rounded-lg bg-bg-sunken/50 p-4 sm:flex-row sm:items-center sm:justify-between",
101
- children: [/* @__PURE__ */ S("div", {
128
+ children: [/* @__PURE__ */ C("div", {
102
129
  className: "flex items-start gap-3",
103
- children: [/* @__PURE__ */ x("div", {
130
+ children: [/* @__PURE__ */ S("div", {
104
131
  className: e("rounded-lg p-2", c ? "bg-red-100 dark:bg-red-900/30" : s ? "bg-amber-100 dark:bg-amber-900/30" : "bg-blue-100 dark:bg-blue-900/30"),
105
- children: c ? /* @__PURE__ */ x(f, { className: "h-4 w-4 text-red-600 dark:text-red-400" }) : s ? /* @__PURE__ */ x(m, { className: "h-4 w-4 text-amber-600 dark:text-amber-400" }) : /* @__PURE__ */ x(b, { className: "h-4 w-4 text-blue-600 dark:text-blue-400" })
106
- }), /* @__PURE__ */ S("div", { children: [
107
- /* @__PURE__ */ x("p", {
132
+ children: c ? /* @__PURE__ */ S(f, { className: "h-4 w-4 text-red-600 dark:text-red-400" }) : s ? /* @__PURE__ */ S(m, { className: "h-4 w-4 text-amber-600 dark:text-amber-400" }) : /* @__PURE__ */ S(b, { className: "h-4 w-4 text-blue-600 dark:text-blue-400" })
133
+ }), /* @__PURE__ */ C("div", { children: [
134
+ /* @__PURE__ */ S("p", {
108
135
  className: "font-medium text-text-primary",
109
136
  children: t.propertyTitle
110
137
  }),
111
- /* @__PURE__ */ S("p", {
138
+ /* @__PURE__ */ C("p", {
112
139
  className: "text-sm text-text-secondary",
113
140
  children: [
114
141
  t.packageName,
@@ -116,12 +143,12 @@ function T() {
116
143
  t.providerName
117
144
  ]
118
145
  }),
119
- /* @__PURE__ */ S("div", {
146
+ /* @__PURE__ */ C("div", {
120
147
  className: "mt-1 flex flex-wrap gap-1",
121
- children: [t.servicesIncluded.slice(0, 3).map((e, t) => /* @__PURE__ */ x("span", {
148
+ children: [t.servicesIncluded.slice(0, 3).map((e, t) => /* @__PURE__ */ S("span", {
122
149
  className: "inline-block rounded-md bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary",
123
150
  children: e
124
- }, t)), t.servicesIncluded.length > 3 && /* @__PURE__ */ S("span", {
151
+ }, t)), t.servicesIncluded.length > 3 && /* @__PURE__ */ C("span", {
125
152
  className: "inline-block rounded-md bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary",
126
153
  children: [
127
154
  "+",
@@ -131,47 +158,47 @@ function T() {
131
158
  })]
132
159
  })
133
160
  ] })]
134
- }), /* @__PURE__ */ S("div", {
161
+ }), /* @__PURE__ */ C("div", {
135
162
  className: "flex items-center gap-3",
136
- children: [/* @__PURE__ */ S("div", {
163
+ children: [/* @__PURE__ */ C("div", {
137
164
  className: "text-right",
138
- children: [/* @__PURE__ */ x("p", {
165
+ children: [/* @__PURE__ */ S("p", {
139
166
  className: "text-sm font-medium text-text-primary",
140
167
  children: n(t.nextServiceDate)
141
- }), /* @__PURE__ */ x("p", {
168
+ }), /* @__PURE__ */ S("p", {
142
169
  className: e("text-xs", c ? "text-red-600 dark:text-red-400" : s ? "text-amber-600 dark:text-amber-400" : "text-text-secondary"),
143
170
  children: c ? `${Math.abs(a)} days overdue` : a === 0 ? "Today" : `In ${a} days`
144
171
  })]
145
- }), /* @__PURE__ */ x(o, {
172
+ }), /* @__PURE__ */ S(o, {
146
173
  label: t.status.replace("_", " "),
147
- variant: w(t.status)
174
+ variant: E(t.status)
148
175
  })]
149
176
  })]
150
177
  }, t.id);
151
178
  })
152
179
  })]
153
180
  }),
154
- /* @__PURE__ */ S("div", { children: [
155
- /* @__PURE__ */ x("h2", {
181
+ /* @__PURE__ */ C("div", { children: [
182
+ /* @__PURE__ */ S("h2", {
156
183
  className: "mb-4 text-lg font-semibold text-text-primary",
157
184
  children: "All Contracts"
158
185
  }),
159
- /* @__PURE__ */ x(c, {
160
- searchValue: E,
161
- onSearchChange: D,
186
+ /* @__PURE__ */ S(c, {
187
+ searchValue: k,
188
+ onSearchChange: A,
162
189
  searchPlaceholder: "Search contracts, providers, properties..."
163
190
  }),
164
- /* @__PURE__ */ x("div", {
191
+ /* @__PURE__ */ S("div", {
165
192
  className: "mt-4",
166
- children: O.length > 0 ? /* @__PURE__ */ x(a, {
193
+ children: j.length > 0 ? /* @__PURE__ */ S(a, {
167
194
  columns: [
168
195
  {
169
196
  key: "packageName",
170
197
  header: "Contract",
171
- render: (e) => /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("div", {
198
+ render: (e) => /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("div", {
172
199
  className: "font-medium text-text-primary",
173
200
  children: e.packageName
174
- }), /* @__PURE__ */ x("div", {
201
+ }), /* @__PURE__ */ S("div", {
175
202
  className: "text-xs text-text-secondary",
176
203
  children: e.propertyTitle
177
204
  })] })
@@ -179,7 +206,7 @@ function T() {
179
206
  {
180
207
  key: "providerName",
181
208
  header: "Provider",
182
- render: (e) => /* @__PURE__ */ x("span", {
209
+ render: (e) => /* @__PURE__ */ S("span", {
183
210
  className: "text-sm text-text-primary",
184
211
  children: e.providerName
185
212
  })
@@ -187,12 +214,12 @@ function T() {
187
214
  {
188
215
  key: "servicesIncluded",
189
216
  header: "Coverage",
190
- render: (e) => /* @__PURE__ */ S("div", {
217
+ render: (e) => /* @__PURE__ */ C("div", {
191
218
  className: "max-w-[200px]",
192
- children: [/* @__PURE__ */ S("span", {
219
+ children: [/* @__PURE__ */ C("span", {
193
220
  className: "text-sm text-text-primary",
194
221
  children: [e.servicesIncluded.length, " services"]
195
- }), /* @__PURE__ */ S("p", {
222
+ }), /* @__PURE__ */ C("p", {
196
223
  className: "truncate text-xs text-text-secondary",
197
224
  children: [e.servicesIncluded.slice(0, 2).join(", "), e.servicesIncluded.length > 2 && ` +${e.servicesIncluded.length - 2} more`]
198
225
  })]
@@ -201,10 +228,10 @@ function T() {
201
228
  {
202
229
  key: "monthlyCost",
203
230
  header: "Cost",
204
- render: (e) => /* @__PURE__ */ S("div", { children: [/* @__PURE__ */ x("span", {
231
+ render: (e) => /* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("span", {
205
232
  className: "font-medium text-text-primary",
206
233
  children: t(e.monthlyCost)
207
- }), /* @__PURE__ */ x("span", {
234
+ }), /* @__PURE__ */ S("span", {
208
235
  className: "text-xs text-text-secondary",
209
236
  children: "/mo"
210
237
  })] })
@@ -212,7 +239,7 @@ function T() {
212
239
  {
213
240
  key: "startDate",
214
241
  header: "Start",
215
- render: (e) => /* @__PURE__ */ x("span", {
242
+ render: (e) => /* @__PURE__ */ S("span", {
216
243
  className: "text-sm text-text-primary",
217
244
  children: n(e.startDate)
218
245
  })
@@ -220,7 +247,7 @@ function T() {
220
247
  {
221
248
  key: "endDate",
222
249
  header: "End",
223
- render: (e) => /* @__PURE__ */ x("span", {
250
+ render: (e) => /* @__PURE__ */ S("span", {
224
251
  className: "text-sm text-text-primary",
225
252
  children: n(e.endDate)
226
253
  })
@@ -228,24 +255,24 @@ function T() {
228
255
  {
229
256
  key: "status",
230
257
  header: "Status",
231
- render: (e) => /* @__PURE__ */ x(o, {
258
+ render: (e) => /* @__PURE__ */ S(o, {
232
259
  label: e.status.replace("_", " "),
233
- variant: w(e.status),
260
+ variant: E(e.status),
234
261
  dot: !0
235
262
  })
236
263
  }
237
264
  ],
238
- data: O,
265
+ data: j,
239
266
  keyField: "id",
240
267
  pageSize: 10
241
- }) : /* @__PURE__ */ x(s, {
268
+ }) : /* @__PURE__ */ S(s, {
242
269
  illustration: "empty-search",
243
- icon: /* @__PURE__ */ x(y, { className: "h-12 w-12" }),
270
+ icon: /* @__PURE__ */ S(y, { className: "h-12 w-12" }),
244
271
  title: "No contracts found",
245
272
  description: "Try adjusting your search criteria or create a new contract.",
246
- action: /* @__PURE__ */ S("button", {
273
+ action: /* @__PURE__ */ C("button", {
247
274
  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",
248
- children: [/* @__PURE__ */ x(_, { className: "h-4 w-4" }), "New Contract"]
275
+ children: [/* @__PURE__ */ S(_, { className: "h-4 w-4" }), "New Contract"]
249
276
  })
250
277
  })
251
278
  })
@@ -254,6 +281,6 @@ function T() {
254
281
  });
255
282
  }
256
283
  //#endregion
257
- export { T as AMCManagementPage };
284
+ export { D as AMCManagementPage };
258
285
 
259
286
  //# sourceMappingURL=AMCManagementPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AMCManagementPage.js","names":[],"sources":["../../../../src/housingvista/pages/amc/AMCManagementPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Shield,\n FileText,\n DollarSign,\n Calendar,\n Plus,\n Download,\n CheckCircle,\n Clock,\n AlertTriangle,\n Wrench,\n RotateCcw,\n Eye,\n} from 'lucide-react';\nimport { EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components';\nimport { StatCard } from '../../components';\nimport { DataTable, type Column } from '../../components';\nimport { StatusBadge } from '../../components';\nimport { FilterBar } from '../../components';\nimport { EmptyState } from '../../components';\nimport { useAMCContracts } from '../../hooks';\nimport { cn, formatCurrency, formatDate } from '../../utils/helpers';\nimport type { AMCContract } from '../../types';\n\nfunction getStatusVariant(status: AMCContract['status']): 'success' | 'warning' | 'error' | 'muted' {\n switch (status) {\n case 'active':\n return 'success';\n case 'expiring_soon':\n return 'warning';\n case 'expired':\n return 'error';\n case 'cancelled':\n return 'muted';\n default:\n return 'muted';\n }\n}\n\nexport function AMCManagementPage() {\n const { data: amcContracts } = useAMCContracts();\n const [search, setSearch] = useState('');\n\n const filtered = useMemo(() => {\n if (!search) return amcContracts;\n const q = search.toLowerCase();\n return amcContracts.filter(\n (c) =>\n c.propertyTitle.toLowerCase().includes(q) ||\n c.providerName.toLowerCase().includes(q) ||\n c.packageName.toLowerCase().includes(q)\n );\n }, [amcContracts, search]);\n\n const stats = useMemo(() => {\n const activeContracts = amcContracts.filter((c) => c.status === 'active' || c.status === 'expiring_soon').length;\n const pendingRenewals = amcContracts.filter((c) => c.status === 'expiring_soon').length;\n const totalMonthlySpent = amcContracts\n .filter((c) => c.status === 'active' || c.status === 'expiring_soon')\n .reduce((sum, c) => sum + c.monthlyCost, 0);\n const upcomingServices = amcContracts.filter((c) => {\n if (!c.nextServiceDate) return false;\n const serviceDate = new Date(c.nextServiceDate);\n const now = new Date();\n const daysUntil = (serviceDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24);\n return daysUntil >= 0 && daysUntil <= 30;\n }).length;\n return { activeContracts, pendingRenewals, totalMonthlySpent, upcomingServices };\n }, [amcContracts]);\n\n const scheduledServices = useMemo(\n () =>\n amcContracts\n .filter((c) => c.nextServiceDate && (c.status === 'active' || c.status === 'expiring_soon'))\n .sort((a, b) => new Date(a.nextServiceDate).getTime() - new Date(b.nextServiceDate).getTime()),\n [amcContracts]\n );\n\n const contractColumns: Column<AMCContract>[] = [\n {\n key: 'packageName',\n header: 'Contract',\n render: (item) => (\n <div>\n <div className=\"font-medium text-text-primary\">{item.packageName}</div>\n <div className=\"text-xs text-text-secondary\">{item.propertyTitle}</div>\n </div>\n ),\n },\n {\n key: 'providerName',\n header: 'Provider',\n render: (item) => <span className=\"text-sm text-text-primary\">{item.providerName}</span>,\n },\n {\n key: 'servicesIncluded',\n header: 'Coverage',\n render: (item) => (\n <div className=\"max-w-[200px]\">\n <span className=\"text-sm text-text-primary\">{item.servicesIncluded.length} services</span>\n <p className=\"truncate text-xs text-text-secondary\">\n {item.servicesIncluded.slice(0, 2).join(', ')}\n {item.servicesIncluded.length > 2 && ` +${item.servicesIncluded.length - 2} more`}\n </p>\n </div>\n ),\n },\n {\n key: 'monthlyCost',\n header: 'Cost',\n render: (item) => (\n <div>\n <span className=\"font-medium text-text-primary\">{formatCurrency(item.monthlyCost)}</span>\n <span className=\"text-xs text-text-secondary\">/mo</span>\n </div>\n ),\n },\n {\n key: 'startDate',\n header: 'Start',\n render: (item) => <span className=\"text-sm text-text-primary\">{formatDate(item.startDate)}</span>,\n },\n {\n key: 'endDate',\n header: 'End',\n render: (item) => <span className=\"text-sm text-text-primary\">{formatDate(item.endDate)}</span>,\n },\n {\n key: 'status',\n header: 'Status',\n render: (item) => (\n <StatusBadge label={item.status.replace('_', ' ')} variant={getStatusVariant(item.status)} dot />\n ),\n },\n ];\n\n return (\n <PageLayout\n title=\"AMC Management\"\n description=\"Manage Annual Maintenance Contracts and service packages\"\n purpose=\"Keep your properties maintained without surprises. Track every Annual Maintenance Contract, see what each covers and costs, get ahead of renewals, and know which services are due in the next 30 days so nothing slips.\"\n actions={\n <div className=\"flex items-center gap-2\">\n <button className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\">\n <Download className=\"h-4 w-4\" />\n Export\n </button>\n <button 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 <Plus className=\"h-4 w-4\" />\n New Contract\n </button>\n </div>\n }\n >\n {/* Stats — primary insight zone (one EmphasisPanel per page) */}\n <EmphasisPanel className=\"p-4\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard label=\"Active Contracts\" value={stats.activeContracts} icon={<Shield className=\"h-4 w-4\" />} />\n <StatCard\n label=\"Pending Renewals\"\n value={stats.pendingRenewals}\n icon={<RotateCcw className=\"h-4 w-4\" />}\n trend={stats.pendingRenewals > 0 ? 'up' : 'stable'}\n change={stats.pendingRenewals > 0 ? stats.pendingRenewals : 0}\n />\n <StatCard\n label=\"Total Monthly Spent\"\n value={stats.totalMonthlySpent}\n prefix=\"$\"\n icon={<DollarSign className=\"h-4 w-4\" />}\n />\n <StatCard label=\"Upcoming Services\" value={stats.upcomingServices} icon={<Calendar className=\"h-4 w-4\" />} />\n </div>\n </EmphasisPanel>\n\n {/* Service Schedule Section */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-sm\">\n <h3 className=\"mb-4 text-lg font-semibold text-text-primary\">Upcoming Service Schedule</h3>\n {scheduledServices.length === 0 ? (\n <EmptyState\n illustration=\"empty-generic\"\n title=\"No services scheduled\"\n description=\"Once your active contracts have upcoming service dates, they'll be listed here in order of priority.\"\n className=\"border-0 bg-transparent p-6\"\n />\n ) : (\n <div className=\"space-y-3\">\n {scheduledServices\n .map((contract) => {\n const serviceDate = new Date(contract.nextServiceDate);\n const now = new Date();\n const daysUntil = Math.ceil((serviceDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));\n const isUrgent = daysUntil <= 7;\n const isPast = daysUntil < 0;\n\n return (\n <div\n key={contract.id}\n className=\"flex flex-col gap-3 rounded-lg bg-bg-sunken/50 p-4 sm:flex-row sm:items-center sm:justify-between\"\n >\n <div className=\"flex items-start gap-3\">\n <div\n className={cn(\n 'rounded-lg p-2',\n isPast\n ? 'bg-red-100 dark:bg-red-900/30'\n : isUrgent\n ? 'bg-amber-100 dark:bg-amber-900/30'\n : 'bg-blue-100 dark:bg-blue-900/30'\n )}\n >\n {isPast ? (\n <AlertTriangle className=\"h-4 w-4 text-red-600 dark:text-red-400\" />\n ) : isUrgent ? (\n <Clock className=\"h-4 w-4 text-amber-600 dark:text-amber-400\" />\n ) : (\n <Wrench className=\"h-4 w-4 text-blue-600 dark:text-blue-400\" />\n )}\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">{contract.propertyTitle}</p>\n <p className=\"text-sm text-text-secondary\">\n {contract.packageName} &middot; {contract.providerName}\n </p>\n <div className=\"mt-1 flex flex-wrap gap-1\">\n {contract.servicesIncluded.slice(0, 3).map((service, idx) => (\n <span\n key={idx}\n className=\"inline-block rounded-md bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {service}\n </span>\n ))}\n {contract.servicesIncluded.length > 3 && (\n <span className=\"inline-block rounded-md bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\">\n +{contract.servicesIncluded.length - 3} more\n </span>\n )}\n </div>\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <div className=\"text-right\">\n <p className=\"text-sm font-medium text-text-primary\">{formatDate(contract.nextServiceDate)}</p>\n <p\n className={cn(\n 'text-xs',\n isPast\n ? 'text-red-600 dark:text-red-400'\n : isUrgent\n ? 'text-amber-600 dark:text-amber-400'\n : 'text-text-secondary'\n )}\n >\n {isPast\n ? `${Math.abs(daysUntil)} days overdue`\n : daysUntil === 0\n ? 'Today'\n : `In ${daysUntil} days`}\n </p>\n </div>\n <StatusBadge\n label={contract.status.replace('_', ' ')}\n variant={getStatusVariant(contract.status)}\n />\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n\n {/* Contracts Table */}\n <div>\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">All Contracts</h2>\n <FilterBar\n searchValue={search}\n onSearchChange={setSearch}\n searchPlaceholder=\"Search contracts, providers, properties...\"\n />\n <div className=\"mt-4\">\n {filtered.length > 0 ? (\n <DataTable columns={contractColumns} data={filtered} keyField=\"id\" pageSize={10} />\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n icon={<Shield className=\"h-12 w-12\" />}\n title=\"No contracts found\"\n description=\"Try adjusting your search criteria or create a new contract.\"\n action={\n <button 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 <Plus className=\"h-4 w-4\" />\n New Contract\n </button>\n }\n />\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AMCManagementPage.js","names":[],"sources":["../../../../src/housingvista/pages/amc/AMCManagementPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport {\n Shield,\n FileText,\n DollarSign,\n Calendar,\n Plus,\n Download,\n CheckCircle,\n Clock,\n AlertTriangle,\n Wrench,\n RotateCcw,\n Eye,\n} from 'lucide-react';\nimport { EmphasisPanel, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components';\nimport { StatCard } from '../../components';\nimport { DataTable, type Column } from '../../components';\nimport { StatusBadge } from '../../components';\nimport { FilterBar } from '../../components';\nimport { EmptyState } from '../../components';\nimport { useAMCContracts } from '../../hooks';\nimport { cn, formatCurrency, formatDate } from '../../utils/helpers';\nimport type { AMCContract } from '../../types';\n\nfunction getStatusVariant(status: AMCContract['status']): 'success' | 'warning' | 'error' | 'muted' {\n switch (status) {\n case 'active':\n return 'success';\n case 'expiring_soon':\n return 'warning';\n case 'expired':\n return 'error';\n case 'cancelled':\n return 'muted';\n default:\n return 'muted';\n }\n}\n\nexport function AMCManagementPage() {\n const navigate = useNavigate();\n const { data: amcContracts } = useAMCContracts();\n const [search, setSearch] = useState('');\n\n const filtered = useMemo(() => {\n if (!search) return amcContracts;\n const q = search.toLowerCase();\n return amcContracts.filter(\n (c) =>\n c.propertyTitle.toLowerCase().includes(q) ||\n c.providerName.toLowerCase().includes(q) ||\n c.packageName.toLowerCase().includes(q)\n );\n }, [amcContracts, search]);\n\n const stats = useMemo(() => {\n const activeContracts = amcContracts.filter((c) => c.status === 'active' || c.status === 'expiring_soon').length;\n const pendingRenewals = amcContracts.filter((c) => c.status === 'expiring_soon').length;\n const totalMonthlySpent = amcContracts\n .filter((c) => c.status === 'active' || c.status === 'expiring_soon')\n .reduce((sum, c) => sum + c.monthlyCost, 0);\n const upcomingServices = amcContracts.filter((c) => {\n if (!c.nextServiceDate) return false;\n const serviceDate = new Date(c.nextServiceDate);\n const now = new Date();\n const daysUntil = (serviceDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24);\n return daysUntil >= 0 && daysUntil <= 30;\n }).length;\n return { activeContracts, pendingRenewals, totalMonthlySpent, upcomingServices };\n }, [amcContracts]);\n\n const scheduledServices = useMemo(\n () =>\n amcContracts\n .filter((c) => c.nextServiceDate && (c.status === 'active' || c.status === 'expiring_soon'))\n .sort((a, b) => new Date(a.nextServiceDate).getTime() - new Date(b.nextServiceDate).getTime()),\n [amcContracts]\n );\n\n const contractColumns: Column<AMCContract>[] = [\n {\n key: 'packageName',\n header: 'Contract',\n render: (item) => (\n <div>\n <div className=\"font-medium text-text-primary\">{item.packageName}</div>\n <div className=\"text-xs text-text-secondary\">{item.propertyTitle}</div>\n </div>\n ),\n },\n {\n key: 'providerName',\n header: 'Provider',\n render: (item) => <span className=\"text-sm text-text-primary\">{item.providerName}</span>,\n },\n {\n key: 'servicesIncluded',\n header: 'Coverage',\n render: (item) => (\n <div className=\"max-w-[200px]\">\n <span className=\"text-sm text-text-primary\">{item.servicesIncluded.length} services</span>\n <p className=\"truncate text-xs text-text-secondary\">\n {item.servicesIncluded.slice(0, 2).join(', ')}\n {item.servicesIncluded.length > 2 && ` +${item.servicesIncluded.length - 2} more`}\n </p>\n </div>\n ),\n },\n {\n key: 'monthlyCost',\n header: 'Cost',\n render: (item) => (\n <div>\n <span className=\"font-medium text-text-primary\">{formatCurrency(item.monthlyCost)}</span>\n <span className=\"text-xs text-text-secondary\">/mo</span>\n </div>\n ),\n },\n {\n key: 'startDate',\n header: 'Start',\n render: (item) => <span className=\"text-sm text-text-primary\">{formatDate(item.startDate)}</span>,\n },\n {\n key: 'endDate',\n header: 'End',\n render: (item) => <span className=\"text-sm text-text-primary\">{formatDate(item.endDate)}</span>,\n },\n {\n key: 'status',\n header: 'Status',\n render: (item) => (\n <StatusBadge label={item.status.replace('_', ' ')} variant={getStatusVariant(item.status)} dot />\n ),\n },\n ];\n\n return (\n <PageLayout\n title=\"AMC Management\"\n description=\"Manage Annual Maintenance Contracts and service packages\"\n purpose=\"Keep your properties maintained without surprises. Track every Annual Maintenance Contract, see what each covers and costs, get ahead of renewals, and know which services are due in the next 30 days so nothing slips.\"\n actions={\n <div className=\"flex items-center gap-2\">\n <button className=\"inline-flex items-center gap-2 rounded-md border border-border-subtle px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken\">\n <Download className=\"h-4 w-4\" />\n Export\n </button>\n <button 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 <Plus className=\"h-4 w-4\" />\n New Contract\n </button>\n </div>\n }\n >\n {/* Stats — primary insight zone (one EmphasisPanel per page) */}\n <EmphasisPanel className=\"p-4\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <StatCard label=\"Active Contracts\" value={stats.activeContracts} icon={<Shield className=\"h-4 w-4\" />} />\n <StatCard\n label=\"Pending Renewals\"\n value={stats.pendingRenewals}\n icon={<RotateCcw className=\"h-4 w-4\" />}\n trend={stats.pendingRenewals > 0 ? 'up' : 'stable'}\n change={stats.pendingRenewals > 0 ? stats.pendingRenewals : 0}\n />\n <StatCard\n label=\"Total Monthly Spent\"\n value={stats.totalMonthlySpent}\n prefix=\"$\"\n icon={<DollarSign className=\"h-4 w-4\" />}\n />\n <StatCard label=\"Upcoming Services\" value={stats.upcomingServices} icon={<Calendar className=\"h-4 w-4\" />} />\n </div>\n </EmphasisPanel>\n\n <NextSteps\n storageKey=\"housingvista-amc\"\n steps={[\n {\n id: 'pick-property',\n label: 'Add coverage for a property',\n description: 'Choose a property to set up a new maintenance contract.',\n onClick: () => navigate('/properties'),\n },\n {\n id: 'compare-providers',\n label: 'Compare your providers',\n description: 'Search by provider name to weigh coverage and monthly cost.',\n onClick: () => {\n const firstProvider = amcContracts[0]?.providerName;\n if (firstProvider) setSearch(firstProvider);\n },\n },\n {\n id: 'check-legal',\n label: 'Review contract paperwork',\n description: 'Open the legal hub to manage the underlying documents.',\n onClick: () => navigate('/legal'),\n },\n ]}\n />\n\n {/* Service Schedule Section */}\n <div className=\"rounded-lg border border-border-subtle bg-bg-surface p-5 shadow-sm\">\n <h3 className=\"mb-4 text-lg font-semibold text-text-primary\">Upcoming Service Schedule</h3>\n {scheduledServices.length === 0 ? (\n <EmptyState\n illustration=\"empty-generic\"\n title=\"No services scheduled\"\n description=\"Once your active contracts have upcoming service dates, they'll be listed here in order of priority.\"\n className=\"border-0 bg-transparent p-6\"\n />\n ) : (\n <div className=\"space-y-3\">\n {scheduledServices\n .map((contract) => {\n const serviceDate = new Date(contract.nextServiceDate);\n const now = new Date();\n const daysUntil = Math.ceil((serviceDate.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));\n const isUrgent = daysUntil <= 7;\n const isPast = daysUntil < 0;\n\n return (\n <div\n key={contract.id}\n className=\"flex flex-col gap-3 rounded-lg bg-bg-sunken/50 p-4 sm:flex-row sm:items-center sm:justify-between\"\n >\n <div className=\"flex items-start gap-3\">\n <div\n className={cn(\n 'rounded-lg p-2',\n isPast\n ? 'bg-red-100 dark:bg-red-900/30'\n : isUrgent\n ? 'bg-amber-100 dark:bg-amber-900/30'\n : 'bg-blue-100 dark:bg-blue-900/30'\n )}\n >\n {isPast ? (\n <AlertTriangle className=\"h-4 w-4 text-red-600 dark:text-red-400\" />\n ) : isUrgent ? (\n <Clock className=\"h-4 w-4 text-amber-600 dark:text-amber-400\" />\n ) : (\n <Wrench className=\"h-4 w-4 text-blue-600 dark:text-blue-400\" />\n )}\n </div>\n <div>\n <p className=\"font-medium text-text-primary\">{contract.propertyTitle}</p>\n <p className=\"text-sm text-text-secondary\">\n {contract.packageName} &middot; {contract.providerName}\n </p>\n <div className=\"mt-1 flex flex-wrap gap-1\">\n {contract.servicesIncluded.slice(0, 3).map((service, idx) => (\n <span\n key={idx}\n className=\"inline-block rounded-md bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {service}\n </span>\n ))}\n {contract.servicesIncluded.length > 3 && (\n <span className=\"inline-block rounded-md bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\">\n +{contract.servicesIncluded.length - 3} more\n </span>\n )}\n </div>\n </div>\n </div>\n <div className=\"flex items-center gap-3\">\n <div className=\"text-right\">\n <p className=\"text-sm font-medium text-text-primary\">{formatDate(contract.nextServiceDate)}</p>\n <p\n className={cn(\n 'text-xs',\n isPast\n ? 'text-red-600 dark:text-red-400'\n : isUrgent\n ? 'text-amber-600 dark:text-amber-400'\n : 'text-text-secondary'\n )}\n >\n {isPast\n ? `${Math.abs(daysUntil)} days overdue`\n : daysUntil === 0\n ? 'Today'\n : `In ${daysUntil} days`}\n </p>\n </div>\n <StatusBadge\n label={contract.status.replace('_', ' ')}\n variant={getStatusVariant(contract.status)}\n />\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n\n {/* Contracts Table */}\n <div>\n <h2 className=\"mb-4 text-lg font-semibold text-text-primary\">All Contracts</h2>\n <FilterBar\n searchValue={search}\n onSearchChange={setSearch}\n searchPlaceholder=\"Search contracts, providers, properties...\"\n />\n <div className=\"mt-4\">\n {filtered.length > 0 ? (\n <DataTable columns={contractColumns} data={filtered} keyField=\"id\" pageSize={10} />\n ) : (\n <EmptyState\n illustration=\"empty-search\"\n icon={<Shield className=\"h-12 w-12\" />}\n title=\"No contracts found\"\n description=\"Try adjusting your search criteria or create a new contract.\"\n action={\n <button 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 <Plus className=\"h-4 w-4\" />\n New Contract\n </button>\n }\n />\n )}\n </div>\n </div>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -12,9 +12,9 @@ import { useMemo as u, useState as d } from "react";
12
12
  import { ArrowDownRight as f, ArrowUpRight as p, BarChart3 as m, Building as h, DollarSign as g, Download as _, Eye as v, MapPin as y, Plus as b, TrendingUp as x } from "lucide-react";
13
13
  import { useNavigate as S } from "react-router-dom";
14
14
  import { jsx as C, jsxs as w } from "react/jsx-runtime";
15
- import { EmphasisPanel as T } from "@burdenoff/fe-libs/ui";
15
+ import { EmphasisPanel as T, NextSteps as E } from "@burdenoff/fe-libs/ui";
16
16
  //#region src/housingvista/pages/assets/AssetManagementPage.tsx
17
- function E(e) {
17
+ function D(e) {
18
18
  switch (e) {
19
19
  case "active": return "success";
20
20
  case "under_renovation": return "warning";
@@ -23,20 +23,20 @@ function E(e) {
23
23
  default: return "muted";
24
24
  }
25
25
  }
26
- function D() {
27
- let D = S(), O = l(10), { data: k, loading: A } = c(O.pagination), [j, M] = d(""), N = u(() => {
28
- if (!j) return k;
29
- let e = j.toLowerCase();
30
- return k.filter((t) => t.title.toLowerCase().includes(e) || t.location.toLowerCase().includes(e) || t.type.toLowerCase().includes(e));
31
- }, [k, j]), P = u(() => {
32
- let e = k.reduce((e, t) => e + t.currentValue, 0), t = k.filter((e) => e.rentalYield).reduce((e, t) => e + t.currentValue * (t.rentalYield || 0) / 100 / 12, 0), n = k.length > 0 ? k.reduce((e, t) => e + t.appreciationPercent, 0) / k.length : 0, r = k.reduce((e, t) => e + t.purchasePrice, 0);
26
+ function O() {
27
+ let O = S(), k = l(10), { data: A, loading: j } = c(k.pagination), [M, N] = d(""), P = u(() => {
28
+ if (!M) return A;
29
+ let e = M.toLowerCase();
30
+ return A.filter((t) => t.title.toLowerCase().includes(e) || t.location.toLowerCase().includes(e) || t.type.toLowerCase().includes(e));
31
+ }, [A, M]), F = u(() => {
32
+ let e = A.reduce((e, t) => e + t.currentValue, 0), t = A.filter((e) => e.rentalYield).reduce((e, t) => e + t.currentValue * (t.rentalYield || 0) / 100 / 12, 0), n = A.length > 0 ? A.reduce((e, t) => e + t.appreciationPercent, 0) / A.length : 0, r = A.reduce((e, t) => e + t.purchasePrice, 0);
33
33
  return {
34
34
  totalValue: e,
35
35
  totalMonthlyIncome: t,
36
36
  avgAppreciation: n,
37
37
  totalROI: r > 0 ? (e - r) / r * 100 : 0
38
38
  };
39
- }, [k]);
39
+ }, [A]);
40
40
  return /* @__PURE__ */ w(n, {
41
41
  title: "Asset Management",
42
42
  description: "Monitor and manage your property portfolio performance",
@@ -59,7 +59,7 @@ function D() {
59
59
  children: [
60
60
  /* @__PURE__ */ C(r, {
61
61
  label: "Total Value",
62
- value: P.totalValue,
62
+ value: F.totalValue,
63
63
  prefix: "$",
64
64
  icon: /* @__PURE__ */ C(g, { className: "h-4 w-4" }),
65
65
  trend: "up",
@@ -67,7 +67,7 @@ function D() {
67
67
  }),
68
68
  /* @__PURE__ */ C(r, {
69
69
  label: "Monthly Income",
70
- value: Math.round(P.totalMonthlyIncome),
70
+ value: Math.round(F.totalMonthlyIncome),
71
71
  prefix: "$",
72
72
  icon: /* @__PURE__ */ C(x, { className: "h-4 w-4" }),
73
73
  trend: "up",
@@ -75,14 +75,14 @@ function D() {
75
75
  }),
76
76
  /* @__PURE__ */ C(r, {
77
77
  label: "Avg. Appreciation",
78
- value: `${P.avgAppreciation.toFixed(1)}%`,
78
+ value: `${F.avgAppreciation.toFixed(1)}%`,
79
79
  icon: /* @__PURE__ */ C(m, { className: "h-4 w-4" }),
80
80
  trend: "up",
81
81
  change: 2
82
82
  }),
83
83
  /* @__PURE__ */ C(r, {
84
84
  label: "Overall ROI",
85
- value: `${P.totalROI.toFixed(1)}%`,
85
+ value: `${F.totalROI.toFixed(1)}%`,
86
86
  icon: /* @__PURE__ */ C(h, { className: "h-4 w-4" }),
87
87
  trend: "up",
88
88
  change: 3
@@ -90,13 +90,39 @@ function D() {
90
90
  ]
91
91
  })
92
92
  }),
93
+ /* @__PURE__ */ C(E, {
94
+ storageKey: "housingvista-assets",
95
+ steps: [
96
+ {
97
+ id: "open-asset",
98
+ label: "Open an asset to see full performance",
99
+ description: "Drill into value history, yield, and ROI for any property.",
100
+ onClick: () => {
101
+ let e = A[0];
102
+ e && O(`/assets/${e.id}`);
103
+ }
104
+ },
105
+ {
106
+ id: "compare-market",
107
+ label: "Compare against market trends",
108
+ description: "Check market analytics to benchmark your portfolio.",
109
+ onClick: () => O("/market-analytics")
110
+ },
111
+ {
112
+ id: "add-asset",
113
+ label: "Add a property you already own",
114
+ description: "Bring an existing holding into your portfolio view.",
115
+ onClick: () => O("/properties/new")
116
+ }
117
+ ]
118
+ }),
93
119
  /* @__PURE__ */ C("div", {
94
120
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
95
- children: k.map((n) => {
121
+ children: A.map((n) => {
96
122
  let r = n.currentValue - n.purchasePrice >= 0;
97
123
  return /* @__PURE__ */ w("div", {
98
124
  className: "cursor-pointer rounded-lg border border-border-subtle bg-bg-surface p-4 shadow-sm transition-shadow hover:shadow-md",
99
- onClick: () => D(`/assets/${n.id}`),
125
+ onClick: () => O(`/assets/${n.id}`),
100
126
  children: [/* @__PURE__ */ w("div", {
101
127
  className: "mb-3 flex items-start justify-between",
102
128
  children: [/* @__PURE__ */ w("div", {
@@ -114,7 +140,7 @@ function D() {
114
140
  })] })]
115
141
  }), /* @__PURE__ */ C(a, {
116
142
  label: n.status.replace("_", " "),
117
- variant: E(n.status)
143
+ variant: D(n.status)
118
144
  })]
119
145
  }), /* @__PURE__ */ w("div", {
120
146
  className: "grid grid-cols-2 gap-3",
@@ -162,13 +188,13 @@ function D() {
162
188
  children: "All Assets"
163
189
  }),
164
190
  /* @__PURE__ */ C(s, {
165
- searchValue: j,
166
- onSearchChange: M,
191
+ searchValue: M,
192
+ onSearchChange: N,
167
193
  searchPlaceholder: "Search assets by name, location, or type..."
168
194
  }),
169
195
  /* @__PURE__ */ C("div", {
170
196
  className: "mt-4",
171
- children: N.length > 0 ? /* @__PURE__ */ C(i, {
197
+ children: P.length > 0 ? /* @__PURE__ */ C(i, {
172
198
  columns: [
173
199
  {
174
200
  key: "title",
@@ -239,7 +265,7 @@ function D() {
239
265
  header: "Status",
240
266
  render: (e) => /* @__PURE__ */ C(a, {
241
267
  label: e.status.replace("_", " "),
242
- variant: E(e.status)
268
+ variant: D(e.status)
243
269
  })
244
270
  },
245
271
  {
@@ -248,24 +274,24 @@ function D() {
248
274
  sortable: !1,
249
275
  render: (e) => /* @__PURE__ */ w("button", {
250
276
  onClick: (t) => {
251
- t.stopPropagation(), D(`/assets/${e.id}`);
277
+ t.stopPropagation(), O(`/assets/${e.id}`);
252
278
  },
253
279
  className: "inline-flex items-center gap-1 rounded-md border border-border-subtle px-2 py-1 text-xs font-medium text-text-primary transition-colors hover:bg-bg-sunken",
254
280
  children: [/* @__PURE__ */ C(v, { className: "h-3 w-3" }), "View"]
255
281
  })
256
282
  }
257
283
  ],
258
- data: N,
284
+ data: P,
259
285
  keyField: "id",
260
- onRowClick: (e) => D(`/assets/${e.id}`),
286
+ onRowClick: (e) => O(`/assets/${e.id}`),
261
287
  pageSize: 10,
262
288
  serverPagination: {
263
- page: O.page,
264
- pageSize: O.pageSize,
265
- hasNextPage: k.length >= O.pageSize,
266
- loading: A,
267
- onPageChange: O.setPage,
268
- onPageSizeChange: O.setPageSize
289
+ page: k.page,
290
+ pageSize: k.pageSize,
291
+ hasNextPage: A.length >= k.pageSize,
292
+ loading: j,
293
+ onPageChange: k.setPage,
294
+ onPageSizeChange: k.setPageSize
269
295
  }
270
296
  }) : /* @__PURE__ */ C(o, {
271
297
  illustration: "empty-search",
@@ -283,6 +309,6 @@ function D() {
283
309
  });
284
310
  }
285
311
  //#endregion
286
- export { D as AssetManagementPage };
312
+ export { O as AssetManagementPage };
287
313
 
288
314
  //# sourceMappingURL=AssetManagementPage.js.map