@reblu/site-blocks 0.6.0 → 0.8.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.
package/dist/index.cjs CHANGED
@@ -21,12 +21,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
23
  ALLOWED_YOUTUBE_HOSTS: () => ALLOWED_YOUTUBE_HOSTS,
24
- AddToCartButton: () => AddToCartButton,
25
- CartIcon: () => CartIcon,
24
+ AddedToCartToast: () => AddedToCartToast,
26
25
  CartLineList: () => CartLineList,
27
26
  CartSummary: () => CartSummary,
28
27
  CheckoutForm: () => CheckoutForm,
29
28
  CheckoutLoginPrompt: () => CheckoutLoginPrompt,
29
+ DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE: () => DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE,
30
+ DEFAULT_SHOP_ERROR_MESSAGES: () => DEFAULT_SHOP_ERROR_MESSAGES,
30
31
  DEFAULT_SHOP_PRICE_BANDS: () => DEFAULT_SHOP_PRICE_BANDS,
31
32
  MarkdownRenderer: () => MarkdownRenderer,
32
33
  OrderConfirmation: () => OrderConfirmation,
@@ -38,6 +39,7 @@ __export(src_exports, {
38
39
  Treatment: () => Treatment,
39
40
  buildShareUrls: () => buildShareUrls,
40
41
  formatPrice: () => formatPrice,
42
+ getShopErrorMessage: () => getShopErrorMessage,
41
43
  isAllowedYouTubeHost: () => isAllowedYouTubeHost,
42
44
  markdownToSafeHtml: () => markdownToSafeHtml,
43
45
  readingTime: () => readingTime,
@@ -78,6 +80,25 @@ function buildShareUrls(url, title) {
78
80
  };
79
81
  }
80
82
 
83
+ // src/lib/shop-error-messages.ts
84
+ var DEFAULT_SHOP_ERROR_MESSAGES = {
85
+ STOCK_CHANGED: "Alguno de los productos de tu carrito ya no tiene stock suficiente.",
86
+ PRICE_CHANGED: "El precio de alguno de los productos de tu carrito ha cambiado. Rev\xEDsalo antes de continuar.",
87
+ PRODUCT_UNAVAILABLE: "Alguno de los productos de tu carrito ya no est\xE1 disponible.",
88
+ DISCOUNT_INVALID: "El c\xF3digo de descuento no es v\xE1lido.",
89
+ SHIPPING_UNAVAILABLE: "El env\xEDo no est\xE1 disponible para la direcci\xF3n indicada.",
90
+ INVALID_INPUT: "Revisa los datos introducidos.",
91
+ STORE_DISABLED: "La tienda no est\xE1 disponible en este momento.",
92
+ PAYMENT_PROVIDER_ERROR: "No hemos podido conectar con la pasarela de pago. Int\xE9ntalo de nuevo.",
93
+ INTERNAL_ERROR: "Ha ocurrido un error inesperado. Int\xE9ntalo de nuevo en unos minutos."
94
+ };
95
+ var DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE = "No se ha podido completar la operaci\xF3n. Int\xE9ntalo de nuevo.";
96
+ function getShopErrorMessage(code, overrides, fallback = DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE) {
97
+ if (!code) return fallback;
98
+ const messages = { ...DEFAULT_SHOP_ERROR_MESSAGES, ...overrides };
99
+ return messages[code] ?? fallback;
100
+ }
101
+
81
102
  // ../../node_modules/.pnpm/devlop@1.1.0/node_modules/devlop/lib/default.js
82
103
  function ok() {
83
104
  }
@@ -13627,103 +13648,16 @@ function ShopFilters({
13627
13648
  ] });
13628
13649
  }
13629
13650
 
13630
- // src/components/add-to-cart-button.tsx
13651
+ // src/components/cart-line-list.tsx
13631
13652
  var import_utils8 = require("@reblu/site-ui/utils");
13632
13653
  var import_jsx_runtime8 = require("react/jsx-runtime");
