@idkwebsites/components 0.1.8 → 0.1.14

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.
package/dist/index.cjs CHANGED
@@ -383,8 +383,62 @@ function ServicesList({
383
383
  );
384
384
  }
385
385
 
386
- // src/components/TeamMember.tsx
386
+ // src/lib/linkify.tsx
387
387
  var import_jsx_runtime4 = require("react/jsx-runtime");
388
+ var LINK_REGEX = /((https?:\/\/|www\.)[^\s]+|[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}|(?:[a-z0-9-]+\.)+[a-z]{2,}(?:\/[^\s]*)?)/gi;
389
+ function buildHref(raw) {
390
+ if (raw.includes("@") && !raw.startsWith("http")) {
391
+ return `mailto:${raw}`;
392
+ }
393
+ if (raw.startsWith("http://") || raw.startsWith("https://")) {
394
+ return raw;
395
+ }
396
+ if (raw.startsWith("www.")) {
397
+ return `https://${raw}`;
398
+ }
399
+ return `https://${raw}`;
400
+ }
401
+ function trimTrailingPunctuation(value) {
402
+ let text = value;
403
+ let trailing = "";
404
+ while (text && /[),.!?:;]+$/.test(text)) {
405
+ trailing = text.slice(-1) + trailing;
406
+ text = text.slice(0, -1);
407
+ }
408
+ return { text, trailing };
409
+ }
410
+ function renderLinkedText(text) {
411
+ if (!text) return null;
412
+ const matches = Array.from(text.matchAll(LINK_REGEX));
413
+ if (matches.length === 0) return text;
414
+ const nodes = [];
415
+ let lastIndex = 0;
416
+ matches.forEach((match, index) => {
417
+ const matchText = match[0];
418
+ const start = match.index ?? 0;
419
+ if (start > lastIndex) {
420
+ nodes.push(text.slice(lastIndex, start));
421
+ }
422
+ const { text: cleanText, trailing } = trimTrailingPunctuation(matchText);
423
+ if (cleanText) {
424
+ const href = buildHref(cleanText);
425
+ nodes.push(
426
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { href, target: "_blank", rel: "noopener noreferrer", children: cleanText }, `link-${start}-${index}`)
427
+ );
428
+ }
429
+ if (trailing) {
430
+ nodes.push(trailing);
431
+ }
432
+ lastIndex = start + matchText.length;
433
+ });
434
+ if (lastIndex < text.length) {
435
+ nodes.push(text.slice(lastIndex));
436
+ }
437
+ return nodes;
438
+ }
439
+
440
+ // src/components/TeamMember.tsx
441
+ var import_jsx_runtime5 = require("react/jsx-runtime");
388
442
  function TeamMember({
389
443
  member,
390
444
  className,
@@ -395,32 +449,32 @@ function TeamMember({
395
449
  imagePosition = "left"
396
450
  }) {
397
451
  const initials = member.name?.split(" ").map((part) => part[0]).slice(0, 2).join("").toUpperCase();
398
- const avatar = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "idk-team__avatar", children: member.photo?.url ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("img", { src: member.photo.url, alt: member.name }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: initials }) });
452
+ const avatar = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "idk-team__avatar", children: member.photo?.url ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: member.photo.url, alt: member.name }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: initials }) });
399
453
  if (layout === "profile") {
400
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: ["idk-team__profile", className].filter(Boolean).join(" "), children: [
454
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: ["idk-team__profile", className].filter(Boolean).join(" "), children: [
401
455
  imagePosition === "left" ? avatar : null,
402
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "idk-team__info", children: [
403
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "idk-card__title", children: member.name }),
404
- showRole ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "idk-card__description", children: member.role || "Staff" }) : null,
405
- showBio && member.bio ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "idk-team__bio", children: member.bio }) : null,
406
- showEmail ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "idk-card__meta", children: member.email }) : null
456
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "idk-team__info", children: [
457
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { className: "idk-card__title", children: member.name }),
458
+ showRole ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "idk-card__description", children: member.role || "Staff" }) : null,
459
+ showBio && member.bio ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "idk-team__bio", children: renderLinkedText(member.bio) }) : null,
460
+ showEmail ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "idk-card__meta", children: member.email }) : null
407
461
  ] }),
408
462
  imagePosition === "right" ? avatar : null
409
463
  ] });
410
464
  }
411
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: ["idk-card", className].filter(Boolean).join(" "), children: [
412
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "idk-team__avatar", children: member.photo?.url ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("img", { src: member.photo.url, alt: member.name }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: initials }) }),
413
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "idk-team__info", children: [
414
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "idk-card__title", children: member.name }),
415
- showRole ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "idk-card__description", children: member.role || "Staff" }) : null,
416
- showBio && member.bio ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "idk-team__bio", children: member.bio }) : null,
417
- showEmail ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "idk-card__meta", children: member.email }) : null
465
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: ["idk-card", className].filter(Boolean).join(" "), children: [
466
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "idk-team__avatar", children: member.photo?.url ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: member.photo.url, alt: member.name }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: initials }) }),
467
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "idk-team__info", children: [
468
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { className: "idk-card__title", children: member.name }),
469
+ showRole ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "idk-card__description", children: member.role || "Staff" }) : null,
470
+ showBio && member.bio ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "idk-team__bio", children: renderLinkedText(member.bio) }) : null,
471
+ showEmail ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "idk-card__meta", children: member.email }) : null
418
472
  ] })
419
473
  ] });
420
474
  }
421
475
 
422
476
  // src/components/TeamGrid.tsx
423
- var import_jsx_runtime5 = require("react/jsx-runtime");
477
+ var import_jsx_runtime6 = require("react/jsx-runtime");
424
478
  function TeamGrid({
425
479
  columns = 3,
426
480
  className,
@@ -438,7 +492,7 @@ function TeamGrid({
438
492
  }) {
439
493
  const { data, isLoading, error } = useTeam(query);
440
494
  if (isLoading) {
441
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "idk-state", children: loadingMessage });
495
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "idk-state", children: loadingMessage });
442
496
  }
443
497
  let members = data?.team ? [...data.team] : [];
444
498
  if (filter) {
@@ -451,15 +505,15 @@ function TeamGrid({
451
505
  members = members.slice(0, Math.max(0, limit));
452
506
  }
453
507
  if (error || members.length === 0) {
454
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "idk-state", children: emptyMessage });
508
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "idk-state", children: emptyMessage });
455
509
  }
