@cartbase/storefront 0.20.0 → 0.21.0

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 (109) hide show
  1. package/LICENSE +21 -21
  2. package/package.json +4 -1
  3. package/src/api/auth.ts +108 -108
  4. package/src/api/carts.ts +523 -523
  5. package/src/api/categories.ts +184 -184
  6. package/src/api/checkout.ts +526 -526
  7. package/src/api/collections.ts +130 -130
  8. package/src/api/consent.ts +75 -75
  9. package/src/api/content.ts +125 -125
  10. package/src/api/customers.ts +303 -303
  11. package/src/api/gift-cards.ts +112 -112
  12. package/src/api/http.ts +181 -180
  13. package/src/api/index.ts +30 -30
  14. package/src/api/menus.ts +77 -77
  15. package/src/api/metaobjects.ts +136 -136
  16. package/src/api/orders.ts +290 -290
  17. package/src/api/redirects.ts +37 -37
  18. package/src/api/regions.ts +200 -200
  19. package/src/api/search.ts +163 -163
  20. package/src/api/store.ts +56 -35
  21. package/src/api/types.ts +91 -91
  22. package/src/cart-drawer/context.tsx +778 -778
  23. package/src/cart-drawer/cross-sell-carousel.tsx +211 -211
  24. package/src/cart-drawer/cross-sell-sidebar.tsx +158 -158
  25. package/src/cart-drawer/gift-wrap.tsx +82 -82
  26. package/src/cart-drawer/item/index.tsx +162 -162
  27. package/src/cart-drawer/item/upsell.tsx +110 -110
  28. package/src/cart-drawer/labels.ts +123 -123
  29. package/src/cart-drawer/mutation-queue.ts +78 -78
  30. package/src/cart-drawer/notes.tsx +131 -131
  31. package/src/cart-drawer/payment-badges.tsx +36 -96
  32. package/src/cart-drawer/sticky-footer.tsx +73 -73
  33. package/src/cart-drawer/summary-breakdown.tsx +197 -197
  34. package/src/checkout/address-error-copy.ts +117 -117
  35. package/src/checkout/boxnow-locker-selector.tsx +410 -410
  36. package/src/checkout/compare-addresses.ts +40 -40
  37. package/src/checkout/discount-section.tsx +218 -218
  38. package/src/checkout/error-copy-codes.ts +63 -63
  39. package/src/checkout/geocode.ts +154 -154
  40. package/src/checkout/gift-card-section.tsx +224 -224
  41. package/src/checkout/index.ts +72 -72
  42. package/src/checkout/labels.ts +495 -495
  43. package/src/checkout/payment-button.tsx +372 -372
  44. package/src/checkout/payment-error-copy.ts +154 -154
  45. package/src/checkout/promotion-error-copy.ts +91 -91
  46. package/src/common/country-flag.tsx +52 -52
  47. package/src/common/country-select.tsx +11 -11
  48. package/src/common/icons/cartbase-mark.ts +9 -0
  49. package/src/common/icons/payment-marks.ts +73 -0
  50. package/src/common/icons/social-marks.ts +61 -0
  51. package/src/common/index.ts +35 -20
  52. package/src/common/market-select.tsx +57 -57
  53. package/src/common/payment-icons.tsx +54 -0
  54. package/src/common/powered-by-cartbase.tsx +47 -0
  55. package/src/common/social-links.tsx +65 -0
  56. package/src/index.ts +12 -12
  57. package/src/lib/country-name.ts +59 -59
  58. package/src/lib/get-product-price.ts +133 -133
  59. package/src/lib/media-image.tsx +39 -39
  60. package/src/lib/payment-constants.ts +53 -53
  61. package/src/lib/platform.ts +13 -13
  62. package/src/lib/price.tsx +39 -39
  63. package/src/lib/store-api-error.ts +36 -36
  64. package/src/lib/variant-caption.ts +32 -32
  65. package/src/locales/bg.ts +3 -0
  66. package/src/locales/context.ts +37 -37
  67. package/src/locales/en.ts +26 -26
  68. package/src/locales/es.ts +3 -0
  69. package/src/locales/index.ts +19 -19
  70. package/src/locales/provider.tsx +59 -59
  71. package/src/locales/types.ts +77 -77
  72. package/src/order/index.ts +62 -62
  73. package/src/order/labels.ts +79 -79
  74. package/src/order/order-totals.tsx +250 -250
  75. package/src/primitives/select-field.tsx +93 -93
  76. package/src/products/image-gallery.tsx +43 -43
  77. package/src/products/option-select.tsx +67 -67
  78. package/src/products/product-info.tsx +5 -5
  79. package/src/products/product-price.tsx +69 -69
  80. package/src/products/product-promises.tsx +61 -61
  81. package/src/products/product-specs.tsx +65 -65
  82. package/src/products/product-tabs.tsx +123 -123
  83. package/src/products/purchase-options.tsx +130 -130
  84. package/src/products/sets.ts +110 -110
  85. package/src/products/variant-matching.ts +71 -71
  86. package/src/products/variant-url.ts +74 -74
  87. package/src/reviews-ui/lightbox-state.ts +46 -46
  88. package/src/reviews-ui/review-header.tsx +166 -166
  89. package/src/reviews-ui/review-lightbox.tsx +271 -271
  90. package/src/reviews-ui/review-list.tsx +193 -193
  91. package/src/reviews-ui/review-widget.tsx +219 -218
  92. package/src/reviews-ui/widget-options.ts +55 -55
  93. package/src/store/category-template.tsx +136 -136
  94. package/src/store/index.ts +40 -40
  95. package/src/store/labels.ts +10 -0
  96. package/src/tracking/chatgpt-pixel.tsx +99 -99
  97. package/src/tracking/consent-init.tsx +62 -62
  98. package/src/tracking/events.ts +348 -348
  99. package/src/tracking/ga4.tsx +93 -93
  100. package/src/tracking/google-ads.ts +84 -84
  101. package/src/tracking/gtm.tsx +60 -60
  102. package/src/tracking/inline-script.ts +49 -49
  103. package/src/tracking/oaiq.ts +206 -206
  104. package/src/tracking/tiktok-pixel.tsx +91 -91
  105. package/src/tracking/track-init.tsx +56 -56
  106. package/src/tracking/track-order-purchase.tsx +122 -122
  107. package/src/tracking/ttq.ts +180 -180
  108. package/src/tracking/use-tracking-config.ts +54 -54
  109. package/theme/index.css +25 -25
