@wealthx/shadcn 1.5.22 → 1.5.23

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.
@@ -64,12 +64,17 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
64
64
  function ClientSearch({
65
65
  clients,
66
66
  value,
67
- onValueChange
67
+ onValueChange,
68
+ onSearch,
69
+ isSearching,
70
+ hasMore,
71
+ onLoadMore,
72
+ isLoadingMore
68
73
  }) {
69
74
  const [query, setQuery] = React.useState("");
70
75
  const [open, setOpen] = React.useState(false);
71
76
  const selected = clients.find((c) => c.id === value);
72
- const filtered = clients.filter((c) => {
77
+ const filtered = onSearch ? clients : clients.filter((c) => {
73
78
  const q = query.toLowerCase();
74
79
  return c.name.toLowerCase().includes(q) || c.email.toLowerCase().includes(q);
75
80
  });
@@ -79,67 +84,79 @@ function ClientSearch({
79
84
  {
80
85
  value: selected ? selected.name : query,
81
86
  onChange: (e) => {
82
- setQuery(e.target.value);
87
+ const v = e.target.value;
88
+ setQuery(v);
83
89
  if (selected) onValueChange(void 0);
84
- setOpen(e.target.value.length > 0);
90
+ setOpen(v.length > 0);
91
+ onSearch == null ? void 0 : onSearch(v);
85
92
  },
86
93
  onBlur: () => setTimeout(() => setOpen(false), 150),
87
94
  placeholder: "Search by name or email\u2026",
88
95
  autoComplete: "off"
89
96
  }
90
97
  ),
91
- open && (filtered.length > 0 || query.length > 0) && /* @__PURE__ */ jsx("div", { className: "absolute z-50 mt-1 w-full border border-border bg-popover shadow-md", children: filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: "No clients found." }) : filtered.map((c) => /* @__PURE__ */ jsxs(
92
- Button,
93
- {
94
- type: "button",
95
- variant: "ghost",
96
- className: "h-auto w-full flex-col items-start gap-0.5 px-3 py-2 text-left hover:bg-primary/5",
97
- onMouseDown: (e) => e.preventDefault(),
98
- onClick: () => {
99
- onValueChange(c.id);
100
- setQuery("");
101
- setOpen(false);
98
+ open && (filtered.length > 0 || query.length > 0 || isSearching) && /* @__PURE__ */ jsx("div", { className: "absolute z-50 mt-1 max-h-64 w-full overflow-y-auto border border-border bg-popover shadow-md", children: isSearching ? /* @__PURE__ */ jsx("p", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: "Searching..." }) : filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-6 text-center text-sm text-muted-foreground", children: "No clients found." }) : /* @__PURE__ */ jsxs(Fragment, { children: [
99
+ filtered.map((c) => /* @__PURE__ */ jsxs(
100
+ Button,
101
+ {
102
+ type: "button",
103
+ variant: "ghost",
104
+ className: "h-auto w-full flex-col items-start gap-0.5 px-3 py-2 text-left hover:bg-primary/5",
105
+ onMouseDown: (e) => e.preventDefault(),
106
+ onClick: () => {
107
+ onValueChange(c.id);
108
+ setQuery("");
109
+ setOpen(false);
110
+ },
111
+ children: [
112
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: c.name }),
113
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: c.email })
114
+ ]
102
115
  },
103
- children: [
104
- /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: c.name }),
105
- /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: c.email })
106
- ]
107
- },
108
- c.id
109
- )) })
116
+ c.id
117
+ )),
118
+ hasMore && onLoadMore && /* @__PURE__ */ jsx(
119
+ Button,
120
+ {
121
+ type: "button",
122
+ variant: "ghost",
123
+ size: "sm",
124
+ className: "w-full text-sm text-primary",
125
+ disabled: isLoadingMore,
126
+ onMouseDown: (e) => e.preventDefault(),
127
+ onClick: onLoadMore,
128
+ children: isLoadingMore ? "Loading..." : "Load more"
129
+ }
130
+ )
131
+ ] }) })
110
132
  ] });