456
510
  const gridStyle = { gridTemplateColumns: `repeat(${Math.max(1, columns)}, minmax(0, 1fr))` };
457
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
511
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
458
512
  "div",
459
513
  {
460
514
  className: ["idk-team", className].filter(Boolean).join(" "),
461
515
  style: gridStyle,
462
- children: members.map((member) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
516
+ children: members.map((member) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
463
517
  TeamMember,
464
518
  {
465
519
  member,
@@ -478,7 +532,7 @@ function TeamGrid({
478
532
  // src/components/ContactForm.tsx
479
533
  var import_react6 = require("react");
480
534
  var import_react_query7 = require("@tanstack/react-query");
481
- var import_jsx_runtime6 = require("react/jsx-runtime");
535
+ var import_jsx_runtime7 = require("react/jsx-runtime");
482
536
  var DEFAULT_FIELDS = ["name", "email", "phone", "message"];
483
537
  function ContactForm({
484
538
  fields = DEFAULT_FIELDS,
@@ -524,10 +578,10 @@ function ContactForm({
524
578
  formType
525
579
  });
526
580
  };
527
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("form", { className: ["idk-form", className].filter(Boolean).join(" "), onSubmit: handleSubmit, children: [
528
- fields.includes("name") && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "idk-form__field", children: [
529
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Name" }),
530
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
581
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("form", { className: ["idk-form", className].filter(Boolean).join(" "), onSubmit: handleSubmit, children: [
582
+ fields.includes("name") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "idk-form__field", children: [
583
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Name" }),
584
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
531
585
  "input",
532
586
  {
533
587
  value: formState.name,
@@ -536,9 +590,9 @@ function ContactForm({
536
590
  }
537
591
  )
538
592
  ] }),
539
- fields.includes("email") && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "idk-form__field", children: [
540
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Email" }),
541
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
593
+ fields.includes("email") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "idk-form__field", children: [
594
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Email" }),
595
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
542
596
  "input",
543
597
  {
544
598
  type: "email",
@@ -548,9 +602,9 @@ function ContactForm({
548
602
  }
549
603
  )
550
604
  ] }),
551
- fields.includes("phone") && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "idk-form__field", children: [
552
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Phone" }),
553
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
605
+ fields.includes("phone") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "idk-form__field", children: [
606
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Phone" }),
607
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
554
608
  "input",
555
609
  {
556
610
  value: formState.phone,
@@ -558,9 +612,9 @@ function ContactForm({
558
612
  }
559
613
  )
560
614
  ] }),
561
- fields.includes("subject") && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "idk-form__field", children: [
562
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Subject" }),
563
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
615
+ fields.includes("subject") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "idk-form__field", children: [
616
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Subject" }),
617
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
564
618
  "input",
565
619
  {
566
620
  value: formState.subject,
@@ -568,9 +622,9 @@ function ContactForm({
568
622
  }
569
623
  )
570
624
  ] }),
571
- fields.includes("message") && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { className: "idk-form__field", children: [
572
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "Message" }),
573
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
625
+ fields.includes("message") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "idk-form__field", children: [
626
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Message" }),
627
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
574
628
  "textarea",
575
629
  {
576
630
  value: formState.message,
@@ -580,15 +634,27 @@ function ContactForm({
580
634
  }
581
635
  )
582
636
  ] }),
583
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "submit", className: "idk-button", disabled: mutation.isPending, children: mutation.isPending ? "Sending..." : submitLabel }),
584
- mutation.isError ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "idk-form__error", children: "Something went wrong. Please try again." }) : null,
585
- mutation.isSuccess ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "idk-form__success", children: "Thanks! We'll be in touch soon." }) : null
637
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "submit", className: "idk-button", disabled: mutation.isPending, children: mutation.isPending ? "Sending..." : submitLabel }),
638
+ mutation.isError ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "idk-form__error", children: "Something went wrong. Please try again." }) : null,
639
+ mutation.isSuccess ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "idk-form__success", children: "Thanks! We'll be in touch soon." }) : null
586
640
  ] });
587
641
  }
588
642
 
589
643
  // src/components/BookingWidget.tsx
590
644
  var import_react7 = require("react");
