@burdenoff/microfe-proserviceworld 2026.624.1 → 2026.625.1

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 (31) hide show
  1. package/dist/proserviceworld/pages/AdminReportsPage.js +365 -332
  2. package/dist/proserviceworld/pages/AdminReportsPage.js.map +1 -1
  3. package/dist/proserviceworld/pages/AdminUsersPage.js +257 -237
  4. package/dist/proserviceworld/pages/AdminUsersPage.js.map +1 -1
  5. package/dist/proserviceworld/pages/AnalyticsPage.js +343 -315
  6. package/dist/proserviceworld/pages/AnalyticsPage.js.map +1 -1
  7. package/dist/proserviceworld/pages/BookingsPage.js +191 -174
  8. package/dist/proserviceworld/pages/BookingsPage.js.map +1 -1
  9. package/dist/proserviceworld/pages/DashboardPage.js +383 -346
  10. package/dist/proserviceworld/pages/DashboardPage.js.map +1 -1
  11. package/dist/proserviceworld/pages/DocumentsPage.js +383 -318
  12. package/dist/proserviceworld/pages/DocumentsPage.js.map +1 -1
  13. package/dist/proserviceworld/pages/MessagesPage.js +70 -75
  14. package/dist/proserviceworld/pages/MessagesPage.js.map +1 -1
  15. package/dist/proserviceworld/pages/PaymentsPage.js +367 -340
  16. package/dist/proserviceworld/pages/PaymentsPage.js.map +1 -1
  17. package/dist/proserviceworld/pages/ProjectsPage.js +428 -381
  18. package/dist/proserviceworld/pages/ProjectsPage.js.map +1 -1
  19. package/dist/proserviceworld/pages/ProviderDetailPage.js +390 -346
  20. package/dist/proserviceworld/pages/ProviderDetailPage.js.map +1 -1
  21. package/dist/proserviceworld/pages/ProvidersPage.js +245 -244
  22. package/dist/proserviceworld/pages/ProvidersPage.js.map +1 -1
  23. package/dist/proserviceworld/pages/ReviewsPage.js +14 -14
  24. package/dist/proserviceworld/pages/ReviewsPage.js.map +1 -1
  25. package/dist/proserviceworld/pages/ServiceDetailsPage.js +338 -305
  26. package/dist/proserviceworld/pages/ServiceDetailsPage.js.map +1 -1
  27. package/dist/proserviceworld/pages/ServicesPage.js +156 -153
  28. package/dist/proserviceworld/pages/ServicesPage.js.map +1 -1
  29. package/dist/proserviceworld/pages/VerificationPage.js +260 -251
  30. package/dist/proserviceworld/pages/VerificationPage.js.map +1 -1
  31. package/package.json +2 -2
@@ -2,30 +2,30 @@ import { useProServiceWorldStore as e } from "../store/proserviceworldStore.js";
2
2
  import { useMemo as t, useState as n } from "react";
3
3
  import { ArrowUpDown as r, Calendar as i, CheckCircle2 as a, ChevronRight as o, Clock as s, DollarSign as c, Filter as l, Loader2 as u, Search as d, User as f, XCircle as p } from "lucide-react";
4
4
  import { jsx as m, jsxs as h } from "react/jsx-runtime";
5
- import { Badge as g, Button as _, Card as v, CardContent as y, CardHeader as b, CardTitle as x, Input as S } from "@burdenoff/fe-libs/ui";
5
+ import { Badge as g, Button as _, Card as v, CardContent as y, GlassCard as b, IllustratedEmptyState as x, Input as S } from "@burdenoff/fe-libs/ui";
6
6
  //#region src/proserviceworld/pages/BookingsPage.tsx
