storefront-layouts 1.0.9 → 1.0.13

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.
Files changed (108) hide show
  1. package/dist/components/shipping/ProductDeliveryInfoSection.d.ts.map +1 -1
  2. package/dist/components/shipping/ProductDeliveryInfoSection.js +10 -3
  3. package/dist/components/ui/address-selector.d.ts.map +1 -1
  4. package/dist/components/ui/address-selector.js +4 -3
  5. package/dist/components/ui/button.js +1 -1
  6. package/dist/components/ui/checkout-button.d.ts.map +1 -1
  7. package/dist/components/ui/checkout-button.js +2 -1
  8. package/dist/components/ui/product-card.d.ts.map +1 -1
  9. package/dist/components/ui/product-card.js +15 -4
  10. package/dist/components/ui/route-skeleton-loader.d.ts.map +1 -1
  11. package/dist/components/ui/route-skeleton-loader.js +6 -2
  12. package/dist/components/ui/sheet.d.ts.map +1 -1
  13. package/dist/components/ui/sheet.js +2 -2
  14. package/dist/components/ui/skeletons/checkout-skeleton.js +1 -1
  15. package/dist/editor/blocks/defaults/clothing-minimal-home.js +1 -1
  16. package/dist/editor/blocks/migrate-clothing-minimal.js +1 -1
  17. package/dist/hooks/use-pdp-variation.d.ts +57 -0
  18. package/dist/hooks/use-pdp-variation.d.ts.map +1 -0
  19. package/dist/hooks/use-pdp-variation.js +69 -0
  20. package/dist/hooks/use-product-by-slug.d.ts.map +1 -1
  21. package/dist/hooks/use-product-by-slug.js +0 -5
  22. package/dist/hooks/use-product-variation-selection.js +1 -1
  23. package/dist/hooks/use-shipping-quote.d.ts +1 -0
  24. package/dist/hooks/use-shipping-quote.d.ts.map +1 -1
  25. package/dist/hooks/use-shipping-quote.js +3 -0
  26. package/dist/layouts/booking/pages/ProductDetailPage.d.ts.map +1 -1
  27. package/dist/layouts/booking/pages/ProductDetailPage.js +130 -223
  28. package/dist/layouts/booking-agenda/pages/ProductDetailPage.d.ts.map +1 -1
  29. package/dist/layouts/booking-agenda/pages/ProductDetailPage.js +130 -223
  30. package/dist/layouts/clothing/components/ClothingHomePage.d.ts.map +1 -1
  31. package/dist/layouts/clothing/components/ClothingHomePage.js +40 -2
  32. package/dist/layouts/clothing/pages/ProductDetailPage.d.ts.map +1 -1
  33. package/dist/layouts/clothing/pages/ProductDetailPage.js +127 -209
  34. package/dist/layouts/clothing/pages/ProductsPage.d.ts.map +1 -1
  35. package/dist/layouts/clothing/pages/ProductsPage.js +2 -5
  36. package/dist/layouts/clothing-minimal/components/ClothingHomePageMinimal.d.ts.map +1 -1
  37. package/dist/layouts/clothing-minimal/components/ClothingHomePageMinimal.js +5 -3
  38. package/dist/layouts/clothing-minimal/components/clothing-minimal-block-render.d.ts.map +1 -1
  39. package/dist/layouts/clothing-minimal/components/clothing-minimal-block-render.js +13 -4
  40. package/dist/layouts/clothing-minimal/pages/ProductDetailPage.d.ts.map +1 -1
  41. package/dist/layouts/clothing-minimal/pages/ProductDetailPage.js +130 -223
  42. package/dist/layouts/clothing-minimal/pages/ProductsPage.d.ts.map +1 -1
  43. package/dist/layouts/clothing-minimal/pages/ProductsPage.js +2 -5
  44. package/dist/layouts/electronics/components/ElectronicsGridProductCard.js +1 -1
  45. package/dist/layouts/electronics/components/ElectronicsStoreHeader.d.ts.map +1 -1
  46. package/dist/layouts/electronics/components/ElectronicsStoreHeader.js +10 -9
  47. package/dist/layouts/electronics/pages/ProductDetailPage.d.ts.map +1 -1
  48. package/dist/layouts/electronics/pages/ProductDetailPage.js +130 -223
  49. package/dist/layouts/electronics/pages/ProductsPage.d.ts.map +1 -1
  50. package/dist/layouts/electronics/pages/ProductsPage.js +2 -5
  51. package/dist/layouts/electronics-grid/components/ElectronicsGridProductCard.js +1 -1
  52. package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.d.ts.map +1 -1
  53. package/dist/layouts/electronics-grid/components/ElectronicsHomePageGrid.js +4 -5
  54. package/dist/layouts/electronics-grid/pages/ProductDetailPage.d.ts.map +1 -1
  55. package/dist/layouts/electronics-grid/pages/ProductDetailPage.js +130 -223
  56. package/dist/layouts/electronics-grid/pages/ProductsPage.d.ts.map +1 -1
  57. package/dist/layouts/electronics-grid/pages/ProductsPage.js +2 -5
  58. package/dist/layouts/food/pages/MenuPage.js +1 -1
  59. package/dist/layouts/food/pages/ProductDetailPage.d.ts.map +1 -1
  60. package/dist/layouts/food/pages/ProductDetailPage.js +37 -140
  61. package/dist/layouts/food/pages/ProductsPage.d.ts.map +1 -1
  62. package/dist/layouts/food/pages/ProductsPage.js +2 -5
  63. package/dist/layouts/food-modern/pages/MenuPage.js +1 -1
  64. package/dist/layouts/food-modern/pages/ProductDetailPage.d.ts.map +1 -1
  65. package/dist/layouts/food-modern/pages/ProductDetailPage.js +130 -223
  66. package/dist/layouts/food-modern/pages/ProductsPage.d.ts.map +1 -1
  67. package/dist/layouts/food-modern/pages/ProductsPage.js +2 -5
  68. package/dist/layouts/motivational-speaker/pages/ProductsPage.d.ts.map +1 -1
  69. package/dist/layouts/motivational-speaker/pages/ProductsPage.js +2 -5
  70. package/dist/layouts/shared/components/PdpColorSwatch.d.ts +11 -0
  71. package/dist/layouts/shared/components/PdpColorSwatch.d.ts.map +1 -0
  72. package/dist/layouts/shared/components/PdpColorSwatch.js +29 -0
  73. package/dist/layouts/shared/components/PdpVariationSelectors.d.ts +13 -0
  74. package/dist/layouts/shared/components/PdpVariationSelectors.d.ts.map +1 -0
  75. package/dist/layouts/shared/components/PdpVariationSelectors.js +65 -0
  76. package/dist/layouts/shared/components/StoreCartSheet.d.ts +8 -0
  77. package/dist/layouts/shared/components/StoreCartSheet.d.ts.map +1 -0
  78. package/dist/layouts/shared/components/StoreCartSheet.js +16 -0
  79. package/dist/layouts/shared/components/StoreHeader.d.ts.map +1 -1
  80. package/dist/layouts/shared/components/StoreHeader.js +13 -12
  81. package/dist/layouts/shared/components/headers/ClothingMinimalHeader.d.ts.map +1 -1
  82. package/dist/layouts/shared/components/headers/ClothingMinimalHeader.js +5 -7
  83. package/dist/layouts/shared/pages/CartPage.d.ts.map +1 -1
  84. package/dist/layouts/shared/pages/CartPage.js +6 -5
  85. package/dist/layouts/shared/pages/CheckoutPage.d.ts.map +1 -1
  86. package/dist/layouts/shared/pages/CheckoutPage.js +209 -107
  87. package/dist/layouts/shared/product-category-filter-chip.d.ts +2 -0
  88. package/dist/layouts/shared/product-category-filter-chip.d.ts.map +1 -0
  89. package/dist/layouts/shared/product-category-filter-chip.js +6 -0
  90. package/dist/lib/pdp-cart-actions.d.ts +5 -0
  91. package/dist/lib/pdp-cart-actions.d.ts.map +1 -0
  92. package/dist/lib/pdp-cart-actions.js +19 -0
  93. package/dist/lib/product-variation-utils.d.ts +17 -0
  94. package/dist/lib/product-variation-utils.d.ts.map +1 -1
  95. package/dist/lib/product-variation-utils.js +193 -14
  96. package/dist/lib/services/checkout.service.d.ts +11 -0
  97. package/dist/lib/services/checkout.service.d.ts.map +1 -1
  98. package/dist/lib/services/shipping.service.d.ts +3 -0
  99. package/dist/lib/services/shipping.service.d.ts.map +1 -1
  100. package/dist/lib/store-config-utils.d.ts.map +1 -1
  101. package/dist/lib/store-config-utils.js +104 -11
  102. package/dist/lib/store-context.d.ts.map +1 -1
  103. package/dist/lib/store-context.js +23 -8
  104. package/dist/lib/utils/asset-helpers.d.ts +2 -0
  105. package/dist/lib/utils/asset-helpers.d.ts.map +1 -1
  106. package/dist/lib/utils/asset-helpers.js +24 -0
  107. package/dist/styles/index.css +143 -45
  108. package/package.json +8 -2
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { Button } from '../../../components/ui/button.js';
4
- import { ArrowLeft, ShieldCheck, CheckCircle, MapPin, Lock, ChevronRight, Tag, Truck, ChevronDown } from 'lucide-react';
4
+ import { ArrowLeft, CheckCircle, Lock, ChevronDown, Trash2 } from 'lucide-react';
5
5
  import Link from 'next/link';
6
6
  import Image from 'next/image';
7
7
  import { useState, useEffect, useRef } from 'react';
@@ -22,17 +22,120 @@ import { countries, getCountryByName, getCitiesByCountry } from '../../../lib/co
22
22
  import { calculateVAT, getVATLabel } from '../../../lib/utils/fee-calculations.js';
23
23
  import { shippingService } from '../../../lib/services/shipping.service.js';
24
24
  import { feesService } from '../../../lib/services/fees.service.js';
25
- import { CheckoutSkeleton } from '../../../components/ui/skeletons/checkout-skeleton.js';
25
+ import { getCartLineImage } from '../../../lib/product-variation-utils.js';
26
26
  import { useAnalytics } from '../../../hooks/use-analytics.js';