591
- var import_jsx_runtime7 = require("react/jsx-runtime");
645
+ var import_jsx_runtime8 = require("react/jsx-runtime");
646
+ var parseDateOnly = (value) => {
647
+ if (!value) return null;
648
+ const normalized = value.includes("T") ? value.split("T")[0] : value;
649
+ const parsed = /* @__PURE__ */ new Date(`${normalized}T00:00:00`);
650
+ return Number.isNaN(parsed.getTime()) ? null : parsed;
651
+ };
652
+ var addDays = (dateStr, days) => {
653
+ const parsed = parseDateOnly(dateStr);
654
+ if (!parsed) return dateStr;
655
+ parsed.setDate(parsed.getDate() + days);
656
+ return parsed.toISOString().slice(0, 10);
657
+ };
592
658
  function BookingWidget({
593
659
  className,
594
660
  showStaffSelection = true,
@@ -615,7 +681,16 @@ function BookingWidget({
615
681
  staffLayout = "grid",
616
682
  staffColumns = 2,
617
683
  showAnyStaffOption = true,
618
- timeLayout = "split"
684
+ staffPageSize = 8,
685
+ showStaffPagination,
686
+ timeLayout = "split",
687
+ availabilityDays: availabilityDaysProp = 7,
688
+ enableDatePaging = true,
689
+ datePickerMode = "list",
690
+ calendarVariant = "default",
691
+ maxAdvanceMonths = 3,
692
+ disabledWeekdays = [],
693
+ showFullyBookedLabel = true
619
694
  }) {
620
695
  const resolvedServicesQuery = (0, import_react7.useMemo)(
621
696
  () => services ? { ...servicesQuery, enabled: false } : servicesQuery,
@@ -634,6 +709,17 @@ function BookingWidget({
634
709
  const [serviceSearch, setServiceSearch] = (0, import_react7.useState)("");
635
710
  const [categoryFilter, setCategoryFilter] = (0, import_react7.useState)("all");
636
711
  const [servicePage, setServicePage] = (0, import_react7.useState)(1);
712
+ const [staffPage, setStaffPage] = (0, import_react7.useState)(1);
713
+ const [availabilityDays, setAvailabilityDays] = (0, import_react7.useState)(
714
+ Math.max(1, availabilityDaysProp)
715
+ );
716
+ const [availabilityStartDate, setAvailabilityStartDate] = (0, import_react7.useState)(
717
+ () => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
718
+ );
719
+ const [calendarMonth, setCalendarMonth] = (0, import_react7.useState)(() => {
720
+ const now = /* @__PURE__ */ new Date();
721
+ return new Date(now.getFullYear(), now.getMonth(), 1);
722
+ });
637
723
  const [bookingError, setBookingError] = (0, import_react7.useState)(null);
638
724
  const [details, setDetails] = (0, import_react7.useState)({
639
725
  name: "",
@@ -665,6 +751,9 @@ function BookingWidget({
665
751
  (0, import_react7.useEffect)(() => {
666
752
  setServicePage(1);
667
753
  }, [serviceSearch, categoryFilter]);
754
+ (0, import_react7.useEffect)(() => {
755
+ setStaffPage(1);
756
+ }, [selectedService?.id, teamData, teamFilter]);
668
757
  const pagedServices = (0, import_react7.useMemo)(() => {
669
758
  const pageSize = Math.max(1, servicePageSize);
670
759
  return filteredServices.slice(0, pageSize * servicePage);
@@ -680,10 +769,21 @@ function BookingWidget({
680
769
  const teamList = teamData?.team || [];
681
770
  return teamFilter ? teamList.filter(teamFilter) : teamList;
682
771
  }, [selectedService, teamData, teamFilter]);
772
+ const pagedStaff = (0, import_react7.useMemo)(() => {
773
+ const pageSize = Math.max(1, staffPageSize);
774
+ return staffOptions.slice(0, pageSize * staffPage);
775
+ }, [staffOptions, staffPage, staffPageSize]);
776
+ const hasMoreStaff = staffOptions.length > pagedStaff.length;
777
+ const shouldPaginateStaff = showStaffPagination ?? hasMoreStaff;
778
+ const availabilityEndDate = (0, import_react7.useMemo)(
779
+ () => addDays(availabilityStartDate, Math.max(1, availabilityDays) - 1),
780
+ [availabilityStartDate, availabilityDays]
781
+ );
683
782
  const availability = useAvailability({
684
783
  serviceId: selectedService?.id || "",
685
784
  staffId: selectedStaff?.id,
686
- days: 7,
785
+ startDate: availabilityStartDate,
786
+ endDate: availabilityEndDate,
687
787
  enabled: Boolean(selectedService)
688
788
  });
689
789
  const timeZone = availability.data?.timeZone || "America/Chicago";
@@ -753,18 +853,6 @@ function BookingWidget({
753
853
  setSelectedEndTime(null);
754
854
  setBookingError(null);
755
855
  };
756
- (0, import_react7.useEffect)(() => {
757
- if (step !== "time") return;
758
- if (!availability.data?.dates?.length) return;
759
- if (selectedDate) return;
760
- setSelectedDate(availability.data.dates[0].date);
761
- }, [step, availability.data, selectedDate]);
762
- const parseDateOnly = (value) => {
763
- if (!value) return null;
764
- const normalized = value.includes("T") ? value.split("T")[0] : value;
765
- const parsed = /* @__PURE__ */ new Date(`${normalized}T00:00:00`);
766
- return Number.isNaN(parsed.getTime()) ? null : parsed;
767
- };
768
856
  const parseDateTime = (value, fallbackDate) => {
769
857
  if (!value) return null;
770
858
  const direct = new Date(value);
@@ -810,6 +898,118 @@ function BookingWidget({
810
898
  const remaining = minutes % 60;
811
899
  return remaining === 0 ? `${hours} hr${hours > 1 ? "s" : ""}` : `${hours} hr ${remaining} min`;
812
900
  };
901
+ const todayString = (0, import_react7.useMemo)(() => (/* @__PURE__ */ new Date()).toISOString().slice(0, 10), []);
902
+ const todayDate = (0, import_react7.useMemo)(() => {
903
+ const now = /* @__PURE__ */ new Date();
904
+ now.setHours(0, 0, 0, 0);
905
+ return now;
906
+ }, []);
907
+ const disabledWeekdaysSet = (0, import_react7.useMemo)(() => new Set(disabledWeekdays), [disabledWeekdays]);
908
+ const getMonthStart = (0, import_react7.useCallback)((date) => {
909
+ return new Date(date.getFullYear(), date.getMonth(), 1);
910
+ }, []);
911
+ const getMonthEnd = (0, import_react7.useCallback)((date) => {
912
+ return new Date(date.getFullYear(), date.getMonth() + 1, 0);
913
+ }, []);
914
+ const getMonthDays = (0, import_react7.useCallback)(
915
+ (date) => {
916
+ const start = getMonthStart(date);
917
+ const end = getMonthEnd(date);
918
+ const days = [];
919
+ const startDay = start.getDay();
920
+ for (let i = startDay; i > 0; i -= 1) {
921
+ const d = new Date(start);
922
+ d.setDate(start.getDate() - i);
923
+ days.push({ date: d.toISOString().slice(0, 10), isCurrentMonth: false });
924
+ }
925
+ for (let day = 1; day <= end.getDate(); day += 1) {
926
+ const d = new Date(date.getFullYear(), date.getMonth(), day);
927
+ days.push({ date: d.toISOString().slice(0, 10), isCurrentMonth: true });
928
+ }
929
+ const remainder = 7 - (days.length % 7 || 7);
930
+ for (let i = 1; i <= remainder; i += 1) {
931
+ const d = new Date(end);
932
+ d.setDate(end.getDate() + i);
933
+ days.push({ date: d.toISOString().slice(0, 10), isCurrentMonth: false });
934
+ }
935
+ return days;
936
+ },
937
+ [getMonthEnd, getMonthStart]
938
+ );
939
+ const maxAdvanceDate = (0, import_react7.useMemo)(() => {
940
+ if (!maxAdvanceMonths || maxAdvanceMonths <= 0) return null;
941
+ const maxMonth = new Date(todayDate.getFullYear(), todayDate.getMonth() + maxAdvanceMonths - 1, 1);
942
+ return getMonthEnd(maxMonth);
943
+ }, [getMonthEnd, maxAdvanceMonths, todayDate]);
944
+ const maxAdvanceMonthStart = (0, import_react7.useMemo)(() => {
945
+ if (!maxAdvanceMonths || maxAdvanceMonths <= 0) return null;
946
+ return new Date(todayDate.getFullYear(), todayDate.getMonth() + maxAdvanceMonths - 1, 1);
947
+ }, [maxAdvanceMonths, todayDate]);
948
+ const handlePrevDates = () => {
949
+ if (availabilityStartDate <= todayString) return;
950
+ setAvailabilityStartDate((prev) => addDays(prev, -availabilityDays));
951
+ setSelectedDate(null);
952
+ setSelectedTime(null);
953
+ setSelectedEndTime(null);
954
+ setBookingError(null);
955
+ };
956
+ const handleNextDates = () => {
957
+ if (maxAdvanceDate) {
958
+ const nextStart = parseDateOnly(addDays(availabilityStartDate, availabilityDays));
959
+ if (nextStart && nextStart > maxAdvanceDate) {
960
+ return;
961
+ }
962
+ }
963
+ setAvailabilityStartDate((prev) => addDays(prev, availabilityDays));
964
+ setSelectedDate(null);
965
+ setSelectedTime(null);
966
+ setSelectedEndTime(null);
967
+ setBookingError(null);
968
+ };
969
+ const handlePrevMonth = () => {
970
+ setCalendarMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() - 1, 1));
971
+ setSelectedDate(null);
972
+ setSelectedTime(null);
973
+ setSelectedEndTime(null);
974
+ setBookingError(null);
975
+ };
976
+ const handleNextMonth = () => {
977
+ if (maxAdvanceMonthStart) {
978
+ const nextMonth = new Date(calendarMonth.getFullYear(), calendarMonth.getMonth() + 1, 1);
979
+ if (nextMonth > maxAdvanceMonthStart) return;
980
+ }
981
+ setCalendarMonth((prev) => new Date(prev.getFullYear(), prev.getMonth() + 1, 1));
982
+ setSelectedDate(null);
983
+ setSelectedTime(null);
984
+ setSelectedEndTime(null);
985
+ setBookingError(null);
986
+ };
987
+ (0, import_react7.useEffect)(() => {
988
+ if (step !== "time") return;
989
+ if (!availability.data?.dates?.length) return;
990
+ const matches = selectedDate ? availability.data.dates.some((entry) => entry.date === selectedDate) : false;
991
+ if (matches) return;
992
+ setSelectedDate(availability.data.dates[0].date);
993
+ }, [step, availability.data, selectedDate]);
994
+ (0, import_react7.useEffect)(() => {
995
+ if (!selectedService) return;
996
+ if (datePickerMode === "calendar") {
997
+ const now = /* @__PURE__ */ new Date();
998
+ setCalendarMonth(new Date(now.getFullYear(), now.getMonth(), 1));
999
+ return;
1000
+ }
1001
+ setAvailabilityStartDate((/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
1002
+ setAvailabilityDays(Math.max(1, availabilityDaysProp));
1003
+ }, [selectedService?.id, selectedStaff?.id, availabilityDaysProp, datePickerMode]);
1004
+ (0, import_react7.useEffect)(() => {
1005
+ if (datePickerMode !== "calendar") return;
1006
+ const start = getMonthStart(calendarMonth);
1007
+ const end = getMonthEnd(calendarMonth);
1008
+ const startString = start.toISOString().slice(0, 10);
1009
+ const daysInMonth = end.getDate();
1010
+ setAvailabilityStartDate(startString);
1011
+ setAvailabilityDays(daysInMonth);
1012
+ }, [calendarMonth, datePickerMode, getMonthEnd, getMonthStart]);
813
1013
  const handleBack = () => {
814
1014
  if (step === "service") return;
815
1015
  if (step === "staff") {
@@ -879,32 +1079,32 @@ function BookingWidget({
879
1079
  };
880
1080
  const isServicesLoading = services ? false : servicesLoading;
881
1081
  if (isServicesLoading) {
882
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-state", children: "Loading booking options..." });
1082
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-state", children: "Loading booking options..." });
883
1083
  }
884
1084
  if (!servicesList.length) {
885
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-state", children: "No services available." });
1085
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-state", children: "No services available." });
886
1086
  }
887
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1087
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
888
1088
  "div",
889
1089
  {
890
1090
  ref: widgetRef,
891
1091
  className: ["idk-booking", className].filter(Boolean).join(" "),
892
1092
  children: [
893
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-booking__header", children: [
894
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-booking__title-wrap", children: [
895
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { className: "idk-booking__title", children: title }),
896
- subtitle ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "idk-booking__subtitle", children: subtitle }) : null
1093
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-booking__header", children: [
1094
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-booking__title-wrap", children: [
1095
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { className: "idk-booking__title", children: title }),
1096
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "idk-booking__subtitle", children: subtitle }) : null
897
1097
  ] }),
898
- step !== "service" && step !== "done" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "idk-link", onClick: handleBack, children: "Back" }) : null
1098
+ step !== "service" && step !== "done" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "idk-link", onClick: handleBack, children: "Back" }) : null
899
1099
  ] }),
900
- step !== "done" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-booking__progress", children: [
901
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { children: [
1100
+ step !== "done" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-booking__progress", children: [
1101
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { children: [
902
1102
  "Step ",
903
1103
  stepNumber,
904
1104
  " of ",
905
1105
  totalSteps
906
1106
  ] }),
907
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-booking__bar", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1107
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-booking__bar", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
908
1108
  "div",
909
1109
  {
910
1110
  className: "idk-booking__bar-fill",
@@ -912,10 +1112,10 @@ function BookingWidget({
912
1112
  }
913
1113
  ) })
914
1114
  ] }) : null,
915
- step === "service" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-booking__step", children: [
916
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h4", { children: "Select a service" }),
917
- enableServiceSearch || enableCategoryFilter ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-booking__filters", children: [
918
- enableServiceSearch ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1115
+ step === "service" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-booking__step", children: [
1116
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { children: "Select a service" }),
1117
+ enableServiceSearch || enableCategoryFilter ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-booking__filters", children: [
1118
+ enableServiceSearch ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
919
1119
  "input",