@@ -1,96 +1,36 @@
1
- "use client"
2
-
3
- import type { ReactNode } from "react"
4
-
5
- /**
6
- * CartPaymentBadges — row of small payment-method logos shown near the
7
- * checkout button.
8
- *
9
- * Ported from `@1click/ui/src/cart-drawer/payment-badges.tsx` (v2.3.1);
10
- * originally extracted from mindpages-storefront
11
- * src/modules/cart-drawer/cart-payment-badges.tsx.
12
- * Inline SVGs are kept so stores don't need to provide asset files for the
13
- * default set, but stores can pass their own badges map via the `badges`
14
- * prop to override.
15
- */
16
-
17
- type BadgeKey = "visa" | "mastercard" | "applepay" | "googlepay" | "amex"
18
-
19
- const defaultBadges: Record<BadgeKey, ReactNode> = {
20
- visa: (
21
- <svg viewBox="0 0 48 32" width="42" height="28" fill="none">
22
- <rect width="48" height="32" rx="4" fill="#fff" stroke="#e4e4e7" strokeWidth="1" />
23
- <path
24
- d="M20.3 21h-2.7l1.7-10.5h2.7L20.3 21zm-4.7 0l-2.5-7.2-.3-1.5c-.5-1.3-1.7-1.8-1.7-1.8h-.1l-1 .2L7 21h2.8l.6-1.5h3.4l.3 1.5h2.5zm-3.2-3.6l1.4-3.8.8 3.8h-2.2zM32 10.5L29.3 21h-2.5l1.5-8.2-.1-.2-2 8.4h-2l-2-8.4v.3L20.7 21h-2.4l2.8-10.5h3.4l1.7 7.2 1.7-7.2H32zm8.8 0L38 21h-2.5l2.8-10.5h2.5z"
25
- fill="#1a1f71"
26
- />
27
- </svg>
28
- ),
29
- mastercard: (
30
- <svg viewBox="0 0 48 32" width="42" height="28" fill="none">
31
- <rect width="48" height="32" rx="4" fill="#fff" stroke="#e4e4e7" strokeWidth="1" />
32
- <circle cx="19" cy="16" r="8" fill="#eb001b" />
33
- <circle cx="29" cy="16" r="8" fill="#f79e1b" />
34
- <path d="M24 9.8a8 8 0 010 12.4 8 8 0 000-12.4z" fill="#ff5f00" />
35
- </svg>
36
- ),
37
- applepay: (
38
- <svg viewBox="0 0 48 32" width="42" height="28" fill="none">
39
- <rect width="48" height="32" rx="4" fill="#000" />
40
- <g fill="#fff">
41
- <path d="M15.2 11.8c-.6.7-1.5 1.2-2.4 1.1-.1-1 .4-2 .9-2.6.6-.7 1.5-1.2 2.3-1.2.1 1-.3 2-.8 2.7zm.8 1.4c-1.3-.1-2.5.8-3.1.8s-1.6-.7-2.7-.7c-1.4 0-2.7.8-3.4 2.1-1.4 2.5-.4 6.2 1 8.2.7 1 1.5 2.1 2.6 2s1.4-.7 2.7-.7 1.6.7 2.7.7 1.8-1 2.5-2c.8-1.1 1.1-2.2 1.1-2.3-1.2-.5-2-1.8-2-3.3 0-1.3.7-2.5 1.8-3.1-.7-1-1.8-1.7-3.2-1.7z" />
42
- <path d="M25 12.5v10.8h1.7v-3.7h2.3c2.1 0 3.6-1.5 3.6-3.6s-1.5-3.5-3.5-3.5H25zm1.7 1.4h1.9c1.5 0 2.3.8 2.3 2.1s-.8 2.1-2.3 2.1h-1.9v-4.2zm8.8 9.5c1.1 0 2.1-.5 2.5-1.4h0v1.3H39.6v-5.2c0-1.8-1.4-2.9-3.5-2.9-2 0-3.4 1.1-3.4 2.8h1.6c.1-.8.9-1.4 1.8-1.4 1.2 0 1.8.5 1.8 1.5v.7l-2.4.1c-2.2.1-3.4 1-3.4 2.6 0 1.6 1.2 2.7 2.9 2.7v-.8zm.4-1.3c-1 0-1.7-.5-1.7-1.3 0-.8.6-1.3 1.8-1.4l2.1-.1v.7c0 1.2-1 2.1-2.2 2.1z" />
43
- </g>
44
- </svg>
45
- ),
46
- googlepay: (
47
- <svg viewBox="0 0 48 32" width="42" height="28" fill="none">
48
- <rect width="48" height="32" rx="4" fill="#fff" stroke="#e4e4e7" strokeWidth="1" />
49
- <path
50
- d="M23.5 16.7v3.1h-1v-7.6h2.7c.7 0 1.2.2 1.7.6.5.4.7.9.7 1.5s-.2 1.1-.7 1.5c-.5.4-1 .6-1.7.6h-1.7zm0-3.5v2.5h1.7c.4 0 .8-.2 1.1-.4.3-.3.4-.6.4-1s-.1-.7-.4-1c-.3-.3-.6-.4-1.1-.4h-1.7z"
51
- fill="#3c4043"
52
- />
53
- <path
54
- d="M30.6 14.2c.7 0 1.3.2 1.8.6.4.4.7 1 .7 1.7v3.3h-1v-.7c-.4.6-.9.9-1.6.9-.6 0-1.1-.2-1.5-.5-.4-.3-.6-.8-.6-1.3 0-.5.2-1 .5-1.3.4-.3.9-.5 1.5-.5.6 0 1.1.2 1.4.5v-.3c0-.4-.2-.7-.4-.9-.3-.2-.6-.4-1-.4-.6 0-1 .2-1.3.7l-.8-.5c.5-.7 1.1-1 2-1h.3zm-1 4.6c.3.2.6.3 1 .3s.7-.1 1-.3c.3-.2.4-.5.4-.8s-.1-.6-.4-.8c-.3-.2-.6-.3-1-.3s-.7.1-1 .3c-.3.2-.4.5-.4.8s.2.6.4.8z"
55
- fill="#3c4043"
56
- />
57
- <path d="M37 14.4l-2.4 5.5h-1l.9-1.9-1.6-3.6h1.1l1 2.5 1-2.5H37z" fill="#3c4043" />
58
- <path d="M18.3 16c0-.3 0-.6-.1-.9h-4.6v1.7h2.7c-.1.6-.4 1.1-.9 1.4v1.2h1.5c.9-.8 1.4-2 1.4-3.4z" fill="#4285f4" />
59
- <path d="M13.6 19.7c1.2 0 2.2-.4 3-1.1l-1.5-1.2c-.4.3-.9.4-1.5.4-1.2 0-2.1-.8-2.5-1.8H9.7v1.2c.7 1.5 2.2 2.5 3.9 2.5z" fill="#34a853" />
60
- <path d="M11.1 16c0-.3.1-.7.2-1v-1.2H9.7c-.4.7-.6 1.4-.6 2.2s.2 1.5.6 2.2l1.6-1.2c-.1-.3-.2-.7-.2-1z" fill="#fbbc04" />
61
- <path d="M13.6 12.2c.7 0 1.3.2 1.8.7l1.3-1.3c-.8-.8-1.9-1.2-3.1-1.2-1.7 0-3.2 1-3.9 2.5l1.6 1.2c.4-1.1 1.3-1.9 2.3-1.9z" fill="#ea4335" />
62
- </svg>
63
- ),
64
- amex: (
65
- <svg viewBox="0 0 48 32" width="42" height="28" fill="none">
66
- <rect width="48" height="32" rx="4" fill="#006fcf" />
67
- <text x="24" y="20" fill="#fff" fontSize="10" fontWeight="700" textAnchor="middle" fontFamily="Arial, sans-serif">
68
- AMEX
69
- </text>
70
- </svg>
71
- ),
72
- }
73
-
74
- type CartPaymentBadgesProps = {
75
- methods?: BadgeKey[]
76
- badges?: Partial<Record<BadgeKey, ReactNode>>
77
- }
78
-
79
- export function CartPaymentBadges({
80
- methods = ["visa", "mastercard", "googlepay", "applepay"],
81
- badges,
82
- }: CartPaymentBadgesProps) {
83
- const resolved = { ...defaultBadges, ...badges }
84
- return (
85
- <div className="flex items-center justify-center gap-2 px-5 py-3">
86
- {methods.map((method) => (
87
- <div
88
- key={method}
89
- className="opacity-70 hover:opacity-100 transition-opacity"
90
- >
91
- {resolved[method]}
92
- </div>
93
- ))}
94
- </div>
95
- )
96
- }
1
+ "use client"
2
+
3
+ import type { ReactNode } from "react"
4
+ import { PaymentIcon, type PaymentMethod } from "../common/payment-icons"
5
+
6
+ /**
7
+ * CartPaymentBadges — row of small payment-method logos shown near the
8
+ * checkout button.
9
+ *
10
+ * Ported from `@1click/ui/src/cart-drawer/payment-badges.tsx` (v2.3.1);
11
+ * originally extracted from mindpages-storefront
12
+ * src/modules/cart-drawer/cart-payment-badges.tsx. Since 2026-09-17 the
13
+ * badges are the kit's payment marks (`common/payment-icons`), the same the
14
+ * footer shows, so any mark the kit carries can be named; a store can still
15
+ * pass its own badge per method through `badges`.
16
+ */
17
+
18
+ type CartPaymentBadgesProps = {
19
+ methods?: PaymentMethod[]
20
+ badges?: Partial<Record<PaymentMethod, ReactNode>>
21
+ }
22
+
23
+ export function CartPaymentBadges({
24
+ methods = ["visa", "mastercard", "googlepay", "applepay"],
25
+ badges,
26
+ }: CartPaymentBadgesProps) {
27
+ return (
28
+ <div className="flex items-center justify-center gap-2 px-5 py-3">
29
+ {methods.map((method) => (
30
+ <div key={method} className="opacity-70 transition-opacity hover:opacity-100">
31
+ {badges?.[method] ?? <PaymentIcon method={method} className="h-7" />}
32
+ </div>
33
+ ))}
34
+ </div>
35
+ )
36
+ }
@@ -1,73 +1,73 @@
1
- "use client"
2
-
3
- import Link from "next/link"
4
-
5
- import { Price } from "../lib/price"
6
- import { productTotal } from "../lib/cart-helpers"
7
- import { useCartDrawer } from "./context"
8
-
9
- /**
10
- * CartStickyFooter — bottom-of-drawer subtotal + checkout CTA with
11
- * iPhone home-indicator safe-area padding.
12
- *
13
- * Ported from `@1click/ui/src/cart-drawer/sticky-footer.tsx` (v2.3.1);
14
- * originally extracted from mindpages-storefront
15
- * src/modules/cart-drawer/cart-sticky-footer.tsx. Amounts EUR major units.
16
- */
17
-
18
- export function CartStickyFooter() {
19
- const { cart, close, labels, hrefs } = useCartDrawer()
20
- if (!cart || !cart.items?.length) return null
21
-
22
- // Drawer is pre-checkout context — never read `cart.total` here.
23
- // `cart.total` includes shipping/tax/COD fee, all of which are
24
- // checkout-context state that must not leak into the shopping
25
- // drawer. Sum of product line totals only.
26
- const total = productTotal(cart.items)
27
- const currencyCode = cart.currency_code
28
-
29
- return (
30
- <div
31
- className="flex-shrink-0 bg-card px-5 sm:px-6 pt-4 sm:pt-5 relative z-10"
32
- style={{
33
- boxShadow: "0 -4px 12px rgba(0,0,0,0.04)",
34
- paddingBottom: "max(1.25rem, env(safe-area-inset-bottom, 1.25rem))",
35
- }}
36
- >
37
- <div className="flex items-baseline justify-between mb-1">
38
- <span className="text-[15px] font-bold text-foreground">
39
- {labels.subtotal}
40
- </span>
41
- <Price
42
- amount={total}
43
- currencyCode={currencyCode}
44
- className="text-xl font-bold text-foreground tracking-tight"
45
- />
46
- </div>
47
- <p className="text-[11px] text-muted-foreground mb-3.5 sm:mb-4">
48
- {labels.taxAndShipping}
49
- </p>
50
- <Link href={hrefs.checkout} onClick={close}>
51
- <button
52
- type="button"
53
- className="w-full h-[52px] bg-foreground hover:bg-foreground/90 active:bg-foreground/95 text-card text-[15px] sm:text-sm font-semibold rounded-[2px] flex items-center justify-center gap-2.5 transition-colors active:scale-[0.98]"
54
- >
55
- <svg
56
- width="16"
57
- height="16"
58
- viewBox="0 0 16 16"
59
- fill="none"
60
- stroke="currentColor"
61
- strokeWidth="1.5"
62
- strokeLinecap="round"
63
- strokeLinejoin="round"
64
- >
65
- <rect x="3" y="6" width="10" height="8" rx="1.5" />
66
- <path d="M5.5 6V4.5a2.5 2.5 0 015 0V6" />
67
- </svg>
68
- {labels.secureCheckout}
69
- </button>
70
- </Link>
71
- </div>
72
- )
73
- }
1
+ "use client"
2
+
3
+ import Link from "next/link"
4
+
5
+ import { Price } from "../lib/price"
6
+ import { productTotal } from "../lib/cart-helpers"
7
+ import { useCartDrawer } from "./context"
8
+
9
+ /**
10
+ * CartStickyFooter — bottom-of-drawer subtotal + checkout CTA with
11
+ * iPhone home-indicator safe-area padding.
12
+ *
13
+ * Ported from `@1click/ui/src/cart-drawer/sticky-footer.tsx` (v2.3.1);
14
+ * originally extracted from mindpages-storefront
15
+ * src/modules/cart-drawer/cart-sticky-footer.tsx. Amounts EUR major units.
16
+ */
17
+
18
+ export function CartStickyFooter() {
19
+ const { cart, close, labels, hrefs } = useCartDrawer()
20
+ if (!cart || !cart.items?.length) return null
21
+
22
+ // Drawer is pre-checkout context — never read `cart.total` here.
23
+ // `cart.total` includes shipping/tax/COD fee, all of which are
24
+ // checkout-context state that must not leak into the shopping
25
+ // drawer. Sum of product line totals only.
26
+ const total = productTotal(cart.items)
27
+ const currencyCode = cart.currency_code
28
+
29
+ return (
30
+ <div
31
+ className="flex-shrink-0 bg-card px-5 sm:px-6 pt-4 sm:pt-5 relative z-10"
32
+ style={{
33
+ boxShadow: "0 -4px 12px rgba(0,0,0,0.04)",
34
+ paddingBottom: "max(1.25rem, env(safe-area-inset-bottom, 1.25rem))",
35
+ }}
36
+ >
37
+ <div className="flex items-baseline justify-between mb-1">
38
+ <span className="text-[15px] font-bold text-foreground">
39
+ {labels.subtotal}
40
+ </span>
41
+ <Price
42
+ amount={total}
43
+ currencyCode={currencyCode}
44
+ className="text-xl font-bold text-foreground tracking-tight"
45
+ />
46
+ </div>
47
+ <p className="text-[11px] text-muted-foreground mb-3.5 sm:mb-4">
48
+ {labels.taxAndShipping}
49
+ </p>
50
+ <Link href={hrefs.checkout} onClick={close}>
51
+ <button
52
+ type="button"
53
+ className="w-full h-[52px] bg-foreground hover:bg-foreground/90 active:bg-foreground/95 text-card text-[15px] sm:text-sm font-semibold rounded-[2px] flex items-center justify-center gap-2.5 transition-colors active:scale-[0.98]"
54
+ >
55
+ <svg
56
+ width="16"
57
+ height="16"
58
+ viewBox="0 0 16 16"
59
+ fill="none"
60
+ stroke="currentColor"
61
+ strokeWidth="1.5"
62
+ strokeLinecap="round"
63
+ strokeLinejoin="round"
64
+ >
65
+ <rect x="3" y="6" width="10" height="8" rx="1.5" />
66
+ <path d="M5.5 6V4.5a2.5 2.5 0 015 0V6" />
67
+ </svg>
68
+ {labels.secureCheckout}
69
+ </button>
70
+ </Link>
71
+ </div>
72
+ )
73
+ }