111
133
  }
112
- var FORMAT_OPTIONS = [
113
- { value: "call", label: "Call", icon: /* @__PURE__ */ jsx(Phone, { className: "h-4 w-4" }) },
114
- {
134
+ function getFormatOptions(platform) {
135
+ const call = {
136
+ value: "call",
137
+ label: "Call",
138
+ icon: /* @__PURE__ */ jsx(Phone, { className: "h-4 w-4" })
139
+ };
140
+ const googleMeet = {
115
141
  value: "google-meet",
116
142
  label: "Google Meet",
117
143
  icon: /* @__PURE__ */ jsx(Video, { className: "h-4 w-4" })
118
- },
119
- {
144
+ };
145
+ const msTeams = {
120
146
  value: "microsoft-teams",
121
147
  label: "MS Teams",
122
148
  icon: /* @__PURE__ */ jsx(Users, { className: "h-4 w-4" })
123
- },
124
- {
125
- value: "offline",
126
- label: "Offline",
127
- icon: /* @__PURE__ */ jsx(MapPin, { className: "h-4 w-4" })
128
- }
129
- ];
130
- var CLIENT_FORMAT_OPTIONS = [
131
- { value: "call", label: "Call", icon: /* @__PURE__ */ jsx(Phone, { className: "h-4 w-4" }) },
132
- {
133
- value: "online",
134
- label: "Online Meeting",
135
- icon: /* @__PURE__ */ jsx(Video, { className: "h-4 w-4" })
136
- },
137
- {
149
+ };
150
+ const offline = {
138
151
  value: "offline",
139
152
  label: "Offline Meeting",
140
153
  icon: /* @__PURE__ */ jsx(MapPin, { className: "h-4 w-4" })
141
- }
142
- ];
154
+ };
155
+ if (platform === "google-meet") return [call, googleMeet, offline];
156
+ if (platform === "microsoft-teams") return [call, msTeams, offline];
157
+ if (platform === "any") return [call, googleMeet, msTeams, offline];
158
+ return [call, offline];
159
+ }
143
160
  function MeetingFormatSection({
144
161
  format,
145
162
  onFormatChange,
@@ -269,6 +286,11 @@ function AppointmentBookDialog({
269
286
  open,
270
287
  onOpenChange,
271
288
  clients = [],
289
+ onSearchClients,
290
+ isSearchingClients,
291
+ hasMoreClients,
292
+ onLoadMoreClients,
293
+ isLoadingMoreClients,
272
294
  meetingTypes = [],
273
295
  amSlots,
274
296
  pmSlots,
@@ -279,11 +301,12 @@ function AppointmentBookDialog({
279
301
  advisorInfo,
280
302
  initialClientId,
281
303
  defaultMeetingFormat,
304
+ onlinePlatform,
282
305
  guestInfo,
283
306
  onBook
284
307
  }) {
285
308
  var _a, _b, _c;
286
- const isClientMode = clients.length === 0;
309
+ const isClientMode = clients.length === 0 && !onSearchClients;
287
310
  const showGuestForm = isClientMode && !((guestInfo == null ? void 0 : guestInfo.name) && (guestInfo == null ? void 0 : guestInfo.email));
288
311
  const disabledDayOfWeek = React.useMemo(
289
312
  () => schedule == null ? void 0 : schedule.filter((d) => !d.enabled).map((d) => DAY_MAP[d.day]).filter((n) => n !== void 0),
@@ -375,7 +398,12 @@ function AppointmentBookDialog({
375
398
  {
376
399
  clients,
377
400
  value: clientId,
378
- onValueChange: setClientId
401
+ onValueChange: setClientId,
402
+ onSearch: onSearchClients,
403
+ isSearching: isSearchingClients,
404
+ hasMore: hasMoreClients,
405
+ onLoadMore: onLoadMoreClients,
406
+ isLoadingMore: isLoadingMoreClients
379
407
  }
380
408
  )
381
409
  ] }),
@@ -433,7 +461,7 @@ function AppointmentBookDialog({
433
461
  )
434
462
  ] })
435
463
  ] }),