920
1120
  {
921
1121
  type: "search",
@@ -924,19 +1124,19 @@ function BookingWidget({
924
1124
  placeholder: serviceSearchPlaceholder
925
1125
  }
926
1126
  ) : null,
927
- enableCategoryFilter && categories.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1127
+ enableCategoryFilter && categories.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
928
1128
  "select",
929
1129
  {
930
1130
  value: categoryFilter,
931
1131
  onChange: (event) => setCategoryFilter(event.target.value),
932
1132
  children: [
933
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: "all", children: categoryLabel }),
934
- categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("option", { value: category, children: category }, category))
1133
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: "all", children: categoryLabel }),
1134
+ categories.map((category) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("option", { value: category, children: category }, category))
935
1135
  ]
936
1136
  }
937
1137
  ) : null
938
1138
  ] }) : null,
939
- filteredServices.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-state", children: "No services match your filters." }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1139
+ filteredServices.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-state", children: "No services match your filters." }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
940
1140
  "div",
941
1141
  {
942
1142
  className: [
@@ -949,7 +1149,7 @@ function BookingWidget({
949
1149
  },
950
1150
  children: pagedServices.map((service) => {
951
1151
  const isSelected = selectedService?.id === service.id;
952
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1152
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
953
1153
  "button",
954
1154
  {
955
1155
  type: "button",
@@ -967,20 +1167,20 @@ function BookingWidget({
967
1167
  }
968
1168
  },
969
1169
  children: [
970
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-card__header", children: [
971
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "idk-card__title", children: service.name }),
972
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "idk-card__aside", children: [
973
- isSelected ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "idk-card__check", children: "\u2713" }) : null,
974
- typeof service.price === "number" && service.price > 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "idk-card__price", children: [
1170
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-card__header", children: [
1171
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-card__title", children: service.name }),
1172
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "idk-card__aside", children: [
1173
+ isSelected ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-card__check", children: "\u2713" }) : null,
1174
+ typeof service.price === "number" && service.price > 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: "idk-card__price", children: [
975
1175
  "$",
976
1176
  (service.price / 100).toFixed(2)
977
1177
  ] }) : null
978
1178
  ] })
979
1179
  ] }),
