@ticketboothapp/booking 1.2.62 → 1.2.63

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.
@@ -11,7 +11,6 @@ import {
11
11
  quoteChangeBooking,
12
12
  confirmFreeChangeBooking,
13
13
  createChangeBookingPaymentIntent,
14
- confirmBookingWithoutPayment,
15
14
  getAddOns,
16
15
  validatePromoCode,
17
16
  getPromoDiscount,
@@ -33,7 +32,6 @@ import {
33
32
  } from '../../lib/booking-constants';
34
33
  import { getSundayOfWeek } from '../../lib/booking/sunday-week';
35
34
  import { Calendar } from './Calendar';
36
- import { AdminPaymentChoiceModal } from './AdminPaymentChoiceModal';
37
35
  import { ItineraryBox } from './ItineraryBox';
38
36
  import { ItineraryPlaceholder } from './ItineraryPlaceholder';
39
37
  import { PickupTimeSelector } from './PickupTimeSelector';
@@ -98,7 +96,6 @@ import { getItineraryStepLabel } from '../../lib/booking/itinerary-display';
98
96
  import { MANAGE_BOOKING_FROM_CHANGE_PAYMENT, MANAGE_BOOKING_QUERY_FROM } from '../../lib/manage-booking-post-checkout';
99
97
  import { useBookingHost } from '../../runtime';
100
98
  import type { BookingFlowUiOptions } from './booking-flow-ui';
101
- import type { ProviderDashboardChangeBookingPayload } from './provider-dashboard-change-booking';
102
99
  import type { ChangeBookingFlowProps, ChangeFlowSelectionPreview } from './booking-flow-types';
103
100
  import { BOOKING_FLOW_ABANDON_EVENT } from '../../providers/booking-dialog-provider';
104
101
 
@@ -113,7 +110,6 @@ export type { ChangeBookingFlowProps } from './booking-flow-types';
113
110
  *
114
111
  * Until the first successful quote, `selfServeCheckoutPlaceholder` still avoids showing unchecked totals.
115
112
  *
116
- * **Provider dashboard** (`onChangeBooking`) — unchanged; manual pricing via `flowUi.providerDashboardChangePricingUi`.
117
113
  */
118
114
  function mergeQuoteSliceWithServerPreview(
119
115
  slice: ReturnType<typeof sliceChangeQuoteForUi>,
@@ -410,9 +406,8 @@ function pickOutboundMatchingPreviousSelection(
410
406
  anchor: { productOptionId: string | null; minutesFromMidnight: number },
411
407
  companyTimezone: string,
412
408
  optionsMap: Map<string, { mostPopular?: boolean }>,
413
- isAdmin: boolean
414
409
  ): Availability | null {
415
- const selectable = timesForSelectedDate.filter((a) => (a.vacancies ?? 0) > 0 || isAdmin);
410
+ const selectable = timesForSelectedDate.filter((a) => (a.vacancies ?? 0) > 0);
416
411
  if (selectable.length === 0) return null;
417
412
 
418
413
  const withOption =
@@ -446,9 +441,8 @@ function pickReturnMatchingPreviousSelection(
446
441
  sortedReturnOptions: ReturnOption[],
447
442
  anchor: { returnLocation: string; minutesFromMidnight: number },
448
443
  companyTimezone: string,
449
- isAdmin: boolean
450
444
  ): ReturnOption | null {
451
- const eligible = sortedReturnOptions.filter((o) => (o.vacancies ?? 0) > 0 || isAdmin);
445
+ const eligible = sortedReturnOptions.filter((o) => (o.vacancies ?? 0) > 0);
452
446
  if (eligible.length === 0) return null;
453
447
 
454
448
  const sameLoc = eligible.filter((o) => o.returnLocation === anchor.returnLocation);
@@ -637,7 +631,7 @@ function resolveInitialAvailabilityFromBooking(
637
631
  }
638
632
 
639
633
  /**
640
- * Customer self-serve and provider-dashboard **change booking** only (no standard new-booking paths).
634
+ * Customer self-serve **change booking** only (no standard new-booking paths).
641
635
  * Duplicated from {@link NewBookingFlow} intentionally so each flow can evolve independently.
642
636
  */
643
637
  export function ChangeBookingFlow({
@@ -662,7 +656,6 @@ export function ChangeBookingFlow({
662
656
  partnerPortalBooking = false,
663
657
  availabilityPricingProfileId,
664
658
  availabilityCancellationPolicyProfileId,
665
- onChangeBooking,
666
659
  }: ChangeBookingFlowProps) {
667
660
  /** Always the booking’s sold currency — not the site currency switcher / parent default. */
668
661
  const currency = useMemo((): Currency => {
@@ -674,16 +667,6 @@ export function ChangeBookingFlow({
674
667
  return DEFAULT_CURRENCY;
675
668
  }, [originalReceipt?.currency, initialValues?.currency, currencyFromParent]);
676
669
 
677
- const isManualOverrideEligibleLine = (line: { editable: boolean; type?: string; label?: string }): boolean => {
678
- if (!line.editable) return false;
679
- const type = (line.type ?? '').toUpperCase();
680
- const label = (line.label ?? '').toLowerCase();
681
- const isPromoLikeType =
682
- type.includes('PROMO') || type.includes('DISCOUNT') || type.includes('VOUCHER') || type.includes('GIFT');
683
- const isPromoLikeLabel =
684
- label.includes('promo') || label.includes('discount') || label.includes('voucher') || label.includes('gift');
685
- return !(isPromoLikeType || isPromoLikeLabel);
686
- };
687
670
  const { env, analytics } = useBookingHost();
688
671
  const { t } = useTranslations();
689
672
  const { locale } = useLocale();
@@ -692,15 +675,12 @@ export function ChangeBookingFlow({
692
675
  const cancellationPolicyProfileIdForAvailabilities =
693
676
  (availabilityCancellationPolicyProfileId ?? '').trim() || null;
694
677
  const {
695
- permissions,
696
678
  isSimplifiedPricingView,
697
679
  onShowManage,
698
680
  getSuccessUrl,
699
681
  suppressCalendarDateScroll,
700
- mode: bookingAppMode,
701
682
  } = useBookingApp();
702
683
  const availabilitiesCache = useAvailabilitiesCache();
703
- const isAdmin = permissions.viewerRole === 'admin';
704
684
  const [availabilities, setAvailabilities] = useState<Availability[]>([]);
705
685
  const [selectedAvailability, setSelectedAvailability] = useState<Availability | null>(null);
706
686
  const [selectedReturnOption, setSelectedReturnOption] = useState<ReturnOption | null>(null);
@@ -799,12 +779,6 @@ export function ChangeBookingFlow({
799
779
  differenceTotal: number;
800
780
  };
801
781
  } | null>(null);
802
- /** Admin only: skip sending confirmation at creation (provider dashboard). */
803
- const [skipConfirmationCommunications, setSkipConfirmationCommunications] = useState(false);
804
- /** Admin only: disable all auto communications for this booking (provider dashboard). */
805
- const [disableAutoCommunications, setDisableAutoCommunications] = useState(false);
806
- /** Admin only: show choice to pay now or confirm without payment (full balance owed). */
807
- const [showAdminPaymentChoice, setShowAdminPaymentChoice] = useState(false);
808
782
  const hasAppliedInitialValuesRef = useRef(false);
809
783
  const hasAppliedInitialQuantitiesRef = useRef(false);
810
784
  const hasHydratedAddOnsFromReceiptRef = useRef(false);
@@ -823,10 +797,8 @@ export function ChangeBookingFlow({
823
797
  return null;
824
798
  }
825
799
  }, [initialValues?.dateTime, companyTimezone]);
826
- const isProviderDashboardChange = Boolean(onChangeBooking);
827
- const isCustomerSelfServeChange = !isProviderDashboardChange;
828
800
  /** Do not render catalog-/FE-derived dollar amounts in UI until `quoteChangeBooking` returns `serverDisplay`. */
829
- const suppressSelfServeCurrencyUi = isCustomerSelfServeChange;
801
+ const suppressSelfServeCurrencyUi = true;
830
802
 
831
803
  useEffect(() => {
832
804
  setPartnerAttributionConfirmed(false);
@@ -836,13 +808,13 @@ export function ChangeBookingFlow({
836
808
  * user picks a different return time — baseline is the first auto-selected return for this outbound.
837
809
  */
838
810
  const [implicitReturnBaselineId, setImplicitReturnBaselineId] = useState<string | null>(null);
839
- /** Any change flow (self-serve or provider): promo from booking is fixed — show read-only, never add new. */
811
+ /** Promo from booking is fixed — show read-only, never add new. */
840
812
  const lockedPromoCode = initialValues?.promoCode?.trim()
841
813
  ? initialValues.promoCode.trim().toUpperCase()
842
814
  : null;
843
815
  /** Public self-serve only: cannot reduce tickets below original counts. */
844
816
  const changeBookingMinimumQuantities = useMemo(() => {
845
- if (!isCustomerSelfServeChange || !initialValues?.bookingItems?.length) return undefined;
817
+ if (!initialValues?.bookingItems?.length) return undefined;
846
818
  const m: Record<string, number> = {};
847
819
  for (const item of initialValues.bookingItems) {
848
820
  const key = item.category?.trim();
@@ -850,30 +822,7 @@ export function ChangeBookingFlow({
850
822
  m[key] = Math.max(0, Number(item.count) || 0);
851
823
  }
852
824
  return m;
853
- }, [isCustomerSelfServeChange, initialValues?.bookingItems]);
854
- const [adminChoiceData, setAdminChoiceData] = useState<{
855
- reservationReference: string;
856
- reservationExpiration?: string;
857
- checkoutBreakdown: { lineItems: Array<{ label: string; amount: number; type?: string; quantity?: number }>; totalAmount: number; currency: string };
858
- totalAmount: number;
859
- datePart: string;
860
- timePart: string;
861
- availabilityProductOptionId: string;
862
- itineraryDisplay?: ItineraryDisplayStep[] | null;
863
- clientSecret: string;
864
- ticketLinesForModal: CheckoutModalLineItem[];
865
- feeLineItems: OrderSummary['feeLineItems'];
866
- returnPriceAdjustment: number;
867
- cancellationPolicyFee: number;
868
- cancellationPolicyLabel?: string;
869
- subtotal: number;
870
- tax: number;
871
- totalQuantity: number;
872
- isTaxIncludedInPrice: boolean;
873
- taxRate: number;
874
- promoDiscountAmount: number;
875
- discountLabel?: string | null;
876
- } | null>(null);
825
+ }, [initialValues?.bookingItems]);
877
826
  const [latestChangeQuote, setLatestChangeQuote] = useState<{
878
827
  priceDiff: number;
879
828
  currency: Currency;
@@ -1710,14 +1659,12 @@ export function ChangeBookingFlow({
1710
1659
  }, [initialValues?.productId, product.productId]);
1711
1660
 
1712
1661
  /**
1713
- * Receipt pricing on protected seats/fees — **customer self-serve only**: Rule A (exact receipt unit when same calendar day
1714
- * + same product option) vs Rule B (`max(receipt, live)` when date or option changes). Provider dashboard uses live catalog.
1662
+ * Receipt pricing on protected seats/fees: Rule A (exact receipt unit when same calendar day
1663
+ * + same product option) vs Rule B (`max(receipt, live)` when date or option changes).
1715
1664
  */
1716
1665
  const changeFlowApplyReceiptPaidFloors = useMemo(
1717
- () =>
1718
- !isProviderDashboardChange &&
1719
- changeFlowBookingParentProductIdForFloors === product.productId.trim(),
1720
- [isProviderDashboardChange, changeFlowBookingParentProductIdForFloors, product.productId],
1666
+ () => changeFlowBookingParentProductIdForFloors === product.productId.trim(),
1667
+ [changeFlowBookingParentProductIdForFloors, product.productId],
1721
1668
  );
1722
1669
 
1723
1670
  useEffect(() => {
@@ -1843,27 +1790,27 @@ export function ChangeBookingFlow({
1843
1790
 
1844
1791
  const initialAddOnMinQtyByKey = useMemo(() => {
1845
1792
  const map = new Map<string, number>();
1846
- if (!isCustomerSelfServeChange) return map;
1793
+ if (false) return map;
1847
1794
  for (const sel of initialAddOnBaselineSelections) {
1848
1795
  const key = `${sel.addOnId.trim()}::${sel.variantId?.trim() || ''}`;
1849
1796
  map.set(key, (map.get(key) ?? 0) + Math.max(1, Number(sel.quantity) || 1));
1850
1797
  }
1851
1798
  return map;
1852
- }, [isCustomerSelfServeChange, initialAddOnBaselineSelections]);
1799
+ }, [true, initialAddOnBaselineSelections]);
1853
1800
 
1854
1801
  const initialAddOnMinTotalByAddOnId = useMemo(() => {
1855
1802
  const map = new Map<string, number>();
1856
- if (!isCustomerSelfServeChange) return map;
1803
+ if (false) return map;
1857
1804
  for (const sel of initialAddOnBaselineSelections) {
1858
1805
  const addOnId = sel.addOnId.trim();
1859
1806
  map.set(addOnId, (map.get(addOnId) ?? 0) + Math.max(1, Number(sel.quantity) || 1));
1860
1807
  }
1861
1808
  return map;
1862
- }, [isCustomerSelfServeChange, initialAddOnBaselineSelections]);
1809
+ }, [true, initialAddOnBaselineSelections]);
1863
1810
 
1864
1811
  const applyChangeFlowAddOnFloor = useCallback(
1865
1812
  (nextSelections: Array<{ addOnId: string; variantId?: string; quantity?: number }>) => {
1866
- if (!isCustomerSelfServeChange || initialAddOnMinQtyByKey.size === 0) return nextSelections;
1813
+ if (false || initialAddOnMinQtyByKey.size === 0) return nextSelections;
1867
1814
  const qtyByKey = new Map<string, number>();
1868
1815
  for (const sel of nextSelections) {
1869
1816
  const key = `${sel.addOnId.trim()}::${sel.variantId?.trim() || ''}`;
@@ -1890,7 +1837,7 @@ export function ChangeBookingFlow({
1890
1837
  return { addOnId, variantId, quantity: qty };
1891
1838
  });
1892
1839
  },
1893
- [isCustomerSelfServeChange, initialAddOnMinQtyByKey, initialAddOnMinTotalByAddOnId]
1840
+ [true, initialAddOnMinQtyByKey, initialAddOnMinTotalByAddOnId]
1894
1841
  );
1895
1842
 
1896
1843
  const updateAddOnSelections = useCallback(
@@ -2504,14 +2451,14 @@ export function ChangeBookingFlow({
2504
2451
  const options = selectedAvailability?.returnOptions ?? [];
2505
2452
  const serverReturnMap = latestChangeQuote?.serverPreview?.returnOptionPriceByReturnAvailabilityId;
2506
2453
  const floor = effectiveChangeFlowReturnUnitFloorPerPerson;
2507
- const applyReturnFloor = floor != null && isCustomerSelfServeChange;
2454
+ const applyReturnFloor = floor != null && true;
2508
2455
  return options.map((opt) => {
2509
2456
  const vacancyCredit = changeFlowSeatCreditForReturnAvailabilityId(opt.returnAvailabilityId);
2510
2457
  const adjustedVacancies = Math.max(0, opt.vacancies ?? 0) + vacancyCredit;
2511
2458
  const rawPerPerson = opt.priceAdjustmentByCurrency?.[currency] ?? 0;
2512
2459
  const flooredPerPerson = applyReturnFloor ? Math.max(rawPerPerson, floor) : rawPerPerson;
2513
2460
  let perPerson = flooredPerPerson;
2514
- if (isCustomerSelfServeChange && serverReturnMap && opt.returnAvailabilityId) {
2461
+ if (true && serverReturnMap && opt.returnAvailabilityId) {
2515
2462
  const sid = opt.returnAvailabilityId.trim();
2516
2463
  const sp = serverReturnMap[sid];
2517
2464
  if (sp != null && Number.isFinite(sp)) {
@@ -2534,7 +2481,7 @@ export function ChangeBookingFlow({
2534
2481
  }, [
2535
2482
  selectedAvailability?.returnOptions,
2536
2483
  effectiveChangeFlowReturnUnitFloorPerPerson,
2537
- isCustomerSelfServeChange,
2484
+ true,
2538
2485
  currency,
2539
2486
  changeFlowSeatCreditForReturnAvailabilityId,
2540
2487
  latestChangeQuote?.serverPreview?.returnOptionPriceByReturnAvailabilityId,
@@ -2543,11 +2490,11 @@ export function ChangeBookingFlow({
2543
2490
  const selectedReturnOptionWithFloor = useMemo(() => {
2544
2491
  if (!selectedReturnOption) return selectedReturnOption;
2545
2492
  const floor = effectiveChangeFlowReturnUnitFloorPerPerson;
2546
- const applyReturnFloor = floor != null && isCustomerSelfServeChange;
2493
+ const applyReturnFloor = floor != null && true;
2547
2494
  const rawPerPerson = selectedReturnOption.priceAdjustmentByCurrency?.[currency] ?? 0;
2548
2495
  let perPerson = rawPerPerson;
2549
2496
  const serverReturnMap = latestChangeQuote?.serverPreview?.returnOptionPriceByReturnAvailabilityId;
2550
- if (isCustomerSelfServeChange && serverReturnMap && selectedReturnOption.returnAvailabilityId) {
2497
+ if (true && serverReturnMap && selectedReturnOption.returnAvailabilityId) {
2551
2498
  const sid = selectedReturnOption.returnAvailabilityId.trim();
2552
2499
  const sp = serverReturnMap[sid];
2553
2500
  if (sp != null && Number.isFinite(sp)) {
@@ -2568,7 +2515,7 @@ export function ChangeBookingFlow({
2568
2515
  }, [
2569
2516
  selectedReturnOption,
2570
2517
  effectiveChangeFlowReturnUnitFloorPerPerson,
2571
- isCustomerSelfServeChange,
2518
+ true,
2572
2519
  currency,
2573
2520
  latestChangeQuote?.serverPreview?.returnOptionPriceByReturnAvailabilityId,
2574
2521
  ]);
@@ -2609,7 +2556,7 @@ export function ChangeBookingFlow({
2609
2556
  /** Quote `ticketUnitPriceByCategory` overrides catalog units for ticket rows (customer self-serve only). */
2610
2557
  const pricingForTicketSelector = useMemo(() => {
2611
2558
  const m = latestChangeQuote?.serverPreview?.ticketUnitPriceByCategory;
2612
- if (!isCustomerSelfServeChange || !m) return pricing;
2559
+ if (false || !m) return pricing;
2613
2560
  return pricing.map((r) => {
2614
2561
  const u = m[r.category.toUpperCase()];
2615
2562
  if (u == null || !Number.isFinite(u)) return r;
@@ -2620,7 +2567,7 @@ export function ChangeBookingFlow({
2620
2567
  baseInDisplayCurrency: u,
2621
2568
  };
2622
2569
  });
2623
- }, [pricing, latestChangeQuote?.serverPreview?.ticketUnitPriceByCategory, isCustomerSelfServeChange]);
2570
+ }, [pricing, latestChangeQuote?.serverPreview?.ticketUnitPriceByCategory, true]);
2624
2571
 
2625
2572
  // Price breakdown: mid-layer returns line items (base + one per rule/deal). UI renders each line; rate in brackets when used.
2626
2573
  const getPriceBreakdown = useCallback((category: string, priceCAD: number, baseInDisplayCurrency: number | undefined, appliedAdjustments: Array<{ type: string; id: string; name: string; changeByCurrency?: Record<string, number> }> = []): PriceBreakdownData | null => {
@@ -2725,7 +2672,7 @@ export function ChangeBookingFlow({
2725
2672
 
2726
2673
  // When return selection (or refreshed availabilities) caps the party below current ticket counts, trim tickets (non-admin).
2727
2674
  useEffect(() => {
2728
- if (isAdmin || !selectedAvailability) return;
2675
+ if (false || !selectedAvailability) return;
2729
2676
  const cap = effectivePartySizeCap;
2730
2677
  if (totalQuantity <= cap) return;
2731
2678
  const over = totalQuantity - cap;
@@ -2753,7 +2700,7 @@ export function ChangeBookingFlow({
2753
2700
  effectivePartySizeCap,
2754
2701
  totalQuantity,
2755
2702
  selectedAvailability,
2756
- isAdmin,
2703
+ false,
2757
2704
  changeBookingMinimumQuantities,
2758
2705
  ]);
2759
2706
 
@@ -2827,7 +2774,7 @@ export function ChangeBookingFlow({
2827
2774
  */
2828
2775
  const changeFlowProtectedReturnAdjustment = useMemo(() => {
2829
2776
  if (totalQuantity <= 0) return returnPriceAdjustment;
2830
- if (isProviderDashboardChange) return returnPriceAdjustment;
2777
+ if (false) return returnPriceAdjustment;
2831
2778
  if (effectiveChangeFlowReturnUnitFloorPerPerson == null) return returnPriceAdjustment;
2832
2779
  const livePerPerson =
2833
2780
  returnOptionCatalogPerPerson ?? (selectedReturnOption?.priceAdjustmentByCurrency?.[currency] ?? 0);
@@ -2841,7 +2788,7 @@ export function ChangeBookingFlow({
2841
2788
  }, [
2842
2789
  totalQuantity,
2843
2790
  returnPriceAdjustment,
2844
- isProviderDashboardChange,
2791
+ false,
2845
2792
  effectiveChangeFlowReturnUnitFloorPerPerson,
2846
2793
  selectedReturnOption,
2847
2794
  returnOptionCatalogPerPerson,
@@ -2852,7 +2799,7 @@ export function ChangeBookingFlow({
2852
2799
 
2853
2800
  /** Return row amount for PriceSummary, Stripe breakdown, and CheckoutModal (catalog vs protected same-product-option). */
2854
2801
  const checkoutReturnLineAmount = useMemo(() => {
2855
- if (isCustomerSelfServeChange) {
2802
+ if (true) {
2856
2803
  return changeFlowProtectedReturnAdjustment;
2857
2804
  }
2858
2805
  if (changeFlowApplyReceiptPaidFloors) {
@@ -2860,7 +2807,7 @@ export function ChangeBookingFlow({
2860
2807
  }
2861
2808
  return returnPriceAdjustment;
2862
2809
  }, [
2863
- isCustomerSelfServeChange,
2810
+ true,
2864
2811
  changeFlowApplyReceiptPaidFloors,
2865
2812
  changeFlowProtectedReturnAdjustment,
2866
2813
  returnPriceAdjustment,
@@ -2932,35 +2879,13 @@ export function ChangeBookingFlow({
2932
2879
  return [...feeLineItems, ...addOnLines];
2933
2880
  }, [feeLineItems, addOnSelections, addOns]);
2934
2881
 
2935
- const providerPricingUi = flowUi?.providerDashboardChangePricingUi;
2936
- const providerQuotedLines = providerPricingUi?.quotedLines ?? [];
2937
- const providerEditableLines = providerQuotedLines.filter((line) => isManualOverrideEligibleLine(line));
2938
- const showProviderPricingInlineEditor =
2939
- isProviderDashboardChange && isAdmin && (
2940
- providerPricingUi?.loading ||
2941
- providerPricingUi?.error != null ||
2942
- providerQuotedLines.length > 0
2943
- );
2944
- const normalizeReceiptLabel = (value: string): string =>
2945
- value
2946
- .toLowerCase()
2947
- .replace(/\([^)]*\)/g, '')
2948
- .replace(/[^a-z0-9]+/g, '')
2949
- .trim();
2950
- const providerEditableLineByNormalizedLabel = useMemo(() => {
2951
- const m = new Map<string, (typeof providerEditableLines)[number]>();
2952
- for (const line of providerEditableLines) {
2953
- const key = normalizeReceiptLabel(line.label ?? '');
2954
- if (key) m.set(key, line);
2955
- }
2956
- return m;
2957
- }, [providerEditableLines]);
2958
-
2959
2882
  const checkoutPriceSummaryLines = useMemo((): PriceSummaryLine[] => {
2960
2883
  if (!selectedAvailability) return [];
2961
2884
  const returnLineAmount = checkoutReturnLineAmount;
2885
+ /** Show row when a return is selected and either the priced amount is non-zero or a receipt return floor exists (catalog slot can be $0 while floored total is not). */
2962
2886
  const showReturnLine =
2963
- Boolean(selectedReturnOption) && Math.abs(returnLineAmount) > 0.0005;
2887
+ Boolean(selectedReturnOption) &&
2888
+ (Math.abs(returnLineAmount) > 0.0005 || effectiveChangeFlowReturnUnitFloorPerPerson != null);
2964
2889
  return [
2965
2890
  ...ticketLineItemsForChangeFlowDisplay.map((line): PriceSummaryLine => {
2966
2891
  const rate = pricing.find((r) => r.category === line.category);
@@ -2972,13 +2897,8 @@ export function ChangeBookingFlow({
2972
2897
  );
2973
2898
  return {
2974
2899
  kind: 'ticket',
2975
- lineKey:
2976
- showProviderPricingInlineEditor
2977
- ? providerEditableLineByNormalizedLabel.get(normalizeReceiptLabel(line.category))?.lineKey
2978
- : undefined,
2979
- editable:
2980
- showProviderPricingInlineEditor &&
2981
- providerEditableLineByNormalizedLabel.has(normalizeReceiptLabel(line.category)),
2900
+ lineKey: undefined,
2901
+ editable: false,
2982
2902
  category: line.category,
2983
2903
  qty: line.qty,
2984
2904
  itemTotal: line.itemTotal,
@@ -3013,25 +2933,8 @@ export function ChangeBookingFlow({
3013
2933
  fee.name.toLowerCase().includes('license'));
3014
2934
  return {
3015
2935
  kind: 'line' as const,
3016
- lineKey:
3017
- showProviderPricingInlineEditor
3018
- ? providerEditableLineByNormalizedLabel.get(
3019
- normalizeReceiptLabel(
3020
- feeLineItems.some((f) => f.name === fee.name)
3021
- ? `${fee.name} (${totalQuantity} ${totalQuantity === 1 ? 'person' : 'people'})`
3022
- : fee.name
3023
- )
3024
- )?.lineKey
3025
- : undefined,
3026
- editable:
3027
- showProviderPricingInlineEditor &&
3028
- providerEditableLineByNormalizedLabel.has(
3029
- normalizeReceiptLabel(
3030
- feeLineItems.some((f) => f.name === fee.name)
3031
- ? `${fee.name} (${totalQuantity} ${totalQuantity === 1 ? 'person' : 'people'})`
3032
- : fee.name
3033
- )
3034
- ),
2936
+ lineKey: undefined,
2937
+ editable: false,
3035
2938
  label: feeLineItems.some((f) => f.name === fee.name)
3036
2939
  ? `${fee.name} (${totalQuantity} ${totalQuantity === 1 ? 'person' : 'people'})`
3037
2940
  : fee.name,
@@ -3057,8 +2960,7 @@ export function ChangeBookingFlow({
3057
2960
  effectiveCancellationPolicyLabel,
3058
2961
  feeLineItemsWithAddOns,
3059
2962
  feeLineItems,
3060
- showProviderPricingInlineEditor,
3061
- providerEditableLineByNormalizedLabel,
2963
+ effectiveChangeFlowReturnUnitFloorPerPerson,
3062
2964
  ]);
3063
2965
 
3064
2966
  const checkoutPriceSummaryLinesForCheckout = useMemo(() => {
@@ -3524,62 +3426,31 @@ export function ChangeBookingFlow({
3524
3426
  addOnSelections,
3525
3427
  initialAddOnMinQtyByKey,
3526
3428
  ]);
3527
- const hasChangeSelection =
3528
- isProviderDashboardChange
3529
- ? changeSelectionDetails.hasOperationalChangesFromInitial
3530
- : changeSelectionDetails.hasChangesFromInitial;
3429
+ const hasChangeSelection = changeSelectionDetails.hasChangesFromInitial;
3531
3430
 
3532
3431
  const changeFlowNeedsServerPrice =
3533
- isCustomerSelfServeChange &&
3432
+ true &&
3534
3433
  hasChangeSelection &&
3535
3434
  !!initialValues?.bookingReference?.trim() &&
3536
3435
  !!lastName.trim();
3537
3436
 
3538
- const isChangeQuoteBlocked = isCustomerSelfServeChange && latestChangeQuote?.canProceed === false;
3539
- const requiresReturnInChangeFlow = isCustomerSelfServeChange && !!initialValues?.returnAvailabilityId?.trim();
3437
+ const isChangeQuoteBlocked = true && latestChangeQuote?.canProceed === false;
3438
+ const requiresReturnInChangeFlow = true && !!initialValues?.returnAvailabilityId?.trim();
3540
3439
  const missingRequiredReturnSelection = requiresReturnInChangeFlow && !selectedReturnOption;
3541
3440
 
3542
3441
  const changeFlowSubmitDisabled =
3543
3442
  missingRequiredReturnSelection ||
3544
- (isCustomerSelfServeChange &&
3443
+ (true &&
3545
3444
  changeFlowNeedsServerPrice &&
3546
3445
  (changeQuoteLoading || (!latestChangeQuote && !changeQuoteFetchError)));
3547
3446
 
3548
- const providerTotalsPreview =
3549
- showProviderPricingInlineEditor && providerPricingUi?.totalsPreview
3550
- ? providerPricingUi.totalsPreview
3551
- : null;
3552
- const providerHasEditedLineOverrides =
3553
- isProviderDashboardChange &&
3554
- providerQuotedLines.some((line) => {
3555
- if (!isManualOverrideEligibleLine(line)) return false;
3556
- const raw = providerPricingUi?.lineAmountInputs?.[line.lineKey];
3557
- const parsed = raw == null || raw.trim() === '' ? line.amount : Number(raw);
3558
- if (!Number.isFinite(parsed)) return false;
3559
- const rounded = Math.round(parsed * 100) / 100;
3560
- return Math.abs(rounded - line.amount) > 0.0001;
3561
- });
3562
- const providerHasAdditionalAdjustments =
3563
- isProviderDashboardChange &&
3564
- (providerPricingUi?.additionalAdjustments ?? []).some((adj) => {
3565
- const parsed = Number((adj.amountInput ?? '').trim());
3566
- const hasAmount = Number.isFinite(parsed) && parsed > 0;
3567
- const currentAmount = hasAmount ? (Math.round(parsed * 100) / 100).toFixed(2) : '';
3568
- const originalAmount = adj.originalAmountInput ?? '';
3569
- const currentLabel = (adj.label ?? '').trim();
3570
- const originalLabel = (adj.originalLabel ?? '').trim();
3571
- const currentMode = adj.mode;
3572
- const originalMode = adj.originalMode;
3573
- if (!originalMode) return hasAmount || currentLabel.length > 0;
3574
- return currentAmount !== originalAmount || currentLabel !== originalLabel || currentMode !== originalMode;
3575
- });
3576
- const hasEffectiveChangeSelection =
3577
- hasChangeSelection || providerHasEditedLineOverrides || providerHasAdditionalAdjustments;
3447
+ const providerTotalsPreview = null;
3448
+ const hasEffectiveChangeSelection = hasChangeSelection;
3578
3449
 
3579
3450
  const displayedChangeAmounts = resolveChangeFlowDisplayedAmounts({
3580
3451
  providerPreview: providerTotalsPreview,
3581
3452
  serverQuotePreview:
3582
- isCustomerSelfServeChange && latestChangeQuote?.serverDisplay
3453
+ true && latestChangeQuote?.serverDisplay
3583
3454
  ? latestChangeQuote.serverDisplay
3584
3455
  : null,
3585
3456
  fromCart: {
@@ -3595,13 +3466,13 @@ export function ChangeBookingFlow({
3595
3466
  const changeFlowClientEstimateDue = (() => {
3596
3467
  if (!originalReceipt) return totalPrice;
3597
3468
  // Customer self-serve: amount due comes from POST .../change/quote (`amountDueCents` / priceDiff), not FE delta math.
3598
- if (isCustomerSelfServeChange && latestChangeQuote != null && !changeQuoteFetchError) {
3469
+ if (true && latestChangeQuote != null && !changeQuoteFetchError) {
3599
3470
  return normalizeNearZeroOwed(latestChangeQuote.priceDiff);
3600
3471
  }
3601
3472
  return changeFlowBalanceVsOriginal({
3602
3473
  newTotal: displayChangeFlowProposedTotal,
3603
3474
  originalReceiptTotal: originalReceipt.total,
3604
- audience: isProviderDashboardChange ? 'provider' : 'customer',
3475
+ audience: 'customer',
3605
3476
  });
3606
3477
  })();
3607
3478
 
@@ -3610,14 +3481,6 @@ export function ChangeBookingFlow({
3610
3481
 
3611
3482
  const changeCheckoutButtonLabel = (() => {
3612
3483
  if (!hasEffectiveChangeSelection) return undefined;
3613
- if (isProviderDashboardChange) {
3614
- const est = Math.round(changeFlowClientEstimateDue * 100) / 100;
3615
- return est > 0
3616
- ? `Change booking (${formatCurrencyAmount(est, currency, locale as 'en' | 'fr')})`
3617
- : est < 0
3618
- ? `Change booking (${formatCurrencyAmount(est, currency, locale as 'en' | 'fr')})`
3619
- : 'Change booking (no charge)';
3620
- }
3621
3484
  if (changeFlowNeedsServerPrice) {
3622
3485
  if (changeQuoteLoading) {
3623
3486
  const tr = t('booking.updatingPrice');
@@ -3651,39 +3514,8 @@ export function ChangeBookingFlow({
3651
3514
  const checkoutFormError =
3652
3515
  (error || '') ||
3653
3516
  (missingRequiredReturnSelection ? 'Removing return option in self-serve is not available. Please contact support.' : '') ||
3654
- (isCustomerSelfServeChange && isChangeQuoteBlocked ? (latestChangeQuote?.reasonIfBlocked ?? '') : '') ||
3655
- (isCustomerSelfServeChange ? changeQuoteFetchError ?? '' : '');
3656
-
3657
- const providerPricingOverrides =
3658
- isProviderDashboardChange && providerQuotedLines.length > 0
3659
- ? providerQuotedLines
3660
- .filter((line) => isManualOverrideEligibleLine(line))
3661
- .map((line) => {
3662
- const raw = providerPricingUi?.lineAmountInputs?.[line.lineKey];
3663
- const parsed = raw == null || raw.trim() === '' ? line.amount : Number(raw);
3664
- if (!Number.isFinite(parsed)) return null;
3665
- const rounded = Math.round(parsed * 100) / 100;
3666
- return Math.abs(rounded - line.amount) > 0.0001
3667
- ? { lineKey: line.lineKey, amount: rounded, reason: 'Provider dashboard override' }
3668
- : null;
3669
- })
3670
- .filter((v): v is { lineKey: string; amount: number; reason: string } => v != null)
3671
- : [];
3672
- const providerAdditionalAdjustments =
3673
- isProviderDashboardChange
3674
- ? (providerPricingUi?.additionalAdjustments ?? [])
3675
- .map((adj) => {
3676
- const parsed = Number((adj.amountInput ?? '').trim());
3677
- if (!Number.isFinite(parsed) || parsed <= 0) return null;
3678
- const rounded = Math.round(parsed * 100) / 100;
3679
- const signed = adj.mode === 'DISCOUNT' ? -rounded : rounded;
3680
- return {
3681
- label: adj.label?.trim() || (signed < 0 ? 'Provider discount' : 'Provider charge'),
3682
- amount: signed,
3683
- };
3684
- })
3685
- .filter((v): v is { label: string; amount: number } => v != null)
3686
- : [];
3517
+ (true && isChangeQuoteBlocked ? (latestChangeQuote?.reasonIfBlocked ?? '') : '') ||
3518
+ (true ? changeQuoteFetchError ?? '' : '');
3687
3519
 
3688
3520
  const changeFlowSelectionPreview = useMemo((): ChangeFlowSelectionPreview | null => {
3689
3521
  if (!selectedAvailability || totalQuantity <= 0) return null;
@@ -3789,7 +3621,7 @@ export function ChangeBookingFlow({
3789
3621
 
3790
3622
  /** Debounced server quote so CTA + “amount owed” match PaymentIntent; avoids free confirm when FE estimate ≠ BE. */
3791
3623
  useEffect(() => {
3792
- if (!isCustomerSelfServeChange) {
3624
+ if (false) {
3793
3625
  setChangeQuoteLoading(false);
3794
3626
  setChangeQuoteFetchError(null);
3795
3627
  setLatestChangeQuote(null);
@@ -3880,7 +3712,7 @@ export function ChangeBookingFlow({
3880
3712
  window.clearTimeout(timer);
3881
3713
  };
3882
3714
  }, [
3883
- isCustomerSelfServeChange,
3715
+ true,
3884
3716
  hasChangeSelection,
3885
3717
  selectedAvailability,
3886
3718
  selectedAvailability?.dateTime,
@@ -3931,8 +3763,7 @@ export function ChangeBookingFlow({
3931
3763
  timesForSelectedDate,
3932
3764
  anchor,
3933
3765
  companyTimezone,
3934
- optionsMap,
3935
- isAdmin
3766
+ optionsMap
3936
3767
  );
3937
3768
  changeFlowOutboundAnchorRef.current = null;
3938
3769
  if (matched) {
@@ -4023,8 +3854,7 @@ export function ChangeBookingFlow({
4023
3854
  const fromAnchor = pickReturnMatchingPreviousSelection(
4024
3855
  sorted,
4025
3856
  returnAnchor,
4026
- companyTimezone,
4027
- isAdmin
3857
+ companyTimezone
4028
3858
  );
4029
3859
  changeFlowReturnAnchorRef.current = null;
4030
3860
  if (fromAnchor) {
@@ -4070,7 +3900,7 @@ export function ChangeBookingFlow({
4070
3900
  selectedAvailability,
4071
3901
  selectedReturnOption,
4072
3902
  companyTimezone,
4073
- isAdmin,
3903
+ false,
4074
3904
  initialValues?.returnAvailabilityId,
4075
3905
  initialValues?.returnDateTime,
4076
3906
  ]);
@@ -4133,9 +3963,9 @@ export function ChangeBookingFlow({
4133
3963
  const firstWithInventory = dates.find((d) => {
4134
3964
  const rows = availabilitiesByDate[d] ?? [];
4135
3965
  if (rows.length === 0) return false;
4136
- if (isAdmin) return rows.some((a) => (a.vacancies ?? 0) > 0);
3966
+ if (false) return rows.some((a) => (a.vacancies ?? 0) > 0);
4137
3967
  if (
4138
- isCustomerSelfServeChange &&
3968
+ true &&
4139
3969
  changeFlowInitialTicketCount > 0
4140
3970
  ) {
4141
3971
  return rows.some(
@@ -4144,7 +3974,7 @@ export function ChangeBookingFlow({
4144
3974
  }
4145
3975
  return rows.some((a) => (a.vacancies ?? 0) > 0);
4146
3976
  });
4147
- const first = firstWithInventory ?? (isAdmin && dates[0] ? dates[0] : undefined);
3977
+ const first = firstWithInventory ?? (false && dates[0] ? dates[0] : undefined);
4148
3978
  if (!first) return;
4149
3979
 
4150
3980
  hasAutoSelectedPartnerDateRef.current = true;
@@ -4167,8 +3997,8 @@ export function ChangeBookingFlow({
4167
3997
  selectedDate,
4168
3998
  dates,
4169
3999
  availabilitiesByDate,
4170
- isAdmin,
4171
- isCustomerSelfServeChange,
4000
+ false,
4001
+ true,
4172
4002
  changeFlowInitialTicketCount,
4173
4003
  getCalendarEffectiveOutboundVacancies,
4174
4004
  useWindowScroll,
@@ -4206,7 +4036,7 @@ export function ChangeBookingFlow({
4206
4036
  };
4207
4037
 
4208
4038
  const handleQuantityChange = (category: string, delta: number) => {
4209
- const maxAvailable = isAdmin ? Number.MAX_SAFE_INTEGER : effectivePartySizeCap;
4039
+ const maxAvailable = false ? Number.MAX_SAFE_INTEGER : effectivePartySizeCap;
4210
4040
  const currentQty = quantities[category] || 0;
4211
4041
  const minQ =
4212
4042
  changeBookingMinimumQuantities != null
@@ -4214,7 +4044,7 @@ export function ChangeBookingFlow({
4214
4044
  : 0;
4215
4045
  const newQty = Math.max(minQ, currentQty + delta);
4216
4046
  // Admin can overbook; non-admin cannot exceed vacancies
4217
- if (delta > 0 && !isAdmin && orderSummary.totalQuantity >= maxAvailable) {
4047
+ if (delta > 0 && !false && orderSummary.totalQuantity >= maxAvailable) {
4218
4048
  return;
4219
4049
  }
4220
4050
  setQuantities(prev => ({
@@ -4347,30 +4177,27 @@ export function ChangeBookingFlow({
4347
4177
  return;
4348
4178
  }
4349
4179
 
4350
- const skipContactFields = isProviderDashboardChange;
4351
- if (!skipContactFields) {
4352
- // Validate email (required)
4353
- if (!email) {
4354
- setError(t('booking.enterEmail') || 'Please enter your email address');
4355
- return;
4356
- }
4180
+ // Validate email (required)
4181
+ if (!email) {
4182
+ setError(t('booking.enterEmail') || 'Please enter your email address');
4183
+ return;
4184
+ }
4357
4185
 
4358
- if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
4359
- setError(t('booking.invalidEmail') || 'Please enter a valid email address');
4360
- return;
4361
- }
4186
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
4187
+ setError(t('booking.invalidEmail') || 'Please enter a valid email address');
4188
+ return;
4189
+ }
4362
4190
 
4363
- // Validate first name (required)
4364
- if (!firstName?.trim()) {
4365
- setError(t('booking.enterFirstName') || 'Please enter your first name');
4366
- return;
4367
- }
4191
+ // Validate first name (required)
4192
+ if (!firstName?.trim()) {
4193
+ setError(t('booking.enterFirstName') || 'Please enter your first name');
4194
+ return;
4195
+ }
4368
4196
 
4369
- // Validate last name (required for manage booking lookup)
4370
- if (!lastName?.trim()) {
4371
- setError(t('booking.enterLastName') || 'Please enter your last name');
4372
- return;
4373
- }
4197
+ // Validate last name (required for manage booking lookup)
4198
+ if (!lastName?.trim()) {
4199
+ setError(t('booking.enterLastName') || 'Please enter your last name');
4200
+ return;
4374
4201
  }
4375
4202
 
4376
4203
  // Allow checkout if pickup location is selected OR if user chose "I don't know"
@@ -4398,44 +4225,6 @@ export function ChangeBookingFlow({
4398
4225
  return;
4399
4226
  }
4400
4227
 
4401
- if (onChangeBooking) {
4402
- const pickupForChange = pickupLocationId
4403
- ? product.pickupLocations?.find((loc) => loc.id === pickupLocationId)
4404
- : null;
4405
- await onChangeBooking({
4406
- productId: availabilityProductOptionId,
4407
- dateTime: selectedAvailability.dateTime,
4408
- bookingItems,
4409
- returnAvailabilityId: selectedReturnOption?.returnAvailabilityId ?? null,
4410
- pickupLocationId: pickupLocationId ?? null,
4411
- travelerHotel: pickupForChange?.name ?? null,
4412
- startTime: selectedAvailability.dateTime ?? null,
4413
- passengerCount: null,
4414
- childSafetySeatsCount: null,
4415
- foodRestrictions: null,
4416
- addOnSelections: addOnSelections.length > 0 ? addOnSelections : null,
4417
- cancellationPolicyId: cancellationPolicyId ?? initialValues?.cancellationPolicyId ?? null,
4418
- promoCode: appliedPromoCode ?? null,
4419
- newTotalAmount: displayChangeFlowProposedTotal,
4420
- additionalHoursCount: null,
4421
- pricingAdjustment:
4422
- providerPricingOverrides.length > 0 || providerAdditionalAdjustments.length > 0
4423
- ? {
4424
- mode: 'MANUAL_LINES',
4425
- lineOverrides: providerPricingOverrides,
4426
- additionalAdjustments: providerAdditionalAdjustments,
4427
- }
4428
- : undefined,
4429
- capacitySeatCredit: {
4430
- enabled: true,
4431
- previousPassengerCount: changeFlowInitialTicketCount,
4432
- previousAvailabilityId: initialValues?.availabilityId ?? null,
4433
- previousReturnAvailabilityId: initialValues?.returnAvailabilityId ?? null,
4434
- },
4435
- });
4436
- setLoading(false);
4437
- return;
4438
- }
4439
4228
 
4440
4229
  const bookingSourceContext = buildBookingSourceContext(bookingSourceAttribution, {
4441
4230
  clientChannelSource: inferClientBookingSourceFromProductIds(
@@ -4443,18 +4232,17 @@ export function ChangeBookingFlow({
4443
4232
  availabilityProductOptionId,
4444
4233
  ),
4445
4234
  forcePartnerPortalChannel: partnerPortalBooking,
4446
- forceDashboardSource: bookingAppMode === 'provider-dashboard',
4235
+ forceDashboardSource: false,
4447
4236
  });
4448
4237
 
4449
4238
  // Get the hotel name if a pickup location was selected
4450
4239
  const selectedPickupLocation = pickupLocationId
4451
4240
  ? product.pickupLocations?.find(loc => loc.id === pickupLocationId)
4452
4241
  : null;
4453
- let quotedPriceDiff: number | null = null;
4454
4242
  let changeIntentIdForCheckout: string | undefined;
4455
4243
  let changeBookingReferenceForPaidFlow: string | undefined;
4456
4244
 
4457
- if (isCustomerSelfServeChange) {
4245
+ {
4458
4246
  const changeBookingReference = initialValues?.bookingReference?.trim();
4459
4247
  const changeLastName = lastName.trim();
4460
4248
  if (!changeBookingReference || !changeLastName) {
@@ -4482,7 +4270,6 @@ export function ChangeBookingFlow({
4482
4270
  },
4483
4271
  currency
4484
4272
  );
4485
- quotedPriceDiff = quoteSlice.priceDiff;
4486
4273
  changeBookingReferenceForPaidFlow = changeBookingReference;
4487
4274
  changeIntentIdForCheckout = quoteSlice.changeIntentId ?? undefined;
4488
4275
  setLatestChangeQuote(
@@ -4574,13 +4361,11 @@ export function ChangeBookingFlow({
4574
4361
  // Build checkout breakdown from the exact same values we show in the UI and Stripe modal.
4575
4362
  // Backend will charge totalAmount and store this as the receipt so /manage matches.
4576
4363
  const taxForBreakdown = effectivePromoDiscountAmount > 0 ? effectiveTax : tax;
4577
- const amountDueForCheckout = isCustomerSelfServeChange
4578
- ? changeFlowBalanceVsOriginal({
4579
- newTotal: changeFlowNewBookingTotal,
4580
- originalReceiptTotal: originalReceipt?.total ?? 0,
4581
- audience: 'customer',
4582
- })
4583
- : totalPrice;
4364
+ const amountDueForCheckout = changeFlowBalanceVsOriginal({
4365
+ newTotal: changeFlowNewBookingTotal,
4366
+ originalReceiptTotal: originalReceipt?.total ?? 0,
4367
+ audience: 'customer',
4368
+ });
4584
4369
  const lines = [
4585
4370
  ...ticketLineItemsForChangeFlowDisplay.map((line) => ({
4586
4371
  label: line.category,
@@ -4657,8 +4442,7 @@ export function ChangeBookingFlow({
4657
4442
  roundingLabel: t('booking.rounding') || 'Rounding',
4658
4443
  });
4659
4444
 
4660
- const paymentIntent = isCustomerSelfServeChange
4661
- ? await createChangeBookingPaymentIntent(
4445
+ const paymentIntent = await createChangeBookingPaymentIntent(
4662
4446
  (() => {
4663
4447
  const id = changeIntentIdForCheckout ?? latestChangeQuote?.changeIntentId;
4664
4448
  if (!id) {
@@ -4666,76 +4450,8 @@ export function ChangeBookingFlow({
4666
4450
  }
4667
4451
  return id;
4668
4452
  })()
4669
- )
4670
- : await createPaymentIntent({
4671
- productId: product.productId,
4672
- optionId: availabilityProductOptionId,
4673
- date: datePart,
4674
- time: timePart,
4675
- quantity: totalQuantity,
4676
- customerEmail: email,
4677
- customerFirstName: firstName.trim() || undefined,
4678
- customerLastName: lastName.trim() || undefined,
4679
- currency: currency,
4680
- travelerHotel: selectedPickupLocation?.name || undefined,
4681
- pickupLocationId: pickupLocationId || undefined,
4682
- itineraryDisplay: itineraryDisplay ?? undefined,
4683
- returnAvailabilityId: selectedReturnOption?.returnAvailabilityId,
4684
- promoCode: (lockedPromoCode || appliedPromoCode) || undefined,
4685
- cancellationPolicyId: cancellationPolicyId || undefined,
4686
- termsAcceptedAt: termsAcceptedAt ?? undefined,
4687
- checkoutBreakdown,
4688
- skipConfirmationCommunications: isAdmin && skipConfirmationCommunications ? true : undefined,
4689
- disableAutoCommunications: isAdmin && disableAutoCommunications ? true : undefined,
4690
- ...bookingSourceContext,
4691
- });
4453
+ );
4692
4454
 
4693
- // Admin: show choice to pay now or confirm without payment (customer owes full balance)
4694
- if (isAdmin) {
4695
- const adminReservationRef =
4696
- initialValues?.bookingReference?.trim() ??
4697
- changeBookingReferenceForPaidFlow ??
4698
- '';
4699
- if (!adminReservationRef) {
4700
- throw new Error('Missing reservation reference for admin payment flow');
4701
- }
4702
- setError('');
4703
- setAdminChoiceData({
4704
- reservationReference: adminReservationRef,
4705
- reservationExpiration: undefined,
4706
- checkoutBreakdown,
4707
- totalAmount: amountDueForCheckout,
4708
- datePart,
4709
- timePart,
4710
- availabilityProductOptionId,
4711
- itineraryDisplay: itineraryDisplay ?? undefined,
4712
- clientSecret: paymentIntent.clientSecret ?? '',
4713
- ticketLinesForModal: ticketLineItemsForChangeFlowDisplay.map((line) => {
4714
- const rate = pricing.find((r) => r.category === line.category);
4715
- const breakdown = getPriceBreakdown(
4716
- line.category,
4717
- rate?.priceCAD ?? 0,
4718
- rate?.baseInDisplayCurrency,
4719
- rate?.appliedAdjustments ?? []
4720
- );
4721
- return { line, breakdown };
4722
- }),
4723
- feeLineItems: feeLineItemsWithAddOns,
4724
- returnPriceAdjustment: checkoutReturnLineAmount,
4725
- cancellationPolicyFee,
4726
- cancellationPolicyLabel: effectiveCancellationPolicyLabel,
4727
- subtotal: effectiveSubtotal,
4728
- tax: effectivePromoDiscountAmount > 0 ? effectiveTax : tax,
4729
- totalQuantity,
4730
- isTaxIncludedInPrice,
4731
- taxRate: pricingConfig?.taxRate ?? 0,
4732
- promoDiscountAmount: effectivePromoDiscountAmount > 0 ? effectivePromoDiscountAmount : 0,
4733
- discountLabel: appliedPromoCode ? `Promo: ${appliedPromoCode}` : (originalReceipt?.promoLabel || undefined),
4734
- });
4735
- setShowAdminPaymentChoice(true);
4736
- setLoading(false);
4737
- return;
4738
- }
4739
4455
 
4740
4456
  const ticketLinesForModal: CheckoutModalLineItem[] = ticketLineItemsForChangeFlowDisplay.map((line) => {
4741
4457
  const rate = pricing.find((r) => r.category === line.category);
@@ -4757,7 +4473,7 @@ export function ChangeBookingFlow({
4757
4473
  // Paid change: always return to stable ref+lastName + explicit intent (not reservationRef).
4758
4474
  // /manage-booking runs bounded refresh only when `from=change_payment` (see manage-booking page).
4759
4475
  successUrlOverride:
4760
- isCustomerSelfServeChange && changeBookingReferenceForPaidFlow
4476
+ true && changeBookingReferenceForPaidFlow
4761
4477
  ? (() => {
4762
4478
  const origin = typeof window !== 'undefined' ? window.location.origin : '';
4763
4479
  const ref = encodeURIComponent(
@@ -4785,7 +4501,7 @@ export function ChangeBookingFlow({
4785
4501
  promoDiscountAmount: effectivePromoDiscountAmount > 0 ? effectivePromoDiscountAmount : 0,
4786
4502
  discountLabel: appliedPromoCode ? `Promo: ${appliedPromoCode}` : (originalReceipt?.promoLabel || undefined),
4787
4503
  changeTotals:
4788
- isCustomerSelfServeChange && originalReceipt
4504
+ true && originalReceipt
4789
4505
  ? {
4790
4506
  previousTotal: originalReceipt.total,
4791
4507
  newTotal: displayChangeFlowProposedTotal,
@@ -4854,85 +4570,7 @@ export function ChangeBookingFlow({
4854
4570
  }
4855
4571
  };
4856
4572
 
4857
- const handleConfirmWithoutPayment = async () => {
4858
- if (!adminChoiceData) return;
4859
- setLoading(true);
4860
- setError('');
4861
- try {
4862
- const bookingSourceContext = buildBookingSourceContext(bookingSourceAttribution, {
4863
- clientChannelSource: inferClientBookingSourceFromProductIds(
4864
- product.productId,
4865
- adminChoiceData.availabilityProductOptionId,
4866
- ),
4867
- forcePartnerPortalChannel: partnerPortalBooking,
4868
- forceDashboardSource: bookingAppMode === 'provider-dashboard',
4869
- });
4870
- const result = await confirmBookingWithoutPayment({
4871
- reservationReference: adminChoiceData.reservationReference,
4872
- productId: product.productId,
4873
- optionId: adminChoiceData.availabilityProductOptionId,
4874
- date: adminChoiceData.datePart,
4875
- time: adminChoiceData.timePart,
4876
- customerEmail: email || undefined,
4877
- customerFirstName: firstName.trim() || undefined,
4878
- customerLastName: lastName.trim() || undefined,
4879
- currency: currency,
4880
- travelerHotel: product.pickupLocations?.find(loc => loc.id === pickupLocationId)?.name || undefined,
4881
- pickupLocationId: pickupLocationId || undefined,
4882
- itineraryDisplay: adminChoiceData.itineraryDisplay ?? undefined,
4883
- termsAcceptedAt: termsAcceptedAt ?? undefined,
4884
- skipConfirmationCommunications: skipConfirmationCommunications ? true : undefined,
4885
- disableAutoCommunications: disableAutoCommunications ? true : undefined,
4886
- checkoutBreakdown: adminChoiceData.checkoutBreakdown,
4887
- depositAmount: 0,
4888
- balanceAmount: adminChoiceData.totalAmount,
4889
- totalAmount: adminChoiceData.totalAmount,
4890
- ...bookingSourceContext,
4891
- });
4892
- pendingReservationRef.current = null;
4893
- const ref = formatBookingRefForDisplay(result.bookingReference);
4894
- const ln = lastName.trim();
4895
- setShowAdminPaymentChoice(false);
4896
- setAdminChoiceData(null);
4897
- onSuccess?.({ reservationReference: adminChoiceData.reservationReference });
4898
- if (onShowManage) {
4899
- onShowManage({ ref, lastName: ln });
4900
- } else {
4901
- const params = new URLSearchParams({ ref, lastName: ln, booking_complete: '1' });
4902
- window.location.href = `/manage-booking?${params.toString()}`;
4903
- }
4904
- } catch (err) {
4905
- setError(err instanceof Error ? err.message : 'Failed to confirm booking');
4906
- } finally {
4907
- setLoading(false);
4908
- }
4909
- };
4910
4573
 
4911
- const handlePayNow = () => {
4912
- if (!adminChoiceData) return;
4913
- setShowAdminPaymentChoice(false);
4914
- setCheckoutClientSecret(adminChoiceData.clientSecret);
4915
- setCheckoutModalData({
4916
- reservationReference: adminChoiceData.reservationReference,
4917
- reservationExpiration: adminChoiceData.reservationExpiration,
4918
- customerLastName: lastName.trim(),
4919
- ticketLines: adminChoiceData.ticketLinesForModal,
4920
- feeLineItems: adminChoiceData.feeLineItems,
4921
- returnPriceAdjustment: adminChoiceData.returnPriceAdjustment,
4922
- cancellationPolicyFee: adminChoiceData.cancellationPolicyFee,
4923
- cancellationPolicyLabel: adminChoiceData.cancellationPolicyLabel,
4924
- subtotal: adminChoiceData.subtotal,
4925
- tax: adminChoiceData.tax,
4926
- total: adminChoiceData.totalAmount,
4927
- totalQuantity: adminChoiceData.totalQuantity,
4928
- isTaxIncludedInPrice: adminChoiceData.isTaxIncludedInPrice,
4929
- taxRate: adminChoiceData.taxRate,
4930
- promoDiscountAmount: adminChoiceData.promoDiscountAmount,
4931
- discountLabel: adminChoiceData.discountLabel,
4932
- });
4933
- setShowCheckoutModal(true);
4934
- setAdminChoiceData(null);
4935
- };
4936
4574
 
4937
4575
  if (activeOptions.length === 0) {
4938
4576
  return (
@@ -4944,17 +4582,6 @@ export function ChangeBookingFlow({
4944
4582
 
4945
4583
  return (
4946
4584
  <div className="booking-flow-root space-y-8">
4947
- {/* Admin: choose to pay now or confirm without payment (full balance owed) */}
4948
- <AdminPaymentChoiceModal
4949
- open={!!(showAdminPaymentChoice && adminChoiceData)}
4950
- totalAmount={adminChoiceData?.totalAmount ?? 0}
4951
- currency={currency}
4952
- loading={loading}
4953
- error={error}
4954
- onPayNow={handlePayNow}
4955
- onConfirmWithoutPayment={handleConfirmWithoutPayment}
4956
- onCancel={() => { setShowAdminPaymentChoice(false); setAdminChoiceData(null); setError(''); }}
4957
- />
4958
4585
  {checkoutModalData && (
4959
4586
  <CheckoutModal
4960
4587
  open={showCheckoutModal}
@@ -5028,12 +4655,12 @@ export function ChangeBookingFlow({
5028
4655
  syncVisibleWeekToSelectedDate={true}
5029
4656
  selectableSoldOutDate={changeFlowOriginalDate}
5030
4657
  partySizeRequiredForCalendarSelection={
5031
- isCustomerSelfServeChange && !isAdmin && changeFlowInitialTicketCount > 0
4658
+ true && !false && changeFlowInitialTicketCount > 0
5032
4659
  ? changeFlowInitialTicketCount
5033
4660
  : undefined
5034
4661
  }
5035
4662
  getEffectiveVacancies={
5036
- isCustomerSelfServeChange && !isAdmin && changeFlowInitialTicketCount > 0
4663
+ true && !false && changeFlowInitialTicketCount > 0
5037
4664
  ? getCalendarEffectiveOutboundVacancies
5038
4665
  : undefined
5039
4666
  }
@@ -5057,7 +4684,7 @@ export function ChangeBookingFlow({
5057
4684
  earliestDate={earliestAvailabilityDate}
5058
4685
  onVisibleRangeChange={handleVisibleRangeChange}
5059
4686
  currency={currency}
5060
- showCapacity={isAdmin}
4687
+ showCapacity={false}
5061
4688
  extraDiscountPercent={calendarDiscountPercent}
5062
4689
  capDiscountBadgesToBookingDate={changeFlowOriginalDate}
5063
4690
  />
@@ -5113,7 +4740,7 @@ export function ChangeBookingFlow({
5113
4740
  selectedTicketCount={totalQuantity}
5114
4741
  optionsMap={optionsMap}
5115
4742
  hasAnyMostPopular={hasAnyMostPopular}
5116
- isAdmin={isAdmin}
4743
+ isAdmin={false}
5117
4744
  pickupLocationSkipped={pickupLocationSkipped}
5118
4745
  t={t}
5119
4746
  onTimeSelect={handleTimeSelect}
@@ -5129,7 +4756,7 @@ export function ChangeBookingFlow({
5129
4756
  companyTimezone={companyTimezone}
5130
4757
  currency={currency}
5131
4758
  locale={locale}
5132
- isAdmin={isAdmin}
4759
+ isAdmin={false}
5133
4760
  t={t}
5134
4761
  onReturnSelect={(option) => {
5135
4762
  const raw = selectedAvailability.returnOptions?.find(
@@ -5157,7 +4784,7 @@ export function ChangeBookingFlow({
5157
4784
  resourceCount={selectedReturnOption ? null : (selectedAvailability.resourceCount ?? null)}
5158
4785
  currency={currency}
5159
4786
  locale={locale}
5160
- isAdmin={isAdmin}
4787
+ isAdmin={false}
5161
4788
  isSimplifiedPricingView={isSimplifiedPricingView}
5162
4789
  t={t}
5163
4790
  onQuantityChange={handleQuantityChange}
@@ -5179,7 +4806,7 @@ export function ChangeBookingFlow({
5179
4806
  currency={currency}
5180
4807
  locale={locale}
5181
4808
  onSelectionsChange={updateAddOnSelections}
5182
- minimumTotalByAddOnId={isCustomerSelfServeChange ? initialAddOnMinTotalByAddOnId : undefined}
4809
+ minimumTotalByAddOnId={initialAddOnMinTotalByAddOnId}
5183
4810
  suppressPrices={false}
5184
4811
  />
5185
4812
  )}
@@ -5209,99 +4836,15 @@ export function ChangeBookingFlow({
5209
4836
  currency={currency}
5210
4837
  locale={locale}
5211
4838
  t={t}
5212
- extraBetweenTaxAndTotal={
5213
- <>
5214
- {showProviderPricingInlineEditor && providerPricingUi?.error ? (
5215
- <div className="mt-2 text-sm text-red-700">{providerPricingUi.error}</div>
5216
- ) : null}
5217
- {showProviderPricingInlineEditor &&
5218
- providerPricingUi?.loading &&
5219
- providerQuotedLines.length === 0 ? (
5220
- <div className="mt-2 text-sm text-stone-500">Loading price lines...</div>
5221
- ) : null}
5222
- {showProviderPricingInlineEditor &&
5223
- providerPricingUi?.helperText &&
5224
- !providerPricingUi.error ? (
5225
- <div className="mt-2 text-xs text-stone-500">{providerPricingUi.helperText}</div>
5226
- ) : null}
5227
- </>
5228
- }
5229
- extraBeforeSubtotal={
5230
- showProviderPricingInlineEditor && (providerPricingUi?.additionalAdjustments?.length ?? 0) > 0 ? (
5231
- <div className="space-y-1">
5232
- {providerPricingUi?.additionalAdjustments?.map((adj) => (
5233
- <div key={adj.id} className="flex items-center justify-between gap-2 text-sm">
5234
- <div className="flex min-w-0 items-center gap-1">
5235
- <button
5236
- type="button"
5237
- className="rounded border border-stone-300 px-1 text-xs text-stone-600 hover:bg-stone-100"
5238
- onClick={() => providerPricingUi?.onRemoveAdditionalAdjustment?.(adj.id)}
5239
- >
5240
- -
5241
- </button>
5242
- <input
5243
- type="text"
5244
- className="w-40 rounded border border-stone-300 px-2 py-0.5 text-sm"
5245
- placeholder="Line description"
5246
- value={adj.label}
5247
- onChange={(e) =>
5248
- providerPricingUi?.onUpdateAdditionalAdjustment?.(adj.id, { label: e.target.value })
5249
- }
5250
- />
5251
- </div>
5252
- <div className="flex items-center gap-1">
5253
- <select
5254
- className="rounded border border-stone-300 px-1 py-0.5 text-xs"
5255
- value={adj.mode}
5256
- onChange={(e) =>
5257
- providerPricingUi?.onUpdateAdditionalAdjustment?.(adj.id, {
5258
- mode: e.target.value as 'DISCOUNT' | 'CHARGE',
5259
- })
5260
- }
5261
- >
5262
- <option value="DISCOUNT">-</option>
5263
- <option value="CHARGE">+</option>
5264
- </select>
5265
- <input
5266
- type="text"
5267
- inputMode="decimal"
5268
- className="h-6 w-24 rounded border border-stone-300 bg-white px-2 py-0.5 text-right text-sm font-medium leading-none text-stone-700"
5269
- placeholder="0.00"
5270
- value={adj.amountInput}
5271
- onChange={(e) =>
5272
- providerPricingUi?.onUpdateAdditionalAdjustment?.(adj.id, {
5273
- amountInput: e.target.value,
5274
- })
5275
- }
5276
- />
5277
- </div>
5278
- </div>
5279
- ))}
5280
- <button
5281
- type="button"
5282
- className="rounded border border-stone-300 px-2 py-0.5 text-xs text-stone-600 hover:bg-stone-100"
5283
- onClick={() => providerPricingUi?.onAddAdditionalAdjustment?.()}
5284
- >
5285
- + add line item
5286
- </button>
5287
- </div>
5288
- ) : showProviderPricingInlineEditor ? (
5289
- <button
5290
- type="button"
5291
- className="rounded border border-stone-300 px-2 py-0.5 text-xs text-stone-600 hover:bg-stone-100"
5292
- onClick={() => providerPricingUi?.onAddAdditionalAdjustment?.()}
5293
- >
5294
- + add line item
5295
- </button>
5296
- ) : undefined
5297
- }
4839
+ extraBetweenTaxAndTotal={undefined}
4840
+ extraBeforeSubtotal={undefined}
5298
4841
  firstName={firstName}
5299
4842
  lastName={lastName}
5300
4843
  email={email}
5301
4844
  onFirstNameChange={(v) => { setFirstName(v); setError(''); }}
5302
4845
  onLastNameChange={(v) => { setLastName(v); setError(''); }}
5303
4846
  onEmailChange={(v) => { setEmail(v); setError(''); }}
5304
- readOnlyContactFields
4847
+ readOnlyContactFields={false}
5305
4848
  pickupLocations={
5306
4849
  selectedDate && product.pickupLocations && product.pickupLocations.length > 0
5307
4850
  ? product.pickupLocations
@@ -5335,38 +4878,29 @@ export function ChangeBookingFlow({
5335
4878
  setTermsAccepted(checked);
5336
4879
  setTermsAcceptedAt(checked ? new Date().toISOString() : null);
5337
4880
  }}
5338
- isAdmin={isAdmin}
4881
+ isAdmin={false}
5339
4882
  showCommunicationAdminSection={false}
5340
- skipConfirmationCommunications={skipConfirmationCommunications}
5341
- disableAutoCommunications={disableAutoCommunications}
5342
- onSkipConfirmationChange={setSkipConfirmationCommunications}
5343
- onDisableCommunicationsChange={setDisableAutoCommunications}
4883
+ skipConfirmationCommunications={false}
4884
+ disableAutoCommunications={false}
4885
+ onSkipConfirmationChange={() => {}}
4886
+ onDisableCommunicationsChange={() => {}}
5344
4887
  error={checkoutFormError}
5345
4888
  loading={loading}
5346
4889
  totalQuantity={totalQuantity}
5347
4890
  onCheckout={handleCheckout}
5348
4891
  submitLabel={changeCheckoutButtonLabel ?? deferredInvoiceSubmitLabel}
5349
4892
  hideSubmitButton={
5350
- showCheckoutModal ||
5351
- showAdminPaymentChoice ||
5352
- !hasEffectiveChangeSelection ||
5353
- isChangeQuoteBlocked
4893
+ showCheckoutModal || !hasEffectiveChangeSelection || isChangeQuoteBlocked
5354
4894
  }
5355
4895
  submitDisabled={changeFlowSubmitDisabled}
5356
4896
  attributionSummary={flowUi?.partnerAttributionSummary}
5357
4897
  attributionConfirmLabel={flowUi?.partnerAttributionConfirmLabel}
5358
4898
  attributionConfirmed={partnerAttributionConfirmed}
5359
4899
  onAttributionConfirmedChange={setPartnerAttributionConfirmed}
5360
- lineAmountInputs={showProviderPricingInlineEditor ? providerPricingUi?.lineAmountInputs : undefined}
5361
- onLineAmountInputChange={
5362
- showProviderPricingInlineEditor ? providerPricingUi?.onLineAmountInputChange : undefined
5363
- }
5364
- onLineAmountInputBlur={
5365
- showProviderPricingInlineEditor ? providerPricingUi?.onLineAmountInputBlur : undefined
5366
- }
5367
- onLineAmountReset={
5368
- showProviderPricingInlineEditor ? providerPricingUi?.onLineAmountReset : undefined
5369
- }
4900
+ lineAmountInputs={undefined}
4901
+ onLineAmountInputChange={undefined}
4902
+ onLineAmountInputBlur={undefined}
4903
+ onLineAmountReset={undefined}
5370
4904
  />
5371
4905
  </>
5372
4906
  )}