7
7
  var C = {
8
8
  pending: {
9
9
  label: "Pending",
10
- color: "text-yellow-600",
10
+ color: "text-status-warning-text",
11
11
  icon: s,
12
12
  badgeVariant: "secondary"
13
13
  },
14
14
  in_progress: {
15
15
  label: "In Progress",
16
- color: "text-blue-600",
16
+ color: "text-accent-blue",
17
17
  icon: u,
18
18
  badgeVariant: "default"
19
19
  },
20
20
  completed: {
21
21
  label: "Completed",
22
- color: "text-green-600",
22
+ color: "text-status-success-text",
23
23
  icon: a,
24
24
  badgeVariant: "outline"
25
25
  },
26
26
  cancelled: {
27
27
  label: "Cancelled",
28
- color: "text-red-600",
28
+ color: "text-status-error-text",
29
29
  icon: p,
30
30
  badgeVariant: "destructive"
31
31
  }
@@ -55,12 +55,12 @@ function w() {
55
55
  D === e ? A(!k) : (O(e), A(!1));
56
56
  };
57
57
  return /* @__PURE__ */ h("div", {
58
- className: "space-y-6 p-6",
58
+ className: "space-y-6 p-6 bg-bg-canvas min-h-screen",
59
59
  children: [
60
60
  /* @__PURE__ */ h("div", {
61
61
  className: "flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between",
62
62
  children: [/* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h1", {
63
- className: "text-2xl font-semibold",
63
+ className: "text-2xl font-semibold tracking-tight",
64
64
  children: "Bookings"
65
65
  }), /* @__PURE__ */ m("p", {
66
66
  className: "text-sm text-text-secondary",
@@ -73,70 +73,75 @@ function w() {
73
73
  /* @__PURE__ */ h("div", {
74
74
  className: "grid gap-4 sm:grid-cols-2 lg:grid-cols-4",
75
75
  children: [
76
- /* @__PURE__ */ m(v, { children: /* @__PURE__ */ m(y, {
77
- className: "pt-4",
76
+ /* @__PURE__ */ m(b, {
77
+ treatment: "metric",
78
+ className: "border-border-seam",
78
79
  children: /* @__PURE__ */ h("div", {
79
80
  className: "flex items-center gap-3",
80
81
  children: [/* @__PURE__ */ m("div", {
81
- className: "rounded-lg bg-blue-100 p-2 dark:bg-blue-950",
82
- children: /* @__PURE__ */ m(i, { className: "h-5 w-5 text-blue-600" })
82
+ className: "rounded-lg bg-status-info-bg-subtle p-2",
83
+ children: /* @__PURE__ */ m(i, { className: "h-5 w-5 text-accent-blue" })
83
84
  }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
84
- className: "text-2xl font-bold",
85
+ className: "text-2xl font-bold tabular-nums",
85
86
  children: s.length
86
87
  }), /* @__PURE__ */ m("p", {
87
88
  className: "text-xs text-text-secondary",
88
89
  children: "Total Bookings"
89
90
  })] })]
90
91
  })
91
- }) }),
92
- /* @__PURE__ */ m(v, { children: /* @__PURE__ */ m(y, {
93
- className: "pt-4",
92
+ }),
93
+ /* @__PURE__ */ m(b, {
94
+ treatment: "metric",
95
+ className: "border-border-seam",
94
96
  children: /* @__PURE__ */ h("div", {
95
97
  className: "flex items-center gap-3",
96
98
  children: [/* @__PURE__ */ m("div", {
97
- className: "rounded-lg bg-green-100 p-2 dark:bg-green-950",
98
- children: /* @__PURE__ */ m(a, { className: "h-5 w-5 text-green-600" })
99
+ className: "rounded-lg bg-status-success-bg-subtle p-2",
100
+ children: /* @__PURE__ */ m(a, { className: "h-5 w-5 text-status-success-text" })
99
101
  }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("p", {
100
- className: "text-2xl font-bold",
102
+ className: "text-2xl font-bold tabular-nums",
101
103
  children: F.completed ?? 0
102
104
  }), /* @__PURE__ */ m("p", {
103
105
  className: "text-xs text-text-secondary",
104
106
  children: "Completed"
105
107
  })] })]
106
108
  })
107
- }) }),
108
- /* @__PURE__ */ m(v, { children: /* @__PURE__ */ m(y, {
109
- className: "pt-4",
109
+ }),
110
+ /* @__PURE__ */ m(b, {
111
+ treatment: "metric",
112
+ className: "border-border-seam",
110
113
  children: /* @__PURE__ */ h("div", {
111
114
  className: "flex items-center gap-3",
112
115
  children: [/* @__PURE__ */ m("div", {
113
- className: "rounded-lg bg-yellow-100 p-2 dark:bg-yellow-950",
114
- children: /* @__PURE__ */ m(u, { className: "h-5 w-5 text-yellow-600" })
116
+ className: "rounded-lg bg-status-warning-bg-subtle p-2",
117
+ children: /* @__PURE__ */ m(u, { className: "h-5 w-5 text-status-warning-text" })
115
118
  }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ h("p", {
116
- className: "text-2xl font-bold",
119
+ className: "text-2xl font-bold tabular-nums",
117
120
  children: [L, "%"]
118
121
  }), /* @__PURE__ */ m("p", {
119
122
  className: "text-xs text-text-secondary",
120
123
  children: "Avg. In-Progress"
121
124
  })] })]
122
125
  })
123
- }) }),
124
- /* @__PURE__ */ m(v, { children: /* @__PURE__ */ m(y, {
125
- className: "pt-4",
126
+ }),
127
+ /* @__PURE__ */ m(b, {
128
+ treatment: "glass",
129
+ glow: !0,
130
+ className: "border-border-seam",
126
131
  children: /* @__PURE__ */ h("div", {
127
132
  className: "flex items-center gap-3",
128
133
  children: [/* @__PURE__ */ m("div", {
129
- className: "rounded-lg bg-purple-100 p-2 dark:bg-purple-950",
130
- children: /* @__PURE__ */ m(c, { className: "h-5 w-5 text-purple-600" })
134
+ className: "rounded-lg bg-accent-purple-subtle p-2",
135
+ children: /* @__PURE__ */ m(c, { className: "h-5 w-5 text-accent-purple" })
131
136
  }), /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ h("p", {
132
- className: "text-2xl font-bold",
137
+ className: "text-2xl font-bold tabular-nums",
133
138
  children: ["$", I.toLocaleString()]
134
139
  }), /* @__PURE__ */ m("p", {
135
140
  className: "text-xs text-text-secondary",
136
141
  children: "Total Budget"
137
142
  })] })]
138
143
  })
139
- }) })
144
+ })
140
145
  ]
141
146
  }),
142
147
  /* @__PURE__ */ h("div", {
@@ -150,7 +155,7 @@ function w() {
150
155
  className: "pl-10"
151
156
  })]