980
- service.description ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-card__description", children: service.description }) : null,
981
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-card__meta", children: [
982
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: formatDuration(service.duration) }),
983
- service.category ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "idk-pill", children: service.category }) : null
1180
+ service.description ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-card__description", children: service.description }) : null,
1181
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-card__meta", children: [
1182
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: formatDuration(service.duration) }),
1183
+ service.category ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-pill", children: service.category }) : null
984
1184
  ] })
985
1185
  ]
986
1186
  },
@@ -989,8 +1189,8 @@ function BookingWidget({
989
1189
  })
990
1190
  }
991
1191
  ),
992
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-booking__actions", children: [
993
- shouldPaginate ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1192
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-booking__actions", children: [
1193
+ shouldPaginate ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
994
1194
  "button",
995
1195
  {
996
1196
  type: "button",
@@ -1000,12 +1200,12 @@ function BookingWidget({
1000
1200
  children: hasMoreServices ? "Show more services" : "All services shown"
1001
1201
  }
1002
1202
  ) : null,
1003
- selectedService && !autoAdvanceOnSelect ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "button", className: "idk-button", onClick: handleServiceContinue, children: "Continue" }) : null
1203
+ selectedService && !autoAdvanceOnSelect ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "button", className: "idk-button", onClick: handleServiceContinue, children: "Continue" }) : null
1004
1204
  ] })
1005
1205
  ] }),
1006
- step === "staff" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-booking__step", children: [
1007
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h4", { children: "Select a team member" }),
1008
- staffOptions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-state", children: "No team members available." }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1206
+ step === "staff" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-booking__step", children: [
1207
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { children: "Select a team member" }),
1208
+ staffOptions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-state", children: "No team members available." }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1009
1209
  "div",
1010
1210
  {
1011
1211
  className: [
@@ -1014,7 +1214,7 @@ function BookingWidget({
1014
1214
  ].join(" "),
1015
1215
  style: staffLayout === "grid" ? { gridTemplateColumns: `repeat(${Math.max(1, staffColumns)}, minmax(0, 1fr))` } : void 0,
1016
1216
  children: [
1017
- showAnyStaffOption && canSkipStaff ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1217
+ showAnyStaffOption && canSkipStaff ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1018
1218
  "button",
1019
1219
  {
1020
1220
  type: "button",
@@ -1030,16 +1230,16 @@ function BookingWidget({
1030
1230
  }
1031
1231
  },
1032
1232
  children: [
1033
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-card__header", children: [
1034
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "idk-card__title", children: "Any Available" }),
1035
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "idk-card__badge", children: "Recommended" })
1233
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-card__header", children: [
1234
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-card__title", children: "Any Available" }),
1235
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-card__badge", children: "Recommended" })
1036
1236
  ] }),
1037
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "idk-card__description", children: "We'll match you with the first available stylist." })
1237
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "idk-card__description", children: "We'll match you with the first available stylist." })
1038
1238
  ]
1039
1239
  },
1040
1240
  "any-staff"
1041
1241
  ) : null,
1042
- staffOptions.map((staff) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1242
+ pagedStaff.map((staff) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1043
1243
  "button",
1044
1244
  {
1045
1245
  type: "button",
@@ -1055,12 +1255,12 @@ function BookingWidget({
1055
1255
  scrollToTop();
1056
1256
  }
1057
1257
  },
1058
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-team__card", children: [
1059
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-team__avatar", children: staff.photo?.url ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: staff.photo.url, alt: staff.name }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: staff.name.split(" ").map((part) => part[0]).slice(0, 2).join("").toUpperCase() }) }),
1060
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
1061
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "idk-card__title", children: staff.name }),
1062
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "idk-card__meta", children: staff.role || "Staff" }),
1063
- staff.bio ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "idk-card__description", children: staff.bio }) : null
1258
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-team__card", children: [
1259
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-team__avatar", children: staff.photo?.url ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: staff.photo.url, alt: staff.name }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: staff.name.split(" ").map((part) => part[0]).slice(0, 2).join("").toUpperCase() }) }),
1260
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1261
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-card__title", children: staff.name }),
1262
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-card__meta", children: staff.role || "Staff" }),
1263
+ staff.bio ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "idk-card__description", children: renderLinkedText(staff.bio) }) : null
1064
1264
  ] })
1065
1265
  ] })
1066
1266
  },
@@ -1069,8 +1269,18 @@ function BookingWidget({
1069
1269
  ]
1070
1270
  }
1071
1271
  ),
1072
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-booking__actions", children: [
1073
- canSkipStaff ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1272
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-booking__actions", children: [
1273
+ shouldPaginateStaff ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1274
+ "button",
1275
+ {
1276
+ type: "button",
1277
+ className: "idk-button idk-button--ghost",
1278
+ onClick: () => setStaffPage((prev) => hasMoreStaff ? prev + 1 : 1),
1279
+ disabled: !hasMoreStaff && staffPage === 1,
1280
+ children: hasMoreStaff ? "Show more staff" : staffPage > 1 ? "Show fewer staff" : "All staff shown"
1281
+ }
1282
+ ) : null,
1283
+ canSkipStaff ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1074
1284
  "button",
