@anker-in/ui 0.3.2 → 0.3.4

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.d.mts CHANGED
@@ -611,6 +611,12 @@ interface BookingFormPageData {
611
611
  emailDescription?: string;
612
612
  dealsType?: string;
613
613
  agrees?: string[];
614
+ fieldRuquired?: string;
615
+ agreeRuquired?: string;
616
+ emailValidError?: string;
617
+ errorMsg?: {
618
+ [key: string]: string;
619
+ };
614
620
  };
615
621
  }
616
622
  /**
@@ -645,6 +651,8 @@ interface BookingSuccessPageData {
645
651
  * 活动标题
646
652
  */
647
653
  event?: string;
654
+ contactUs?: string;
655
+ contactUsLink?: string;
648
656
  /**
649
657
  * Demo Room 标题
650
658
  */
@@ -665,6 +673,10 @@ interface BookingSuccessPageData {
665
673
  * 取消预约按钮
666
674
  */
667
675
  cancelAppointment?: string;
676
+ /**
677
+ * 改变领取状态按钮(门店店员身份时显示)
678
+ */
679
+ changeStatusButton?: string;
668
680
  /**
669
681
  * 编辑预约按钮
670
682
  */
package/dist/index.d.ts CHANGED
@@ -611,6 +611,12 @@ interface BookingFormPageData {
611
611
  emailDescription?: string;
612
612
  dealsType?: string;
613
613
  agrees?: string[];
614
+ fieldRuquired?: string;
615
+ agreeRuquired?: string;
616
+ emailValidError?: string;
617
+ errorMsg?: {
618
+ [key: string]: string;
619
+ };
614
620
  };
615
621
  }
616
622
  /**
@@ -645,6 +651,8 @@ interface BookingSuccessPageData {
645
651
  * 活动标题
646
652
  */
647
653
  event?: string;
654
+ contactUs?: string;
655
+ contactUsLink?: string;
648
656
  /**
649
657
  * Demo Room 标题
650
658
  */
@@ -665,6 +673,10 @@ interface BookingSuccessPageData {
665
673
  * 取消预约按钮
666
674
  */
667
675
  cancelAppointment?: string;
676
+ /**
677
+ * 改变领取状态按钮(门店店员身份时显示)
678
+ */
679
+ changeStatusButton?: string;
668
680
  /**
669
681
  * 编辑预约按钮
670
682
  */
package/dist/index.js CHANGED
@@ -10867,7 +10867,9 @@ var QuestionnaireForm2 = ({
10867
10867
  error,
10868
10868
  initialResponses
10869
10869
  }) => {
10870
- const [responses, setResponses] = React15.useState(() => initialResponses || {});
10870
+ const [responses, setResponses] = React15.useState(
10871
+ () => initialResponses || {}
10872
+ );
10871
10873
  const [errors, setErrors] = React15.useState({});
10872
10874
  const [agreements, setAgreements] = React15.useState({});
10873
10875
  const [agreementError, setAgreementError] = React15.useState("");
@@ -10889,8 +10891,12 @@ var QuestionnaireForm2 = ({
10889
10891
  });
10890
10892
  return seeded;
10891
10893
  });
10892
- const prevHasBookedBeforeRef = React15.useRef(initialResponses?.["has_booked_before"] === "option2");
10893
- const hasBookedBeforeInitialized = React15.useRef(!!initialResponses?.["has_booked_before"]);
10894
+ const prevHasBookedBeforeRef = React15.useRef(
10895
+ initialResponses?.["has_booked_before"] === "option2"
10896
+ );
10897
+ const hasBookedBeforeInitialized = React15.useRef(
10898
+ !!initialResponses?.["has_booked_before"]
10899
+ );
10894
10900
  const hasBookedBeforeQuestion = questions.find(
10895
10901
  (q) => (q.key || q.id) === "has_booked_before"
10896
10902
  );
@@ -10980,7 +10986,7 @@ var QuestionnaireForm2 = ({
10980
10986
  if (!emailRegex.test(value)) {
10981
10987
  setErrors((prev) => ({
10982
10988
  ...prev,
10983
- [questionId]: "Please enter a valid email address"
10989
+ [questionId]: pageData?.emailValidError || "Please enter a valid email address"
10984
10990
  }));
10985
10991
  }
10986
10992
  };
@@ -11018,7 +11024,7 @@ var QuestionnaireForm2 = ({
11018
11024
  const questionId = getQuestionId(question);
11019
11025
  const value = responses[questionId];
11020
11026
  if (!value || Array.isArray(value) && value.length === 0) {
11021
- newErrors[questionId] = "This field is required";
11027
+ newErrors[questionId] = pageData?.fieldRuquired || "This field is required";
11022
11028
  }
11023
11029
  }
11024
11030
  });