152
157
  }), /* @__PURE__ */ h("div", {
153
- className: "flex items-center gap-2",
158
+ className: "flex flex-wrap items-center gap-2",
154
159
  children: [/* @__PURE__ */ m(l, { className: "h-4 w-4 text-text-secondary" }), [
155
160
  "all",
156
161
  "pending",
@@ -162,7 +167,7 @@ function w() {
162
167
  size: "sm",
163
168
  onClick: () => E(e),
164
169
  children: [e === "all" ? "All" : C[e].label, /* @__PURE__ */ h("span", {
165
- className: "ml-1 text-xs opacity-70",
170
+ className: "ml-1 text-xs opacity-70 tabular-nums",
166
171
  children: [
167
172
  "(",
168
173
  F[e] ?? 0,
@@ -173,7 +178,7 @@ function w() {
173
178
  })]
174
179
  }),
175
180
  /* @__PURE__ */ m("div", {
176
- className: "flex gap-2",
181
+ className: "flex flex-wrap gap-2",
177
182
  children: [
178
183
  {
179
184
  field: "date",
@@ -189,7 +194,8 @@ function w() {
189
194
  }
190
195
  ].map(({ field: e, label: t }) => /* @__PURE__ */ h("button", {
191
196
  onClick: () => R(e),
192
- className: `flex items-center gap-1 rounded border px-3 py-1 text-xs ${D === e ? "border-primary bg-action-primary-bg/5 text-primary" : "text-text-secondary hover:bg-bg-sunken/50"}`,
197
+ "aria-pressed": D === e,
198
+ className: `flex items-center gap-1 rounded border px-3 py-1 text-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${D === e ? "border-border-strong bg-accent-soft text-text-primary" : "border-border-seam text-text-secondary hover:bg-bg-sunken/50"}`,
193
199
  children: [/* @__PURE__ */ m(r, { className: "h-3 w-3" }), t]
194
200
  }, e))
195
201
  }),
@@ -197,13 +203,20 @@ function w() {
197
203
  className: "grid gap-6 lg:grid-cols-3",
198
204
  children: [/* @__PURE__ */ m("div", {
199
205
  className: `space-y-3 ${P ? "lg:col-span-2" : "lg:col-span-3"}`,
200
- children: N.length === 0 ? /* @__PURE__ */ m(v, { children: /* @__PURE__ */ m(y, {
201
- className: "py-12 text-center text-text-secondary",
202
- children: "No bookings match your filters."
203
- }) }) : N.map((e) => {
206
+ children: N.length === 0 ? /* @__PURE__ */ m(v, {
207
+ className: "border-border-seam",
208
+ children: /* @__PURE__ */ m(y, {
209
+ className: "py-4",
210
+ children: /* @__PURE__ */ m(x, {
211
+ illustration: "empty-search",
212
+ title: "No bookings found",
213
+ description: "No bookings match your current filters."
214
+ })
215
+ })
216
+ }) : N.map((e) => {
204
217
  let t = C[e.status], n = t.icon;
205
218
  return /* @__PURE__ */ m(v, {
206
- className: `cursor-pointer transition-colors hover:bg-bg-sunken/30 ${j === e.id ? "border-primary ring-1 ring-primary" : ""}`,
219
+ className: `cursor-pointer border-border-seam transition-shadow hover:shadow-pop ${j === e.id ? "border-border-strong ring-1 ring-border-focus" : ""}`,
207
220
  onClick: () => M(j === e.id ? null : e.id),
208
221
  children: /* @__PURE__ */ h(y, {
209
222
  className: "pt-4",
@@ -243,7 +256,7 @@ function w() {
243
256
  ]
244
257
  }),
245
258
  /* @__PURE__ */ h("span", {
246
- className: "flex items-center gap-1",
259
+ className: "flex items-center gap-1 tabular-nums",
247
260
  children: [
248
261
  /* @__PURE__ */ m(c, { className: "h-3 w-3" }),
249
262
  " $",
@@ -261,7 +274,7 @@ function w() {
261
274
  children: t.label
262
275
  }),
263
276
  e.status === "in_progress" && /* @__PURE__ */ h("span", {
264
- className: "text-sm font-medium",
277
+ className: "text-sm font-medium tabular-nums",
265
278
  children: [e.progress, "%"]
266
279
  }),
267
280
  /* @__PURE__ */ m(o, { className: "h-4 w-4 text-text-secondary" })
@@ -272,7 +285,7 @@ function w() {
272
285
  children: /* @__PURE__ */ m("div", {
273
286
  className: "h-2 w-full overflow-hidden rounded-full bg-bg-sunken",
274
287
  children: /* @__PURE__ */ m("div", {
275
- className: "h-2 rounded-full bg-blue-500 transition-all",
288
+ className: "h-2 rounded-full bg-action-primary-bg transition-all",
276
289
  style: { width: `${e.progress}%` }
277
290
  })
278
291
  })
@@ -282,138 +295,142 @@ function w() {
282
295
  })
283
296
  }), P && /* @__PURE__ */ m("div", {
284
297
  className: "space-y-4",
285
- children: /* @__PURE__ */ h(v, { children: [/* @__PURE__ */ m(b, { children: /* @__PURE__ */ h("div", {
286
- className: "flex items-center justify-between",
287
- children: [/* @__PURE__ */ m(x, {
288
- className: "text-base",
289
- children: "Booking Details"
290
- }), /* @__PURE__ */ m(_, {
291
- variant: "outline",
292
- size: "sm",
293
- onClick: () => M(null),
294
- children: "Close"
295
- })]
296
- }) }), /* @__PURE__ */ h(y, {
297
- className: "space-y-4",
298
- children: [
299
- /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h3", {
300
- className: "font-semibold",
301
- children: P.title
302
- }), /* @__PURE__ */ m("p", {
303
- className: "mt-1 text-sm text-text-secondary",
304
- children: P.description
305
- })] }),
306
- /* @__PURE__ */ m(g, {
307
- variant: C[P.status].badgeVariant,
308
- children: C[P.status].label
309
- }),
310
- P.status === "in_progress" && /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ h("div", {
311
- className: "flex items-center justify-between text-sm",
312
- children: [/* @__PURE__ */ m("span", {
313
- className: "text-text-secondary",
314
- children: "Progress"
315
- }), /* @__PURE__ */ h("span", {
316
- className: "font-medium",
317
- children: [P.progress, "%"]
318
- })]
319
- }), /* @__PURE__ */ m("div", {
320
- className: "mt-1 h-2 w-full overflow-hidden rounded-full bg-bg-sunken",
321
- children: /* @__PURE__ */ m("div", {
322
- className: "h-2 rounded-full bg-blue-500",
323
- style: { width: `${P.progress}%` }
324
- })
325
- })] }),
326
- /* @__PURE__ */ h("div", {
327
- className: "space-y-2 border-t pt-3 text-sm",
328
- children: [
329
- /* @__PURE__ */ h("div", {
330
- className: "flex justify-between",
331
- children: [/* @__PURE__ */ m("span", {
332
- className: "text-text-secondary",
333
- children: "Service"
334
- }), /* @__PURE__ */ m("span", {
335
- className: "font-medium",
336
- children: P.serviceName
337
- })]
338
- }),
339
- /* @__PURE__ */ h("div", {
340
- className: "flex justify-between",
341
- children: [/* @__PURE__ */ m("span", {
342
- className: "text-text-secondary",
343
- children: "Provider"
344
- }), /* @__PURE__ */ m("span", {
345
- className: "font-medium",
346
- children: P.providerName
347
- })]
348
- }),
349
- /* @__PURE__ */ h("div", {
350
- className: "flex justify-between",
351
- children: [/* @__PURE__ */ m("span", {
352
- className: "text-text-secondary",
353
- children: "Budget"
354
- }), /* @__PURE__ */ h("span", {
355
- className: "font-medium",
356
- children: ["$", P.budget.toLocaleString()]
357
- })]
358
- }),
359
- /* @__PURE__ */ h("div", {
360
- className: "flex justify-between",
361
- children: [/* @__PURE__ */ m("span", {
362
- className: "text-text-secondary",
363
- children: "Start Date"
364
- }), /* @__PURE__ */ m("span", {
365
- className: "font-medium",
366
- children: P.startDate
367
- })]
368
- }),
369
- /* @__PURE__ */ h("div", {
370
- className: "flex justify-between",
371
- children: [/* @__PURE__ */ m("span", {
372
- className: "text-text-secondary",
373
- children: "End Date"
374
- }), /* @__PURE__ */ m("span", {
375
- className: "font-medium",
376
- children: P.endDate
377
- })]
378
- }),
379
- /* @__PURE__ */ h("div", {
380
- className: "flex justify-between",
381
- children: [/* @__PURE__ */ m("span", {
382
- className: "text-text-secondary",
383
- children: "Payment"
384
- }), /* @__PURE__ */ m(g, {
385
- variant: "secondary",
386
- children: P.paymentStatus
387
- })]
388
- }),
389
- /* @__PURE__ */ h("div", {
390
- className: "flex justify-between",
391
- children: [/* @__PURE__ */ m("span", {
392
- className: "text-text-secondary",
393
- children: "Method"
394
- }), /* @__PURE__ */ m("span", {
395
- className: "font-medium",
396
- children: P.paymentMethod.replace("_", " ")
397
- })]
298
+ children: /* @__PURE__ */ h(b, {
299
+ treatment: "glass",
300
+ className: "border-border-seam lg:sticky lg:top-6",
301
+ children: [/* @__PURE__ */ h("div", {
302
+ className: "flex items-center justify-between",
303
+ children: [/* @__PURE__ */ m("h2", {
304
+ className: "text-base font-semibold tracking-tight",
305
+ children: "Booking Details"
306
+ }), /* @__PURE__ */ m(_, {
307
+ variant: "outline",
308
+ size: "sm",
309
+ onClick: () => M(null),
310
+ children: "Close"
311
+ })]
312
+ }), /* @__PURE__ */ h("div", {
313
+ className: "mt-4 space-y-4",
314
+ children: [
315
+ /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ m("h3", {
316
+ className: "font-semibold",
317
+ children: P.title
318
+ }), /* @__PURE__ */ m("p", {
319
+ className: "mt-1 text-sm text-text-secondary",
320
+ children: P.description
321
+ })] }),
322
+ /* @__PURE__ */ m(g, {
323
+ variant: C[P.status].badgeVariant,
324
+ children: C[P.status].label
325
+ }),
326
+ P.status === "in_progress" && /* @__PURE__ */ h("div", { children: [/* @__PURE__ */ h("div", {
327
+ className: "flex items-center justify-between text-sm",
328
+ children: [/* @__PURE__ */ m("span", {
329
+ className: "text-text-secondary",
330
+ children: "Progress"
331
+ }), /* @__PURE__ */ h("span", {
332
+ className: "font-medium tabular-nums",
333
+ children: [P.progress, "%"]
334
+ })]
335
+ }), /* @__PURE__ */ m("div", {
336
+ className: "mt-1 h-2 w-full overflow-hidden rounded-full bg-bg-sunken",
337
+ children: /* @__PURE__ */ m("div", {
338
+ className: "h-2 rounded-full bg-action-primary-bg",
339
+ style: { width: `${P.progress}%` }
398
340
  })
399
- ]
400
- }),
401
- /* @__PURE__ */ h("div", {
402
- className: "flex gap-2 border-t pt-3",
403
- children: [/* @__PURE__ */ m(_, {
404
- className: "flex-1",
405
- size: "sm",
406
- variant: "outline",
407
- children: "Message Provider"
408
- }), P.status === "pending" && /* @__PURE__ */ m(_, {
409
- className: "flex-1",
410
- size: "sm",
411
- variant: "destructive",
412
- children: "Cancel"
413
- })]
414
- })
415
- ]
416
- })] })
341
+ })] }),
342
+ /* @__PURE__ */ h("div", {
343
+ className: "space-y-2 border-t border-border-seam pt-3 text-sm",
344
+ children: [
345
+ /* @__PURE__ */ h("div", {
346
+ className: "flex justify-between",
347
+ children: [/* @__PURE__ */ m("span", {
348
+ className: "text-text-secondary",
349
+ children: "Service"
350
+ }), /* @__PURE__ */ m("span", {
351
+ className: "font-medium",
352
+ children: P.serviceName
353
+ })]
354
+ }),
355
+ /* @__PURE__ */ h("div", {
356
+ className: "flex justify-between",
357
+ children: [/* @__PURE__ */ m("span", {
358
+ className: "text-text-secondary",
359
+ children: "Provider"
360
+ }), /* @__PURE__ */ m("span", {
361
+ className: "font-medium",
362
+ children: P.providerName
363
+ })]
364
+ }),
365
+ /* @__PURE__ */ h("div", {
366
+ className: "flex justify-between",
367
+ children: [/* @__PURE__ */ m("span", {
368
+ className: "text-text-secondary",
369
+ children: "Budget"
370
+ }), /* @__PURE__ */ h("span", {
371
+ className: "font-medium tabular-nums",
372
+ children: ["$", P.budget.toLocaleString()]
373
+ })]
374
+ }),
375
+ /* @__PURE__ */ h("div", {
376
+ className: "flex justify-between",
377
+ children: [/* @__PURE__ */ m("span", {
378
+ className: "text-text-secondary",
379
+ children: "Start Date"
380
+ }), /* @__PURE__ */ m("span", {
381
+ className: "font-medium",
382
+ children: P.startDate
383
+ })]
384
+ }),
385
+ /* @__PURE__ */ h("div", {
386
+ className: "flex justify-between",
387
+ children: [/* @__PURE__ */ m("span", {
388
+ className: "text-text-secondary",
389
+ children: "End Date"
390
+ }), /* @__PURE__ */ m("span", {
391
+ className: "font-medium",
392
+ children: P.endDate
393
+ })]
394
+ }),
395
+ /* @__PURE__ */ h("div", {
396
+ className: "flex justify-between",
397
+ children: [/* @__PURE__ */ m("span", {
398
+ className: "text-text-secondary",
399
+ children: "Payment"
400
+ }), /* @__PURE__ */ m(g, {
401
+ variant: "secondary",
402
+ children: P.paymentStatus
403
+ })]
404
+ }),
405
+ /* @__PURE__ */ h("div", {
406
+ className: "flex justify-between",
407
+ children: [/* @__PURE__ */ m("span", {
408
+ className: "text-text-secondary",
409
+ children: "Method"
410
+ }), /* @__PURE__ */ m("span", {
411
+ className: "font-medium",
412
+ children: P.paymentMethod.replace("_", " ")
413
+ })]
414
+ })
415
+ ]
416
+ }),
417
+ /* @__PURE__ */ h("div", {
418
+ className: "flex gap-2 border-t border-border-seam pt-3",
419
+ children: [/* @__PURE__ */ m(_, {
420
+ className: "flex-1",
421
+ size: "sm",
422
+ variant: "outline",
423
+ children: "Message Provider"
424
+ }), P.status === "pending" && /* @__PURE__ */ m(_, {
425
+ className: "flex-1",
426
+ size: "sm",
427
+ variant: "destructive",
428
+ children: "Cancel"
429
+ })]
430
+ })
431
+ ]
432
+ })]
433
+ })
417
434
  })]
418
435
  })
419
436
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"BookingsPage.js","names":[],"sources":["../../../src/proserviceworld/pages/BookingsPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n Clock,\n CheckCircle2,\n XCircle,\n Loader2,\n Calendar,\n DollarSign,\n User,\n ChevronRight,\n Filter,\n ArrowUpDown,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport type { BookingStatus } from '../types';\n\nconst statusConfig: Record<\n BookingStatus,\n {\n label: string;\n color: string;\n icon: typeof Clock;\n badgeVariant: 'default' | 'secondary' | 'outline' | 'destructive';\n }\n> = {\n pending: { label: 'Pending', color: 'text-yellow-600', icon: Clock, badgeVariant: 'secondary' },\n in_progress: {\n label: 'In Progress',\n color: 'text-blue-600',\n icon: Loader2,\n badgeVariant: 'default',\n },\n completed: {\n label: 'Completed',\n color: 'text-green-600',\n icon: CheckCircle2,\n badgeVariant: 'outline',\n },\n cancelled: {\n label: 'Cancelled',\n color: 'text-red-600',\n icon: XCircle,\n badgeVariant: 'destructive',\n },\n};\n\ntype SortField = 'date' | 'budget' | 'progress';\n\nexport function BookingsPage() {\n const { bookings } = useProServiceWorldStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [statusFilter, setStatusFilter] = useState<BookingStatus | 'all'>('all');\n const [sortField, setSortField] = useState<SortField>('date');\n const [sortAsc, setSortAsc] = useState(false);\n const [selectedBookingId, setSelectedBookingId] = useState<string | null>(null);\n\n const filtered = useMemo(() => {\n let result = bookings;\n\n if (statusFilter !== 'all') {\n result = result.filter((b) => b.status === statusFilter);\n }\n\n if (searchQuery.trim()) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (b) =>\n b.title.toLowerCase().includes(q) ||\n b.providerName.toLowerCase().includes(q) ||\n b.serviceName.toLowerCase().includes(q)\n );\n }\n\n result = [...result].sort((a, b) => {\n const cmp =\n sortField === 'date'\n ? new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n : sortField === 'budget'\n ? b.budget - a.budget\n : b.progress - a.progress;\n return sortAsc ? -cmp : cmp;\n });\n\n return result;\n }, [bookings, searchQuery, statusFilter, sortField, sortAsc]);\n\n const selectedBooking = selectedBookingId\n ? bookings.find((b) => b.id === selectedBookingId)\n : null;\n\n const statusCounts = useMemo(() => {\n const counts: Record<string, number> = { all: bookings.length };\n for (const b of bookings) {\n counts[b.status] = (counts[b.status] ?? 0) + 1;\n }\n return counts;\n }, [bookings]);\n\n const totalBudget = bookings.reduce((sum, b) => sum + b.budget, 0);\n const avgProgress = Math.round(\n bookings.filter((b) => b.status === 'in_progress').reduce((sum, b) => sum + b.progress, 0) /\n Math.max(1, bookings.filter((b) => b.status === 'in_progress').length)\n );\n\n const handleSort = (field: SortField) => {\n if (sortField === field) setSortAsc(!sortAsc);\n else {\n setSortField(field);\n setSortAsc(false);\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">Bookings</h1>\n <p className=\"text-sm text-text-secondary\">\n Manage and track all your service bookings.\n </p>\n </div>\n <Button size=\"sm\">\n <Calendar className=\"mr-2 h-4 w-4\" /> New Booking\n </Button>\n </div>\n\n {/* Stats */}\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-blue-100 p-2 dark:bg-blue-950\">\n <Calendar className=\"h-5 w-5 text-blue-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{bookings.length}</p>\n <p className=\"text-xs text-text-secondary\">Total Bookings</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-green-100 p-2 dark:bg-green-950\">\n <CheckCircle2 className=\"h-5 w-5 text-green-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{statusCounts.completed ?? 0}</p>\n <p className=\"text-xs text-text-secondary\">Completed</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-yellow-100 p-2 dark:bg-yellow-950\">\n <Loader2 className=\"h-5 w-5 text-yellow-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">{avgProgress}%</p>\n <p className=\"text-xs text-text-secondary\">Avg. In-Progress</p>\n </div>\n </div>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-purple-100 p-2 dark:bg-purple-950\">\n <DollarSign className=\"h-5 w-5 text-purple-600\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold\">${totalBudget.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">Total Budget</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search bookings by title, provider, or service...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10\"\n />\n </div>\n <div className=\"flex items-center gap-2\">\n <Filter className=\"h-4 w-4 text-text-secondary\" />\n {(['all', 'pending', 'in_progress', 'completed', 'cancelled'] as const).map((status) => (\n <Button\n key={status}\n variant={statusFilter === status ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setStatusFilter(status)}\n >\n {status === 'all' ? 'All' : statusConfig[status].label}\n <span className=\"ml-1 text-xs opacity-70\">({statusCounts[status] ?? 0})</span>\n </Button>\n ))}\n </div>\n </div>\n\n {/* Sort controls */}\n <div className=\"flex gap-2\">\n {[\n { field: 'date' as SortField, label: 'Date' },\n { field: 'budget' as SortField, label: 'Budget' },\n { field: 'progress' as SortField, label: 'Progress' },\n ].map(({ field, label }) => (\n <button\n key={field}\n onClick={() => handleSort(field)}\n className={`flex items-center gap-1 rounded border px-3 py-1 text-xs ${\n sortField === field\n ? 'border-primary bg-action-primary-bg/5 text-primary'\n : 'text-text-secondary hover:bg-bg-sunken/50'\n }`}\n >\n <ArrowUpDown className=\"h-3 w-3\" />\n {label}\n </button>\n ))}\n </div>\n\n <div className=\"grid gap-6 lg:grid-cols-3\">\n {/* Booking list */}\n <div className={`space-y-3 ${selectedBooking ? 'lg:col-span-2' : 'lg:col-span-3'}`}>\n {filtered.length === 0 ? (\n <Card>\n <CardContent className=\"py-12 text-center text-text-secondary\">\n No bookings match your filters.\n </CardContent>\n </Card>\n ) : (\n filtered.map((booking) => {\n const config = statusConfig[booking.status];\n const StatusIcon = config.icon;\n return (\n <Card\n key={booking.id}\n className={`cursor-pointer transition-colors hover:bg-bg-sunken/30 ${\n selectedBookingId === booking.id ? 'border-primary ring-1 ring-primary' : ''\n }`}\n onClick={() =>\n setSelectedBookingId(selectedBookingId === booking.id ? null : booking.id)\n }\n >\n <CardContent className=\"pt-4\">\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex items-center gap-2\">\n <StatusIcon className={`h-4 w-4 ${config.color}`} />\n <h3 className=\"font-medium\">{booking.title}</h3>\n </div>\n <p className=\"text-sm text-text-secondary line-clamp-1\">\n {booking.description}\n </p>\n <div className=\"flex flex-wrap items-center gap-4 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <User className=\"h-3 w-3\" /> {booking.providerName}\n </span>\n <span className=\"flex items-center gap-1\">\n <Calendar className=\"h-3 w-3\" /> {booking.startDate}\n </span>\n <span className=\"flex items-center gap-1\">\n <DollarSign className=\"h-3 w-3\" /> ${booking.budget.toLocaleString()}\n </span>\n </div>\n </div>\n <div className=\"flex flex-col items-end gap-2\">\n <Badge variant={config.badgeVariant}>{config.label}</Badge>\n {booking.status === 'in_progress' && (\n <span className=\"text-sm font-medium\">{booking.progress}%</span>\n )}\n <ChevronRight className=\"h-4 w-4 text-text-secondary\" />\n </div>\n </div>\n\n {/* Progress bar for in-progress bookings */}\n {booking.status === 'in_progress' && (\n <div className=\"mt-3\">\n <div className=\"h-2 w-full overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-2 rounded-full bg-blue-500 transition-all\"\n style={{ width: `${booking.progress}%` }}\n />\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n );\n })\n )}\n </div>\n\n {/* Detail panel */}\n {selectedBooking && (\n <div className=\"space-y-4\">\n <Card>\n <CardHeader>\n <div className=\"flex items-center justify-between\">\n <CardTitle className=\"text-base\">Booking Details</CardTitle>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setSelectedBookingId(null)}>\n Close\n </Button>\n </div>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <h3 className=\"font-semibold\">{selectedBooking.title}</h3>\n <p className=\"mt-1 text-sm text-text-secondary\">\n {selectedBooking.description}\n </p>\n </div>\n\n <Badge variant={statusConfig[selectedBooking.status].badgeVariant}>\n {statusConfig[selectedBooking.status].label}\n </Badge>\n\n {selectedBooking.status === 'in_progress' && (\n <div>\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-text-secondary\">Progress</span>\n <span className=\"font-medium\">{selectedBooking.progress}%</span>\n </div>\n <div className=\"mt-1 h-2 w-full overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-2 rounded-full bg-blue-500\"\n style={{ width: `${selectedBooking.progress}%` }}\n />\n </div>\n </div>\n )}\n\n <div className=\"space-y-2 border-t pt-3 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Service</span>\n <span className=\"font-medium\">{selectedBooking.serviceName}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Provider</span>\n <span className=\"font-medium\">{selectedBooking.providerName}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Budget</span>\n <span className=\"font-medium\">${selectedBooking.budget.toLocaleString()}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Start Date</span>\n <span className=\"font-medium\">{selectedBooking.startDate}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">End Date</span>\n <span className=\"font-medium\">{selectedBooking.endDate}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Payment</span>\n <Badge variant=\"secondary\">{selectedBooking.paymentStatus}</Badge>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Method</span>\n <span className=\"font-medium\">\n {selectedBooking.paymentMethod.replace('_', ' ')}\n </span>\n </div>\n </div>\n\n <div className=\"flex gap-2 border-t pt-3\">\n <Button className=\"flex-1\" size=\"sm\" variant=\"outline\">\n Message Provider\n </Button>\n {selectedBooking.status === 'pending' && (\n <Button className=\"flex-1\" size=\"sm\" variant=\"destructive\">\n Cancel\n </Button>\n )}\n </div>\n </CardContent>\n </Card>\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"BookingsPage.js","names":[],"sources":["../../../src/proserviceworld/pages/BookingsPage.tsx"],"sourcesContent":["import { useState, useMemo } from 'react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Input,\n GlassCard,\n IllustratedEmptyState,\n} from '@burdenoff/fe-libs/ui';\nimport {\n Search,\n Clock,\n CheckCircle2,\n XCircle,\n Loader2,\n Calendar,\n DollarSign,\n User,\n ChevronRight,\n Filter,\n ArrowUpDown,\n} from 'lucide-react';\nimport { useProServiceWorldStore } from '../store/proserviceworldStore';\nimport type { BookingStatus } from '../types';\n\nconst statusConfig: Record<\n BookingStatus,\n {\n label: string;\n color: string;\n icon: typeof Clock;\n badgeVariant: 'default' | 'secondary' | 'outline' | 'destructive';\n }\n> = {\n pending: {\n label: 'Pending',\n color: 'text-status-warning-text',\n icon: Clock,\n badgeVariant: 'secondary',\n },\n in_progress: {\n label: 'In Progress',\n color: 'text-accent-blue',\n icon: Loader2,\n badgeVariant: 'default',\n },\n completed: {\n label: 'Completed',\n color: 'text-status-success-text',\n icon: CheckCircle2,\n badgeVariant: 'outline',\n },\n cancelled: {\n label: 'Cancelled',\n color: 'text-status-error-text',\n icon: XCircle,\n badgeVariant: 'destructive',\n },\n};\n\ntype SortField = 'date' | 'budget' | 'progress';\n\nexport function BookingsPage() {\n const { bookings } = useProServiceWorldStore();\n const [searchQuery, setSearchQuery] = useState('');\n const [statusFilter, setStatusFilter] = useState<BookingStatus | 'all'>('all');\n const [sortField, setSortField] = useState<SortField>('date');\n const [sortAsc, setSortAsc] = useState(false);\n const [selectedBookingId, setSelectedBookingId] = useState<string | null>(null);\n\n const filtered = useMemo(() => {\n let result = bookings;\n\n if (statusFilter !== 'all') {\n result = result.filter((b) => b.status === statusFilter);\n }\n\n if (searchQuery.trim()) {\n const q = searchQuery.toLowerCase();\n result = result.filter(\n (b) =>\n b.title.toLowerCase().includes(q) ||\n b.providerName.toLowerCase().includes(q) ||\n b.serviceName.toLowerCase().includes(q)\n );\n }\n\n result = [...result].sort((a, b) => {\n const cmp =\n sortField === 'date'\n ? new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()\n : sortField === 'budget'\n ? b.budget - a.budget\n : b.progress - a.progress;\n return sortAsc ? -cmp : cmp;\n });\n\n return result;\n }, [bookings, searchQuery, statusFilter, sortField, sortAsc]);\n\n const selectedBooking = selectedBookingId\n ? bookings.find((b) => b.id === selectedBookingId)\n : null;\n\n const statusCounts = useMemo(() => {\n const counts: Record<string, number> = { all: bookings.length };\n for (const b of bookings) {\n counts[b.status] = (counts[b.status] ?? 0) + 1;\n }\n return counts;\n }, [bookings]);\n\n const totalBudget = bookings.reduce((sum, b) => sum + b.budget, 0);\n const avgProgress = Math.round(\n bookings.filter((b) => b.status === 'in_progress').reduce((sum, b) => sum + b.progress, 0) /\n Math.max(1, bookings.filter((b) => b.status === 'in_progress').length)\n );\n\n const handleSort = (field: SortField) => {\n if (sortField === field) setSortAsc(!sortAsc);\n else {\n setSortField(field);\n setSortAsc(false);\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 bg-bg-canvas min-h-screen\">\n {/* Header */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold tracking-tight\">Bookings</h1>\n <p className=\"text-sm text-text-secondary\">Manage and track all your service bookings.</p>\n </div>\n <Button size=\"sm\">\n <Calendar className=\"mr-2 h-4 w-4\" /> New Booking\n </Button>\n </div>\n\n {/* Stats */}\n <div className=\"grid gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-info-bg-subtle p-2\">\n <Calendar className=\"h-5 w-5 text-accent-blue\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">{bookings.length}</p>\n <p className=\"text-xs text-text-secondary\">Total Bookings</p>\n </div>\n </div>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-success-bg-subtle p-2\">\n <CheckCircle2 className=\"h-5 w-5 text-status-success-text\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">{statusCounts.completed ?? 0}</p>\n <p className=\"text-xs text-text-secondary\">Completed</p>\n </div>\n </div>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"border-border-seam\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-status-warning-bg-subtle p-2\">\n <Loader2 className=\"h-5 w-5 text-status-warning-text\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">{avgProgress}%</p>\n <p className=\"text-xs text-text-secondary\">Avg. In-Progress</p>\n </div>\n </div>\n </GlassCard>\n <GlassCard treatment=\"glass\" glow className=\"border-border-seam\">\n <div className=\"flex items-center gap-3\">\n <div className=\"rounded-lg bg-accent-purple-subtle p-2\">\n <DollarSign className=\"h-5 w-5 text-accent-purple\" />\n </div>\n <div>\n <p className=\"text-2xl font-bold tabular-nums\">${totalBudget.toLocaleString()}</p>\n <p className=\"text-xs text-text-secondary\">Total Budget</p>\n </div>\n </div>\n </GlassCard>\n </div>\n\n {/* Filters */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center\">\n <div className=\"relative flex-1\">\n <Search className=\"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-text-secondary\" />\n <Input\n placeholder=\"Search bookings by title, provider, or service...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"pl-10\"\n />\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Filter className=\"h-4 w-4 text-text-secondary\" />\n {(['all', 'pending', 'in_progress', 'completed', 'cancelled'] as const).map((status) => (\n <Button\n key={status}\n variant={statusFilter === status ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setStatusFilter(status)}\n >\n {status === 'all' ? 'All' : statusConfig[status].label}\n <span className=\"ml-1 text-xs opacity-70 tabular-nums\">\n ({statusCounts[status] ?? 0})\n </span>\n </Button>\n ))}\n </div>\n </div>\n\n {/* Sort controls */}\n <div className=\"flex flex-wrap gap-2\">\n {[\n { field: 'date' as SortField, label: 'Date' },\n { field: 'budget' as SortField, label: 'Budget' },\n { field: 'progress' as SortField, label: 'Progress' },\n ].map(({ field, label }) => (\n <button\n key={field}\n onClick={() => handleSort(field)}\n aria-pressed={sortField === field}\n className={`flex items-center gap-1 rounded border px-3 py-1 text-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus ${\n sortField === field\n ? 'border-border-strong bg-accent-soft text-text-primary'\n : 'border-border-seam text-text-secondary hover:bg-bg-sunken/50'\n }`}\n >\n <ArrowUpDown className=\"h-3 w-3\" />\n {label}\n </button>\n ))}\n </div>\n\n <div className=\"grid gap-6 lg:grid-cols-3\">\n {/* Booking list */}\n <div className={`space-y-3 ${selectedBooking ? 'lg:col-span-2' : 'lg:col-span-3'}`}>\n {filtered.length === 0 ? (\n <Card className=\"border-border-seam\">\n <CardContent className=\"py-4\">\n <IllustratedEmptyState\n illustration=\"empty-search\"\n title=\"No bookings found\"\n description=\"No bookings match your current filters.\"\n />\n </CardContent>\n </Card>\n ) : (\n filtered.map((booking) => {\n const config = statusConfig[booking.status];\n const StatusIcon = config.icon;\n return (\n <Card\n key={booking.id}\n className={`cursor-pointer border-border-seam transition-shadow hover:shadow-pop ${\n selectedBookingId === booking.id\n ? 'border-border-strong ring-1 ring-border-focus'\n : ''\n }`}\n onClick={() =>\n setSelectedBookingId(selectedBookingId === booking.id ? null : booking.id)\n }\n >\n <CardContent className=\"pt-4\">\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"flex-1 space-y-2\">\n <div className=\"flex items-center gap-2\">\n <StatusIcon className={`h-4 w-4 ${config.color}`} />\n <h3 className=\"font-medium\">{booking.title}</h3>\n </div>\n <p className=\"text-sm text-text-secondary line-clamp-1\">\n {booking.description}\n </p>\n <div className=\"flex flex-wrap items-center gap-4 text-xs text-text-secondary\">\n <span className=\"flex items-center gap-1\">\n <User className=\"h-3 w-3\" /> {booking.providerName}\n </span>\n <span className=\"flex items-center gap-1\">\n <Calendar className=\"h-3 w-3\" /> {booking.startDate}\n </span>\n <span className=\"flex items-center gap-1 tabular-nums\">\n <DollarSign className=\"h-3 w-3\" /> ${booking.budget.toLocaleString()}\n </span>\n </div>\n </div>\n <div className=\"flex flex-col items-end gap-2\">\n <Badge variant={config.badgeVariant}>{config.label}</Badge>\n {booking.status === 'in_progress' && (\n <span className=\"text-sm font-medium tabular-nums\">\n {booking.progress}%\n </span>\n )}\n <ChevronRight className=\"h-4 w-4 text-text-secondary\" />\n </div>\n </div>\n\n {/* Progress bar for in-progress bookings */}\n {booking.status === 'in_progress' && (\n <div className=\"mt-3\">\n <div className=\"h-2 w-full overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-2 rounded-full bg-action-primary-bg transition-all\"\n style={{ width: `${booking.progress}%` }}\n />\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n );\n })\n )}\n </div>\n\n {/* Detail rail */}\n {selectedBooking && (\n <div className=\"space-y-4\">\n <GlassCard treatment=\"glass\" className=\"border-border-seam lg:sticky lg:top-6\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-base font-semibold tracking-tight\">Booking Details</h2>\n <Button variant=\"outline\" size=\"sm\" onClick={() => setSelectedBookingId(null)}>\n Close\n </Button>\n </div>\n <div className=\"mt-4 space-y-4\">\n <div>\n <h3 className=\"font-semibold\">{selectedBooking.title}</h3>\n <p className=\"mt-1 text-sm text-text-secondary\">{selectedBooking.description}</p>\n </div>\n\n <Badge variant={statusConfig[selectedBooking.status].badgeVariant}>\n {statusConfig[selectedBooking.status].label}\n </Badge>\n\n {selectedBooking.status === 'in_progress' && (\n <div>\n <div className=\"flex items-center justify-between text-sm\">\n <span className=\"text-text-secondary\">Progress</span>\n <span className=\"font-medium tabular-nums\">{selectedBooking.progress}%</span>\n </div>\n <div className=\"mt-1 h-2 w-full overflow-hidden rounded-full bg-bg-sunken\">\n <div\n className=\"h-2 rounded-full bg-action-primary-bg\"\n style={{ width: `${selectedBooking.progress}%` }}\n />\n </div>\n </div>\n )}\n\n <div className=\"space-y-2 border-t border-border-seam pt-3 text-sm\">\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Service</span>\n <span className=\"font-medium\">{selectedBooking.serviceName}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Provider</span>\n <span className=\"font-medium\">{selectedBooking.providerName}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Budget</span>\n <span className=\"font-medium tabular-nums\">\n ${selectedBooking.budget.toLocaleString()}\n </span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Start Date</span>\n <span className=\"font-medium\">{selectedBooking.startDate}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">End Date</span>\n <span className=\"font-medium\">{selectedBooking.endDate}</span>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Payment</span>\n <Badge variant=\"secondary\">{selectedBooking.paymentStatus}</Badge>\n </div>\n <div className=\"flex justify-between\">\n <span className=\"text-text-secondary\">Method</span>\n <span className=\"font-medium\">\n {selectedBooking.paymentMethod.replace('_', ' ')}\n </span>\n </div>\n </div>\n\n <div className=\"flex gap-2 border-t border-border-seam pt-3\">\n <Button className=\"flex-1\" size=\"sm\" variant=\"outline\">\n Message Provider\n </Button>\n {selectedBooking.status === 'pending' && (\n <Button className=\"flex-1\" size=\"sm\" variant=\"destructive\">\n Cancel\n </Button>\n )}\n </div>\n </div>\n </GlassCard>\n </div>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}