1075
1285
  {
1076
1286
  type: "button",
@@ -1083,7 +1293,7 @@ function BookingWidget({
1083
1293
  children: "Continue without selecting"
1084
1294
  }
1085
1295
  ) : null,
1086
- !autoAdvanceOnSelect ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1296
+ !autoAdvanceOnSelect ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1087
1297
  "button",
1088
1298
  {
1089
1299
  type: "button",
@@ -1095,37 +1305,137 @@ function BookingWidget({
1095
1305
  ) : null
1096
1306
  ] })
1097
1307
  ] }),
1098
- step === "time" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-booking__step", children: [
1099
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h4", { children: "Select a time" }),
1100
- availability.isLoading ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-state", children: "Loading availability..." }) : availability.data ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: ["idk-availability", timeLayout === "split" ? "idk-availability--split" : ""].join(" "), children: [
1101
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-availability__dates", children: availability.data.dates.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1102
- "button",
1308
+ step === "time" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-booking__step", children: [
1309
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { children: "Select a time" }),
1310
+ availability.isLoading ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-state", children: "Loading availability..." }) : availability.data ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: ["idk-availability", timeLayout === "split" ? "idk-availability--split" : ""].join(" "), children: [
1311
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-availability__dates", children: datePickerMode === "calendar" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1312
+ "div",
1103
1313
  {
1104
- type: "button",
1105
- className: entry.date === selectedDate ? "is-active" : void 0,
1106
- onClick: () => {
1107
- setSelectedDate(entry.date);
1108
- setSelectedTime(null);
1109
- setSelectedEndTime(null);
1110
- setBookingError(null);
1314
+ className: [
1315
+ "idk-calendar",
1316
+ calendarVariant === "compact" ? "idk-calendar--compact" : ""
1317
+ ].filter(Boolean).join(" "),
1318
+ children: [
1319
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-calendar__header", children: [
1320
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1321
+ "button",
1322
+ {
1323
+ type: "button",
1324
+ className: "idk-button idk-button--ghost",
1325
+ onClick: handlePrevMonth,
1326
+ disabled: calendarMonth <= getMonthStart(todayDate),
1327
+ children: "Previous"
1328
+ }
1329
+ ),
1330
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-calendar__title", children: new Intl.DateTimeFormat("en-US", {
1331
+ month: "long",
1332
+ year: "numeric"
1333
+ }).format(calendarMonth) }),
1334
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1335
+ "button",
1336
+ {
1337
+ type: "button",
1338
+ className: "idk-button idk-button--ghost",
1339
+ onClick: handleNextMonth,
1340
+ disabled: Boolean(maxAdvanceMonthStart && calendarMonth >= maxAdvanceMonthStart),
1341
+ children: "Next"
1342
+ }
1343
+ )
1344
+ ] }),
1345
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-calendar__weekdays", children: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"].map((label) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: label }, label)) }),
1346
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-calendar__grid", children: getMonthDays(calendarMonth).map((day) => {
1347
+ const entry = availability.data?.dates?.find(
1348
+ (item) => item.date === day.date
1349
+ );
1350
+ const hasAvailable = entry?.slots?.some((slot) => slot.available) ?? false;
1351
+ const dateValue = parseDateOnly(day.date);
1352
+ const isPast = dateValue ? dateValue < todayDate : false;
1353
+ const isBeyondMax = maxAdvanceDate ? dateValue ? dateValue > maxAdvanceDate : false : false;
1354
+ const weekday = dateValue ? dateValue.getDay() : null;
1355
+ const isDisabledWeekday = weekday !== null ? disabledWeekdaysSet.has(weekday) : false;
1356
+ const isBlocked = Boolean(entry) && !hasAvailable;
1357
+ const isDisabled = !entry || isPast || isBeyondMax || isBlocked || isDisabledWeekday;
1358
+ const isActive = selectedDate === day.date;
1359
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1360
+ "button",
1361
+ {
1362
+ type: "button",
1363
+ className: [
1364
+ "idk-calendar__day",
1365
+ day.isCurrentMonth ? "" : "is-muted",
1366
+ hasAvailable ? "is-available" : "",
1367
+ isBlocked ? "is-blocked" : "",
1368
+ isDisabledWeekday ? "is-disabled" : "",
1369
+ isActive ? "is-active" : ""
1370
+ ].filter(Boolean).join(" "),
1371
+ disabled: isDisabled,
1372
+ onClick: () => {
1373
+ setSelectedDate(day.date);
1374
+ setSelectedTime(null);
1375
+ setSelectedEndTime(null);
1376
+ setBookingError(null);
1377
+ },
1378
+ children: [
1379
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: day.date.split("-")[2] }),
1380
+ showFullyBookedLabel && isBlocked && day.isCurrentMonth ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-calendar__label", children: calendarVariant === "compact" ? "Full" : "Fully booked" }) : null
1381
+ ]
1382
+ },
1383
+ day.date
1384
+ );
1385
+ }) })
1386
+ ]
1387
+ }
1388
+ ) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1389
+ enableDatePaging ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-availability__nav", children: [
1390
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1391
+ "button",
1392
+ {
1393
+ type: "button",
1394
+ className: "idk-button idk-button--ghost",
1395
+ onClick: handlePrevDates,
1396
+ disabled: availabilityStartDate <= todayString,
1397
+ children: "Previous"
1398
+ }
1399
+ ),
1400
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1401
+ "button",
1402
+ {
1403
+ type: "button",
1404
+ className: "idk-button idk-button--ghost",
1405
+ onClick: handleNextDates,
1406
+ children: "Next"
1407
+ }
1408
+ )
1409
+ ] }) : null,
1410
+ availability.data.dates.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1411
+ "button",
1412
+ {
1413
+ type: "button",
1414
+ className: entry.date === selectedDate ? "is-active" : void 0,
1415
+ onClick: () => {
1416
+ setSelectedDate(entry.date);
1417
+ setSelectedTime(null);
1418
+ setSelectedEndTime(null);
1419
+ setBookingError(null);
1420
+ },
1421
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-date-chip__day", children: formatDateLabel(entry.date) })
1111
1422
  },