436
- !(isClientMode && defaultMeetingFormat) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
464
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
437
465
  /* @__PURE__ */ jsx(Label, { children: "Meeting format" }),
438
466
  /* @__PURE__ */ jsx(
439
467
  MeetingFormatSection,
@@ -447,7 +475,7 @@ function AppointmentBookDialog({
447
475
  advisorOfficeAddress,
448
476
  clientHomeAddress,
449
477
  isClientMode,
450
- formatOptions: isClientMode ? CLIENT_FORMAT_OPTIONS : FORMAT_OPTIONS
478
+ formatOptions: getFormatOptions(onlinePlatform)
451
479
  }
452
480
  )
453
481
  ] }),
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  AppointmentConfirmDialog,
3
3
  AppointmentRescheduleDialog
4
- } from "./chunk-SET6GFGL.mjs";
4
+ } from "./chunk-ZSMQZ3VN.mjs";
5
5
  import {
6
6
  Sheet,
7
7
  SheetContent
@@ -86,6 +86,9 @@ function AppointmentDetailSheet({
86
86
  clientProfile,
87
87
  amSlots,
88
88
  pmSlots,
89
+ onDateChange,
90
+ schedule,
91
+ isLoadingSlots,
89
92
  onAccept,
90
93
  onDecline,
91
94
  onReschedule,
@@ -286,6 +289,9 @@ function AppointmentDetailSheet({
286
289
  currentDate: appointment.date,
287
290
  currentTimeStart: appointment.timeStart,
288
291
  currentTimeEnd: appointment.timeEnd,
292
+ onDateChange,
293
+ schedule,
294
+ isLoadingSlots,
289
295
  onReschedule: (date, slot, note) => {
290
296
  onReschedule == null ? void 0 : onReschedule(appointment.id, date, slot, note);
291
297
  setRescheduleOpen(false);
@@ -98,6 +98,15 @@ function AppointmentConfirmDialog({
98
98
  ] })
99
99
  ] }) });
100
100
  }
101
+ var DAY_MAP = {
102
+ Sun: 0,
103
+ Mon: 1,
104
+ Tue: 2,
105
+ Wed: 3,
106
+ Thu: 4,
107
+ Fri: 5,
108
+ Sat: 6
109
+ };
101
110
  function AppointmentRescheduleDialog({
102
111
  open,
103
112
  onOpenChange,
@@ -106,11 +115,19 @@ function AppointmentRescheduleDialog({
106
115
  currentDate,
107
116
  currentTimeStart,
108
117
  currentTimeEnd,
118
+ onDateChange,
119
+ schedule,
120
+ isLoadingSlots,
109
121
  onReschedule
110
122
  }) {
111
123
  const [date, setDate] = React.useState(/* @__PURE__ */ new Date());
112
124
  const [slot, setSlot] = React.useState();
113
125
  const [note, setNote] = React.useState("");
126
+ const today = React.useMemo(() => /* @__PURE__ */ new Date(), []);
127
+ const disabledDayOfWeek = React.useMemo(
128
+ () => schedule == null ? void 0 : schedule.filter((d) => !d.enabled).map((d) => DAY_MAP[d.day]).filter((n) => n !== void 0),
129
+ [schedule]
130
+ );
114
131
  const handleOpenChange = (next) => {
115
132
  if (!next) {
116
133
  setDate(/* @__PURE__ */ new Date());
@@ -128,87 +145,93 @@ function AppointmentRescheduleDialog({
128
145
  /* @__PURE__ */ jsx(DialogDescription, { children: "Select a new date and time slot. The client will be notified by email." })
129
146
  ] }),
130
147
  /* @__PURE__ */ jsx(Separator, {}),
131
- (currentDate || currentTimeStart) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
132
- /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Current booking" }),
133
- /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 border border-border bg-muted/30 px-3 py-2.5 text-sm text-muted-foreground", children: [
134
- currentDate && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
135
- /* @__PURE__ */ jsx(CalendarIcon, { className: "h-3.5 w-3.5 shrink-0" }),
136
- currentDate
137
- ] }),
138
- currentTimeStart && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
139
- /* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5 shrink-0" }),
140
- currentTimeStart,
141
- currentTimeEnd ? ` \u2013 ${currentTimeEnd}` : ""
148
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 overflow-y-auto max-h-[calc(90vh-200px)]", children: [
149
+ (currentDate || currentTimeStart) && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
150
+ /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Current booking" }),
151
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 border border-border bg-muted/30 px-3 py-2.5 text-sm text-muted-foreground", children: [
152
+ currentDate && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
153
+ /* @__PURE__ */ jsx(CalendarIcon, { className: "h-3.5 w-3.5 shrink-0" }),
154
+ currentDate
155
+ ] }),
156
+ currentTimeStart && /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1.5", children: [
157
+ /* @__PURE__ */ jsx(Clock, { className: "h-3.5 w-3.5 shrink-0" }),
158
+ currentTimeStart,
159
+ currentTimeEnd ? ` \u2013 ${currentTimeEnd}` : ""
160
+ ] })
142
161
  ] })