@@ -11029,7 +11035,7 @@ var QuestionnaireForm2 = ({
11029
11035
  );
11030
11036
  if (!allAgreed) {
11031
11037
  setAgreementError(
11032
- "Please agree to all terms and conditions to continue"
11038
+ pageData?.agreeRuquired || "Please agree to all terms and conditions to continue"
11033
11039
  );
11034
11040
  setErrors(newErrors);
11035
11041
  return false;
@@ -11060,7 +11066,9 @@ var QuestionnaireForm2 = ({
11060
11066
  onSubmit?.(finalResponses);
11061
11067
  } else {
11062
11068
  setTimeout(() => {
11063
- const firstErrorElement = document.querySelector('[data-has-error="true"]');
11069
+ const firstErrorElement = document.querySelector(
11070
+ '[data-has-error="true"]'
11071
+ );
11064
11072
  if (firstErrorElement) {
11065
11073
  firstErrorElement.scrollIntoView({
11066
11074
  behavior: "smooth",
@@ -11416,7 +11424,7 @@ var QuestionnaireForm2 = ({
11416
11424
  children: loading ? pageData?.submitting || "Submitting..." : pageData?.submit || "Submit Booking"
11417
11425
  }
11418
11426
  ),
11419
- error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center w-full p-4", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[#FF4D4D] font-bold", children: error.message }) })
11427
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center w-full p-4", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-[#FF4D4D] font-bold", children: pageData?.errorMsg?.[String(error.code)] || pageData?.errorMsg?.[error.code || ""] || error.message }) })
11420
11428
  ] })
11421
11429
  ] });
11422
11430
  };
@@ -11513,6 +11521,25 @@ var DateTimePicker2 = ({
11513
11521
  });
11514
11522
  return dates;
11515
11523
  }, [timeslotsData, demoRoom?.timezone, timezone5]);