1112
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "idk-date-chip__day", children: formatDateLabel(entry.date) })
1113
- },
1114
- entry.date
1115
- )) }),
1116
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-availability__panel", children: [
1117
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-availability__panel-header", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
1118
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-availability__panel-title", children: selectedDate ? formatDateHeading(selectedDate) : availability.data.dates[0]?.date ? formatDateHeading(availability.data.dates[0].date) : "Select a date" }),
1119
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-availability__panel-subtitle", children: timeZoneLabel })
1423
+ entry.date
1424
+ ))
1425
+ ] }) }),
1426
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-availability__panel", children: [
1427
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-availability__panel-header", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1428
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-availability__panel-title", children: selectedDate ? formatDateHeading(selectedDate) : availability.data.dates[0]?.date ? formatDateHeading(availability.data.dates[0].date) : "Select a date" }),
1429
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-availability__panel-subtitle", children: timeZoneLabel })
1120
1430
  ] }) }),
1121
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-availability__slots", children: (() => {
1122
- const activeEntry = availability.data.dates.find((entry) => entry.date === selectedDate) || availability.data.dates[0];
1123
- if (!activeEntry) return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-state", children: "Select a date to see times." });
1431
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-availability__slots", children: (() => {
1432
+ const activeEntry = selectedDate ? availability.data.dates.find((entry) => entry.date === selectedDate) : availability.data.dates[0];
1433
+ if (!activeEntry) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-state", children: "Select a date to see times." });
1124
1434
  const slots = (activeEntry.slots || []).filter((slot) => slot.available);
1125
1435
  if (slots.length === 0) {
1126
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-state", children: "No available times for this date." });
1436
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-state", children: "No available times for this date." });
1127
1437
  }
1128
- return slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1438
+ return slots.map((slot, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1129
1439
  "button",
1130
1440
  {
1131
1441
  type: "button",
@@ -1143,12 +1453,12 @@ function BookingWidget({
1143
1453
  },
1144
1454
  children: formatTimeLabel(slot.time)
1145
1455
  },
1146
- `${slot.time}-${slot.endTime}`
1456
+ `${activeEntry.date}-${slot.time}-${slot.endTime}-${index}`
1147
1457
  ));
1148
1458
  })() })
1149
1459
  ] })
1150
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-state", children: "No availability found." }),
1151
- !autoAdvanceOnSelect ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-booking__actions", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1460
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-state", children: "No availability found." }),
1461
+ !autoAdvanceOnSelect ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-booking__actions", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1152
1462
  "button",
1153
1463
  {
1154
1464
  type: "button",
@@ -1159,37 +1469,37 @@ function BookingWidget({
1159
1469
  }
1160
1470
  ) }) : null
1161
1471
  ] }),
1162
- step === "details" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("form", { className: "idk-form", onSubmit: handleSubmit, children: [
1163
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h4", { children: "Your details" }),
1164
- bookingError ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-booking__error", children: bookingError }) : null,
1165
- selectedService && selectedTime ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-booking__summary", children: [
1166
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
1167
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "idk-booking__summary-label", children: "Service" }),
1168
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: selectedService.name })
1472
+ step === "details" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("form", { className: "idk-form", onSubmit: handleSubmit, children: [
1473
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h4", { children: "Your details" }),
1474
+ bookingError ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-booking__error", children: bookingError }) : null,
1475
+ selectedService && selectedTime ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-booking__summary", children: [
1476
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1477
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-booking__summary-label", children: "Service" }),
1478
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: selectedService.name })
1169
1479
  ] }),
1170
- selectedStaff ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
1171
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "idk-booking__summary-label", children: "Staff" }),
1172
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { children: selectedStaff.name })
1480
+ selectedStaff ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1481
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-booking__summary-label", children: "Staff" }),
1482
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: selectedStaff.name })
1173
1483
  ] }) : null,
1174
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
1175
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "idk-booking__summary-label", children: "When" }),
1176
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { children: [
1484
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1485
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-booking__summary-label", children: "When" }),
1486
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { children: [
1177
1487
  formatDateHeading(selectedDate || ""),
1178
1488
  " \xB7 ",
1179
1489
  formatTimeLabel(selectedTime)
1180
1490
  ] })
1181
1491
  ] }),
1182
- selectedService.price ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { children: [
1183
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "idk-booking__summary-label", children: "Price" }),
1184
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { children: [
1492
+ selectedService.price ? /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
1493
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "idk-booking__summary-label", children: "Price" }),
1494
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { children: [
1185
1495
  "$",
1186
1496
  (selectedService.price / 100).toFixed(2)
1187
1497
  ] })
1188
1498
  ] }) : null
1189
1499
  ] }) : null,
1190
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "idk-form__field", children: [
1191
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Name" }),
1192
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1500
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "idk-form__field", children: [
1501
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Name" }),
1502
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1193
1503
  "input",
1194
1504
  {
1195
1505
  value: details.name,
@@ -1198,9 +1508,9 @@ function BookingWidget({
1198
1508
  }
1199
1509
  )
1200
1510
  ] }),
1201
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "idk-form__field", children: [
1202
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Email" }),
1203
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1511
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "idk-form__field", children: [
1512
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Email" }),
1513
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1204
1514
  "input",
1205
1515
  {
1206
1516
  type: "email",
@@ -1210,9 +1520,9 @@ function BookingWidget({
1210
1520
  }
1211
1521
  )
1212
1522
  ] }),
1213
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "idk-form__field", children: [
1214
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Phone" }),
1215
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1523
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "idk-form__field", children: [
1524
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Phone" }),
1525
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1216
1526
  "input",
1217
1527
  {
1218
1528
  value: details.phone,
@@ -1220,9 +1530,9 @@ function BookingWidget({
1220
1530
  }
1221
1531
  )
1222
1532
  ] }),
1223
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("label", { className: "idk-form__field", children: [
1224
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: "Notes" }),
1225
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1533
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("label", { className: "idk-form__field", children: [
1534
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: "Notes" }),
1535
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1226
1536
  "textarea",
1227
1537
  {
1228
1538
  rows: 4,
@@ -1231,12 +1541,12 @@ function BookingWidget({
1231
1541
  }
1232
1542
  )
1233
1543
  ] }),
1234
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("button", { type: "submit", className: "idk-button", disabled: createBooking.isPending, children: createBooking.isPending ? "Booking..." : "Confirm booking" })
1544
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("button", { type: "submit", className: "idk-button", disabled: createBooking.isPending, children: createBooking.isPending ? "Booking..." : "Confirm booking" })
1235
1545
  ] }),