143
- ] })
144
- ] }),
145
- /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[auto_1fr] items-start gap-5", children: [
146
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
147
- /* @__PURE__ */ jsx(Label, { children: "New date" }),
148
- /* @__PURE__ */ jsx(
149
- Calendar,
150
- {
151
- mode: "single",
152
- selected: date,
153
- onSelect: (d) => {
154
- setDate(d);
155
- setSlot(void 0);
156
- },
157
- captionLayout: "label",
158
- fromDate: /* @__PURE__ */ new Date(),
159
- disabled: { before: /* @__PURE__ */ new Date() },
160
- className: "border border-border"
161
- }
162
- )
163
162
  ] }),
164
- /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-5", children: date ? /* @__PURE__ */ jsxs(Fragment, { children: [
165
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
163
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[auto_1fr] items-start gap-5", children: [
164
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
165
+ /* @__PURE__ */ jsx(Label, { children: "New date" }),
166
+ /* @__PURE__ */ jsx(
167
+ Calendar,
168
+ {
169
+ mode: "single",
170
+ selected: date,
171
+ onSelect: (d) => {
172
+ setDate(d);
173
+ setSlot(void 0);
174
+ if (d) onDateChange == null ? void 0 : onDateChange(d);
175
+ },
176
+ captionLayout: "label",
177
+ fromDate: today,
178
+ disabled: disabledDayOfWeek && disabledDayOfWeek.length > 0 ? [{ before: today }, { dayOfWeek: disabledDayOfWeek }] : { before: today },
179
+ className: "border border-border"
180
+ }
181
+ )
182
+ ] }),
183
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-5", children: date ? isLoadingSlots ? /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-2 py-8 text-center", children: [
184
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Loading slots\u2026" }),
185
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Fetching available times for the selected date." })
186
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
187
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
188
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Select a time slot" }),
189
+ /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
190
+ totalAvailable,
191
+ " available"
192
+ ] })
193
+ ] }),
194
+ /* @__PURE__ */ jsx(
195
+ AppointmentSlotSection,
196
+ {
197
+ label: "Morning",
198
+ slots: amSlots,
199
+ selectedSlotId: slot == null ? void 0 : slot.id,
200
+ onSelect: setSlot
201
+ }
202
+ ),
203
+ /* @__PURE__ */ jsx(
204
+ AppointmentSlotSection,
205
+ {
206
+ label: "Afternoon",
207
+ slots: pmSlots,
208
+ selectedSlotId: slot == null ? void 0 : slot.id,
209
+ onSelect: setSlot
210
+ }
211
+ )
212
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-2 py-8 text-center", children: [
166
213
  /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Select a time slot" }),