13633
13654
  var DEFAULT_LABELS2 = {
13634
- add: "A\xF1adir al carrito",
13635
- adding: "A\xF1adiendo\u2026",
13636
- outOfStock: "Agotado"
13637
- };
13638
- function AddToCartButton({
13639
- onAddToCart,
13640
- disabled,
13641
- outOfStock,
13642
- pending,
13643
- labels,
13644
- className
13645
- }) {
13646
- const t = { ...DEFAULT_LABELS2, ...labels };
13647
- const isDisabled = Boolean(disabled || outOfStock || pending);
13648
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
13649
- "button",
13650
- {
13651
- type: "button",
13652
- onClick: onAddToCart,
13653
- disabled: isDisabled,
13654
- "data-slot": "add-to-cart-button",
13655
- className: (0, import_utils8.cn)(
13656
- "inline-flex items-center justify-center gap-2 rounded-xl px-4 py-2.5 text-sm font-semibold transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
13657
- isDisabled ? "cursor-not-allowed bg-muted text-muted-foreground" : "bg-primary text-primary-foreground hover:bg-primary/90",
13658
- className
13659
- ),
13660
- children: outOfStock ? t.outOfStock : pending ? t.adding : t.add
13661
- }
13662
- );
13663
- }
13664
-
13665
- // src/components/cart-icon.tsx
13666
- var import_utils9 = require("@reblu/site-ui/utils");
13667
- var import_jsx_runtime9 = require("react/jsx-runtime");
13668
- var DEFAULT_LABELS3 = {
13669
- cart: "Carrito",
13670
- itemsSuffix: (count) => `${count} art\xEDculo${count === 1 ? "" : "s"}`
13671
- };
13672
- function CartIcon({ itemCount, href, labels, className }) {
13673
- const t = { ...DEFAULT_LABELS3, ...labels };
13674
- const ariaLabel = itemCount > 0 ? `${t.cart} (${t.itemsSuffix(itemCount)})` : t.cart;
13675
- const displayCount = itemCount > 99 ? "99+" : String(itemCount);
13676
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
13677
- "a",
13678
- {
13679
- href,
13680
- "aria-label": ariaLabel,
13681
- "data-slot": "cart-icon",
13682
- className: (0, import_utils9.cn)(
13683
- "relative inline-flex items-center justify-center rounded-lg p-2 text-foreground/80 transition-colors hover:bg-muted/60 hover:text-foreground",
13684
- className
13685
- ),
13686
- children: [
13687
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
13688
- "svg",
13689
- {
13690
- viewBox: "0 0 24 24",
13691
- fill: "none",
13692
- stroke: "currentColor",
13693
- strokeWidth: 2,
13694
- strokeLinecap: "round",
13695
- strokeLinejoin: "round",
13696
- className: "h-5 w-5",
13697
- "aria-hidden": "true",
13698
- children: [
13699
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "9", cy: "21", r: "1" }),
13700
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("circle", { cx: "20", cy: "21", r: "1" }),
13701
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6" })
13702
- ]
13703
- }
13704
- ),
13705
- itemCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
13706
- "span",
13707
- {
13708
- "aria-hidden": "true",
13709
- className: "absolute -top-0.5 -right-0.5 flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-primary px-1 text-[10px] font-bold leading-none tabular-nums text-primary-foreground",
13710
- children: displayCount
13711
- }
13712
- )
13713
- ]
13714
- }
13715
- );
13716
- }
13717
-
13718
- // src/components/cart-line-list.tsx
13719
- var import_utils10 = require("@reblu/site-ui/utils");
13720
- var import_jsx_runtime10 = require("react/jsx-runtime");
13721
- var DEFAULT_LABELS4 = {
13722
13655
  quantityLabel: "Cantidad",
13723
13656
  decrease: "Reducir cantidad",
13724
13657
  increase: "Aumentar cantidad",
13725
13658
  remove: "Eliminar",
13726
- unitPriceSuffix: "/ ud."
13659
+ unitPriceSuffix: "/ ud.",
13660
+ cancelledNotice: "Pago cancelado: tu carrito sigue aqu\xED"
13727
13661
  };
13728
13662
  function lineKey(productId, variantId) {
13729
13663
  return `${productId}-${variantId ?? "no-variant"}`;
@@ -13733,40 +13667,51 @@ function CartLineList({
13733
13667
  onQuantityChange,
13734
13668
  onRemove,
13735
13669
  liveMessage,
13670
+ notice,
13736
13671
  labels,
13737
13672
  currencyCode,
13738
13673
  locale,
13739
13674
  className
13740
13675
  }) {
13741
- const t = { ...DEFAULT_LABELS4, ...labels };
13742
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: (0, import_utils10.cn)("space-y-4", className), "data-slot": "cart-line-list", children: [
13743
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { "aria-live": "polite", className: "sr-only", children: liveMessage }),
13744
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ul", { className: "space-y-4", children: items.map((item) => {
13676
+ const t = { ...DEFAULT_LABELS2, ...labels };
13677
+ const noticeContent = notice === true ? t.cancelledNotice : notice;
13678
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: (0, import_utils8.cn)("space-y-4", className), "data-slot": "cart-line-list", children: [
13679
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { "aria-live": "polite", className: "sr-only", children: liveMessage }),
13680
+ noticeContent != null && noticeContent !== false && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
13681
+ "div",
13682
+ {
13683
+ role: "status",
13684
+ className: "rounded-lg bg-muted px-3 py-2 text-sm text-muted-foreground",
13685
+ "data-slot": "cart-line-list-notice",
13686
+ children: noticeContent
13687
+ }
13688
+ ),
13689
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("ul", { className: "space-y-4", children: items.map((item) => {
13745
13690
  const maxQty = item.maxStock ?? Infinity;
13746
13691
  const atMax = item.quantity >= maxQty;
13747
13692
  const atMin = item.quantity <= 1;
13748
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
13693
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
13749
13694
  "li",
13750
13695
  {
13751
13696
  className: "flex gap-4 rounded-xl border border-border bg-card p-4",
13752
13697
  children: [
13753
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "h-20 w-20 flex-shrink-0 overflow-hidden rounded-lg bg-muted", children: item.imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("img", { src: item.imageUrl, alt: item.name, className: "h-full w-full object-cover" }) : null }),
13754
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "min-w-0 flex-1", children: [
13755
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "truncate text-sm font-semibold leading-tight", children: item.name }),
13756
- item.variantName && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground", children: item.variantName }),
13757
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "mt-1 text-sm text-muted-foreground", children: [
13698
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "h-20 w-20 flex-shrink-0 overflow-hidden rounded-lg bg-muted", children: item.imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: item.imageUrl, alt: item.name, className: "h-full w-full object-cover" }) : null }),
13699
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "min-w-0 flex-1", children: [
13700
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "truncate text-sm font-semibold leading-tight", children: item.name }),
13701
+ item.variantName && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground", children: item.variantName }),
13702
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { className: "mt-1 text-sm text-muted-foreground", children: [
13758
13703
  formatPrice(item.unitPrice, currencyCode, locale),
13759
13704
  " ",
13760
13705
  t.unitPriceSuffix
13761
13706
  ] }),
13762
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
13707
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
13763
13708
  "div",