1236
- step === "done" && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "idk-booking__done", children: [
1237
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "idk-booking__done-title", children: "Booking confirmed!" }),
1238
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "idk-booking__done-text", children: "We'll send a confirmation email shortly with your appointment details." }),
1239
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1546
+ step === "done" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "idk-booking__done", children: [
1547
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-booking__done-title", children: "Booking confirmed!" }),
1548
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "idk-booking__done-text", children: "We'll send a confirmation email shortly with your appointment details." }),
1549
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1240
1550
  "button",
1241
1551
  {
1242
1552
  type: "button",
@@ -1259,7 +1569,7 @@ function BookingWidget({
1259
1569
 
1260
1570
  // src/components/AvailabilityPicker.tsx
1261
1571
  var import_react8 = require("react");
1262
- var import_jsx_runtime8 = require("react/jsx-runtime");
1572
+ var import_jsx_runtime9 = require("react/jsx-runtime");
1263
1573
  function AvailabilityPicker({
1264
1574
  serviceId,
1265
1575
  staffId,
@@ -1277,15 +1587,15 @@ function AvailabilityPicker({
1277
1587
  days
1278
1588
  });
1279
1589
  if (isLoading) {
1280
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-state", children: "Loading availability..." });
1590
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "idk-state", children: "Loading availability..." });
1281
1591
  }
1282
1592
  if (!data?.dates?.length) {
1283
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-state", children: "No availability found." });
1593
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "idk-state", children: "No availability found." });
1284
1594
  }
1285
1595
  const activeDate = selectedDate || data.dates[0]?.date;
1286
1596
  const activeSlots = data.dates.find((entry) => entry.date === activeDate)?.slots || [];
1287
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: ["idk-availability", className].filter(Boolean).join(" "), children: [
1288
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-availability__dates", children: data.dates.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1597
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: ["idk-availability", className].filter(Boolean).join(" "), children: [
1598
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "idk-availability__dates", children: data.dates.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1289
1599
  "button",
1290
1600
  {
1291
1601
  type: "button",
@@ -1298,7 +1608,7 @@ function AvailabilityPicker({
1298
1608
  },
1299
1609
  entry.date
1300
1610
  )) }),
1301
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-availability__slots", children: activeSlots.filter((slot) => slot.available).length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "idk-state", children: "No slots available." }) : activeSlots.filter((slot) => slot.available).map((slot) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1611
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "idk-availability__slots", children: activeSlots.filter((slot) => slot.available).length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "idk-state", children: "No slots available." }) : activeSlots.filter((slot) => slot.available).map((slot) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1302
1612
  "button",
1303
1613
  {
1304
1614
  type: "button",
@@ -1321,22 +1631,22 @@ function AvailabilityPicker({
1321
1631
  }
1322
1632
 
1323
1633
  // src/components/ServicePicker.tsx
1324
- var import_jsx_runtime9 = require("react/jsx-runtime");
1634
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1325
1635
  function ServicePicker({
1326
1636
  services,
1327
1637
  selectedId,
1328
1638
  onSelect,
1329
1639
  className
1330
1640
  }) {
1331
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: ["idk-picker", className].filter(Boolean).join(" "), children: services.map((service) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1641
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: ["idk-picker", className].filter(Boolean).join(" "), children: services.map((service) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1332
1642
  "button",
1333
1643
  {
1334
1644
  type: "button",
1335
1645
  className: selectedId === service.id ? "is-active" : void 0,
1336
1646
  onClick: () => onSelect?.(service),
1337
1647
  children: [
1338
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: service.name }),
1339
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("small", { children: [
1648
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: service.name }),
1649
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("small", { children: [
1340
1650
  service.duration,
1341
1651
  " min"
1342
1652
  ] })
@@ -1347,22 +1657,22 @@ function ServicePicker({
1347
1657
  }
1348
1658
 
1349
1659
  // src/components/StaffPicker.tsx
1350
- var import_jsx_runtime10 = require("react/jsx-runtime");
1660
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1351
1661
  function StaffPicker({
1352
1662
  staff,
1353
1663
  selectedId,
1354
1664
  onSelect,
1355
1665
  className
1356
1666
  }) {
1357
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: ["idk-picker", className].filter(Boolean).join(" "), children: staff.map((member) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1667
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: ["idk-picker", className].filter(Boolean).join(" "), children: staff.map((member) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1358
1668
  "button",
1359
1669
  {
1360
1670
  type: "button",
1361
1671
  className: selectedId === member.id ? "is-active" : void 0,
1362
1672
  onClick: () => onSelect?.(member),
1363
1673
  children: [
1364
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: member.name }),
1365
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("small", { children: member.role || "Staff" })
1674
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: member.name }),
1675
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("small", { children: member.role || "Staff" })
1366
1676
  ]
1367
1677
  },
1368
1678
  member.id
@@ -1370,14 +1680,14 @@ function StaffPicker({
1370
1680
  }
1371
1681
 
1372
1682
  // src/components/DatePicker.tsx
1373
- var import_jsx_runtime11 = require("react/jsx-runtime");
1683
+ var import_jsx_runtime12 = require("react/jsx-runtime");
1374
1684
  function DatePicker({
1375
1685
  dates,
1376
1686
  selectedDate,
1377
1687
  onSelect,
1378
1688
  className
1379
1689
  }) {
1380
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: ["idk-picker", className].filter(Boolean).join(" "), children: dates.map((date) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1690
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: ["idk-picker", className].filter(Boolean).join(" "), children: dates.map((date) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1381
1691
  "button",
1382
1692
  {
1383
1693
  type: "button",
@@ -1390,14 +1700,14 @@ function DatePicker({
1390
1700
  }
1391
1701
 
1392
1702
  // src/components/TimePicker.tsx
1393
- var import_jsx_runtime12 = require("react/jsx-runtime");
1703
+ var import_jsx_runtime13 = require("react/jsx-runtime");
1394
1704
  function TimePicker({
1395
1705
  slots,
1396
1706
  selectedTime,
1397
1707
  onSelect,
1398
1708
  className
1399
1709
  }) {
1400
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: ["idk-picker", className].filter(Boolean).join(" "), children: slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1710
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: ["idk-picker", className].filter(Boolean).join(" "), children: slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1401
1711
  "button",
1402
1712
  {
1403
1713
  type: "button",