167
- /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground", children: [
168
- totalAvailable,
169
- " available"
170
- ] })
214
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Pick a date on the left to see available slots." })
215
+ ] }) })
216
+ ] }),
217
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
218
+ /* @__PURE__ */ jsxs(Label, { htmlFor: "reschedule-note", children: [
219
+ "Note",
220
+ " ",
221
+ /* @__PURE__ */ jsx("span", { className: "font-normal text-muted-foreground", children: "(optional)" })
171
222
  ] }),
172
223
  /* @__PURE__ */ jsx(
173
- AppointmentSlotSection,
224
+ Textarea,
174
225
  {
175
- label: "Morning",
176
- slots: amSlots,
177
- selectedSlotId: slot == null ? void 0 : slot.id,
178
- onSelect: setSlot
179
- }
180
- ),
181
- /* @__PURE__ */ jsx(
182
- AppointmentSlotSection,
183
- {
184
- label: "Afternoon",
185
- slots: pmSlots,
186
- selectedSlotId: slot == null ? void 0 : slot.id,
187
- onSelect: setSlot
226
+ id: "reschedule-note",
227
+ placeholder: "e.g. Rescheduling due to an internal conflict \u2014 apologies for the inconvenience\u2026",
228
+ value: note,
229
+ onChange: (e) => setNote(e.target.value),
230
+ className: "w-full resize-none",
231
+ rows: 2
188
232
  }
189
233
  )
190
- ] }) : /* @__PURE__ */ jsxs("div", { className: "flex h-full flex-col items-center justify-center gap-2 py-8 text-center", children: [
191
- /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold", children: "Select a time slot" }),
192
- /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Pick a date on the left to see available slots." })
193
- ] }) })
194
- ] }),
195
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
196
- /* @__PURE__ */ jsxs(Label, { htmlFor: "reschedule-note", children: [
197
- "Note",
198
- " ",
199
- /* @__PURE__ */ jsx("span", { className: "font-normal text-muted-foreground", children: "(optional)" })
200
- ] }),
201
- /* @__PURE__ */ jsx(
202
- Textarea,
203
- {
204
- id: "reschedule-note",
205
- placeholder: "e.g. Rescheduling due to an internal conflict \u2014 apologies for the inconvenience\u2026",
206
- value: note,
207
- onChange: (e) => setNote(e.target.value),
208
- className: "w-full resize-none",
209
- rows: 2
210
- }
211
- )
234
+ ] })
212
235
  ] }),
213
236
  /* @__PURE__ */ jsxs(DialogFooter, { children: [
214
237
  /* @__PURE__ */ jsx(DialogClose, { render: /* @__PURE__ */ jsx(Button, { variant: "outline" }), children: "Cancel" }),
@@ -1054,6 +1054,15 @@ function AppointmentConfirmDialog({
1054
1054
  ] })
1055
1055
  ] }) });
1056
1056
  }