13764
13709
  {
13765
13710
  role: "group",
13766
13711
  "aria-label": t.quantityLabel,
13767
13712
  className: "mt-3 flex items-center gap-3",
13768
13713
  children: [
13769
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
13714
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
13770
13715
  "button",
13771
13716
  {
13772
13717
  type: "button",
@@ -13777,8 +13722,8 @@ function CartLineList({
13777
13722
  children: "\u2212"
13778
13723
  }
13779
13724
  ),
13780
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "w-8 text-center text-sm font-semibold tabular-nums", children: item.quantity }),
13781
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
13725
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "w-8 text-center text-sm font-semibold tabular-nums", children: item.quantity }),
13726
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
13782
13727
  "button",
13783
13728
  {
13784
13729
  type: "button",
@@ -13789,7 +13734,7 @@ function CartLineList({
13789
13734
  children: "+"
13790
13735
  }
13791
13736
  ),
13792
- onRemove && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
13737
+ onRemove && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
13793
13738
  "button",
13794
13739
  {
13795
13740
  type: "button",
@@ -13803,7 +13748,7 @@ function CartLineList({
13803
13748
  }
13804
13749
  )
13805
13750
  ] }),
13806
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex-shrink-0 text-right", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "text-base font-bold", children: formatPrice(item.unitPrice * item.quantity, currencyCode, locale) }) })
13751
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex-shrink-0 text-right", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-base font-bold", children: formatPrice(item.unitPrice * item.quantity, currencyCode, locale) }) })
13807
13752
  ]
13808
13753
  },
13809
13754
  lineKey(item.productId, item.variantId)
@@ -13813,15 +13758,16 @@ function CartLineList({
13813
13758
  }
13814
13759
 
13815
13760
  // src/components/cart-summary.tsx
13816
- var import_utils11 = require("@reblu/site-ui/utils");
13817
- var import_jsx_runtime11 = require("react/jsx-runtime");
13818
- var DEFAULT_LABELS5 = {
13761
+ var import_utils9 = require("@reblu/site-ui/utils");
13762
+ var import_jsx_runtime9 = require("react/jsx-runtime");
13763
+ var DEFAULT_LABELS3 = {
13819
13764
  subtotal: "Subtotal",
13820
13765
  discountPrefix: "Descuento",
13821
13766
  shipping: "Env\xEDo",
13822
13767
  freeShipping: "Env\xEDo gratis",
13823
13768
  shippingCalculated: "Se calcula en el pago",
13824
- total: "Total"
13769
+ total: "Total",
13770
+ cancelledNotice: "Pago cancelado: tu carrito sigue aqu\xED"
13825
13771
  };
13826
13772
  function CartSummary({
13827
13773
  subtotal,
@@ -13830,43 +13776,114 @@ function CartSummary({
13830
13776
  shipping,
13831
13777
  shippingEnabled,
13832
13778
  total,
13779
+ notice,
13833
13780
  labels,
13834
13781
  currencyCode,
13835
13782
  locale,
13836
13783
  className
13837
13784
  }) {
13838
- const t = { ...DEFAULT_LABELS5, ...labels };
13785
+ const t = { ...DEFAULT_LABELS3, ...labels };
13839
13786
  const hasDiscount = Boolean(discount && discount > 0);
13840
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("dl", { className: (0, import_utils11.cn)("space-y-2 text-sm", className), "data-slot": "cart-summary", children: [
13841
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-muted-foreground", children: [
13842
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dt", { children: t.subtotal }),
13843
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dd", { children: formatPrice(subtotal, currencyCode, locale) })
13844
- ] }),
13845
- hasDiscount && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-green-600 dark:text-green-400", children: [
13846
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("dt", { children: [
13847
- t.discountPrefix,
13848
- discountCode ? ` (${discountCode})` : ""
13849
- ] }),
13850
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("dd", { children: [
13851
- "-",
13852
- formatPrice(discount, currencyCode, locale)
13853
- ] })
13854
- ] }),
13855
- shippingEnabled && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between text-muted-foreground", children: [
13856
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dt", { children: t.shipping }),
13857
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dd", { children: shipping == null || !Number.isFinite(shipping) ? t.shippingCalculated : shipping === 0 ? t.freeShipping : formatPrice(shipping, currencyCode, locale) })
13858
- ] }),
13859
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex justify-between border-t border-border pt-2 text-base font-bold", children: [
13860
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dt", { children: t.total }),
13861
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dd", { children: formatPrice(total, currencyCode, locale) })
13862
- ] })
13787
+ const noticeContent = notice === true ? t.cancelledNotice : notice;
13788
+ const hasNotice = noticeContent != null && noticeContent !== false;
13789
+ const breakdown = /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
13790
+ "dl",
13791
+ {
13792
+ className: (0, import_utils9.cn)("space-y-2 text-sm", !hasNotice && className),
13793
+ "data-slot": "cart-summary",
13794
+ children: [
13795
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex justify-between text-muted-foreground", children: [
13796
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dt", { children: t.subtotal }),
13797
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dd", { children: formatPrice(subtotal, currencyCode, locale) })
13798
+ ] }),
13799
+ hasDiscount && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex justify-between text-green-600 dark:text-green-400", children: [
13800
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("dt", { children: [
13801
+ t.discountPrefix,
13802
+ discountCode ? ` (${discountCode})` : ""
13803
+ ] }),
13804
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("dd", { children: [
13805
+ "-",
13806
+ formatPrice(discount, currencyCode, locale)
13807
+ ] })
13808
+ ] }),
13809
+ shippingEnabled && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex justify-between text-muted-foreground", children: [
13810
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dt", { children: t.shipping }),
13811
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dd", { children: shipping == null || !Number.isFinite(shipping) ? t.shippingCalculated : shipping === 0 ? t.freeShipping : formatPrice(shipping, currencyCode, locale) })
13812
+ ] }),
13813
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex justify-between border-t border-border pt-2 text-base font-bold", children: [
13814
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dt", { children: t.total }),
13815
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("dd", { children: formatPrice(total, currencyCode, locale) })
13816
+ ] })
13817
+ ]
13818
+ }
13819
+ );
13820
+ if (!hasNotice) return breakdown;
13821
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: (0, import_utils9.cn)("space-y-3", className), "data-slot": "cart-summary-wrapper", children: [
13822
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
13823
+ "div",
13824
+ {
13825
+ role: "status",
13826
+ className: "rounded-lg bg-muted px-3 py-2 text-sm text-muted-foreground",
13827
+ "data-slot": "cart-summary-notice",
13828
+ children: noticeContent
13829
+ }
13830
+ ),
13831
+ breakdown
13863
13832
  ] });