27
+ function selectedDisplayCurrency() {
28
+ if (typeof document === 'undefined')
29
+ return undefined;
30
+ const value = document.cookie.match(/(?:^|; )shopaza_currency=([^;]+)/)?.[1]?.toUpperCase();
31
+ return value && /^[A-Z]{3}$/.test(value) ? value : undefined;
32
+ }
33
+ function ContactInformationIcon({ className }) {
34
+ return (_jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 90 90", className: className, "aria-hidden": true, children: [_jsx("path", { fill: "#000", d: "M 81.353 50.79 L 63.143 36.799 l 18.302 -15.87 c 0.834 -0.723 0.924 -1.986 0.2 -2.82 c -0.723 -0.834 -1.985 -0.925 -2.82 -0.201 L 58.682 35.374 c -0.005 0.004 -0.009 0.008 -0.014 0.012 l -4.921 4.267 L 28.669 17.907 c -0.834 -0.724 -2.096 -0.633 -2.82 0.201 c -0.723 0.834 -0.634 2.097 0.201 2.82 l 18.44 15.99 l -12.442 9.912 c -0.864 0.688 -1.006 1.946 -0.318 2.81 c 0.395 0.496 0.977 0.754 1.565 0.754 c 0.436 0 0.876 -0.143 1.244 -0.435 l 13.024 -10.375 l 4.874 4.226 c 0.376 0.326 0.843 0.489 1.31 0.489 c 0.467 0 0.934 -0.163 1.31 -0.489 l 5.002 -4.337 l 18.858 14.488 c 0.363 0.279 0.792 0.414 1.217 0.414 c 0.599 0 1.193 -0.268 1.586 -0.781 C 82.393 52.718 82.229 51.463 81.353 50.79 z" }), _jsx("path", { fill: "#000", d: "M 84.004 10.598 H 23.49 c -3.306 0 -5.996 2.69 -5.996 5.996 v 1.616 c -1.125 -0.827 -2.636 -1.044 -3.982 -0.453 c -0.87 0.383 -2.006 0.88 -3.19 1.394 l -0.032 0.014 c -2.526 1.095 -4.385 1.88 -5.378 2.269 c -0.741 0.29 -1.362 0.72 -1.845 1.278 c -8.173 9.429 1.178 26.658 14.071 39.551 c 9.539 9.539 21.449 17.14 30.82 17.139 c 3.296 -0.001 6.278 -0.941 8.731 -3.066 c 0.557 -0.483 0.987 -1.104 1.278 -1.846 c 0.395 -1.009 1.171 -2.847 2.304 -5.456 c 0.507 -1.168 0.996 -2.286 1.373 -3.144 c 0.621 -1.413 0.355 -3.01 -0.578 -4.148 h 22.939 c 3.307 0 5.996 -2.69 5.996 -5.996 v -39.15 C 90 13.288 87.31 10.598 84.004 10.598 z M 56.603 67.439 c -1.152 2.656 -1.947 4.538 -2.36 5.592 c -0.05 0.127 -0.113 0.23 -0.173 0.282 c -7.118 6.171 -22.543 -2.315 -34.105 -13.877 C 8.402 47.872 -0.078 32.445 6.088 25.331 c 0.053 -0.061 0.156 -0.124 0.283 -0.174 c 1.063 -0.416 2.944 -1.21 5.592 -2.359 v 0 c 1.173 -0.509 2.296 -1 3.168 -1.373 l 7.266 12.256 l -4.505 8.393 c -0.843 1.57 -0.562 3.471 0.698 4.732 l 14.007 14.007 c 1.262 1.26 3.164 1.541 4.731 0.696 l 8.404 -4.505 l 12.245 7.267 l 0.006 0.01 C 57.603 65.144 57.11 66.268 56.603 67.439 z M 86.001 55.744 c 0 1.101 -0.896 1.997 -1.997 1.997 H 54.809 l -7.038 -4.177 c -1.201 -0.712 -2.711 -0.744 -3.942 -0.083 l -8.406 4.503 l -14.008 -14.02 l 4.505 -8.392 c 0.66 -1.231 0.628 -2.741 -0.084 -3.943 l -4.343 -7.319 v -7.716 c 0 -1.101 0.896 -1.997 1.997 -1.997 h 60.514 c 1.101 0 1.997 0.896 1.997 1.997 V 55.744 z" })] }));
35
+ }
36
+ function ShippingAddressIcon({ className }) {
37
+ const paths = [
38
+ 'M 24.342 65.261 H 8.063 c -0.557 0 -1.009 -0.451 -1.009 -1.009 c 0 -0.558 0.452 -1.009 1.009 -1.009 h 16.279 c 0.557 0 1.009 0.451 1.009 1.009 C 25.351 64.81 24.899 65.261 24.342 65.261 z',
39
+ 'M 24.77 57.374 H 1.009 C 0.452 57.374 0 56.923 0 56.365 c 0 -0.557 0.452 -1.009 1.009 -1.009 H 24.77 c 0.557 0 1.009 0.452 1.009 1.009 C 25.779 56.923 25.327 57.374 24.77 57.374 z',
40
+ 'M 14.65 49.487 H 1.009 C 0.452 49.487 0 49.036 0 48.478 c 0 -0.557 0.452 -1.009 1.009 -1.009 H 14.65 c 0.557 0 1.009 0.452 1.009 1.009 C 15.659 49.036 15.207 49.487 14.65 49.487 z',
41
+ 'M 14.65 41.6 H 8.063 c -0.557 0 -1.009 -0.452 -1.009 -1.009 c 0 -0.557 0.452 -1.009 1.009 -1.009 h 6.587 c 0.557 0 1.009 0.452 1.009 1.009 C 15.659 41.148 15.207 41.6 14.65 41.6 z',
42
+ 'M 44.983 52.424 H 25.049 c -2.364 0 -4.288 -1.924 -4.288 -4.289 V 37.088 c 0 -2.364 1.924 -4.288 4.288 -4.288 h 15.646 c 2.364 0 4.288 1.924 4.288 4.288 V 52.424 z M 25.049 34.796 c -1.264 0 -2.293 1.029 -2.293 2.293 v 11.046 c 0 1.265 1.029 2.294 2.293 2.294 h 17.939 v -13.34 c 0 -1.264 -1.029 -2.293 -2.293 -2.293 H 25.049 z',
43
+ 'M 77.874 46.638 h -0.539 c -2.738 0 -4.967 -2.228 -4.967 -4.966 c 0 -2.739 2.229 -4.967 4.967 -4.967 h 0.539 c 1.204 0 2.185 0.98 2.185 2.185 v 5.563 C 80.059 45.657 79.079 46.638 77.874 46.638 z M 77.335 38.701 c -1.638 0 -2.971 1.333 -2.971 2.971 c 0 1.638 1.333 2.971 2.971 2.971 h 0.539 c 0.104 0 0.189 -0.085 0.189 -0.189 V 38.89 c 0 -0.104 -0.085 -0.189 -0.189 -0.189 H 77.335 z',
44
+ 'M 72.705 70.122 c -0.034 0 -0.069 -0.002 -0.103 -0.006 c -0.37 -0.038 -0.687 -0.279 -0.824 -0.625 c -0.932 -2.349 -0.905 -4.925 0.074 -7.251 c 0.994 -2.358 2.847 -4.188 5.217 -5.153 c 2.372 -0.964 4.975 -0.949 7.334 0.045 c 2.578 1.086 4.547 3.245 5.401 5.923 c 0.114 0.354 0.02 0.742 -0.242 1.006 c -0.261 0.264 -0.647 0.361 -1.004 0.25 c -5.6 -1.734 -11.778 0.473 -15.022 5.364 C 73.35 69.957 73.037 70.122 72.705 70.122 z M 80.69 58.378 c -2.961 0 -5.779 1.743 -6.999 4.639 c -0.524 1.244 -0.704 2.579 -0.537 3.89 c 3.47 -3.918 8.779 -5.82 13.943 -4.981 c -0.82 -1.308 -2.024 -2.343 -3.471 -2.953 C 82.667 58.569 81.672 58.378 80.69 58.378 z',
45
+ 'M 58.685 31.156 c -4.865 0 -9.446 -6.178 -9.446 -10.966 c 0 -2.383 1.227 -6.382 9.446 -6.382 c 4.783 0 8.674 3.891 8.674 8.674 S 63.468 31.156 58.685 31.156 z M 58.685 15.803 c -4.944 0 -7.45 1.476 -7.45 4.386 c 0 3.706 3.853 8.971 7.45 8.971 c 3.682 0 6.679 -2.996 6.679 -6.678 S 62.367 15.803 58.685 15.803 z',
46
+ 'M 59.367 31.173 l -1.889 -6.443 c -0.274 -0.935 -0.036 -1.916 0.635 -2.622 c 0.673 -0.706 1.643 -0.989 2.588 -0.765 l 6.693 1.607 l -0.146 0.913 c -0.58 3.619 -3.392 6.492 -6.997 7.149 L 59.367 31.173 z M 60.062 23.262 c -0.26 0 -0.433 0.148 -0.503 0.221 c -0.085 0.088 -0.269 0.333 -0.166 0.685 l 1.366 4.661 c 2.061 -0.671 3.675 -2.314 4.31 -4.385 l -4.834 -1.161 C 60.174 23.269 60.115 23.262 60.062 23.262 z',
47
+ 'M 70.875 41.508 c -0.231 0 -0.463 -0.05 -0.681 -0.151 c -0.781 -0.362 -1.72 -0.57 -2.876 -0.639 c -0.527 -0.031 -0.938 -0.468 -0.938 -0.996 v -3.441 c 0 -0.551 0.446 -0.998 0.998 -0.998 h 2.058 c 1.675 0 3.037 1.362 3.037 3.037 v 1.593 c 0 0.546 -0.274 1.047 -0.733 1.341 C 71.477 41.423 71.177 41.508 70.875 41.508 z M 68.376 38.815 c 0.773 0.1 1.468 0.267 2.102 0.501 v -0.995 c 0 -0.574 -0.468 -1.041 -1.042 -1.041 h -1.06 V 38.815 z',
48
+ 'M 54.901 46.866 c -0.149 0 -0.299 -0.033 -0.438 -0.101 c -0.927 -0.452 -1.924 -0.682 -2.965 -0.682 h -7.513 c -0.551 0 -0.998 -0.447 -0.998 -0.998 V 40.77 c 0 -6.643 5.405 -12.057 12.048 -12.068 c 3.748 0 6.846 2.985 7.86 5.793 c 0.171 0.472 0.613 0.788 1.101 0.788 h 3.381 c 0.552 0 0.998 0.447 0.998 0.998 v 3.649 c 0 1.688 -1.373 3.061 -3.061 3.061 h -4.468 c -1.021 0 -1.986 -0.248 -2.837 -0.686 c -1.424 1.229 -2.134 2.42 -2.112 3.543 c 0.007 0.347 -0.168 0.673 -0.461 0.86 C 55.275 46.813 55.088 46.866 54.901 46.866 z M 44.983 44.087 h 6.515 c 0.892 0 1.759 0.131 2.593 0.389 c 0.33 -1.151 1.095 -2.284 2.286 -3.386 c -1.079 -1.119 -1.743 -2.639 -1.743 -4.312 c 0 -0.551 0.446 -0.998 0.998 -0.998 s 0.998 0.447 0.998 0.998 c 0 2.325 1.892 4.218 4.217 4.218 h 4.468 c 0.588 0 1.065 -0.478 1.065 -1.065 v -2.651 h -2.383 c -1.326 0 -2.524 -0.847 -2.978 -2.107 c -0.67 -1.858 -2.97 -4.475 -5.981 -4.475 c -5.544 0.009 -10.054 4.528 -10.054 10.072 V 44.087 z',
49
+ 'M 59.272 61.939 H 54.95 c -2.015 0 -3.655 -1.64 -3.655 -3.655 v -2.541 c 0 -1.83 -1.489 -3.319 -3.32 -3.319 h -3.989 c -0.551 0 -0.998 -0.446 -0.998 -0.998 v -6.341 c 0 -0.551 0.447 -0.998 0.998 -0.998 h 7.513 c 4.837 0 8.772 3.935 8.772 8.771 v 8.083 C 60.27 61.493 59.824 61.939 59.272 61.939 z M 44.983 50.428 h 2.991 c 2.931 0 5.315 2.384 5.315 5.315 v 2.541 c 0 0.915 0.744 1.659 1.659 1.659 h 3.325 v -7.085 c 0 -3.736 -3.04 -6.776 -6.776 -6.776 h -6.515 V 50.428 z',
50
+ 'M 43.232 72.36 c -2.694 0 -4.886 -2.192 -4.886 -4.887 c 0 -0.357 0.045 -0.723 0.139 -1.121 l 1.942 0.458 c -0.057 0.246 -0.086 0.462 -0.086 0.663 c 0 1.594 1.297 2.891 2.891 2.891 s 2.891 -1.297 2.891 -2.891 c 0 -0.201 -0.028 -0.417 -0.086 -0.662 l 1.941 -0.46 c 0.095 0.397 0.14 0.764 0.14 1.122 C 48.118 70.167 45.927 72.36 43.232 72.36 z',
51
+ 'M 43.232 76.192 c -4.807 0 -8.719 -3.911 -8.719 -8.719 c 0 -0.34 0.024 -0.674 0.062 -1.006 l 1.983 0.228 c -0.03 0.255 -0.049 0.514 -0.049 0.778 c 0 3.708 3.016 6.724 6.723 6.724 s 6.723 -3.016 6.723 -6.724 c 0 -0.263 -0.019 -0.521 -0.049 -0.777 l 1.982 -0.23 c 0.039 0.331 0.062 0.666 0.062 1.007 C 51.951 72.281 48.039 76.192 43.232 76.192 z',
52
+ 'M 81.281 76.192 c -4.593 0 -8.411 -3.593 -8.692 -8.179 l 1.992 -0.123 c 0.216 3.536 3.16 6.306 6.7 6.306 c 3.708 0 6.724 -3.016 6.724 -6.724 c 0 -1.388 -0.425 -2.724 -1.228 -3.864 l 1.631 -1.15 C 89.449 63.938 90 65.671 90 67.473 C 90 72.281 86.089 76.192 81.281 76.192 z',
53
+ 'M 81.281 72.36 c -2.694 0 -4.886 -2.192 -4.886 -4.887 s 2.191 -4.886 4.886 -4.886 s 4.887 2.191 4.887 4.886 S 83.975 72.36 81.281 72.36 z M 81.281 64.583 c -1.593 0 -2.89 1.297 -2.89 2.89 c 0 1.594 1.297 2.891 2.89 2.891 c 1.594 0 2.891 -1.297 2.891 -2.891 C 84.172 65.88 82.875 64.583 81.281 64.583 z',
54
+ 'M 73.202 67.579 h -40.58 c -1.143 0 -2.215 -0.56 -2.868 -1.5 c -0.653 -0.939 -0.804 -2.14 -0.405 -3.212 l 1.929 -5.185 c 1.615 -4.339 5.811 -7.255 10.441 -7.255 h 6.257 c 2.931 0 5.315 2.384 5.315 5.315 v 2.541 c 0 0.915 0.744 1.659 1.659 1.659 h 12.403 c 0.575 0 1.114 -0.254 1.477 -0.699 c 0.372 -0.452 0.516 -1.039 0.395 -1.611 l -3.402 -16.07 l 1.953 -0.413 l 3.402 16.07 c 0.248 1.169 -0.046 2.369 -0.805 3.292 c -0.744 0.906 -1.845 1.427 -3.02 1.427 H 54.95 c -2.015 0 -3.655 -1.64 -3.655 -3.655 v -2.541 c 0 -1.83 -1.489 -3.319 -3.32 -3.319 h -6.257 c -3.801 0 -7.245 2.393 -8.571 5.955 l -1.929 5.185 c -0.173 0.467 -0.11 0.969 0.174 1.377 c 0.284 0.409 0.732 0.643 1.229 0.643 h 38.489 c 0.041 -1.15 0.289 -2.269 0.741 -3.342 c 1.415 -3.355 4.617 -5.577 8.157 -5.829 l -9.4 -16.486 l 1.734 -0.988 l 11.263 19.755 l -1.98 -0.249 c -3.356 -0.428 -6.622 1.457 -7.935 4.574 c -0.468 1.109 -0.659 2.283 -0.569 3.49 L 73.202 67.579 z',
55
+ ];
56
+ return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 90 90", className: className, "aria-hidden": true, children: paths.map((d) => (_jsx("path", { fill: "#000", d: d }, d.slice(0, 24)))) }));
57
+ }
58
+ function ShippingMethodIcon({ className }) {
59
+ const paths = [
60
+ 'M 87.364 62.295 h -1.948 v -2 h 1.948 c 0.351 0 0.636 -0.285 0.636 -0.636 V 49.441 c 0 -0.155 -0.058 -0.307 -0.161 -0.424 L 77.65 37.558 c -0.121 -0.136 -0.294 -0.214 -0.476 -0.214 h -9.356 v 22.951 h 8.401 v 2 H 65.818 V 35.344 h 11.356 c 0.752 0 1.47 0.322 1.97 0.885 L 89.334 47.69 C 89.764 48.175 90 48.797 90 49.441 v 10.218 C 90 61.112 88.817 62.295 87.364 62.295 z',
61
+ 'M 67.818 62.295 H 47.291 v -2 h 18.527 V 28.877 c 0 -1.95 -1.202 -3.537 -2.681 -3.537 H 31.866 c -1.479 0 -2.681 1.587 -2.681 3.537 v 30.23 c 0 0.7 0.408 1.188 0.774 1.188 h 8.143 v 2 h -8.143 c -1.53 0 -2.774 -1.43 -2.774 -3.188 v -30.23 c 0 -3.053 2.1 -5.537 4.681 -5.537 h 31.272 c 2.581 0 4.681 2.484 4.681 5.537 V 62.295 z',
62
+ 'M 80.817 66.66 c -3.087 0 -5.598 -2.511 -5.598 -5.598 s 2.511 -5.599 5.598 -5.599 s 5.599 2.512 5.599 5.599 S 83.904 66.66 80.817 66.66 z M 80.817 57.464 c -1.983 0 -3.598 1.614 -3.598 3.599 c 0 1.983 1.614 3.598 3.598 3.598 c 1.984 0 3.599 -1.614 3.599 -3.598 C 84.416 59.078 82.802 57.464 80.817 57.464 z',
63
+ 'M 42.693 66.66 c -3.087 0 -5.598 -2.511 -5.598 -5.598 s 2.511 -5.599 5.598 -5.599 s 5.598 2.512 5.598 5.599 S 45.78 66.66 42.693 66.66 z M 42.693 57.464 c -1.984 0 -3.598 1.614 -3.598 3.599 c 0 1.983 1.614 3.598 3.598 3.598 s 3.598 -1.614 3.598 -3.598 C 46.291 59.078 44.677 57.464 42.693 57.464 z',
64
+ 'M 89 49.819 H 74.619 c -1.358 0 -2.463 -1.104 -2.463 -2.462 v -5.44 c 0 -1.358 1.104 -2.463 2.463 -2.463 h 6.944 v 2 h -6.944 c -0.255 0 -0.463 0.208 -0.463 0.463 v 5.44 c 0 0.255 0.208 0.462 0.463 0.462 H 89 V 49.819 z',
65
+ 'M 21.207 52.942 H 8.615 c -0.552 0 -1 -0.447 -1 -1 s 0.448 -1 1 -1 h 12.592 c 0.552 0 1 0.447 1 1 S 21.759 52.942 21.207 52.942 z',
66
+ 'M 21.207 46.031 H 4.617 c -0.552 0 -1 -0.448 -1 -1 s 0.448 -1 1 -1 h 16.59 c 0.552 0 1 0.448 1 1 S 21.759 46.031 21.207 46.031 z',
67
+ 'M 21.207 39.121 H 1 c -0.552 0 -1 -0.448 -1 -1 s 0.448 -1 1 -1 h 20.207 c 0.552 0 1 0.448 1 1 S 21.759 39.121 21.207 39.121 z',
68
+ 'M 53.547 50.354 h -12.09 c -0.552 0 -1 -0.447 -1 -1 v -8.525 h -1.41 c -0.425 0 -0.804 -0.269 -0.944 -0.67 c -0.14 -0.402 -0.011 -0.848 0.322 -1.113 l 8.455 -6.716 c 0.365 -0.289 0.879 -0.289 1.244 0 l 8.455 6.716 c 0.333 0.265 0.462 0.711 0.322 1.113 c -0.141 0.401 -0.519 0.67 -0.944 0.67 h -1.41 v 8.525 C 54.547 49.906 54.1 50.354 53.547 50.354 z M 42.457 48.354 h 10.09 v -8.525 c 0 -0.422 0.262 -0.783 0.632 -0.93 l -5.677 -4.509 l -5.677 4.509 c 0.37 0.146 0.631 0.508 0.631 0.93 V 48.354 z',
69
+ 'M 47.502 50.354 c -0.553 0 -1 -0.447 -1 -1 v -5.876 c 0 -0.552 0.447 -1 1 -1 s 1 0.448 1 1 v 5.876 C 48.502 49.906 48.055 50.354 47.502 50.354 z',
70
+ ];
71
+ return (_jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 90 90", className: className, "aria-hidden": true, children: paths.map((d, i) => (_jsx("path", { fill: "#000", d: d }, i))) }));
72
+ }
73
+ function shippingMethodSummaryLabel(name) {
74
+ const dash = name.indexOf(' - ');
75
+ return dash > 0 ? name.slice(0, dash).trim() : name.trim();
76
+ }
77
+ function formatBusinessDaysLabel(min, max, fallback) {
78
+ const lo = min ?? fallback;
79
+ const hi = max ?? fallback;
80
+ if (lo == null && hi == null)
81
+ return '';
82
+ if (lo != null && hi != null && lo !== hi) {
83
+ return `${lo}-${hi} business days`;
84
+ }
85
+ const days = lo ?? hi;
86
+ return days === 1 ? '1 business day' : `${days} business days`;
87
+ }
88
+ function shippingMethodDescriptionText(method, deliveryEstimate) {
89
+ const desc = method.description?.trim();
90
+ if (!desc)
91
+ return null;
92
+ if (deliveryEstimate && /^\d+\s*day\(s\)$/i.test(desc))
93
+ return null;
94
+ // Fez (and similar) return API status text — show something shoppers understand
95
+ if (/cost\s+fetched\s+successfully/i.test(desc) || /^success(fully)?$/i.test(desc)) {
96
+ return 'Available for your delivery address';
97
+ }
98
+ return desc;
99
+ }
100
+ function estimatedDeliveryText(method) {
101
+ if (method.estimatedDaysMin != null || method.estimatedDaysMax != null) {
102
+ const label = formatBusinessDaysLabel(method.estimatedDaysMin, method.estimatedDaysMax, method.estimatedDays);
103
+ return label ? `Estimated delivery: ${label}` : null;
104
+ }
105
+ if (method.estimatedDays) {
106
+ const label = formatBusinessDaysLabel(undefined, undefined, method.estimatedDays);
107
+ return label ? `Estimated delivery: ${label}` : null;
108
+ }
109
+ return null;
110
+ }
111
+ function readCachedCartForCheckout(slug) {
112
+ if (typeof window === 'undefined')
113
+ return [];
114
+ try {
115
+ const saved = localStorage.getItem(`cart_${slug}`);
116
+ const items = saved ? JSON.parse(saved) : [];
117
+ return Array.isArray(items) ? items : [];
118
+ }
119
+ catch {
120
+ return [];
121
+ }
122
+ }
27
123
  export function CheckoutPage({ storeConfig }) {
28
124
  const primaryColor = storeConfig.branding.primaryColor;
29
- const { cart, cartTotal, buyNowItem, clearBuyNowItem, setBuyNowItem } = useStore();
125
+ const storeState = useStore();
126
+ const { cart, cartTotal, buyNowItem, clearBuyNowItem, setBuyNowItem, removeFromCart } = storeState;
127
+ const [cachedCart, setCachedCart] = useState([]);
128
+ const [clientCartReady, setClientCartReady] = useState(false);
129
+ useEffect(() => {
130
+ setCachedCart(readCachedCartForCheckout(storeConfig.slug));
131
+ setClientCartReady(true);
132
+ }, [storeConfig.slug]);
30
133
  const { addToast } = useToast();
31
134
  const router = useRouter();
32
135
  const { user, isAuthenticated } = useAuth();
33
136
  const { trackEvent } = useAnalytics();
34
137
  // Read from sessionStorage synchronously on mount if buyNowItem is not in context
35
- const [sessionBuyNowItem] = useState(() => {
138
+ const [sessionBuyNowItem, setSessionBuyNowItem] = useState(() => {
36
139
  if (typeof window === 'undefined')
37
140
  return null;
38
141
  try {
@@ -46,47 +149,35 @@ export function CheckoutPage({ storeConfig }) {
46
149
  }
47
150
  return null;
48
151
  });
49
- // State to track initialization
50
- const [isInitializing, setIsInitializing] = useState(true);
51
152
  const hasRestoredRef = useRef(false);
52
153
  // Restore buyNowItem from sessionStorage to context if needed (only once on mount)
53
154
  useEffect(() => {
54
- // Only run restoration once
55
- if (hasRestoredRef.current) {
155
+ if (hasRestoredRef.current)
56
156
  return;
57
- }
58
157
  hasRestoredRef.current = true;
59
- // If item is already in context, we're done
60
- if (buyNowItem || sessionBuyNowItem) {
61
- setIsInitializing(false);
62
- return;
63
- }
64
- // If we have sessionBuyNowItem but not in context, restore it
65
- if (sessionBuyNowItem) {
158
+ if (!buyNowItem && sessionBuyNowItem) {
66
159
  setBuyNowItem(sessionBuyNowItem);
67
160
  }
68
- // Add a small delay to ensure state propagation
69
- const timer = setTimeout(() => {
70
- setIsInitializing(false);
71
- }, 150);
72
- return () => clearTimeout(timer);
73
161
  // eslint-disable-next-line react-hooks/exhaustive-deps
74
- }, []); // Only run once on mount
75
- // Stop initializing if buyNowItem becomes available after mount
76
- useEffect(() => {
77
- if (buyNowItem && isInitializing) {
78
- setIsInitializing(false);
79
- }
80
- }, [buyNowItem, isInitializing]);
81
- // Use buyNowItem from context or sessionStorage, otherwise use cart
162
+ }, []);
82
163
  const effectiveBuyNowItem = buyNowItem || sessionBuyNowItem;
83
- const checkoutItems = effectiveBuyNowItem ? [effectiveBuyNowItem] : cart;
164
+ const cartForCheckout = cart.length > 0 ? cart : cachedCart;
165
+ const checkoutItems = effectiveBuyNowItem ? [effectiveBuyNowItem] : cartForCheckout;
84
166
  const checkoutTotal = effectiveBuyNowItem
85
167
  ? effectiveBuyNowItem.price * effectiveBuyNowItem.quantity
86
- : cartTotal;
87
- const [step, setStep] = useState('details');
168
+ : cart.length > 0
169
+ ? cartTotal
170
+ : cartForCheckout.reduce((total, item) => total + normalizePrice(item.price) * item.quantity, 0);
171
+ const handleRemoveCheckoutItem = async (itemId) => {
172
+ if (effectiveBuyNowItem && effectiveBuyNowItem.id === itemId) {
173
+ clearBuyNowItem();
174
+ setSessionBuyNowItem(null);
175
+ return;
176
+ }
177
+ await removeFromCart(itemId);
178
+ setCachedCart((prev) => prev.filter((item) => item.id !== itemId));
179
+ };
88
180
  const [loading, setLoading] = useState(false);
89
- const [isLoaded, setIsLoaded] = useState(() => typeof window !== 'undefined');
90
181
  // Address management state
91
182
  const [savedAddresses, setSavedAddresses] = useState([]);
92
183
  const [selectedAddressId, setSelectedAddressId] = useState(null);
@@ -100,6 +191,7 @@ export function CheckoutPage({ storeConfig }) {
100
191
  const [shippingError, setShippingError] = useState(null);
101
192
  const [freeShippingEligible, setFreeShippingEligible] = useState(false);
102
193
  const [freeShippingThreshold, setFreeShippingThreshold] = useState(undefined);
194
+ const [freeShippingEnabled, setFreeShippingEnabled] = useState(false);
103
195
  const [feePreview, setFeePreview] = useState(null);
104
196
  const [isCalculatingFees, setIsCalculatingFees] = useState(false);
105
197
  const { checkout: initiateCheckout, isLoading: isPayazaLoading } = usePayazaCheckout({
@@ -234,11 +326,7 @@ export function CheckoutPage({ storeConfig }) {
234
326
  },
235
327
  });
236
328
  useEffect(() => {
237
- setIsLoaded(true);
238
- }, []);
239
- // Track checkout_start event when checkout page loads with items
240
- useEffect(() => {
241
- if (isLoaded && !isInitializing && storeConfig?.id && (checkoutItems.length > 0 || effectiveBuyNowItem)) {
329
+ if (storeConfig?.id && (checkoutItems.length > 0 || effectiveBuyNowItem)) {
242
330
  const totalValue = checkoutTotal;
243
331
  const itemCount = checkoutItems.length;
244
332
  trackEvent({
@@ -254,42 +342,38 @@ export function CheckoutPage({ storeConfig }) {
254
342
  },
255
343
  }).catch(err => console.warn('Failed to track checkout_start:', err));
256
344
  }
257
- }, [isLoaded, isInitializing, storeConfig?.id, checkoutItems, effectiveBuyNowItem, checkoutTotal, trackEvent]);
258
- // Redirect to home if checkout items are empty (with delay to allow state propagation)
345
+ }, [storeConfig?.id, checkoutItems, effectiveBuyNowItem, checkoutTotal, trackEvent]);
259
346
  useEffect(() => {
260
- if (!isInitializing && isLoaded) {
261
- // Add a delay to ensure buyNowItem state has propagated
262
- const redirectTimer = setTimeout(() => {
263
- // Check again if we have buyNowItem in sessionStorage (even if not in context yet)
264
- const hasBuyNowInStorage = typeof window !== 'undefined' && sessionStorage.getItem('buyNowItem');
265
- // Don't redirect if we have buyNowItem in sessionStorage or if checkoutItems exist
266
- if (hasBuyNowInStorage) {
267
- // If we have it in storage but not in state, try to restore it one more time
268
- if (!effectiveBuyNowItem) {
269
- try {
270
- const stored = sessionStorage.getItem('buyNowItem');
271
- if (stored) {
272
- const parsedItem = JSON.parse(stored);
273
- setBuyNowItem(parsedItem);
274
- return; // Don't redirect, we're restoring the item
275
- }
276
- }
277
- catch (error) {
278
- console.error('Failed to restore buyNowItem:', error);
347
+ const redirectTimer = setTimeout(() => {
348
+ // Check again if we have buyNowItem in sessionStorage (even if not in context yet)
349
+ const hasBuyNowInStorage = typeof window !== 'undefined' && sessionStorage.getItem('buyNowItem');
350
+ // Don't redirect if we have buyNowItem in sessionStorage or if checkoutItems exist
351
+ if (hasBuyNowInStorage) {
352
+ // If we have it in storage but not in state, try to restore it one more time
353
+ if (!effectiveBuyNowItem) {
354
+ try {
355
+ const stored = sessionStorage.getItem('buyNowItem');
356
+ if (stored) {
357
+ const parsedItem = JSON.parse(stored);
358
+ setBuyNowItem(parsedItem);
359
+ return; // Don't redirect, we're restoring the item
279
360
  }
280
361
  }
281
- else {
282
- return; // We have the item, don't redirect
362
+ catch (error) {
363
+ console.error('Failed to restore buyNowItem:', error);
283
364
  }
284
365
  }
285
- // Only redirect if we truly have no items and no buyNowItem in storage
286
- if (!checkoutItems || checkoutItems.length === 0) {
287
- router.push(`/${storeConfig.slug}`);
366
+ else {
367
+ return; // We have the item, don't redirect
288
368
  }
289
- }, 400);
290
- return () => clearTimeout(redirectTimer);
291
- }
292
- }, [checkoutItems, isLoaded, isInitializing, router, storeConfig.slug, effectiveBuyNowItem, setBuyNowItem]);
369
+ }
370
+ // Only redirect if we truly have no items and no buyNowItem in storage
371
+ if (!checkoutItems || checkoutItems.length === 0) {
372
+ router.push(`/${storeConfig.slug}`);
373
+ }
374
+ }, 400);
375
+ return () => clearTimeout(redirectTimer);
376
+ }, [checkoutItems, router, storeConfig.slug, effectiveBuyNowItem, setBuyNowItem]);
293
377
  // Clear buyNowItem when component unmounts or user navigates away
294
378
  useEffect(() => {
295
379
  return () => {
@@ -374,6 +458,9 @@ export function CheckoutPage({ storeConfig }) {
374
458
  if (!formData.city || !formData.country || checkoutItems.length === 0) {
375
459
  setShippingMethods([]);
376
460
  setSelectedShippingMethod(null);
461
+ setFreeShippingEligible(false);
462
+ setFreeShippingThreshold(undefined);
463
+ setFreeShippingEnabled(false);
377
464
  return;
378
465
  }
379
466
  setIsCalculatingShipping(true);
@@ -398,6 +485,7 @@ export function CheckoutPage({ storeConfig }) {
398
485
  setShippingMethods(validMethods);
399
486
  setFreeShippingEligible(result.freeShippingEligible || false);
400
487
  setFreeShippingThreshold(result.freeShippingThreshold);
488
+ setFreeShippingEnabled(result.freeShippingEnabled === true);
401
489
  // Auto-select first method or selected method, but only if it has valid cost
402
490
  if (validMethods.length > 0) {
403
491
  // Find the selected method in valid methods, or use first valid method
@@ -428,6 +516,9 @@ export function CheckoutPage({ storeConfig }) {
428
516
  };
429
517
  // Determine currency from checkout items or store config (avoid switching to USD at checkout)
430
518
  const getCurrency = () => {
519
+ const selected = selectedDisplayCurrency();
520
+ if (selected)
521
+ return selected;
431
522
  if (checkoutItems.length > 0) {
432
523
  const itemCurrency = checkoutItems[0]?.currency ?? checkoutItems[0]?.product?.currency;
433
524
  if (itemCurrency)
@@ -548,14 +639,6 @@ export function CheckoutPage({ storeConfig }) {
548
639
  setErrors(newErrors);
549
640
  return Object.keys(newErrors).length === 0;
550
641
  };
551
- const [promoCode, setPromoCode] = useState('');
552
- const [isPromoApplied, setIsPromoApplied] = useState(false);
553
- const handleApplyPromo = () => {
554
- if (!promoCode)
555
- return;
556
- setIsPromoApplied(true);
557
- addToast('Promo code applied successfully!', 'success');
558
- };
559
642
  // Handle address selection
560
643
  const handleAddressSelect = (addressId) => {
561
644
  if (addressId === null) {
@@ -657,6 +740,8 @@ export function CheckoutPage({ storeConfig }) {
657
740
  productId: item.productId,
658
741
  quantity: item.quantity,
659
742
  price: item.price,
743
+ currency: item.currency ?? currency,
744
+ variationId: item.variantId,
660
745
  variantId: item.variantId,
661
746
  })),
662
747
  customerInfo: {
@@ -679,6 +764,8 @@ export function CheckoutPage({ storeConfig }) {
679
764
  shippingCost: shipping, // Use validated shipping value
680
765
  paymentMethod: 'payaza',
681
766
  customerId: isAuthenticated && user ? user.id : undefined, // Pass customerId for authenticated users
767
+ displayCurrency: currency,
768
+ chargeCurrency: currency,
682
769
  });
683
770
  console.log('[Checkout] Step 1: Order created successfully', {
684
771
  orderId: checkoutResponse.orderId,
@@ -738,7 +825,7 @@ export function CheckoutPage({ storeConfig }) {
738
825
  product: {
739
826
  name: item.product.name,
740
827
  price: item.price,
741
- currency: item.product.currency,
828
+ currency,
742
829
  },
743
830
  quantity: item.quantity,
744
831
  price: item.price,
@@ -872,60 +959,75 @@ export function CheckoutPage({ storeConfig }) {
872
959
  setLoading(false);
873
960
  }
874
961
  };
875
- const handleDetailsSubmit = (e) => {
962
+ const handleDetailsSubmit = async (e) => {
876
963
  e.preventDefault();
877
- if (validateForm()) {
878
- setStep('payment');
879
- window.scrollTo({ top: 0, behavior: 'smooth' });
880
- }
881
- else {
964
+ if (!validateForm()) {
882
965
  addToast('Please fix the errors in the form.', 'error');
883
- // Scroll to the first error or top of form
884
- const firstErrorField = document.querySelector('.border-red-500');
966
+ const firstErrorField = document.querySelector('.border-red-400, .border-red-500');
885
967
  if (firstErrorField) {
886
968
  firstErrorField.scrollIntoView({ behavior: 'smooth', block: 'center' });
887
969
  }
888
970
  else {
889
971
  window.scrollTo({ top: 0, behavior: 'smooth' });
890
972
  }
973
+ return;
891
974
  }
975
+ await handlePayazaCheckout();
892
976
  };
893
- // Show skeleton while initializing or if not loaded
894
- if (isInitializing || !isLoaded) {
895
- return _jsx(CheckoutSkeleton, {});
977
+ const fieldClass = (hasError) => cn('w-full px-4 py-3 rounded-none border bg-white text-base text-gray-900 placeholder:text-gray-400 transition-colors focus:outline-none focus:ring-0', hasError
978
+ ? 'border-red-400 bg-red-50/40 focus:border-red-500'
979
+ : 'border-gray-200 focus:border-gray-900');
980
+ const labelClass = 'text-sm font-medium text-gray-700';
981
+ const sectionClass = 'bg-white p-6 sm:p-8 rounded-sm border border-gray-200/90 shadow-sm';
982
+ const sectionHeaderClass = 'flex items-center gap-3 mb-6 pb-5 border-b border-gray-100';
983
+ if (!clientCartReady && !effectiveBuyNowItem && cart.length === 0) {
984
+ return (_jsx("div", { className: "min-h-screen bg-gray-50/50", "data-checkout-ready": true, "aria-busy": "true" }));
896
985
  }
897
- // Show empty cart message if checkout items are empty (redirect will happen after delay)
898
986
  if (!checkoutItems || checkoutItems.length === 0) {
899
- return (_jsx("div", { className: "min-h-screen bg-gray-50/50 py-12 px-4 sm:px-6 lg:px-8 font-sans", "data-checkout-ready": true, children: _jsx("div", { className: "container mx-auto max-w-6xl", children: _jsx("div", { className: "bg-white rounded-3xl shadow-sm border border-gray-100 p-12 text-center", children: _jsxs("div", { className: "max-w-md mx-auto space-y-6", children: [_jsx("div", { className: "w-20 h-20 mx-auto rounded-full bg-gray-100 flex items-center justify-center", children: _jsx("svg", { className: "w-10 h-10 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" }) }) }), _jsx("h2", { className: "text-2xl font-bold text-gray-900", children: "Your cart is empty" }), _jsx("p", { className: "text-gray-600", children: "Add some items to your cart before proceeding to checkout." }), _jsx("div", { className: "pt-4", children: _jsx(Link, { href: `/${storeConfig.slug}`, children: _jsxs(Button, { size: "lg", className: "bg-black hover:bg-gray-800 text-white rounded-full px-8 py-6 h-auto font-semibold shadow-lg shadow-black/10 hover:shadow-xl transition-all hover:scale-105 flex items-center gap-2 mx-auto", children: [_jsx(ArrowLeft, { className: "w-5 h-5" }), "Continue Shopping"] }) }) })] }) }) }) }));
987
+ return (_jsx("div", { className: "min-h-screen bg-gray-50/50 py-10 px-4 sm:px-6 lg:px-8 font-sans", "data-checkout-ready": true, children: _jsx("div", { className: "container mx-auto max-w-6xl", children: _jsx("div", { className: "bg-white rounded-sm shadow-sm border border-gray-200/90 p-12 text-center", children: _jsxs("div", { className: "max-w-md mx-auto space-y-6", children: [_jsx("div", { className: "w-20 h-20 mx-auto rounded-sm bg-gray-100 flex items-center justify-center", children: _jsx("svg", { className: "w-10 h-10 text-gray-400", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" }) }) }), _jsx("h2", { className: "text-2xl font-bold text-gray-900", children: "Your cart is empty" }), _jsx("p", { className: "text-gray-600", children: "Add some items to your cart before proceeding to checkout." }), _jsx("div", { className: "pt-4", children: _jsx(Link, { href: `/${storeConfig.slug}`, children: _jsxs(Button, { size: "lg", className: "bg-black hover:bg-gray-800 text-white rounded-sm px-8 py-6 h-auto font-semibold flex items-center gap-2 mx-auto", children: [_jsx(ArrowLeft, { className: "w-5 h-5" }), "Continue Shopping"] }) }) })] }) }) }) }));
900
988
  }
901
- return (_jsx("div", { className: "min-h-screen bg-gray-50/50 py-12 px-4 sm:px-6 lg:px-8 font-sans", "data-checkout-ready": true, children: _jsxs("div", { className: "container mx-auto max-w-6xl", children: [_jsxs("div", { className: "mb-10 flex items-center justify-between", children: [_jsxs(Link, { href: `/${storeConfig.slug}/cart`, className: "group flex items-center gap-2 text-gray-500 hover:text-black transition-colors font-medium", children: [_jsx("div", { className: "p-2 rounded-full bg-white border border-gray-200 group-hover:border-black transition-colors", children: _jsx(ArrowLeft, { className: "w-4 h-4" }) }), "Back to Cart"] }), _jsxs("div", { className: "flex items-center gap-2 text-sm font-bold", children: [_jsx("span", { className: cn("px-3 py-1.5 rounded-full transition-colors", step === 'details' ? "bg-black text-white" : "bg-green-100 text-green-700"), children: step === 'details' ? '1' : _jsx(CheckCircle, { className: "w-4 h-4" }) }), _jsx("span", { className: cn(step === 'details' ? "text-black" : "text-gray-500"), children: "Shipping" }), _jsx("div", { className: "w-8 h-0.5 bg-gray-200" }), _jsx("span", { className: cn("px-3 py-1.5 rounded-full transition-colors", step === 'payment' ? "bg-black text-white" : "bg-gray-200 text-gray-500"), children: "2" }), _jsx("span", { className: cn(step === 'payment' ? "text-black" : "text-gray-400"), children: "Payment" })] })] }), _jsxs("div", { className: "flex flex-col lg:flex-row gap-10", children: [_jsx("div", { className: "flex-1", children: step === 'details' ? (_jsxs("form", { onSubmit: handleDetailsSubmit, className: "space-y-8 animate-fade-in", children: [_jsxs("section", { className: "bg-white p-8 rounded-3xl shadow-sm border border-gray-100", children: [_jsxs("div", { className: "flex items-center gap-3 mb-6", children: [_jsx("div", { className: "p-2 bg-blue-50 text-blue-600 rounded-xl", children: _jsx(ShieldCheck, { className: "w-5 h-5" }) }), _jsx("h2", { className: "text-xl font-bold text-gray-900", children: "Contact Information" })] }), _jsx("div", { className: "space-y-4", children: isAuthenticated && user ? (_jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "p-4 bg-gray-50 rounded-xl border border-gray-200", children: [_jsx("p", { className: "text-xs font-bold text-gray-500 uppercase tracking-wider mb-2", children: "Logged in as" }), _jsxs("p", { className: "font-bold text-gray-900", children: [user.firstName, " ", user.lastName] }), _jsx("p", { className: "text-sm text-gray-600", children: user.email })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-bold text-gray-700 ml-1", children: "Email Address" }), _jsx("input", { type: "email", className: cn("w-full px-5 py-3.5 bg-white border-2 rounded-xl focus:outline-none focus:ring-0 transition-all font-medium", errors.email ? "border-red-500 focus:border-red-500" : "border-gray-100 focus:border-black"), placeholder: "john@example.com", value: formData.email, onChange: e => setFormData({ ...formData, email: e.target.value }) }), _jsx("p", { className: "text-xs text-gray-500 ml-1", children: "You can use a different email for this order" }), errors.email && _jsx("p", { className: "text-red-500 text-xs ml-1", children: errors.email })] })] })) : (_jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-bold text-gray-700 ml-1", children: "Email Address" }), _jsx("input", { type: "email", className: cn("w-full px-5 py-3.5 bg-white border-2 rounded-xl focus:outline-none focus:ring-0 transition-all font-medium", errors.email ? "border-red-500 focus:border-red-500" : "border-gray-100 focus:border-black"), placeholder: "john@example.com", value: formData.email, onChange: e => setFormData({ ...formData, email: e.target.value }) }), errors.email && _jsx("p", { className: "text-red-500 text-xs ml-1", children: errors.email })] })) })] }), _jsxs("section", { className: "bg-white p-8 rounded-3xl shadow-sm border border-gray-100", children: [_jsxs("div", { className: "flex items-center gap-3 mb-6", children: [_jsx("div", { className: "p-2 bg-orange-50 text-orange-600 rounded-xl", children: _jsx(MapPin, { className: "w-5 h-5" }) }), _jsx("h2", { className: "text-xl font-bold text-gray-900", children: storeConfig.settings?.shippingEnabled === false ? 'Billing Address' : 'Shipping Address' })] }), isAuthenticated && (_jsx(AddressSelector, { addresses: savedAddresses, selectedAddressId: selectedAddressId, onSelect: handleAddressSelect, isLoading: loadingAddresses, isAuthenticated: isAuthenticated })), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-5", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-bold text-gray-700 ml-1", children: "First Name" }), _jsx("input", { type: "text", className: cn("w-full px-4 py-3 rounded-lg border focus:ring-2 focus:ring-black focus:outline-none transition-all text-base", errors.firstName ? "border-red-300 focus:border-red-500 bg-red-50" : "border-gray-200 focus:border-black"), value: formData.firstName, onChange: e => setFormData({ ...formData, firstName: e.target.value }) }), errors.firstName && _jsx("p", { className: "text-red-500 text-xs ml-1", children: errors.firstName })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-bold text-gray-700 ml-1", children: "Last Name" }), _jsx("input", { type: "text", className: cn("w-full px-4 py-3 rounded-lg border focus:ring-2 focus:ring-black focus:outline-none transition-all text-base", errors.lastName ? "border-red-300 focus:border-red-500 bg-red-50" : "border-gray-200 focus:border-black"), value: formData.lastName, onChange: e => setFormData({ ...formData, lastName: e.target.value }) }), errors.lastName && _jsx("p", { className: "text-red-500 text-xs ml-1", children: errors.lastName })] }), _jsxs("div", { className: "space-y-1.5 md:col-span-2", children: [_jsx("label", { className: "text-sm font-bold text-gray-700 ml-1", children: "Address" }), _jsx("input", { type: "text", className: cn("w-full px-4 py-3 rounded-lg border focus:ring-2 focus:ring-black focus:outline-none transition-all text-base", errors.address ? "border-red-300 focus:border-red-500 bg-red-50" : "border-gray-200 focus:border-black"), placeholder: "123 Main St", value: formData.address, onChange: e => setFormData({ ...formData, address: e.target.value }) }), errors.address && _jsx("p", { className: "text-red-500 text-xs ml-1", children: errors.address })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-bold text-gray-700 ml-1", children: "Country" }), _jsxs("div", { className: "relative", children: [_jsxs("button", { type: "button", onClick: () => setIsCountryDropdownOpen(!isCountryDropdownOpen), className: cn("w-full px-4 py-3 rounded-lg border focus:ring-2 focus:ring-black focus:outline-none transition-all text-left flex items-center justify-between text-base", errors.country ? "border-red-300 focus:border-red-500 bg-red-50" : "border-gray-200 focus:border-black"), children: [_jsx("span", { className: "flex items-center gap-2", children: (() => {
989
+ return (_jsx("div", { className: "min-h-screen bg-gray-50/50 py-8 sm:py-10 px-4 sm:px-6 lg:px-8 font-sans", "data-checkout-ready": true, children: _jsxs("div", { className: "container mx-auto max-w-6xl", children: [_jsx("div", { className: "mb-8", children: _jsxs(Link, { href: `/${storeConfig.slug}/cart`, className: "group inline-flex items-center gap-2 text-sm text-gray-500 hover:text-gray-900 transition-colors font-medium", children: [_jsx(ArrowLeft, { className: "w-4 h-4 transition-transform group-hover:-translate-x-0.5" }), "Back to Cart"] }) }), _jsxs("div", { className: "flex flex-col lg:flex-row gap-6 lg:gap-8 lg:items-start", children: [_jsx("div", { className: "order-1 flex-1 min-w-0 lg:order-1", children: _jsxs("form", { id: "checkout-details-form", onSubmit: handleDetailsSubmit, className: "space-y-5 sm:space-y-6 animate-fade-in", children: [_jsxs("section", { className: sectionClass, children: [_jsxs("div", { className: sectionHeaderClass, children: [_jsx(ContactInformationIcon, { className: "h-6 w-6 shrink-0" }), _jsx("h2", { className: "text-lg font-semibold text-gray-900 tracking-tight", children: "Contact Information" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: labelClass, children: "Email Address" }), _jsx("input", { type: "email", className: fieldClass(!!errors.email), placeholder: "john@example.com", value: formData.email, onChange: (e) => setFormData({ ...formData, email: e.target.value }) }), errors.email && _jsx("p", { className: "text-red-500 text-xs", children: errors.email })] })] }), _jsxs("section", { className: sectionClass, children: [_jsxs("div", { className: sectionHeaderClass, children: [_jsx(ShippingAddressIcon, { className: "h-6 w-6 shrink-0" }), _jsx("h2", { className: "text-lg font-semibold text-gray-900 tracking-tight", children: storeConfig.settings?.shippingEnabled === false ? 'Billing Address' : 'Shipping Address' })] }), isAuthenticated && (_jsx(AddressSelector, { addresses: savedAddresses, selectedAddressId: selectedAddressId, onSelect: handleAddressSelect, isLoading: loadingAddresses, isAuthenticated: isAuthenticated })), _jsxs("div", { className: cn('grid grid-cols-1 md:grid-cols-2 gap-4', isAuthenticated && 'pt-1'), children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: labelClass, children: "First Name" }), _jsx("input", { type: "text", className: fieldClass(!!errors.firstName), value: formData.firstName, onChange: e => setFormData({ ...formData, firstName: e.target.value }) }), errors.firstName && _jsx("p", { className: "text-red-500 text-xs", children: errors.firstName })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: labelClass, children: "Last Name" }), _jsx("input", { type: "text", className: fieldClass(!!errors.lastName), value: formData.lastName, onChange: e => setFormData({ ...formData, lastName: e.target.value }) }), errors.lastName && _jsx("p", { className: "text-red-500 text-xs", children: errors.lastName })] }), _jsxs("div", { className: "space-y-1.5 md:col-span-2", children: [_jsx("label", { className: labelClass, children: "Address" }), _jsx("input", { type: "text", className: fieldClass(!!errors.address), placeholder: "123 Main St", value: formData.address, onChange: e => setFormData({ ...formData, address: e.target.value }) }), errors.address && _jsx("p", { className: "text-red-500 text-xs", children: errors.address })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: labelClass, children: "Country" }), _jsxs("div", { className: "relative", children: [_jsxs("button", { type: "button", onClick: () => setIsCountryDropdownOpen(!isCountryDropdownOpen), className: cn(fieldClass(!!errors.country), 'text-left flex items-center justify-between'), children: [_jsx("span", { className: "flex items-center gap-2", children: (() => {
902
990
  const selectedCountry = getCountryByName(formData.country);
903
991
  return selectedCountry ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-lg", children: selectedCountry.flag }), _jsx("span", { children: selectedCountry.name })] })) : (_jsx("span", { className: "text-gray-400", children: "Select country" }));
904
- })() }), _jsx(ChevronDown, { className: cn("w-5 h-5 text-gray-400 transition-transform", isCountryDropdownOpen && "transform rotate-180") })] }), isCountryDropdownOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-10", onClick: () => setIsCountryDropdownOpen(false) }), _jsx("div", { className: "absolute z-20 w-full mt-1 bg-white border-2 border-gray-100 rounded-xl shadow-xl max-h-64 overflow-y-auto", children: countries.map((country) => (_jsxs("button", { type: "button", onClick: () => {
992
+ })() }), _jsx(ChevronDown, { className: cn("w-5 h-5 text-gray-400 transition-transform", isCountryDropdownOpen && "transform rotate-180") })] }), isCountryDropdownOpen && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-10", onClick: () => setIsCountryDropdownOpen(false) }), _jsx("div", { className: "absolute z-20 w-full mt-1.5 bg-white border border-gray-200 rounded-sm shadow-lg max-h-64 overflow-y-auto", children: countries.map((country) => (_jsxs("button", { type: "button", onClick: () => {
905
993
  setFormData({ ...formData, country: country.name, city: '' }); // Clear city when country changes
906
994
  setIsCountryDropdownOpen(false);
907
995
  setIsCityDropdownOpen(false);
908
- }, className: cn("w-full px-5 py-3 text-left flex items-center gap-3 hover:bg-gray-50 transition-colors", formData.country === country.name && "bg-gray-50 font-medium"), children: [_jsx("span", { className: "text-lg", children: country.flag }), _jsx("span", { children: country.name })] }, country.code))) })] }))] }), errors.country && _jsx("p", { className: "text-red-500 text-xs ml-1", children: errors.country })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-bold text-gray-700 ml-1", children: "City" }), _jsxs("div", { className: "relative", children: [_jsxs("button", { type: "button", onClick: () => {
996
+ }, className: cn("w-full px-4 py-3 text-left flex items-center gap-3 hover:bg-gray-50 transition-colors", formData.country === country.name && "bg-gray-50 font-medium"), children: [_jsx("span", { className: "text-lg", children: country.flag }), _jsx("span", { children: country.name })] }, country.code))) })] }))] }), errors.country && _jsx("p", { className: "text-red-500 text-xs", children: errors.country })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: labelClass, children: "City" }), _jsxs("div", { className: "relative", children: [_jsxs("button", { type: "button", onClick: () => {
909
997
  if (formData.country) {
910
998
  setIsCityDropdownOpen(!isCityDropdownOpen);
911
999
  }
912
1000
  else {
913
1001
  addToast('Please select a country first', 'error');
914
1002
  }
915
- }, disabled: !formData.country, className: cn("w-full px-4 py-3 rounded-lg border focus:ring-2 focus:ring-black focus:outline-none transition-all text-left flex items-center justify-between text-base", errors.city ? "border-red-300 focus:border-red-500 bg-red-50" : "border-gray-200 focus:border-black", !formData.country && "bg-gray-50 text-gray-400 cursor-not-allowed"), children: [_jsx("span", { className: formData.city ? "text-gray-900" : "text-gray-400", children: formData.city || 'Select city' }), _jsx(ChevronDown, { className: cn("w-5 h-5 text-gray-400 transition-transform", isCityDropdownOpen && "transform rotate-180") })] }), isCityDropdownOpen && formData.country && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-10", onClick: () => setIsCityDropdownOpen(false) }), _jsx("div", { className: "absolute z-20 w-full mt-1 bg-white border-2 border-gray-100 rounded-xl shadow-xl max-h-64 overflow-y-auto", children: getCitiesByCountry(formData.country).length > 0 ? (getCitiesByCountry(formData.country).map((city) => (_jsx("button", { type: "button", onClick: () => {
1003
+ }, disabled: !formData.country, className: cn(fieldClass(!!errors.city), 'text-left flex items-center justify-between', !formData.country && 'bg-gray-50 text-gray-400 cursor-not-allowed'), children: [_jsx("span", { className: formData.city ? "text-gray-900" : "text-gray-400", children: formData.city || 'Select city' }), _jsx(ChevronDown, { className: cn("w-5 h-5 text-gray-400 transition-transform", isCityDropdownOpen && "transform rotate-180") })] }), isCityDropdownOpen && formData.country && (_jsxs(_Fragment, { children: [_jsx("div", { className: "fixed inset-0 z-10", onClick: () => setIsCityDropdownOpen(false) }), _jsx("div", { className: "absolute z-20 w-full mt-1.5 bg-white border border-gray-200 rounded-sm shadow-lg max-h-64 overflow-y-auto", children: getCitiesByCountry(formData.country).length > 0 ? (getCitiesByCountry(formData.country).map((city) => (_jsx("button", { type: "button", onClick: () => {
916
1004
  setFormData({ ...formData, city });
917
1005
  setIsCityDropdownOpen(false);
918
- }, className: cn("w-full px-5 py-3 text-left hover:bg-gray-50 transition-colors", formData.city === city && "bg-gray-50 font-medium"), children: city }, city)))) : (_jsx("div", { className: "px-5 py-3 text-gray-500 text-sm", children: "No cities available for this country" })) })] }))] }), errors.city && _jsx("p", { className: "text-red-500 text-xs ml-1", children: errors.city })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-bold text-gray-700 ml-1", children: "Postal/Zip Code" }), _jsx("input", { type: "text", className: cn("w-full px-4 py-3 rounded-lg border focus:ring-2 focus:ring-black focus:outline-none transition-all text-base", errors.postalCode ? "border-red-300 focus:border-red-500 bg-red-50" : "border-gray-200 focus:border-black"), placeholder: "Optional", value: formData.postalCode, onChange: e => setFormData({ ...formData, postalCode: e.target.value }) }), errors.postalCode && _jsx("p", { className: "text-red-500 text-xs ml-1", children: errors.postalCode })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-bold text-gray-700 ml-1", children: "Phone" }), _jsx("input", { type: "tel", className: cn("w-full px-4 py-3 rounded-lg border focus:ring-2 focus:ring-black focus:outline-none transition-all text-base", errors.phone ? "border-red-300 focus:border-red-500 bg-red-50" : "border-gray-200 focus:border-black"), value: formData.phone, onChange: e => setFormData({ ...formData, phone: e.target.value }) }), errors.phone && _jsx("p", { className: "text-red-500 text-xs ml-1", children: errors.phone })] })] }), isAuthenticated && !selectedAddressId && (_jsxs("div", { className: "mt-6 space-y-3", children: [_jsxs("label", { className: "flex items-center gap-3 cursor-pointer group", children: [_jsx("input", { type: "checkbox", checked: saveNewAddress, onChange: (e) => setSaveNewAddress(e.target.checked), className: "w-5 h-5 rounded border-2 border-gray-300 text-black focus:ring-2 focus:ring-black cursor-pointer" }), _jsx("span", { className: "text-sm font-medium text-gray-700 group-hover:text-black transition-colors", children: "Save this address for future use" })] }), saveNewAddress && (_jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-bold text-gray-700 ml-1", children: "Address Label (optional)" }), _jsx("input", { type: "text", value: addressLabel, onChange: (e) => setAddressLabel(e.target.value), placeholder: "e.g., Home, Work, Office", className: "w-full px-5 py-3.5 bg-white border-2 border-gray-100 rounded-xl focus:outline-none focus:ring-0 focus:border-black transition-all font-medium" })] }))] }))] }), storeConfig.settings?.shippingEnabled !== false && (formData.city && formData.country) && (_jsxs("section", { className: "bg-white p-8 rounded-3xl shadow-sm border border-gray-100", children: [_jsxs("div", { className: "flex items-center gap-3 mb-6", children: [_jsx("div", { className: "p-2 bg-purple-50 text-purple-600 rounded-xl", children: _jsx(Truck, { className: "w-5 h-5" }) }), _jsx("h2", { className: "text-xl font-bold text-gray-900", children: "Shipping Method" })] }), freeShippingThreshold !== undefined && !freeShippingEligible && (_jsxs("div", { className: "mb-4 p-3 bg-blue-50 border border-blue-200 rounded-lg", children: [_jsxs("p", { className: "text-xs font-medium text-blue-900 mb-1", children: ["Spend ", formatCurrency(freeShippingThreshold - subtotal, currency), " more for free shipping!"] }), _jsx("div", { className: "w-full bg-blue-200 rounded-full h-2", children: _jsx("div", { className: "bg-blue-600 h-2 rounded-full transition-all", style: {
919
- width: `${Math.min(100, (subtotal / freeShippingThreshold) * 100)}%`,
920
- } }) })] })), isCalculatingShipping ? (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsxs("div", { className: "flex items-center gap-2 text-gray-600", children: [_jsx("div", { className: "animate-spin rounded-full h-5 w-5 border-b-2 border-gray-900" }), _jsx("span", { className: "text-sm font-medium", children: "Calculating shipping options..." })] }) })) : shippingError ? (_jsx("div", { className: "p-4 bg-red-50 border border-red-200 rounded-lg", children: _jsx("p", { className: "text-sm text-red-600", children: shippingError }) })) : shippingMethods.length > 0 ? (_jsx("div", { className: "space-y-3", children: shippingMethods.map((method) => (_jsxs("label", { className: cn("flex items-center justify-between p-4 border-2 rounded-xl cursor-pointer transition-all", selectedShippingMethod?.code === method.code
921
- ? "border-black bg-gray-50"
922
- : "border-gray-200 hover:border-gray-300 bg-white"), children: [_jsxs("div", { className: "flex items-center gap-4 flex-1", children: [_jsx("input", { type: "radio", name: "shippingMethod", value: method.code, checked: selectedShippingMethod?.code === method.code, onChange: () => setSelectedShippingMethod(method), className: "w-5 h-5 text-black focus:ring-2 focus:ring-black cursor-pointer" }), _jsxs("div", { className: "flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("p", { className: "font-bold text-gray-900", children: method.name }), freeShippingEligible && method.cost === 0 && (_jsx("span", { className: "text-xs font-normal text-green-700 bg-green-100 px-2 py-0.5 rounded-full", children: "FREE" }))] }), method.description && (_jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: method.description })), method.estimatedDays && (_jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: method.estimatedDaysMin && method.estimatedDaysMax
923
- ? `Estimated delivery: ${method.estimatedDaysMin}-${method.estimatedDaysMax} business days`
924
- : `Estimated delivery: ${method.estimatedDays} business days` }))] })] }), _jsx("div", { className: "text-right", children: _jsx("p", { className: "font-bold text-gray-900", children: freeShippingEligible && method.cost === 0
925
- ? 'FREE'
926
- : Number.isFinite(method.cost) && method.cost >= 0
927
- ? formatCurrency(method.cost, currency)
928
- : 'Not available' }) })] }, method.code))) })) : (_jsx("div", { className: "p-4 bg-gray-50 border border-gray-200 rounded-lg text-center", children: _jsx("p", { className: "text-sm text-gray-600", children: "No shipping methods available. Please check your address." }) }))] })), _jsxs(Button, { type: "submit", size: "lg", className: "w-full h-14 text-lg font-bold rounded-2xl shadow-xl hover:shadow-2xl hover:-translate-y-0.5 transition-all", style: { backgroundColor: primaryColor }, children: ["Continue to Payment ", _jsx(ChevronRight, { className: "ml-2 w-5 h-5" })] })] })) : (_jsxs("div", { className: "space-y-8 animate-fade-in", children: [_jsxs("section", { className: "bg-white p-6 rounded-3xl shadow-sm border border-gray-100 flex justify-between items-center group hover:border-gray-300 transition-colors cursor-pointer", onClick: () => setStep('details'), children: [_jsxs("div", { className: "flex gap-4 items-center", children: [_jsx("div", { className: "w-10 h-10 bg-green-50 rounded-full flex items-center justify-center border border-green-100", children: _jsx(CheckCircle, { className: "w-5 h-5 text-green-600" }) }), _jsxs("div", { children: [_jsx("p", { className: "text-xs text-gray-500 font-bold uppercase tracking-wider mb-1", children: "Shipping To" }), _jsxs("p", { className: "font-bold text-gray-900", children: [formData.firstName, " ", formData.lastName] }), _jsxs("p", { className: "text-sm text-gray-500", children: [formData.address, ", ", formData.city] })] })] }), _jsx("span", { className: "text-sm font-bold text-blue-600 px-4 py-2 bg-blue-50 rounded-lg group-hover:bg-blue-100 transition-colors", children: "Edit" })] }), isFreeOrder ? (_jsxs("section", { className: "bg-green-50 p-8 rounded-3xl shadow-sm border border-green-100", children: [_jsxs("div", { className: "flex items-center gap-3 mb-4", children: [_jsx("div", { className: "p-2 bg-white text-green-600 rounded-xl", children: _jsx(CheckCircle, { className: "w-5 h-5" }) }), _jsx("h2", { className: "text-xl font-bold text-gray-900", children: "Free Order" })] }), _jsx("p", { className: "text-sm text-green-800 leading-relaxed", children: "No payment is required. Complete your details and confirm to get access to your digital product." })] })) : (_jsxs("section", { className: "bg-white p-8 rounded-3xl shadow-sm border border-gray-100", children: [_jsxs("div", { className: "flex items-center gap-3 mb-6", children: [_jsx("div", { className: "p-2 bg-blue-50 text-blue-600 rounded-xl", children: _jsx(ShieldCheck, { className: "w-5 h-5" }) }), _jsx("h2", { className: "text-xl font-bold text-gray-900", children: "Payment Security" })] }), _jsx("div", { className: "bg-blue-50/50 p-6 rounded-2xl border border-blue-100 mb-6", children: _jsxs("div", { className: "flex items-start gap-4", children: [_jsx(Lock, { className: "w-5 h-5 text-blue-600 mt-1" }), _jsxs("div", { children: [_jsx("h4", { className: "font-bold text-blue-900 mb-1", children: "Encrypted Transaction" }), _jsx("p", { className: "text-sm text-blue-700/80 leading-relaxed", children: "Your payment is processed securely by Payaza. We do not store your card details." })] })] }) }), _jsxs("div", { className: "flex items-center justify-center gap-2 text-xs font-bold text-gray-400 uppercase tracking-widest", children: [_jsx(Lock, { className: "w-3 h-3" }), "256-bit SSL Secure Payment"] })] })), _jsx(Button, { onClick: handlePayazaCheckout, size: "lg", className: "w-full h-16 text-lg font-bold rounded-2xl shadow-xl hover:shadow-2xl hover:-translate-y-0.5 transition-all", style: { backgroundColor: isFreeOrder ? '#059669' : primaryColor }, disabled: loading || isPayazaLoading, children: loading || isPayazaLoading ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin" }), _jsx("span", { children: isFreeOrder ? 'Completing order...' : 'Processing Securely...' })] })) : (_jsxs("div", { className: "flex items-center gap-2", children: [isFreeOrder ? _jsx(CheckCircle, { className: "w-5 h-5" }) : _jsx(Lock, { className: "w-5 h-5" }), _jsx("span", { children: isFreeOrder ? 'Complete Free Order' : 'Pay Now' })] })) })] })) }), _jsxs("div", { className: "w-full lg:w-[400px] flex-shrink-0", children: [_jsxs("div", { className: "bg-white p-8 rounded-3xl shadow-lg border border-gray-100 sticky top-8", children: [_jsx("h2", { className: "text-xl font-black text-gray-900 mb-6", children: "Order Summary" }), _jsx("div", { className: "space-y-6 mb-8 max-h-[400px] overflow-y-auto scrollbar-hide", children: checkoutItems.map((item) => (_jsxs("div", { className: "flex gap-4 group", children: [_jsxs("div", { className: "w-20 h-20 bg-gray-100 rounded-xl overflow-hidden flex-shrink-0 relative border border-gray-200", children: [_jsx(Image, { src: item.product.images[0], alt: item.product.name, fill: true, className: "object-cover group-hover:scale-105 transition-transform duration-500", unoptimized: true }), _jsxs("span", { className: "absolute top-0 right-0 bg-black text-white text-[10px] font-bold px-2 py-1 rounded-bl-lg z-10", children: ["x", item.quantity] })] }), _jsxs("div", { className: "flex-1 py-1", children: [_jsx("p", { className: "font-bold text-gray-900 text-sm line-clamp-2 leading-relaxed", children: item.product.name }), item.variantName && _jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: item.variantName }), _jsx("p", { className: "text-gray-500 text-sm font-medium mt-1", children: normalizePrice(item.price) <= 0
929
- ? 'Free'
930
- : formatCurrency(normalizePrice(item.price), item.product?.currency || currency) })] })] }, item.id))) }), _jsxs("div", { className: "space-y-4 pt-6 border-t-2 border-gray-50", children: [_jsxs("div", { className: "flex justify-between text-gray-500 font-medium text-sm", children: [_jsx("span", { children: "Subtotal" }), _jsx("span", { className: "text-gray-900 font-bold", children: isFreeOrder ? 'Free' : formatCurrency(subtotal, currency) })] }), _jsxs("div", { className: "flex justify-between text-gray-500 font-medium text-sm", children: [_jsxs("span", { children: ["Shipping", selectedShippingMethod ? ` (${selectedShippingMethod.name})` : ''] }), _jsx("span", { className: "text-gray-900 font-bold", children: isCalculatingShipping ? (_jsx("span", { className: "text-gray-400", children: "Calculating..." })) : !selectedShippingMethod ? (_jsx("span", { className: "text-gray-400", children: "Not available" })) : shipping === 0 && freeShippingEligible ? (_jsx("span", { className: "text-green-600", children: "Free" })) : shipping === 0 ? ('Free') : Number.isFinite(shipping) && shipping > 0 ? (formatCurrency(shipping, currency)) : (_jsx("span", { className: "text-gray-400", children: "Not available" })) })] }), customerFeeLines.map((line) => (_jsxs("div", { className: "flex justify-between text-gray-500 font-medium text-sm", children: [_jsx("span", { children: line.label }), _jsx("span", { className: "text-gray-900 font-bold", children: formatCurrency(line.amount, currency) })] }, line.key))), !feePreview && vatAmount > 0 && (_jsxs("div", { className: "flex justify-between text-gray-500 font-medium text-sm", children: [_jsx("span", { children: vatLabel }), _jsx("span", { className: "text-gray-900 font-bold", children: formatCurrency(vatAmount, currency) })] })), _jsxs("div", { className: "flex justify-between items-end pt-4 mt-2 border-t border-gray-100", children: [_jsx("span", { className: "text-base font-bold text-gray-900", children: "Total to pay" }), _jsx("span", { className: "text-3xl font-black text-gray-900 tracking-tight", children: isCalculatingFees ? 'Calculating…' : isFreeOrder ? 'Free' : formatCurrency(total, currency) })] })] }), _jsxs("div", { className: "mt-8 pt-6 border-t border-gray-100 grid grid-cols-3 gap-2 opacity-50 grayscale", children: [_jsx("div", { className: "h-8 bg-gray-100 rounded border border-gray-200" }), _jsx("div", { className: "h-8 bg-gray-100 rounded border border-gray-200" }), _jsx("div", { className: "h-8 bg-gray-100 rounded border border-gray-200" })] })] }), _jsxs("div", { className: "bg-white p-6 rounded-3xl shadow-lg border border-gray-100 mt-6 sticky top-[500px]", children: [_jsxs("h3", { className: "font-bold text-gray-900 mb-4 flex items-center gap-2", children: [_jsx(Tag, { className: "w-4 h-4" }), " Have a promo code?"] }), _jsxs("div", { className: "flex gap-2", children: [_jsx("input", { type: "text", value: promoCode, onChange: (e) => setPromoCode(e.target.value), placeholder: "Enter code", className: "flex-1 px-4 py-2 bg-gray-50 border border-gray-200 rounded-xl focus:outline-none focus:border-black transition-all uppercase placeholder:normal-case font-medium" }), _jsx(Button, { onClick: handleApplyPromo, disabled: !promoCode || isPromoApplied, className: "bg-black text-white rounded-xl", style: isPromoApplied ? { backgroundColor: '#22c55e' } : {}, children: isPromoApplied ? 'Applied' : 'Apply' })] }), isPromoApplied && (_jsxs("p", { className: "text-green-600 text-xs font-bold mt-2 flex items-center gap-1", children: [_jsx(CheckCircle, { className: "w-3 h-3" }), " Discount applied to total"] }))] })] })] })] }) }));
1006
+ }, className: cn("w-full px-4 py-3 text-left hover:bg-gray-50 transition-colors", formData.city === city && "bg-gray-50 font-medium"), children: city }, city)))) : (_jsx("div", { className: "px-4 py-3 text-gray-500 text-sm", children: "No cities available for this country" })) })] }))] }), errors.city && _jsx("p", { className: "text-red-500 text-xs", children: errors.city })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: labelClass, children: "Postal/Zip Code" }), _jsx("input", { type: "text", className: fieldClass(!!errors.postalCode), placeholder: "Optional", value: formData.postalCode, onChange: e => setFormData({ ...formData, postalCode: e.target.value }) }), errors.postalCode && _jsx("p", { className: "text-red-500 text-xs", children: errors.postalCode })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: labelClass, children: "Phone" }), _jsx("input", { type: "tel", className: fieldClass(!!errors.phone), value: formData.phone, onChange: e => setFormData({ ...formData, phone: e.target.value }) }), errors.phone && _jsx("p", { className: "text-red-500 text-xs", children: errors.phone })] })] }), isAuthenticated && !selectedAddressId && (_jsxs("div", { className: "mt-5 pt-5 border-t border-gray-100 space-y-3", children: [_jsxs("label", { className: "flex items-center gap-3 cursor-pointer group", children: [_jsx("input", { type: "checkbox", checked: saveNewAddress, onChange: (e) => setSaveNewAddress(e.target.checked), className: "w-4 h-4 rounded border-gray-300 text-black focus:ring-gray-900 cursor-pointer" }), _jsx("span", { className: "text-sm font-medium text-gray-700 group-hover:text-gray-900 transition-colors", children: "Save this address for future use" })] }), saveNewAddress && (_jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: labelClass, children: "Address Label (optional)" }), _jsx("input", { type: "text", value: addressLabel, onChange: (e) => setAddressLabel(e.target.value), placeholder: "e.g., Home, Work, Office", className: fieldClass() })] }))] }))] }), storeConfig.settings?.shippingEnabled !== false && (formData.city && formData.country) && (_jsxs("section", { className: sectionClass, children: [_jsxs("div", { className: sectionHeaderClass, children: [_jsx(ShippingMethodIcon, { className: "h-6 w-6 shrink-0" }), _jsx("h2", { className: "text-lg font-semibold text-gray-900 tracking-tight", children: "Shipping Method" })] }), (() => {
1007
+ const remainingForFreeShipping = freeShippingEnabled &&
1008
+ freeShippingThreshold !== undefined &&
1009
+ !freeShippingEligible
1010
+ ? freeShippingThreshold - subtotal
1011
+ : 0;
1012
+ if (!(remainingForFreeShipping > 0))
1013
+ return null;
1014
+ return (_jsxs("div", { className: "mb-4 p-3.5 bg-gray-50 border border-gray-200 rounded-sm", children: [_jsxs("p", { className: "text-xs font-medium text-gray-800 mb-2", children: ["Spend ", formatCurrency(remainingForFreeShipping, currency), " more for free shipping"] }), _jsx("div", { className: "w-full bg-gray-200 rounded-sm h-1.5", children: _jsx("div", { className: "bg-gray-900 h-1.5 rounded-sm transition-all", style: {
1015
+ width: `${Math.min(100, (subtotal / freeShippingThreshold) * 100)}%`,
1016
+ } }) })] }));
1017
+ })(), isCalculatingShipping ? (_jsx("div", { className: "flex items-center justify-center p-8", children: _jsxs("div", { className: "flex items-center gap-2 text-gray-600", children: [_jsx("div", { className: "animate-spin rounded-full h-5 w-5 border-b-2 border-gray-900" }), _jsx("span", { className: "text-sm font-medium", children: "Calculating shipping options..." })] }) })) : shippingError ? (_jsx("div", { className: "p-4 bg-red-50 border border-red-200 rounded-sm", children: _jsx("p", { className: "text-sm text-red-600", children: shippingError }) })) : shippingMethods.length > 0 ? (_jsx("div", { className: "space-y-2.5", children: shippingMethods.map((method) => {
1018
+ const isShippingMethodSelected = selectedShippingMethod?.code === method.code;
1019
+ const deliveryEstimate = estimatedDeliveryText(method);
1020
+ const methodDescription = shippingMethodDescriptionText(method, deliveryEstimate);
1021
+ return (_jsxs("label", { className: cn("flex items-center justify-between gap-4 p-4 border rounded-none cursor-pointer transition-all", isShippingMethodSelected
1022
+ ? "border-gray-900 bg-gray-50"
1023
+ : "border-gray-200 hover:border-gray-300 bg-white"), children: [_jsxs("div", { className: "flex items-center gap-3.5 flex-1 min-w-0", children: [_jsx("span", { className: cn('flex h-5 w-5 shrink-0 items-center justify-center rounded-full border-2', isShippingMethodSelected ? 'border-gray-900' : 'border-gray-300'), "aria-hidden": true, children: isShippingMethodSelected ? (_jsx("span", { className: "h-2.5 w-2.5 rounded-full bg-gray-900" })) : null }), _jsx("input", { type: "radio", name: "shippingMethod", value: method.code, checked: isShippingMethodSelected, onChange: () => setSelectedShippingMethod(method), className: "sr-only" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx("p", { className: "font-semibold text-gray-900", children: method.name }), freeShippingEligible && method.cost === 0 && (_jsx("span", { className: "text-[11px] font-medium text-emerald-700 bg-emerald-50 px-2 py-0.5 rounded-sm", children: "FREE" }))] }), methodDescription && (_jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: methodDescription })), deliveryEstimate && (_jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: deliveryEstimate }))] })] }), _jsx("div", { className: "text-right shrink-0", children: _jsx("p", { className: "font-semibold text-gray-900", children: freeShippingEligible && method.cost === 0
1024
+ ? 'FREE'
1025
+ : Number.isFinite(method.cost) && method.cost >= 0
1026
+ ? formatCurrency(method.cost, currency)
1027
+ : 'Not available' }) })] }, method.code));
1028
+ }) })) : (_jsx("div", { className: "p-4 bg-gray-50 border border-gray-200 rounded-sm text-center", children: _jsx("p", { className: "text-sm text-gray-600", children: "No shipping methods available. Please check your address." }) }))] }))] }) }), _jsx("div", { className: "order-2 w-full flex-shrink-0 lg:order-2 lg:w-[380px] lg:sticky lg:top-6 lg:self-start", children: _jsxs("div", { className: "bg-white p-6 sm:p-8 rounded-sm border border-gray-200/90 shadow-sm", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900 tracking-tight mb-5 pb-4 border-b border-gray-100", children: "Order Summary" }), _jsx("div", { className: "space-y-4 mb-6 max-h-[360px] overflow-y-auto scrollbar-hide", children: checkoutItems.map((item) => (_jsxs("div", { className: "flex gap-3.5 group", children: [_jsxs("div", { className: "w-16 h-16 sm:w-[72px] sm:h-[72px] bg-gray-100 rounded-sm overflow-hidden flex-shrink-0 relative border border-gray-200", children: [_jsx(Image, { src: getCartLineImage(item) || item.product.images[0], alt: item.product.name, fill: true, className: "object-cover group-hover:scale-105 transition-transform duration-500", unoptimized: true }), _jsxs("span", { className: "absolute top-0 right-0 bg-gray-900 text-white text-[10px] font-semibold px-1.5 py-0.5 rounded-sm z-10", children: ["x", item.quantity] })] }), _jsxs("div", { className: "flex-1 min-w-0 py-0.5", children: [_jsxs("div", { className: "flex items-start justify-between gap-2", children: [_jsx("p", { className: "font-medium text-gray-900 text-sm line-clamp-2 leading-snug", children: item.product.name }), _jsx("button", { type: "button", onClick: () => void handleRemoveCheckoutItem(item.id), className: "shrink-0 rounded-sm p-1.5 text-gray-400 transition-colors hover:bg-gray-100 hover:text-gray-900", "aria-label": `Remove ${item.product.name} from cart`, children: _jsx(Trash2, { className: "h-4 w-4" }) })] }), item.variantName && _jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: item.variantName }), _jsx("p", { className: "text-gray-600 text-sm font-medium mt-1", children: normalizePrice(item.price) <= 0
1029
+ ? 'Free'
1030
+ : formatCurrency(normalizePrice(item.price), item.currency || currency) })] })] }, item.id))) }), _jsxs("div", { className: "space-y-3 pt-5 border-t border-gray-100", children: [_jsxs("div", { className: "flex justify-between text-gray-500 font-medium text-sm", children: [_jsx("span", { children: "Subtotal" }), _jsx("span", { className: "text-gray-900 font-semibold", children: isFreeOrder ? 'Free' : formatCurrency(subtotal, currency) })] }), _jsxs("div", { className: "flex justify-between text-gray-500 font-medium text-sm", children: [_jsxs("span", { children: ["Shipping", selectedShippingMethod
1031
+ ? ` (${shippingMethodSummaryLabel(selectedShippingMethod.name)})`
1032
+ : ''] }), _jsx("span", { className: "text-gray-900 font-semibold", children: isCalculatingShipping ? (_jsx("span", { className: "text-gray-400", children: "Calculating..." })) : !selectedShippingMethod ? (_jsx("span", { className: "text-gray-400", children: "Not available" })) : shipping === 0 && freeShippingEligible ? (_jsx("span", { className: "text-emerald-600", children: "Free" })) : shipping === 0 ? ('Free') : Number.isFinite(shipping) && shipping > 0 ? (formatCurrency(shipping, currency)) : (_jsx("span", { className: "text-gray-400", children: "Not available" })) })] }), customerFeeLines.map((line) => (_jsxs("div", { className: "flex justify-between text-gray-500 font-medium text-sm", children: [_jsx("span", { children: line.label }), _jsx("span", { className: "text-gray-900 font-semibold", children: formatCurrency(line.amount, currency) })] }, line.key))), !feePreview && vatAmount > 0 && (_jsxs("div", { className: "flex justify-between text-gray-500 font-medium text-sm", children: [_jsx("span", { children: vatLabel }), _jsx("span", { className: "text-gray-900 font-semibold", children: formatCurrency(vatAmount, currency) })] })), _jsxs("div", { className: "flex justify-between items-end pt-4 mt-1 border-t border-gray-100", children: [_jsx("span", { className: "text-sm font-semibold text-gray-900", children: "Total to pay" }), _jsx("span", { className: "text-2xl font-bold text-gray-900 tracking-tight", children: isCalculatingFees ? 'Calculating…' : isFreeOrder ? 'Free' : formatCurrency(total, currency) })] })] }), _jsx("div", { className: "mt-6 pt-5 border-t border-gray-100", children: _jsx(Button, { type: "submit", form: "checkout-details-form", size: "lg", className: "w-full h-12 text-base font-semibold rounded-sm shadow-none transition-all hover:opacity-95 active:scale-[0.99]", style: { backgroundColor: isFreeOrder ? '#059669' : primaryColor }, disabled: loading || isPayazaLoading, children: loading || isPayazaLoading ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin" }), _jsx("span", { children: isFreeOrder ? 'Completing order...' : 'Processing Securely...' })] })) : (_jsxs("div", { className: "flex items-center gap-2", children: [isFreeOrder ? _jsx(CheckCircle, { className: "w-5 h-5" }) : _jsx(Lock, { className: "w-5 h-5" }), _jsx("span", { children: isFreeOrder ? 'Complete Free Order' : 'Pay Now' })] })) }) })] }) })] })] }) }));
931
1033
  }
@@ -0,0 +1,2 @@
1
+ export declare function productCategoryFilterChipClass(active: boolean): string;
2
+ //# sourceMappingURL=product-category-filter-chip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-category-filter-chip.d.ts","sourceRoot":"","sources":["../../../src/layouts/shared/product-category-filter-chip.ts"],"names":[],"mappings":"AAEA,wBAAgB,8BAA8B,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAOtE"}
@@ -0,0 +1,6 @@
1
+ import { cn } from '../../lib/utils/index.js';
2
+ export function productCategoryFilterChipClass(active) {
3
+ return cn('px-1 py-2 text-sm font-semibold whitespace-nowrap transition-colors underline-offset-4 decoration-2', active
4
+ ? 'text-gray-900 underline'
5
+ : 'text-gray-600 hover:text-gray-900 hover:underline');
6
+ }