1057
+ var DAY_MAP = {
1058
+ Sun: 0,
1059
+ Mon: 1,
1060
+ Tue: 2,
1061
+ Wed: 3,
1062
+ Thu: 4,
1063
+ Fri: 5,
1064
+ Sat: 6
1065
+ };
1057
1066
  function AppointmentRescheduleDialog({
1058
1067
  open,
1059
1068
  onOpenChange,
@@ -1062,11 +1071,19 @@ function AppointmentRescheduleDialog({
1062
1071
  currentDate,
1063
1072
  currentTimeStart,
1064
1073
  currentTimeEnd,
1074
+ onDateChange,
1075
+ schedule,
1076
+ isLoadingSlots,
1065
1077
  onReschedule
1066
1078
  }) {
1067
1079
  const [date, setDate] = import_react3.default.useState(/* @__PURE__ */ new Date());
1068
1080
  const [slot, setSlot] = import_react3.default.useState();
1069
1081
  const [note, setNote] = import_react3.default.useState("");
1082
+ const today = import_react3.default.useMemo(() => /* @__PURE__ */ new Date(), []);
1083
+ const disabledDayOfWeek = import_react3.default.useMemo(
1084
+ () => schedule == null ? void 0 : schedule.filter((d) => !d.enabled).map((d) => DAY_MAP[d.day]).filter((n) => n !== void 0),
1085
+ [schedule]
1086
+ );
1070
1087
  const handleOpenChange = (next) => {
1071
1088
  if (!next) {
1072
1089
  setDate(/* @__PURE__ */ new Date());
@@ -1084,87 +1101,93 @@ function AppointmentRescheduleDialog({
1084
1101
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DialogDescription, { children: "Select a new date and time slot. The client will be notified by email." })
1085
1102
  ] }),
1086
1103
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Separator, {}),
1087
- (currentDate || currentTimeStart) && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
1088
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Current booking" }),
1089
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-4 border border-border bg-muted/30 px-3 py-2.5 text-sm text-muted-foreground", children: [
1090
- currentDate && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "flex items-center gap-1.5", children: [
1091
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.Calendar, { className: "h-3.5 w-3.5 shrink-0" }),
1092
- currentDate
1093
- ] }),
1094
- currentTimeStart && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "flex items-center gap-1.5", children: [
1095
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.Clock, { className: "h-3.5 w-3.5 shrink-0" }),
1096
- currentTimeStart,
1097
- currentTimeEnd ? ` \u2013 ${currentTimeEnd}` : ""
1104
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-4 overflow-y-auto max-h-[calc(90vh-200px)]", children: [
1105
+ (currentDate || currentTimeStart) && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
1106
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Current booking" }),
1107
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-4 border border-border bg-muted/30 px-3 py-2.5 text-sm text-muted-foreground", children: [
1108
+ currentDate && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "flex items-center gap-1.5", children: [
1109
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.Calendar, { className: "h-3.5 w-3.5 shrink-0" }),
1110
+ currentDate
1111
+ ] }),
1112
+ currentTimeStart && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "flex items-center gap-1.5", children: [
1113
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react4.Clock, { className: "h-3.5 w-3.5 shrink-0" }),
1114
+ currentTimeStart,
1115
+ currentTimeEnd ? ` \u2013 ${currentTimeEnd}` : ""
1116
+ ] })
1098
1117
  ] })
1099
- ] })
1100
- ] }),
1101
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "grid grid-cols-[auto_1fr] items-start gap-5", children: [
1102
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
1103
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Label, { children: "New date" }),
1104
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1105
- Calendar,
1106
- {
1107
- mode: "single",
1108
- selected: date,
1109
- onSelect: (d) => {
1110
- setDate(d);
1111
- setSlot(void 0);
1112
- },
1113
- captionLayout: "label",
1114
- fromDate: /* @__PURE__ */ new Date(),
1115
- disabled: { before: /* @__PURE__ */ new Date() },
1116
- className: "border border-border"
1117
- }
1118
- )
1119
1118
  ] }),