13864
13833
  }
13865
13834
 
13835
+ // src/components/added-to-cart-toast.tsx
13836
+ var import_utils10 = require("@reblu/site-ui/utils");
13837
+ var import_jsx_runtime10 = (
13838
+ // eslint-disable-next-line @next/next/no-img-element -- toast content, not a Next <Image> layout context
13839
+ require("react/jsx-runtime")
13840
+ );
13841
+ var DEFAULT_LABELS4 = {
13842
+ success: "A\xF1adido al carrito",
13843
+ error: "No se pudo a\xF1adir al carrito",
13844
+ outOfStock: "Producto agotado",
13845
+ viewCart: "Ver carrito"
13846
+ };
13847
+ function AddedToCartToast({
13848
+ status = "success",
13849
+ productName,
13850
+ quantity,
13851
+ imageUrl,
13852
+ cartHref,
13853
+ labels,
13854
+ className
13855
+ }) {
13856
+ const t = { ...DEFAULT_LABELS4, ...labels };
13857
+ const message = status === "error" ? t.error : status === "outOfStock" ? t.outOfStock : t.success;
13858
+ const hasThumbnail = Boolean(imageUrl && imageUrl.trim().length > 0);
13859
+ const variant = status === "success" ? "success" : "error";
13860
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
13861
+ "div",
13862
+ {
13863
+ "data-slot": "added-to-cart-toast",
13864
+ "data-variant": variant,
13865
+ className: (0, import_utils10.cn)(
13866
+ "flex items-center gap-3 rounded-xl border border-border bg-card p-3 text-sm shadow-lg",
13867
+ variant === "success" && "border-green-600/30 dark:border-green-400/30",
13868
+ variant === "error" && "border-destructive/30",
13869
+ className
13870
+ ),
13871
+ children: [
13872
+ hasThumbnail && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("img", { src: imageUrl, alt: productName, className: "h-10 w-10 flex-shrink-0 rounded-lg object-cover" }),
13873
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: "min-w-0 flex-1", children: [
13874
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "truncate font-semibold text-foreground", children: productName }),
13875
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "truncate text-muted-foreground", children: quantity && quantity > 1 ? `${message} \xB7 x${quantity}` : message })
13876
+ ] }),
13877
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("a", { href: cartHref, className: "text-sm font-semibold text-primary underline-offset-2 hover:underline", children: t.viewCart }) })
13878
+ ]
13879
+ }
13880
+ );
13881
+ }
13882
+
13866
13883
  // src/components/checkout-login-prompt.tsx
13867
- var import_utils12 = require("@reblu/site-ui/utils");
13868
- var import_jsx_runtime12 = require("react/jsx-runtime");
13869
- var DEFAULT_LABELS6 = {
13884
+ var import_utils11 = require("@reblu/site-ui/utils");
13885
+ var import_jsx_runtime11 = require("react/jsx-runtime");
13886
+ var DEFAULT_LABELS5 = {
13870
13887
  title: "Identificaci\xF3n",
13871
13888
  description: "Introduce tu email para agilizar el proceso o contin\xFAa como invitado.",
13872
13889
  emailLabel: "Email",
@@ -13890,28 +13907,28 @@ function CheckoutLoginPrompt({
13890
13907
  className
13891
13908
  }) {
13892
13909
  if (!open) return null;
13893
- const t = { ...DEFAULT_LABELS6, ...labels };
13910
+ const t = { ...DEFAULT_LABELS5, ...labels };
13894
13911
  const isValidEmail = EMAIL_PATTERN.test(email.trim());
13895
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
13896
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "fixed inset-0 z-50 bg-black/50", onClick: onClose, "aria-hidden": "true" }),
13897
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
13912
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
13913
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "fixed inset-0 z-50 bg-black/50", onClick: onClose, "aria-hidden": "true" }),
13914
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
13898
13915
  "div",
13899
13916
  {
13900
13917
  role: "dialog",
13901
13918
  "aria-modal": "true",
13902
13919
  "aria-labelledby": "checkout-login-prompt-title",
13903
13920
  "data-slot": "checkout-login-prompt",
13904
- className: (0, import_utils12.cn)(
13921
+ className: (0, import_utils11.cn)(
13905
13922
  "fixed left-1/2 top-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 space-y-5 rounded-2xl border border-border bg-background p-6 shadow-2xl",
13906
13923
  className
13907
13924
  ),
13908
13925
  children: [
13909
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
13910
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
13911
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h2", { id: "checkout-login-prompt-title", className: "text-xl font-bold", children: t.title }),
13912
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: t.description })
13926
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
13927
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { children: [
13928
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { id: "checkout-login-prompt-title", className: "text-xl font-bold", children: t.title }),
13929
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: t.description })
13913
13930
  ] }),
13914
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
13931
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
13915
13932
  "button",