11524
+ React15.useEffect(() => {
11525
+ if (booking || isInitialized || !demoRoom?.timeslots?.length) return;
11526
+ const tz = demoRoom?.timezone || timezone5;
11527
+ const now2 = tz ? dayjs4__default.default().tz(tz) : dayjs4__default.default();
11528
+ const nearestSlot = demoRoom.timeslots.filter((slot) => {
11529
+ const slotTime = tz ? dayjs4__default.default(slot.start_time).tz(tz) : dayjs4__default.default(slot.start_time);
11530
+ return slot.status === "available" && slotTime.isAfter(now2);
11531
+ }).sort((a, b) => {
11532
+ const timeA = tz ? dayjs4__default.default(a.start_time).tz(tz) : dayjs4__default.default(a.start_time);
11533
+ const timeB = tz ? dayjs4__default.default(b.start_time).tz(tz) : dayjs4__default.default(b.start_time);
11534
+ return timeA.unix() - timeB.unix();
11535
+ })[0];
11536
+ if (!nearestSlot) return;
11537
+ const nearestDate = tz ? dayjs4__default.default(nearestSlot.start_time).tz(tz) : dayjs4__default.default(nearestSlot.start_time);
11538
+ setSelectedDate(nearestDate);
11539
+ setCalendarValue(nearestDate);
11540
+ setSelectedTimeslotId(nearestSlot.id);
11541
+ setIsInitialized(true);
11542
+ }, [booking, isInitialized, demoRoom?.timeslots, demoRoom?.timezone, timezone5]);
11516
11543
  React15.useEffect(() => {
11517
11544
  if (!timeslotsData?.timeslots || isInitialized) return;
11518
11545
  const tz = demoRoom?.timezone || timezone5;
@@ -11578,22 +11605,34 @@ var DateTimePicker2 = ({
11578
11605
  return `${start} - ${end}`;
11579
11606
  };
11580
11607
  React15.useEffect(() => {
11581
- if (!booking || hasResolvedBookingSlot || !timeslotsData?.timeslots?.length) return;
11608
+ if (!booking?.booking_date) return;
11609
+ setSelectedDate(dayjs4__default.default(booking.booking_date));
11610
+ setCalendarValue(dayjs4__default.default(booking.booking_date));
11611
+ setIsInitialized(true);
11612
+ if (booking.timeslot_id) {
11613
+ setSelectedTimeslotId(booking.timeslot_id);
11614
+ setHasResolvedBookingSlot(true);
11615
+ }
11616
+ }, [booking?.booking_date, booking?.timeslot_id]);
11617
+ React15.useEffect(() => {
11618
+ if (!booking || hasResolvedBookingSlot || !dayTimeslots.length) return;
11582
11619
  if (booking.timeslot_id) {
11583
11620
  setSelectedTimeslotId(booking.timeslot_id);
11584
11621
  setHasResolvedBookingSlot(true);
11585
11622
  return;
11586
11623
  }
11587
- if (booking.time_slot) {
11588
- const match = timeslotsData.timeslots.find(
11589
- (slot) => formatTimeslot(slot) === booking.time_slot
11590
- );
11591
- if (match) {
11592
- setSelectedTimeslotId(match.id);
11593
- setHasResolvedBookingSlot(true);
11594
- }
11624
+ if (!booking.time_slot) return;
11625
+ const tz = demoRoom?.timezone || timezone5;
11626
+ const target = booking.time_slot.replace(/\s+/g, "");
11627
+ const match = dayTimeslots.find((slot) => {
11628
+ const toHm = (iso) => (tz ? dayjs4__default.default(iso).tz(tz) : dayjs4__default.default(iso)).format("HH:mm");
11629
+ return `${toHm(slot.start_time)}-${toHm(slot.end_time)}` === target;
11630
+ });
11631
+ if (match) {
11632
+ setSelectedTimeslotId(match.id);
11633
+ setHasResolvedBookingSlot(true);
11595
11634
  }
11596
- }, [booking, timeslotsData, hasResolvedBookingSlot]);
11635
+ }, [booking, dayTimeslots, hasResolvedBookingSlot, demoRoom?.timezone, timezone5]);
11597
11636
  const initialResponses = React15.useMemo(() => {
11598
11637
  if (!booking) return void 0;
11599
11638
  return {
@@ -12500,6 +12539,9 @@ var BookingFormO2O = ({
12500
12539
  const [selectedPurposeType, setSelectedPurposeType] = React15.useState(
12501
12540
  () => initialBusinessType || purposeOptions[0]?.type || ""
12502
12541
  );
12542
+ const [isPurposeConfirmed, setIsPurposeConfirmed] = React15.useState(
12543
+ () => !!initialBusinessType && purposeOptions.some((item) => item.type === initialBusinessType)
12544
+ );
12503
12545
  React15.useEffect(() => {
12504
12546
  setSelectedPurposeType((currentType) => {
12505
12547
  if (purposeOptions.some((item) => item.type === currentType)) {
@@ -12513,11 +12555,16 @@ var BookingFormO2O = ({
12513
12555
  }
12514
12556
  return purposeOptions[0]?.type || "";
12515
12557
  });
12558
+ const resolvedFromExplicitSource = !!initialBusinessType && purposeOptions.some((item) => item.type === initialBusinessType) || !!booking?.business_type && purposeOptions.some((item) => item.type === booking.business_type);
12559
+ if (resolvedFromExplicitSource) {
12560
+ setIsPurposeConfirmed(true);
12561
+ }
12516
12562
  }, [purposeOptions, initialBusinessType, booking?.business_type]);
12517
12563
  const selectedPurpose = React15.useMemo(() => {
12518
- return purposeOptions.find((item) => item.type === selectedPurposeType) || purposeOptions[0];
12564
+ return purposeOptions.find((item) => item.type === selectedPurposeType) || {};
12519
12565
  }, [purposeOptions, selectedPurposeType]);
12520
- const selectedPodContent = selectedPurpose?.podContent;
12566
+ const isPodSelected = isPurposeConfirmed && selectedPurpose?.type === "pod";
12567
+ const selectedPodContent = isPodSelected ? selectedPurpose?.podContent : void 0;
12521
12568
  const selectedPodDescription = getPodContentDescription(selectedPodContent);
12522
12569
  const podDesignId = React15.useMemo(() => getQueryParam("design_id"), []);
12523
12570
  const isPodDesignEditMode = !!podDesignId || !!booking?.design_project_id;
@@ -12599,85 +12646,95 @@ var BookingFormO2O = ({
12599
12646
  }
12600
12647
  ) }),
12601
12648
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-[#f5f5f5]", children: [
12602
- !!purposeOptions.length && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("py-[40px] l:py-[24px]", className), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-[16px] l:grid-cols-1", children: [
12603
- /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "rounded-[16px] bg-white px-[28px] py-[24px] l:px-[16px] l:py-[20px]", children: [
12604
- /* @__PURE__ */ jsxRuntime.jsx(
12605
- "label",
12606
- {
12607
- htmlFor: "booking-purpose-select",
12608
- className: "block text-[16px] font-bold text-[#080A0F] l:text-[14px]",
12609
- children: getPurposeLabel(pageData)
12610
- }
12611
- ),
12612
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative mt-[14px]", children: [
12613
- /* @__PURE__ */ jsxRuntime.jsx(
12614
- "select",
12615
- {
12616
- id: "booking-purpose-select",
12617
- value: selectedPurpose?.type || "",
12618
- onChange: (event2) => {
12619
- setSelectedPurposeType(event2.target.value);
12620
- },
12621
- disabled: !!token,
12622
- className: cn(
12623
- "h-[48px] w-full appearance-none rounded-[8px] border border-[#D9DCE1] bg-white px-[16px] pr-[48px] text-[16px] font-medium text-[#2A2C32] outline-none transition-colors focus:border-[#080A0F] focus:ring-2 focus:ring-[#3ADB67]/30 l:text-[14px]",
12624
- token && "pointer-events-none cursor-not-allowed opacity-50"
12625
- ),
12626
- children: purposeOptions.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
12627
- "option",
12628
- {
12629
- value: item.type || "",
12630
- children: item.label || item.type
12631
- },
12632
- `${item.type || item.label || "purpose"}-${index}`
12633
- ))
12634
- }
12635
- ),
12636
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none absolute right-[14px] top-1/2 flex -translate-y-1/2 text-[#080A0F]", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronIcon2, {}) })
12637
- ] }),
12638
- !!selectedPurpose?.purposeNote && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-[16px] max-w-[720px] text-[14px] font-medium leading-[1.35] text-[#080A0F] l:text-[13px]", children: selectedPurpose.purposeNote })
12639
- ] }),
12640
- selectedPurpose?.type === "pod" && !!selectedPodContent && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "rounded-[16px] bg-white px-[28px] py-[20px] l:px-[16px] l:py-[20px]", children: [
12641
- !!selectedPodContent.title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-[16px] font-bold text-[#080A0F] l:text-[14px]", children: selectedPodContent.title }),
12642
- !!selectedPodDescription && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-[6px] text-[13px] font-medium leading-[1.35] text-[#080A0F] l:text-[12px]", children: selectedPodDescription }),
12643
- !!selectedPodImage && /* @__PURE__ */ jsxRuntime.jsx(
12644
- "img",
12645
- {
12646
- src: selectedPodImage,
12647
- alt: selectedPodContent.imageAlt || selectedPodContent.title || "",
12648
- className: "mt-[12px] h-[220px] rounded-[8px] object-cover l:h-auto"
12649
- }
12649
+ !!purposeOptions.length && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("py-[40px] l:py-[24px]", className), children: /* @__PURE__ */ jsxRuntime.jsxs(
12650
+ "div",
12651
+ {
12652
+ className: cn(
12653
+ "grid gap-[16px] l:grid-cols-1",
12654
+ isPodSelected && "grid-cols-2"
12650
12655
  ),
12651
- !!selectedPodButtonText && /* @__PURE__ */ jsxRuntime.jsxs(
12652
- "a",
12653
- {
12654
- href: selectedPodButtonLink || "#",
12655
- "aria-disabled": isPodButtonDisabled,
12656
- tabIndex: isPodButtonDisabled ? -1 : void 0,
12657
- onClick: (event2) => {
12658
- if (isPodButtonDisabled) event2.preventDefault();
12659
- },
12660
- rel: "noopener noreferrer",
12661
- className: cn(
12662
- "mt-[12px] inline-flex h-[42px] items-center justify-center gap-[6px] rounded-full bg-[#080A0F] px-[24px] text-[14px] font-bold text-white transition-colors hover:bg-[#2A2C32]",
12663
- isPodButtonDisabled && "pointer-events-none cursor-not-allowed opacity-50"
12656
+ children: [
12657
+ /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "rounded-[16px] bg-white px-[28px] py-[24px] l:px-[16px] l:py-[20px]", children: [
12658
+ /* @__PURE__ */ jsxRuntime.jsx(
12659
+ "label",
12660
+ {
12661
+ htmlFor: "booking-purpose-select",
12662
+ className: "block text-[16px] font-bold text-[#080A0F] l:text-[14px]",
12663
+ children: getPurposeLabel(pageData)
12664
+ }
12664
12665
  ),
12665
- children: [
12666
- selectedPodButtonIcon && /* @__PURE__ */ jsxRuntime.jsx(
12667
- "img",
12666
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative mt-[14px]", children: [
12667
+ /* @__PURE__ */ jsxRuntime.jsx(
12668
+ "select",
12668
12669
  {
12669
- src: selectedPodButtonIcon,
12670
- alt: "",
12671
- className: "h-[16px] w-[16px]",
12672
- "aria-hidden": "true"
12670
+ id: "booking-purpose-select",
12671
+ value: selectedPurpose?.type || "",
12672
+ onChange: (event2) => {
12673
+ setSelectedPurposeType(event2.target.value);
12674
+ setIsPurposeConfirmed(true);
12675
+ },
12676
+ disabled: !!token,
12677
+ className: cn(
12678
+ "h-[48px] w-full appearance-none rounded-[8px] border border-[#D9DCE1] bg-white px-[16px] pr-[48px] text-[16px] font-medium text-[#2A2C32] outline-none transition-colors focus:border-[#080A0F] focus:ring-2 focus:ring-[#3ADB67]/30 l:text-[14px]",
12679
+ token && "pointer-events-none cursor-not-allowed opacity-50"
12680
+ ),
12681
+ children: purposeOptions.map((item, index) => /* @__PURE__ */ jsxRuntime.jsx(
12682
+ "option",
12683
+ {
12684
+ value: item.type || "",
12685
+ children: item.label || item.type
12686
+ },
12687
+ `${item.type || item.label || "purpose"}-${index}`
12688
+ ))
12673
12689
  }
12674
12690
  ),
12675
- selectedPodButtonText
12676
- ]
12677
- }
12678
- )
12679
- ] })
12680
- ] }) }),
12691
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "pointer-events-none absolute right-[14px] top-1/2 flex -translate-y-1/2 text-[#080A0F]", children: /* @__PURE__ */ jsxRuntime.jsx(ChevronIcon2, {}) })
12692
+ ] }),
12693
+ !!selectedPurpose?.purposeNote && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-[16px] max-w-[720px] text-[14px] font-medium leading-[1.35] text-[#080A0F] l:text-[13px]", children: selectedPurpose.purposeNote })
12694
+ ] }),
12695
+ isPodSelected && !!selectedPodContent && /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "rounded-[16px] bg-white px-[28px] py-[20px] l:px-[16px] l:py-[20px]", children: [
12696
+ !!selectedPodContent.title && /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-[16px] font-bold text-[#080A0F] l:text-[14px]", children: selectedPodContent.title }),
12697
+ !!selectedPodDescription && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-[6px] text-[13px] font-medium leading-[1.35] text-[#080A0F] l:text-[12px]", children: selectedPodDescription }),
12698
+ !!selectedPodImage && /* @__PURE__ */ jsxRuntime.jsx(
12699
+ "img",
12700
+ {
12701
+ src: selectedPodImage,
12702
+ alt: selectedPodContent.imageAlt || selectedPodContent.title || "",
12703
+ className: "mt-[12px] h-[220px] rounded-[8px] object-cover l:h-auto"
12704
+ }
12705
+ ),
12706
+ !!selectedPodButtonText && (booking?.print_status === "unprinted" && booking?.design_project_id || !token) && /* @__PURE__ */ jsxRuntime.jsxs(
12707
+ "a",
12708
+ {
12709
+ href: selectedPodButtonLink || "#",
12710
+ "aria-disabled": isPodButtonDisabled,
12711
+ tabIndex: isPodButtonDisabled ? -1 : void 0,
12712
+ onClick: (event2) => {
12713
+ if (isPodButtonDisabled) event2.preventDefault();
12714
+ },
12715
+ rel: "noopener noreferrer",
12716
+ className: cn(
12717
+ "mt-[12px] inline-flex h-[42px] items-center justify-center gap-[6px] rounded-full bg-[#080A0F] px-[24px] text-[14px] font-bold text-white transition-colors hover:bg-[#2A2C32]",
12718
+ isPodButtonDisabled && "pointer-events-none cursor-not-allowed opacity-50"
12719
+ ),
12720
+ children: [
12721
+ selectedPodButtonIcon && /* @__PURE__ */ jsxRuntime.jsx(
12722
+ "img",
12723
+ {
12724
+ src: selectedPodButtonIcon,
12725
+ alt: "",
12726
+ className: "h-[16px] w-[16px]",
12727
+ "aria-hidden": "true"
12728
+ }
12729
+ ),
12730
+ selectedPodButtonText
12731
+ ]
12732
+ }
12733
+ )
12734
+ ] })
12735
+ ]
12736
+ }
12737
+ ) }),
12681
12738
  /* @__PURE__ */ jsxRuntime.jsx("div", { className, children: /* @__PURE__ */ jsxRuntime.jsx(
12682
12739
  DateTimePicker_default2,
12683
12740
  {
@@ -12747,10 +12804,14 @@ var BookingSuccessO2O = ({
12747
12804
  const [loading, setLoading] = React15.useState(false);
12748
12805
  const [bookingDesign, setBookingDesign] = React15.useState(null);
12749
12806
  const [isCancelled, setIsCancelled] = React15.useState(false);
12807
+ const [isPending, setIsPending] = React15.useState(false);
12750
12808
  const [showCancelDialog, setShowCancelDialog] = React15.useState(false);
12751
12809
  const [cancelLoading, setCancelLoading] = React15.useState(false);
12752
12810
  const [cancelError, setCancelError] = React15.useState(null);
12811
+ const [checkinLoading, setCheckinLoading] = React15.useState(false);
12812
+ const [checkinError, setCheckinError] = React15.useState(null);
12753
12813
  const qrCodeContainerRef = React15.useRef(null);
12814
+ const isStore = Boolean(isStoreUser);
12754
12815
  const handlePrintQRCode = () => {
12755
12816
  const canvas = qrCodeContainerRef.current?.querySelector("canvas");
12756
12817
  const qrImageSrc = canvas?.toDataURL("image/png");
@@ -12788,16 +12849,30 @@ var BookingSuccessO2O = ({
12788
12849
  const subtitle = iframeDoc.createElement("p");
12789
12850
  subtitle.textContent = pageData.podData?.QRCodeSubTitle || "";
12790
12851
  const image = iframeDoc.createElement("img");
12791
- image.src = qrImageSrc;
12792
12852
  image.alt = "QR Code";
12793
12853
  iframeDoc.body.appendChild(title);
12794
12854
  iframeDoc.body.appendChild(subtitle);
12795
12855
  iframeDoc.body.appendChild(image);
12796
- iframe.contentWindow?.focus();
12797
- iframe.contentWindow?.print();
12798
- setTimeout(() => {
12799
- document.body.removeChild(iframe);
12800
- }, 1e3);
12856
+ const doPrint = () => {
12857
+ iframe.contentWindow?.focus();
12858
+ iframe.contentWindow?.print();
12859
+ setTimeout(() => {
12860
+ document.body.removeChild(iframe);
12861
+ }, 1e3);
12862
+ };
12863
+ let printed = false;
12864
+ const triggerPrintOnce = () => {
12865
+ if (printed) return;
12866
+ printed = true;
12867
+ doPrint();
12868
+ };
12869
+ image.onload = triggerPrintOnce;
12870
+ image.onerror = triggerPrintOnce;
12871
+ setTimeout(triggerPrintOnce, 1500);
12872
+ image.src = qrImageSrc;
12873
+ if (image.complete) {
12874
+ triggerPrintOnce();
12875
+ }
12801
12876
  };
12802
12877
  React15.useEffect(() => {
12803
12878
  if (token && apiConfig && !initialBookingData) {
@@ -12808,6 +12883,7 @@ var BookingSuccessO2O = ({
12808
12883
  const booking = await apiClient.getBooking(token, apiConfig.locale);
12809
12884
  setBookingData(booking);
12810
12885
  setIsCancelled(booking.status === "cancelled");
12886
+ setIsPending(booking.status === "pending");
12811
12887
  } catch (err) {
12812
12888
  console.error("Failed to fetch booking data:", err);
12813
12889
  } finally {
@@ -12871,6 +12947,33 @@ var BookingSuccessO2O = ({
12871
12947
  setCancelLoading(false);
12872
12948
  }
12873
12949
  };
12950
+ const handleCheckin = async () => {
12951
+ if (!token || !apiConfig) {
12952
+ setCheckinError(
12953
+ pageData.cancelError || "Unable to check in: Missing token or API configuration"
12954
+ );
12955
+ return;
12956
+ }
12957
+ setCheckinLoading(true);
12958
+ setCheckinError(null);
12959
+ try {
12960
+ const apiClient = createDemoRoomApi(apiConfig);
12961
+ const checkedInBooking = await apiClient.checkinBooking({
12962
+ booking_token: token
12963
+ });
12964
+ if (checkedInBooking) {
12965
+ setBookingData(checkedInBooking);
12966
+ window.location.reload();
12967
+ }
12968
+ } catch (err) {
12969
+ console.error("Failed to check in booking:", err);
12970
+ setCheckinError(
12971
+ pageData.cancelError || "Failed to check in. Please try again."
12972
+ );
12973
+ } finally {
12974
+ setCheckinLoading(false);
12975
+ }
12976
+ };
12874
12977
  if (loading) {
12875
12978
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `min-h-screen py-12 px-6 ${className || ""}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "animate-pulse space-y-6", children: [
12876
12979
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-8 bg-gray-200 rounded w-1/3" }),
@@ -12890,21 +12993,33 @@ var BookingSuccessO2O = ({
12890
12993
  bookingDesign?.order_code;
12891
12994
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `min-h-screen l:py-0 l:px-0 py-12 px-6 ${className || ""}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto", children: [
12892
12995
  /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-[48px] xxl:text-[32px] font-bold text-[#080A0F] mb-8 print:hidden", children: pageData.yourAppointment }),
12893
- isCancelled && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-[16px] l:items-start p-6 mb-4 l:gap-2 flex l:flex-col items-center justify-between print:hidden", children: [
12996
+ isCancelled && !isStore && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-[16px] l:items-start l:p-3 p-6 mb-4 l:gap-2 flex l:flex-col items-center justify-between print:hidden", children: [
12894
12997
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base text-[#080A0F]", children: pageData.appointmentCanceled }),
12895
- onScheduleAgain && bookingData && /* @__PURE__ */ jsxRuntime.jsx(
12896
- "button",
12897
- {
12898
- onClick: () => onScheduleAgain(bookingData.demoroom_code),
12899
- className: "px-6 py-3 text-[16px] bg-black text-white rounded-full hover:bg-gray-800 transition-colors whitespace-nowrap",
12900
- children: pageData.scheduleAgain
12901
- }
12902
- )
12998
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center l:gap-2 gap-4", children: [
12999
+ !!pageData.contactUs && /* @__PURE__ */ jsxRuntime.jsx(
13000
+ "a",
13001
+ {
13002
+ href: pageData?.contactUsLink,
13003
+ target: "_blank",
13004
+ className: "text-[14px] cursor-pointer w-fit rounded-full text-[#080A0F] border-2 border-[#080A0F] px-[20px] l:px-[12px] py-[10px] leading-[1] hover:bg-gray-50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
13005
+ rel: "noreferrer",
13006
+ children: pageData.contactUs
13007
+ }
13008
+ ),
13009
+ onScheduleAgain && bookingData && /* @__PURE__ */ jsxRuntime.jsx(
13010
+ "button",
13011
+ {
13012
+ onClick: () => onScheduleAgain(bookingData.demoroom_code),
13013
+ className: "text-[14px] cursor-pointer w-fit bg-black text-white rounded-full hover:bg-gray-800 border-2 border-[#080A0F] px-[20px] l:px-[12px] py-[10px] leading-[1] transition-colors",
13014
+ children: pageData.scheduleAgain
13015
+ }
13016
+ )
13017
+ ] })
12903
13018
  ] }),
12904
13019
  /* @__PURE__ */ jsxRuntime.jsxs(
12905
13020
  "div",
12906
13021
  {
12907
- className: bookingData.business_type === "pod" ? "grid grid-cols-2 gap-[16px] l:grid-cols-1 print:grid-cols-1" : "",
13022
+ className: bookingData.business_type === "pod" && !isCancelled && !isStore ? "grid grid-cols-2 gap-[16px] l:grid-cols-1 print:grid-cols-1" : "",
12908
13023
  children: [
12909
13024
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-8 bg-white px-[48px] l:px-[16px] l:py-[16px] py-[32px] rounded-[16px] print:hidden", children: [
12910
13025
  /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
@@ -13016,7 +13131,7 @@ var BookingSuccessO2O = ({
13016
13131
  ] })
13017
13132
  ] })
13018
13133
  ] }),
13019
- bookingData.business_type === "pod" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-[16px] px-[48px] l:px-[16px] l:py-[16px] py-[32px] flex flex-col items-center justify-center text-center print:w-full", children: [
13134
+ bookingData.business_type === "pod" && !isStore && !isCancelled && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-[16px] px-[48px] l:px-[16px] l:py-[16px] py-[32px] flex flex-col items-center justify-center text-center print:w-full", children: [
13020
13135
  /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-[24px] l:text-[20px] text-[#4A4C56] text-center", children: pageData.podData?.QRCodeTitle }),
13021
13136
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-gray-500 text-center mt-2", children: pageData.podData?.QRCodeSubTitle }),
13022
13137
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -13034,19 +13149,19 @@ var BookingSuccessO2O = ({
13034
13149
  }
13035
13150
  ),
13036
13151
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-center gap-3 mt-6 print:hidden", children: [
13037
- /* @__PURE__ */ jsxRuntime.jsx(
13152
+ !!pageData.podData?.btnToWallet && /* @__PURE__ */ jsxRuntime.jsx(
13038
13153
  "button",
13039
13154
  {
13040
13155
  onClick: () => onAddToWallet?.(bookingData),
13041
- className: "rounded-full border-2 border-[#080A0F] px-[20px] py-[10px] text-[14px] hover:bg-gray-50 transition-colors",
13156
+ className: "text-[14px] cursor-pointer w-fit rounded-full text-[#080A0F] border-2 border-[#080A0F] px-[20px] py-[10px] leading-[1] hover:bg-gray-50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
13042
13157
  children: pageData.podData?.btnToWallet
13043
13158
  }
13044
13159
  ),
13045
- /* @__PURE__ */ jsxRuntime.jsx(
13160
+ !!pageData.podData?.btnToPrint && /* @__PURE__ */ jsxRuntime.jsx(
13046
13161
  "button",
13047
13162
  {
13048
13163
  onClick: handlePrintQRCode,
13049
- className: "rounded-full border-2 border-[#080A0F] px-[20px] py-[10px] text-[14px] hover:bg-gray-50 transition-colors",
13164
+ className: "text-[14px] cursor-pointer w-fit rounded-full text-[#080A0F] border-2 border-[#080A0F] px-[20px] py-[10px] leading-[1] hover:bg-gray-50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
13050
13165
  children: pageData.podData?.btnToPrint
13051
13166
  }
13052
13167
  )
@@ -13055,8 +13170,8 @@ var BookingSuccessO2O = ({
13055
13170
  ]
13056
13171
  }
13057
13172
  ),
13058
- !isCancelled && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-[64px] print:hidden", children: [
13059
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
13173
+ isPending && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-[64px] pb-4 print:hidden", children: [
13174
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex md:w-full gap-4 md:flex-col md:items-center md:justify-center", children: [
13060
13175
  onEditBooking && token && /* @__PURE__ */ jsxRuntime.jsx(
13061
13176
  "button",
13062
13177
  {
@@ -13065,7 +13180,7 @@ var BookingSuccessO2O = ({
13065
13180
  bookingData.demoroom_code,
13066
13181
  bookingData.business_type
13067
13182
  ),
13068
- className: "text-[14px] cursor-pointer w-fit rounded-full text-[#080A0F] border-2 border-[#080A0F] px-[20px] py-[10px] leading-[1] hover:bg-gray-50 transition-colors",
13183
+ className: "text-[14px] cursor-pointer w-fit bg-black text-white rounded-full hover:bg-gray-800 border-2 border-[#080A0F] l:px-[12px] px-[20px] py-[10px] leading-[1] transition-colors",
13069
13184
  children: pageData.editAppointment
13070
13185
  }
13071
13186
  ),
@@ -13074,13 +13189,25 @@ var BookingSuccessO2O = ({
13074
13189
  {
13075
13190
  onClick: () => setShowCancelDialog(true),
13076
13191
  disabled: cancelLoading,
13077
- className: "text-[14px] cursor-pointer w-fit rounded-full text-[#080A0F] border-2 border-[#080A0F] px-[20px] py-[10px] leading-[1] hover:bg-gray-50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
13192
+ className: "text-[14px] cursor-pointer w-fit rounded-full text-[#080A0F] border-2 border-[#080A0F] px-[20px] l:px-[12px] py-[10px] leading-[1] hover:bg-gray-50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
13078
13193
  children: pageData.cancelAppointment
13079
13194
  }
13080
13195
  )
13081
- ] }),
13196
+ ] }) }),
13082
13197
  cancelError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm mt-2", style: { color: "#FF4D4D" }, children: cancelError })
13083
13198
  ] }),
13199
+ isStore && bookingData?.print_status === "completed" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-[64px] pb-4 print:hidden", children: [
13200
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsx(
13201
+ "button",
13202
+ {
13203
+ onClick: handleCheckin,
13204
+ disabled: checkinLoading,
13205
+ className: "text-[14px] cursor-pointer w-fit rounded-full text-[#080A0F] border-2 border-[#080A0F] px-[20px] l:px-[12px] py-[10px] leading-[1] hover:bg-gray-50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
13206
+ children: pageData.changeStatusButton || "Change Pickup Status"
13207
+ }
13208
+ ) }),
13209
+ checkinError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm mt-2", style: { color: "#FF4D4D" }, children: checkinError })
13210
+ ] }),
13084
13211
  showCancelDialog && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 px-4 print:hidden", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-white rounded-[24px] max-w-[600px] p-8 shadow-xl relative", children: [
13085
13212
  /* @__PURE__ */ jsxRuntime.jsx(
13086
13213
  "button",