1120
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex flex-col gap-5", children: date ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1121
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center justify-between", children: [
1119
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "grid grid-cols-[auto_1fr] items-start gap-5", children: [
1120
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
1121
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Label, { children: "New date" }),
1122
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1123
+ Calendar,
1124
+ {
1125
+ mode: "single",
1126
+ selected: date,
1127
+ onSelect: (d) => {
1128
+ setDate(d);
1129
+ setSlot(void 0);
1130
+ if (d) onDateChange == null ? void 0 : onDateChange(d);
1131
+ },
1132
+ captionLayout: "label",
1133
+ fromDate: today,
1134
+ disabled: disabledDayOfWeek && disabledDayOfWeek.length > 0 ? [{ before: today }, { dayOfWeek: disabledDayOfWeek }] : { before: today },
1135
+ className: "border border-border"
1136
+ }
1137
+ )
1138
+ ] }),
1139
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex flex-col gap-5", children: date ? isLoadingSlots ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex h-full flex-col items-center justify-center gap-2 py-8 text-center", children: [
1140
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm font-semibold", children: "Loading slots\u2026" }),
1141
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs text-muted-foreground", children: "Fetching available times for the selected date." })
1142
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
1143
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center justify-between", children: [
1144
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm font-semibold", children: "Select a time slot" }),
1145
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
1146
+ totalAvailable,
1147
+ " available"
1148
+ ] })
1149
+ ] }),
1150
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1151
+ AppointmentSlotSection,
1152
+ {
1153
+ label: "Morning",
1154
+ slots: amSlots,
1155
+ selectedSlotId: slot == null ? void 0 : slot.id,
1156
+ onSelect: setSlot
1157
+ }
1158
+ ),
1159
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1160
+ AppointmentSlotSection,
1161
+ {
1162
+ label: "Afternoon",
1163
+ slots: pmSlots,
1164
+ selectedSlotId: slot == null ? void 0 : slot.id,
1165
+ onSelect: setSlot
1166
+ }
1167
+ )
1168
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex h-full flex-col items-center justify-center gap-2 py-8 text-center", children: [
1122
1169
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm font-semibold", children: "Select a time slot" }),
1123
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
1124
- totalAvailable,
1125
- " available"
1126
- ] })
1170
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs text-muted-foreground", children: "Pick a date on the left to see available slots." })
1171
+ ] }) })
1172
+ ] }),
1173
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
1174
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Label, { htmlFor: "reschedule-note", children: [
1175
+ "Note",
1176
+ " ",
1177
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "font-normal text-muted-foreground", children: "(optional)" })
1127
1178
  ] }),
1128
1179
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1129
- AppointmentSlotSection,
1130
- {
1131
- label: "Morning",
1132
- slots: amSlots,
1133
- selectedSlotId: slot == null ? void 0 : slot.id,
1134
- onSelect: setSlot
1135
- }
1136
- ),
1137
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1138
- AppointmentSlotSection,
1180
+ Textarea,
1139
1181
  {
1140
- label: "Afternoon",
1141
- slots: pmSlots,
1142
- selectedSlotId: slot == null ? void 0 : slot.id,
1143
- onSelect: setSlot
1182
+ id: "reschedule-note",
1183
+ placeholder: "e.g. Rescheduling due to an internal conflict \u2014 apologies for the inconvenience\u2026",
1184
+ value: note,
1185
+ onChange: (e) => setNote(e.target.value),
1186
+ className: "w-full resize-none",
1187
+ rows: 2
1144
1188
  }
1145
1189
  )
1146
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex h-full flex-col items-center justify-center gap-2 py-8 text-center", children: [
1147
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm font-semibold", children: "Select a time slot" }),
1148
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs text-muted-foreground", children: "Pick a date on the left to see available slots." })
1149
- ] }) })
1150
- ] }),
1151
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
1152
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Label, { htmlFor: "reschedule-note", children: [
1153
- "Note",
1154
- " ",
1155
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "font-normal text-muted-foreground", children: "(optional)" })
1156
- ] }),
1157
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1158
- Textarea,
1159
- {
1160
- id: "reschedule-note",
1161
- placeholder: "e.g. Rescheduling due to an internal conflict \u2014 apologies for the inconvenience\u2026",
1162
- value: note,
1163
- onChange: (e) => setNote(e.target.value),
1164
- className: "w-full resize-none",
1165
- rows: 2
1166
- }
1167
- )
1190
+ ] })
1168
1191
  ] }),
1169
1192
  /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(DialogFooter, { children: [
1170
1193
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(DialogClose, { render: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Button, { variant: "outline" }), children: "Cancel" }),
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  AppointmentConfirmDialog,
3
3
  AppointmentRescheduleDialog
4
- } from "../../chunk-SET6GFGL.mjs";
4
+ } from "../../chunk-ZSMQZ3VN.mjs";
5
5
  import "../../chunk-CQ7HKBEX.mjs";
6
6
  import "../../chunk-2GIYVERS.mjs";
7
7
  import "../../chunk-BS75ICOO.mjs";