13916
13933
  {
13917
13934
  type: "button",
@@ -13922,9 +13939,9 @@ function CheckoutLoginPrompt({
13922
13939
  }
13923
13940
  )
13924
13941
  ] }),
13925
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-2", children: [
13926
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("label", { htmlFor: "checkout-login-prompt-email", className: "text-sm font-medium", children: t.emailLabel }),
13927
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
13942
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-2", children: [
13943
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { htmlFor: "checkout-login-prompt-email", className: "text-sm font-medium", children: t.emailLabel }),
13944
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
13928
13945
  "input",
13929
13946
  {
13930
13947
  id: "checkout-login-prompt-email",
@@ -13933,29 +13950,29 @@ function CheckoutLoginPrompt({
13933
13950
  value: email,
13934
13951
  onChange: (e) => onEmailChange(e.target.value),
13935
13952
  placeholder: t.emailPlaceholder,
13936
- className: (0, import_utils12.cn)(
13953
+ className: (0, import_utils11.cn)(
13937
13954
  "w-full rounded-lg border bg-background px-3 py-2 text-sm transition focus:outline-none focus:ring-2 focus:ring-primary/20",
13938
13955
  error ? "border-destructive" : "border-border focus:border-primary"
13939
13956
  )
13940
13957
  }
13941
13958
  ),
13942
- error && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs text-destructive", children: error })
13959
+ error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-xs text-destructive", children: error })
13943
13960
  ] }),
13944
- /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-2", children: [
13945
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
13961
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-2", children: [
13962
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
13946
13963
  "button",
13947
13964
  {
13948
13965
  type: "button",
13949
13966
  onClick: onSubmitEmail,
13950
13967
  disabled: checking || !isValidEmail,
13951
- className: (0, import_utils12.cn)(
13968
+ className: (0, import_utils11.cn)(
13952
13969
  "flex w-full items-center justify-center gap-2 rounded-xl px-4 py-2.5 text-sm font-semibold transition-all",
13953
13970
  checking || !isValidEmail ? "cursor-not-allowed bg-muted text-muted-foreground" : "bg-primary text-primary-foreground hover:bg-primary/90"
13954
13971
  ),
13955
13972
  children: checking ? t.checking : t.continueWithEmail
13956
13973
  }
13957
13974
  ),
13958
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
13975
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
13959
13976
  "button",
