storefront-layouts 1.0.15 → 1.0.16

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.
@@ -1 +1 @@
1
- {"version":3,"file":"CheckoutPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/pages/CheckoutPage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAiChD,UAAU,iBAAiB;IACzB,WAAW,EAAE,WAAW,CAAC;CAC1B;AA8LD,wBAAgB,YAAY,CAAC,EAAE,WAAW,EAAE,EAAE,iBAAiB,+BAynD9D"}
1
+ {"version":3,"file":"CheckoutPage.d.ts","sourceRoot":"","sources":["../../../../src/layouts/shared/pages/CheckoutPage.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAiChD,UAAU,iBAAiB;IACzB,WAAW,EAAE,WAAW,CAAC;CAC1B;AA8LD,wBAAgB,YAAY,CAAC,EAAE,WAAW,EAAE,EAAE,iBAAiB,+BA+rD9D"}
@@ -241,6 +241,11 @@ export function CheckoutPage({ storeConfig }) {
241
241
  const [freeShippingEnabled, setFreeShippingEnabled] = useState(false);
242
242
  const [feePreview, setFeePreview] = useState(null);
243
243
  const [isCalculatingFees, setIsCalculatingFees] = useState(false);
244
+ const [storeShippingCheckout, setStoreShippingCheckout] = useState({
245
+ enabled: false,
246
+ resolved: false,
247
+ });
248
+ const lastFeePreviewKeyRef = useRef(null);
244
249
  const [formData, setFormData] = useState({
245
250
  email: '',
246
251
  firstName: '',
@@ -537,6 +542,10 @@ export function CheckoutPage({ storeConfig }) {
537
542
  setFreeShippingEnabled(false);
538
543
  return;
539
544
  }
545
+ if (!storeShippingCheckout.resolved || !storeShippingCheckout.enabled) {
546
+ setIsCalculatingShipping(false);
547
+ return;
548
+ }
540
549
  setIsCalculatingShipping(true);
541
550
  setShippingError(null);
542
551
  try {
@@ -609,17 +618,51 @@ export function CheckoutPage({ storeConfig }) {
609
618
  const total = feePreview?.totalPayable ?? fallbackTotal;
610
619
  const customerFeeLines = (feePreview?.customerLines ?? []).filter((line) => line.key !== 'shipping');
611
620
  const shippingEnabledForCheckout = storeConfig.settings?.shippingEnabled !== false;
612
- const showOrderSummaryShippingLine = shouldShowOrderSummaryShippingLine({
613
- shippingEnabled: shippingEnabledForCheckout,
614
- isCalculating: isCalculatingShipping,
615
- selectedMethod: selectedShippingMethod,
616
- });
617
- const showShippingMethodSection = shippingEnabledForCheckout &&
621
+ const checkoutShippingUiActive = shippingEnabledForCheckout &&
622
+ storeShippingCheckout.resolved &&
623
+ storeShippingCheckout.enabled;
624
+ const feePreviewShippingCost = checkoutShippingUiActive ? safeShipping : 0;
625
+ useEffect(() => {
626
+ if (!storeConfig.id || !shippingEnabledForCheckout) {
627
+ setStoreShippingCheckout({ enabled: false, resolved: true });
628
+ return;
629
+ }
630
+ let cancelled = false;
631
+ void shippingService.getStoreShippingStatus(storeConfig.id).then((status) => {
632
+ if (!cancelled) {
633
+ setStoreShippingCheckout({ enabled: status.enabled, resolved: true });
634
+ }
635
+ });
636
+ return () => {
637
+ cancelled = true;
638
+ };
639
+ }, [storeConfig.id, shippingEnabledForCheckout]);
640
+ useEffect(() => {
641
+ if (checkoutShippingUiActive)
642
+ return;
643
+ setIsCalculatingShipping(false);
644
+ setShippingMethods([]);
645
+ setSelectedShippingMethod(null);
646
+ setShippingError(null);
647
+ }, [checkoutShippingUiActive]);
648
+ const showOrderSummaryShippingLine = checkoutShippingUiActive &&
649
+ shouldShowOrderSummaryShippingLine({
650
+ shippingEnabled: true,
651
+ isCalculating: isCalculatingShipping,
652
+ selectedMethod: selectedShippingMethod,
653
+ });
654
+ const showShippingMethodSection = checkoutShippingUiActive &&
618
655
  Boolean(formData.city && formData.country) &&
619
656
  (isCalculatingShipping || Boolean(shippingError) || shippingMethods.length > 0);
620
657
  useEffect(() => {
621
658
  if (!storeConfig.id || safeSubtotal <= 0 || !currency) {
622
659
  setFeePreview(null);
660
+ lastFeePreviewKeyRef.current = null;
661
+ setIsCalculatingFees(false);
662
+ return;
663
+ }
664
+ const requestKey = `${storeConfig.id}:${safeSubtotal.toFixed(2)}:${currency}:${feePreviewShippingCost.toFixed(2)}`;
665
+ if (requestKey === lastFeePreviewKeyRef.current && feePreview) {
623
666
  return;
624
667
  }
625
668
  let cancelled = false;
@@ -629,18 +672,21 @@ export function CheckoutPage({ storeConfig }) {
629
672
  const response = await feesService.calculateFees({
630
673
  storeId: storeConfig.id,
631
674
  subtotal: safeSubtotal,
632
- shippingCost: safeShipping,
675
+ shippingCost: feePreviewShippingCost,
633
676
  currency,
634
677
  orderType: 'product',
635
678
  });
636
- if (!cancelled)
679
+ if (!cancelled) {
637
680
  setFeePreview(response.feeBreakdown);
681
+ lastFeePreviewKeyRef.current = requestKey;
682
+ }
638
683
  }
639
684
  catch (error) {
640
- // Checkout creation recalculates fees authoritatively; preserve a usable fallback preview.
641
685
  console.warn('[Checkout] Fee preview unavailable:', error);
642
- if (!cancelled)
686
+ if (!cancelled) {
643
687
  setFeePreview(null);
688
+ lastFeePreviewKeyRef.current = null;
689
+ }
644
690
  }
645
691
  finally {
646
692
  if (!cancelled)
@@ -651,7 +697,7 @@ export function CheckoutPage({ storeConfig }) {
651
697
  cancelled = true;
652
698
  window.clearTimeout(timer);
653
699
  };
654
- }, [currency, safeShipping, safeSubtotal, storeConfig.id]);
700
+ }, [currency, feePreview, feePreviewShippingCost, safeSubtotal, storeConfig.id]);
655
701
  // Debug logging in development
656
702
  if (process.env.NODE_ENV === 'development' && safeSubtotal > 0 && total === 0) {
657
703
  console.warn('[CheckoutPage] Total calculation issue detected:', {
@@ -667,7 +713,11 @@ export function CheckoutPage({ storeConfig }) {
667
713
  }
668
714
  // Debounced shipping calculation when address changes
669
715
  useEffect(() => {
670
- if (!formData.city || !formData.country || checkoutItems.length === 0) {
716
+ if (!storeShippingCheckout.resolved ||
717
+ !checkoutShippingUiActive ||
718
+ !formData.city ||
719
+ !formData.country ||
720
+ checkoutItems.length === 0) {
671
721
  return;
672
722
  }
673
723
  const timer = setTimeout(() => {
@@ -675,7 +725,16 @@ export function CheckoutPage({ storeConfig }) {
675
725
  }, 500); // Debounce 500ms
676
726
  return () => clearTimeout(timer);
677
727
  // eslint-disable-next-line react-hooks/exhaustive-deps
678
- }, [formData.city, formData.country, formData.postalCode, checkoutItems.length, subtotal, currency]);
728
+ }, [
729
+ storeShippingCheckout.resolved,
730
+ checkoutShippingUiActive,
731
+ formData.city,
732
+ formData.country,
733
+ formData.postalCode,
734
+ checkoutItems.length,
735
+ subtotal,
736
+ currency,
737
+ ]);
679
738
  const validateForm = () => {
680
739
  const newErrors = {};
681
740
  const emailError = getCheckoutEmailValidationError(formData.email);
@@ -23,6 +23,11 @@ export interface DeliveryStatus {
23
23
  enabled: boolean;
24
24
  providers: Record<string, boolean>;
25
25
  }
26
+ export interface StoreShippingCheckoutStatus {
27
+ enabled: boolean;
28
+ automatedShipping: boolean;
29
+ manualZones: boolean;
30
+ }
26
31
  export interface TaxCalculation {
27
32
  tax: number;
28
33
  taxRate: number;
@@ -52,6 +57,7 @@ export declare const shippingService: {
52
57
  * Check if delivery is globally enabled and which providers are active.
53
58
  * Returns a safe default (disabled) on error — callers should fall back gracefully.
54
59
  */
60
+ getStoreShippingStatus(storeId: string): Promise<StoreShippingCheckoutStatus>;
55
61
  getDeliveryStatus(storeId: string): Promise<DeliveryStatus>;
56
62
  /**
57
63
  * Calculate tax
@@ -1 +1 @@
1
- {"version":3,"file":"shipping.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/shipping.service.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,eAAe;IAC1B;;OAEG;4BAC2B;QAC5B,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,GAAG,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE;YACb,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB,CAAC;KACH,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAQhC;;;OAGG;+BAC8B,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAYjE;;OAEG;uBACsB;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;CAOvG,CAAC"}
1
+ {"version":3,"file":"shipping.service.d.ts","sourceRoot":"","sources":["../../../src/lib/services/shipping.service.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,oBAAoB,EAAE,OAAO,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,eAAe;IAC1B;;OAEG;4BAC2B;QAC5B,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,GAAG,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE;YACb,SAAS,CAAC,EAAE,MAAM,CAAC;YACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,KAAK,CAAC,EAAE,MAAM,CAAC;YACf,KAAK,CAAC,EAAE,MAAM,CAAC;SAChB,CAAC;KACH,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAQhC;;;OAGG;oCACmC,MAAM,GAAG,OAAO,CAAC,2BAA2B,CAAC;+BAalD,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAYjE;;OAEG;uBACsB;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,GAAG,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;CAOvG,CAAC"}
@@ -14,6 +14,16 @@ export const shippingService = {
14
14
  * Check if delivery is globally enabled and which providers are active.
15
15
  * Returns a safe default (disabled) on error — callers should fall back gracefully.
16
16
  */
17
+ async getStoreShippingStatus(storeId) {
18
+ try {
19
+ const response = await api.get('/shipping/status', { params: { storeId } });
20
+ if (response.data.status === 'success') {
21
+ return response.data.data;
22
+ }
23
+ }
24
+ catch (_) { }
25
+ return { enabled: false, automatedShipping: false, manualZones: false };
26
+ },
17
27
  async getDeliveryStatus(storeId) {
18
28
  try {
19
29
  const response = await api.get('/delivery/status', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storefront-layouts",
3
- "version": "1.0.15",
3
+ "version": "1.0.16",
4
4
  "lts": true,
5
5
  "type": "module",
6
6
  "description": "Shared layout components for Storefront applications",