13960
13977
  {
13961
13978
  type: "button",
@@ -13972,9 +13989,10 @@ function CheckoutLoginPrompt({
13972
13989
  }
13973
13990
 
13974
13991
  // src/components/checkout-form.tsx
13975
- var import_utils13 = require("@reblu/site-ui/utils");
13976
- var import_jsx_runtime13 = require("react/jsx-runtime");
13977
- var DEFAULT_LABELS7 = {
13992
+ var import_utils12 = require("@reblu/site-ui/utils");
13993
+ var import_phone_input = require("@reblu/site-ui/phone-input");
13994
+ var import_jsx_runtime12 = require("react/jsx-runtime");
13995
+ var DEFAULT_LABELS6 = {
13978
13996
  contactTitle: "Datos de contacto",
13979
13997
  nameLabel: "Nombre completo",
13980
13998
  namePlaceholder: "Tu nombre",
@@ -13994,6 +14012,8 @@ function CheckoutForm({
13994
14012
  contact,
13995
14013
  onContactChange,
13996
14014
  contactErrors,
14015
+ phoneRegion,
14016
+ checkoutError,
13997
14017
  discountCode,
13998
14018
  onDiscountCodeChange,
13999
14019
  onApplyDiscount,
@@ -14011,7 +14031,11 @@ function CheckoutForm({
14011
14031
  locale,
14012
14032
  className
14013
14033
  }) {
14014
- const t = { ...DEFAULT_LABELS7, ...labels };
14034
+ const t = { ...DEFAULT_LABELS6, ...labels };
14035
+ const details = checkoutError?.details;
14036
+ const rejectedPhone = checkoutError?.code === "INVALID_INPUT" && typeof details === "object" && details !== null && !Array.isArray(details) && "field" in details && details.field === "customerPhone" && typeof checkoutError.error === "string" && checkoutError.error.trim().length > 0;
14037
+ const phoneError = contactErrors?.phone ?? (rejectedPhone ? checkoutError.error : void 0);
14038
+ const generalError = checkoutError && !rejectedPhone ? getShopErrorMessage(typeof checkoutError.code === "string" ? checkoutError.code : void 0) : null;
14015
14039
  function patchContact(patch3) {
14016
14040
  onContactChange({ ...contact, ...patch3 });
14017
14041
  }
@@ -14021,22 +14045,22 @@ function CheckoutForm({
14021
14045
  event.preventDefault();
14022
14046
  if (discountCode.trim() && !discountApplying) onApplyDiscount();
14023
14047
  }
14024
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
14048
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
14025
14049
  loginPrompt,
14026
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
14050
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
14027
14051
  "form",
14028
14052
  {
14029
14053
  "data-testid": "checkout-form",
14030
14054
  onSubmit,
14031
- className: (0, import_utils13.cn)("space-y-8", className),
14055
+ className: (0, import_utils12.cn)("space-y-8", className),
14032
14056
  "data-slot": "checkout-form",
14033
14057
  children: [
14034
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("section", { className: "space-y-4", children: [
14035
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h2", { className: "border-b border-border pb-2 text-lg font-semibold", children: t.contactTitle }),
14036
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
14037
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-1", children: [
14038
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { htmlFor: "checkout-form-name", className: "text-sm font-medium", children: t.nameLabel }),
14039
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14058
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("section", { className: "space-y-4", children: [
14059
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h2", { className: "border-b border-border pb-2 text-lg font-semibold", children: t.contactTitle }),
14060
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
14061
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-1", children: [
14062
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("label", { htmlFor: "checkout-form-name", className: "text-sm font-medium", children: t.nameLabel }),
14063
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14040
14064
  "input",
14041
14065
  {
14042
14066
  id: "checkout-form-name",
@@ -14045,17 +14069,17 @@ function CheckoutForm({
14045
14069
  value: contact.name,
14046
14070
  onChange: (e) => patchContact({ name: e.target.value }),
14047
14071
  placeholder: t.namePlaceholder,
14048
- className: (0, import_utils13.cn)(
14072
+ className: (0, import_utils12.cn)(
14049
14073
  "w-full rounded-lg border bg-background px-3 py-2 text-sm transition focus:outline-none focus:ring-2 focus:ring-primary/20",
14050
14074
  contactErrors?.name ? "border-destructive" : "border-border focus:border-primary"
14051
14075
  )
14052
14076
  }
14053
14077
  ),
14054
- contactErrors?.name && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-xs text-destructive", children: contactErrors.name })
14078
+ contactErrors?.name && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs text-destructive", children: contactErrors.name })
14055
14079
  ] }),
14056
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-1", children: [
14057
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { htmlFor: "checkout-form-email", className: "text-sm font-medium", children: t.emailLabel }),
14058
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14080
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-1", children: [
14081
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("label", { htmlFor: "checkout-form-email", className: "text-sm font-medium", children: t.emailLabel }),
14082
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14059
14083
  "input",
14060
14084
  {
14061
14085
  id: "checkout-form-email",
@@ -14064,43 +14088,37 @@ function CheckoutForm({
14064
14088
  value: contact.email,
14065
14089
  onChange: (e) => patchContact({ email: e.target.value }),
14066
14090
  placeholder: t.emailPlaceholder,
14067
- className: (0, import_utils13.cn)(
14091
+ className: (0, import_utils12.cn)(
14068
14092
  "w-full rounded-lg border bg-background px-3 py-2 text-sm transition focus:outline-none focus:ring-2 focus:ring-primary/20",
14069
14093
  contactErrors?.email ? "border-destructive" : "border-border focus:border-primary"
14070
14094
  )
14071
14095
  }
14072
14096
  ),
14073
- contactErrors?.email && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-xs text-destructive", children: contactErrors.email })
14097
+ contactErrors?.email && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs text-destructive", children: contactErrors.email })
14074
14098
  ] }),
14075
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-1", children: [
14076
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { htmlFor: "checkout-form-phone", className: "text-sm font-medium", children: t.phoneLabel }),
14077
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14078
- "input",
14079
- {
14080
- id: "checkout-form-phone",
14081
- type: "tel",
14082
- autoComplete: "tel",
14083
- value: contact.phone ?? "",
14084
- onChange: (e) => patchContact({ phone: e.target.value }),
14085
- className: (0, import_utils13.cn)(
14086
- "w-full rounded-lg border bg-background px-3 py-2 text-sm transition focus:outline-none focus:ring-2 focus:ring-primary/20",
14087
- contactErrors?.phone ? "border-destructive" : "border-border focus:border-primary"
14088
- )
14089
- }
14090
- ),
14091
- contactErrors?.phone && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-xs text-destructive", children: contactErrors.phone })
14092
- ] })
14099
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14100
+ import_phone_input.PhoneInput,
14101
+ {
14102
+ id: "checkout-form-phone",
14103
+ label: t.phoneLabel,
14104
+ region: phoneRegion,
14105
+ value: contact.phone ?? "",
14106
+ onChange: (phone) => patchContact({ phone }),
14107
+ error: phoneError
14108
+ }
14109
+ ) })
14093
14110
  ] })
14094
14111
  ] }),
14095
14112
  children2,
14096
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("section", { className: "space-y-3", children: [
14097
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h2", { className: "border-b border-border pb-2 text-lg font-semibold", children: t.discountTitle }),
14098
- appliedDiscount ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center justify-between rounded-lg border border-green-200 bg-green-50 px-4 py-3 dark:border-green-800 dark:bg-green-900/20", children: [
14099
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex items-center gap-2 text-sm text-green-700 dark:text-green-400", children: [
14100
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-semibold", children: appliedDiscount.code }),
14101
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: t.discountAppliedSuffix(formatPrice(appliedDiscount.amount, currencyCode, locale)) })
14113
+ generalError ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { role: "alert", className: "text-sm text-destructive", children: generalError }) : null,
14114
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("section", { className: "space-y-3", children: [
14115
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("h2", { className: "border-b border-border pb-2 text-lg font-semibold", children: t.discountTitle }),
14116
+ appliedDiscount ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center justify-between rounded-lg border border-green-200 bg-green-50 px-4 py-3 dark:border-green-800 dark:bg-green-900/20", children: [
14117
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex items-center gap-2 text-sm text-green-700 dark:text-green-400", children: [
14118
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "font-semibold", children: appliedDiscount.code }),
14119
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: t.discountAppliedSuffix(formatPrice(appliedDiscount.amount, currencyCode, locale)) })
14102
14120
  ] }),
14103
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14121
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14104
14122
  "button",
14105
14123
  {
14106
14124
  type: "button",
@@ -14110,9 +14128,9 @@ function CheckoutForm({
14110
14128
  children: t.removeDiscount
14111
14129
  }
14112
14130
  )
14113
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex gap-2", children: [
14114
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { htmlFor: "checkout-form-discount-code", className: "sr-only", children: t.discountTitle }),
14115
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14131
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex gap-2", children: [
14132
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("label", { htmlFor: "checkout-form-discount-code", className: "sr-only", children: t.discountTitle }),
14133
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14116
14134
  "input",
14117
14135
  {
14118
14136
  id: "checkout-form-discount-code",
@@ -14124,7 +14142,7 @@ function CheckoutForm({
14124
14142
  className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm uppercase transition focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20"
14125
14143
  }
14126
14144
  ),
14127
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14145
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14128
14146
  "button",
14129
14147
  {
14130
14148
  type: "button",
@@ -14135,14 +14153,14 @@ function CheckoutForm({
14135
14153
  }
14136
14154
  )
14137
14155
  ] }),
14138
- discountError && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-xs text-destructive", children: discountError })
14156
+ discountError && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-xs text-destructive", children: discountError })
14139
14157
  ] }),
14140
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14158
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14141
14159
  "button",
14142
14160
  {
14143
14161
  type: "submit",
14144
14162
  disabled: submitting || submitDisabled,
14145
- className: (0, import_utils13.cn)(
14163
+ className: (0, import_utils12.cn)(
14146
14164
  "flex w-full items-center justify-center gap-2 rounded-xl px-4 py-3 font-semibold transition-all",
14147
14165
  submitting || submitDisabled ? "cursor-not-allowed bg-muted text-muted-foreground" : "bg-primary text-primary-foreground hover:bg-primary/90"
14148
14166
  ),
@@ -14156,9 +14174,9 @@ function CheckoutForm({
14156
14174
  }
14157
14175
 
14158
14176
  // src/components/order-confirmation.tsx
14159
- var import_utils14 = require("@reblu/site-ui/utils");
14160
- var import_jsx_runtime14 = require("react/jsx-runtime");
14161
- var DEFAULT_LABELS8 = {
14177
+ var import_utils13 = require("@reblu/site-ui/utils");
14178
+ var import_jsx_runtime13 = require("react/jsx-runtime");
14179
+ var DEFAULT_LABELS7 = {
14162
14180
  pollingTitle: "Confirmando tu pedido\u2026",
14163
14181
  pollingDescription: "Estamos procesando el pago, un momento\u2026",
14164
14182
  foundTitle: "\xA1Pedido confirmado!",
@@ -14168,72 +14186,131 @@ var DEFAULT_LABELS8 = {
14168
14186
  orderNumberLabel: "Pedido confirmado",
14169
14187
  totalLabel: "Total",
14170
14188
  confirmationEmailPrefix: "Te hemos enviado un email de confirmaci\xF3n a",
14171
- sessionReferenceLabel: "Referencia de sesi\xF3n"
14189
+ sessionReferenceLabel: "Referencia de sesi\xF3n",
14190
+ // REB-837
14191
+ failedTitle: "El pago no se ha completado",
14192
+ failedDescription: "No se ha podido procesar el pago. Tu carrito sigue intacto.",
14193
+ backToCartLabel: "Volver al carrito",
14194
+ refundedTitle: "Este pedido ha sido reembolsado",
14195
+ refundedDescription: "El importe se ha devuelto a tu m\xE9todo de pago original.",
14196
+ partiallyRefundedTitle: "Este pedido ha sido reembolsado parcialmente",
14197
+ partiallyRefundedDescription: "Parte del importe se ha devuelto a tu m\xE9todo de pago original.",
14198
+ pendingTimeoutTitle: "Pedido recibido",
14199
+ pendingTimeoutDescription: "Estamos confirmando el pago; te enviaremos un email en cuanto se complete.",
14200
+ recheckLabel: "Volver a comprobar",
14201
+ notFoundTitle: "No encontramos ning\xFAn pedido",
14202
+ notFoundDescription: "Comprueba el enlace o contacta con nosotros si el problema persiste.",
14203
+ errorTitle: "Ha ocurrido un error",
14204
+ errorDescription: "No hemos podido comprobar el estado de tu pedido.",
14205
+ orderReferenceLabel: "Referencia del pedido"
14172
14206
  };
14173
14207
  function OrderConfirmation({
14174
14208
  status,
14175
14209
  order,
14176
14210
  sessionId,
14211
+ cartHref,
14212
+ onRecheck,
14177
14213
  labels,
14178
14214
  currencyCode,
14179
14215
  locale,
14180
14216
  className
14181
14217
  }) {
14182
- const t = { ...DEFAULT_LABELS8, ...labels };
14183
- const title = status === "polling" ? t.pollingTitle : order ? t.foundTitle : t.timeoutTitle;
14184
- const description = status === "polling" ? t.pollingDescription : order ? t.foundDescription : t.timeoutDescription;
14185
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: (0, import_utils14.cn)("space-y-6 text-center", className), "data-slot": "order-confirmation", children: [
14186
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h1", { className: "text-3xl font-bold", children: title }),
14187
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-lg text-muted-foreground", children: description }),
14188
- order && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "space-y-6", children: [
14189
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14190
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.orderNumberLabel }),
14191
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "font-mono text-lg font-semibold", children: order.orderNumber })
14218
+ const t = { ...DEFAULT_LABELS7, ...labels };
14219
+ const isPolling = status === "polling" || status === "loading";
14220
+ const isFound = status === "found" || status === "paid";
14221
+ const { title, description } = (() => {
14222
+ if (isPolling) return { title: t.pollingTitle, description: t.pollingDescription };
14223
+ if (status === "failed") return { title: t.failedTitle, description: t.failedDescription };
14224
+ if (status === "refunded") return { title: t.refundedTitle, description: t.refundedDescription };
14225
+ if (status === "partially_refunded") {
14226
+ return { title: t.partiallyRefundedTitle, description: t.partiallyRefundedDescription };
14227
+ }
14228
+ if (status === "pending_timeout") {
14229
+ return { title: t.pendingTimeoutTitle, description: t.pendingTimeoutDescription };
14230
+ }
14231
+ if (status === "not_found") return { title: t.notFoundTitle, description: t.notFoundDescription };
14232
+ if (status === "error") return { title: t.errorTitle, description: t.errorDescription };
14233
+ if (isFound || order) return { title: t.foundTitle, description: t.foundDescription };
14234
+ return { title: t.timeoutTitle, description: t.timeoutDescription };
14235
+ })();
14236
+ const showFullOrderSummary = Boolean(order) && (isFound || status === "timeout");
14237
+ const showOrderReference = Boolean(order) && !showFullOrderSummary && (status === "refunded" || status === "partially_refunded" || status === "pending_timeout");
14238
+ const showSessionReference = !order && sessionId && (status === "timeout" || status === "not_found" || status === "pending_timeout");
14239
+ const showRecheck = (status === "pending_timeout" || status === "error") && onRecheck;
14240
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: (0, import_utils13.cn)("space-y-6 text-center", className), "data-slot": "order-confirmation", children: [
14241
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("h1", { className: "text-3xl font-bold", children: title }),
14242
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-lg text-muted-foreground", children: description }),
14243
+ showFullOrderSummary && order && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "space-y-6", children: [
14244
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14245
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.orderNumberLabel }),
14246
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "font-mono text-lg font-semibold", children: order.orderNumber })
14192
14247
  ] }),
14193
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "mx-auto max-w-sm space-y-3 rounded-xl border border-border bg-card p-5 text-left", children: [
14194
- order.items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
14248
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "mx-auto max-w-sm space-y-3 rounded-xl border border-border bg-card p-5 text-left", children: [
14249
+ order.items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
14195
14250
  "div",
14196
14251
  {
14197
14252
  className: "flex justify-between gap-4 text-sm",
14198
14253
  children: [
14199
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "max-w-[60%] truncate text-muted-foreground", children: [
14254
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "max-w-[60%] truncate text-muted-foreground", children: [
14200
14255
  item.product.name,
14201
14256
  item.variant ? ` (${item.variant.name})` : "",
14202
14257
  " x",
14203
14258
  item.quantity
14204
14259
  ] }),
14205
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: formatPrice(item.total, currencyCode, locale) })
14260
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: formatPrice(item.total, currencyCode, locale) })
14206
14261
  ]
14207
14262
  },
14208
14263
  idx
14209
14264
  )),
14210
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "space-y-1 border-t border-border pt-3 text-sm", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between pt-1 text-base font-bold", children: [
14211
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: t.totalLabel }),
14212
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: formatPrice(order.total, currencyCode, locale) })
14265
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "space-y-1 border-t border-border pt-3 text-sm", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex justify-between pt-1 text-base font-bold", children: [
14266
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: t.totalLabel }),
14267
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: formatPrice(order.total, currencyCode, locale) })
14213
14268
  ] }) })
14214
14269
  ] }),
14215
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { className: "mx-auto max-w-sm text-sm text-muted-foreground", children: [
14270
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { className: "mx-auto max-w-sm text-sm text-muted-foreground", children: [
14216
14271
  t.confirmationEmailPrefix,
14217
14272
  " ",
14218
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "font-medium text-foreground", children: order.customerEmail }),
14273
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "font-medium text-foreground", children: order.customerEmail }),
14219
14274
  "."
14220
14275
  ] })
14221
14276
  ] }),
14222
- !order && status === "timeout" && sessionId && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14223
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.sessionReferenceLabel }),
14224
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "break-all font-mono text-sm font-semibold", children: sessionId })
14277
+ showOrderReference && order && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14278
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.orderReferenceLabel }),
14279
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "font-mono text-lg font-semibold", children: order.orderNumber })
14280
+ ] }),
14281
+ status === "failed" && cartHref && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14282
+ "a",
14283
+ {
14284
+ href: cartHref,
14285
+ className: "inline-block text-sm font-semibold text-primary underline-offset-2 hover:underline",
14286
+ children: t.backToCartLabel
14287
+ }
14288
+ ),
14289
+ showRecheck && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14290
+ "button",
14291
+ {
14292
+ type: "button",
14293
+ onClick: onRecheck,
14294
+ className: "inline-flex items-center justify-center rounded-xl bg-primary px-4 py-2.5 text-sm font-semibold text-primary-foreground transition-colors hover:bg-primary/90",
14295
+ children: t.recheckLabel
14296
+ }
14297
+ ),
14298
+ showSessionReference && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14299
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.sessionReferenceLabel }),
14300
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "break-all font-mono text-sm font-semibold", children: sessionId })
14225
14301
  ] })
14226
14302
  ] });
14227
14303
  }
14228
14304
  // Annotate the CommonJS export names for ESM import in node:
14229
14305
  0 && (module.exports = {
14230
14306
  ALLOWED_YOUTUBE_HOSTS,
14231
- AddToCartButton,
14232
- CartIcon,
14307
+ AddedToCartToast,
14233
14308
  CartLineList,
14234
14309
  CartSummary,
14235
14310
  CheckoutForm,
14236
14311
  CheckoutLoginPrompt,
14312
+ DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE,
14313
+ DEFAULT_SHOP_ERROR_MESSAGES,
14237
14314
  DEFAULT_SHOP_PRICE_BANDS,
14238
14315
  MarkdownRenderer,
14239
14316
  OrderConfirmation,
@@ -14245,6 +14322,7 @@ function OrderConfirmation({
14245
14322
  Treatment,
14246
14323
  buildShareUrls,
14247
14324
  formatPrice,
14325
+ getShopErrorMessage,
14248
14326
  isAllowedYouTubeHost,
14249
14327
  markdownToSafeHtml,
14250
14328
  readingTime,