@reblu/site-blocks 0.12.1 → 0.14.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
@@ -22,17 +22,23 @@ var src_exports = {};
22
22
  __export(src_exports, {
23
23
  ALLOWED_YOUTUBE_HOSTS: () => ALLOWED_YOUTUBE_HOSTS,
24
24
  AddedToCartToast: () => AddedToCartToast,
25
+ CartAdjustmentsNotice: () => CartAdjustmentsNotice,
25
26
  CartLineList: () => CartLineList,
26
27
  CartSummary: () => CartSummary,
27
28
  CheckoutForm: () => CheckoutForm,
28
29
  CheckoutLoginPrompt: () => CheckoutLoginPrompt,
30
+ CourseDescription: () => CourseDescription,
31
+ DEFAULT_INVOICE_COUNTRIES: () => DEFAULT_INVOICE_COUNTRIES,
29
32
  DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE: () => DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE,
30
33
  DEFAULT_SHOP_ERROR_MESSAGES: () => DEFAULT_SHOP_ERROR_MESSAGES,
31
34
  DEFAULT_SHOP_PRICE_BANDS: () => DEFAULT_SHOP_PRICE_BANDS,
32
35
  DEFAULT_TRUST_ICONS: () => DEFAULT_TRUST_ICONS,
36
+ EMPTY_FULL_INVOICE_VALUE: () => EMPTY_FULL_INVOICE_VALUE,
33
37
  FaqAccordion: () => FaqAccordion,
38
+ FullInvoiceFields: () => FullInvoiceFields,
34
39
  MarkdownRenderer: () => MarkdownRenderer,
35
40
  OrderConfirmation: () => OrderConfirmation,
41
+ OrderInvoiceLink: () => OrderInvoiceLink,
36
42
  PageBlocks: () => PageBlocks,
37
43
  PageCardGrid: () => PageCardGrid,
38
44
  ParentPage: () => ParentPage,
@@ -49,10 +55,14 @@ __export(src_exports, {
49
55
  formatPrice: () => formatPrice,
50
56
  getShopErrorMessage: () => getShopErrorMessage,
51
57
  isAllowedYouTubeHost: () => isAllowedYouTubeHost,
58
+ isOverSimplifiedInvoiceCap: () => isOverSimplifiedInvoiceCap,
59
+ markdownToPlainText: () => markdownToPlainText,
52
60
  markdownToSafeHtml: () => markdownToSafeHtml,
53
61
  readingTime: () => readingTime,
54
62
  sanitizeHtml: () => sanitizeHtml,
55
- shouldRenderShopFilters: () => shouldRenderShopFilters
63
+ shopIssuesInvoices: () => shopIssuesInvoices,
64
+ shouldRenderShopFilters: () => shouldRenderShopFilters,
65
+ toCheckoutInvoiceFields: () => toCheckoutInvoiceFields
56
66
  });
57
67
  module.exports = __toCommonJS(src_exports);
58
68
 
@@ -98,7 +108,11 @@ var DEFAULT_SHOP_ERROR_MESSAGES = {
98
108
  INVALID_INPUT: "Revisa los datos introducidos.",
99
109
  STORE_DISABLED: "La tienda no est\xE1 disponible en este momento.",
100
110
  PAYMENT_PROVIDER_ERROR: "No hemos podido conectar con la pasarela de pago. Int\xE9ntalo de nuevo.",
101
- INTERNAL_ERROR: "Ha ocurrido un error inesperado. Int\xE9ntalo de nuevo en unos minutos."
111
+ INTERNAL_ERROR: "Ha ocurrido un error inesperado. Int\xE9ntalo de nuevo en unos minutos.",
112
+ // REB-73 — checkout refusals before any payment.
113
+ BILLING_DATA_REQUIRED: "Para emitir tu factura necesitamos tu NIF/NIE o un documento de identificaci\xF3n, tu nombre y tu direcci\xF3n de facturaci\xF3n.",
114
+ INVOICING_NOT_READY: "No se puede completar la compra en este momento. Int\xE9ntalo m\xE1s tarde.",
115
+ FULL_INVOICE_UNAVAILABLE: "Esta tienda no emite facturas completas: contin\xFAa sin solicitarla."
102
116
  };
103
117
  var DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE = "No se ha podido completar la operaci\xF3n. Int\xE9ntalo de nuevo.";
104
118
  function getShopErrorMessage(code, overrides, fallback = DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE) {
@@ -13108,6 +13122,52 @@ function markdownToSafeHtml(markdown) {
13108
13122
  return sanitizeHtml(rawHtml);
13109
13123
  }
13110
13124
 
13125
+ // src/lib/markdown-plain-text.ts
13126
+ var INLINE_TAGS = /* @__PURE__ */ new Set([
13127
+ "a",
13128
+ "abbr",
13129
+ "b",
13130
+ "code",
13131
+ "del",
13132
+ "em",
13133
+ "i",
13134
+ "ins",
13135
+ "kbd",
13136
+ "mark",
13137
+ "s",
13138
+ "small",
13139
+ "span",
13140
+ "strong",
13141
+ "sub",
13142
+ "sup",
13143
+ "u"
13144
+ ]);
13145
+ function collectText(nodes, out) {
13146
+ for (const node of nodes) {
13147
+ if (node.type === "text") {
13148
+ out.push(node.value);
13149
+ } else if (node.type === "element") {
13150
+ const block = !INLINE_TAGS.has(node.tagName);
13151
+ if (block) out.push(" ");
13152
+ collectText(node.children, out);
13153
+ if (block) out.push(" ");
13154
+ }
13155
+ }
13156
+ }
13157
+ function markdownToPlainText(markdown, { maxLength } = {}) {
13158
+ const html5 = markdownToSafeHtml(markdown);
13159
+ if (!html5) return "";
13160
+ const tree = fromParse5(parseFragment(html5));
13161
+ const parts = [];
13162
+ collectText(tree.children, parts);
13163
+ const text3 = parts.join("").replace(/\s+/g, " ").trim();
13164
+ if (maxLength === void 0 || text3.length <= maxLength) return text3;
13165
+ let cut = text3.slice(0, Math.max(0, maxLength - 1));
13166
+ const lastSpace = cut.lastIndexOf(" ");
13167
+ if (lastSpace > 0) cut = cut.slice(0, lastSpace);
13168
+ return `${cut.trimEnd()}\u2026`;
13169
+ }
13170
+
13111
13171
  // src/components/markdown-renderer.tsx
13112
13172
  var import_utils = require("@reblu/site-ui/utils");
13113
13173
  var import_html_react_parser = require("html-react-parser");
@@ -13280,13 +13340,60 @@ function SafeHtml({ html: html5, className, headingOffset = 0 }) {
13280
13340
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_utils.cn)("max-w-none", className), "data-slot": "safe-html", children: parse3(html5, buildOptions(headingOffset)) });
13281
13341
  }
13282
13342
 
13343
+ // src/components/course-description.tsx
13344
+ var import_utils2 = require("@reblu/site-ui/utils");
13345
+ var import_jsx_runtime2 = require("react/jsx-runtime");
13346
+ function isVisiblyEmpty(html5) {
13347
+ if (/<(img|iframe|hr)\b/i.test(html5)) return false;
13348
+ return html5.replace(/<[^>]*>/g, "").trim() === "";
13349
+ }
13350
+ function CourseDescription({
13351
+ description,
13352
+ heading,
13353
+ headingLevel = 2,
13354
+ headingId = "course-description-heading",
13355
+ headingOffset,
13356
+ className,
13357
+ headingClassName,
13358
+ contentClassName
13359
+ }) {
13360
+ const html5 = markdownToSafeHtml(typeof description === "string" ? description : null);
13361
+ if (!html5 || isVisiblyEmpty(html5)) return null;
13362
+ const hasHeading = heading !== void 0 && heading !== null && heading !== "";
13363
+ const offset = headingOffset ?? (hasHeading ? headingLevel - 1 : 0);
13364
+ const body3 = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
13365
+ SafeHtml,
13366
+ {
13367
+ html: html5,
13368
+ headingOffset: offset,
13369
+ className: (0, import_utils2.cn)("text-muted-foreground", contentClassName)
13370
+ }
13371
+ );
13372
+ if (!hasHeading) {
13373
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { "data-slot": "course-description", className, children: body3 });
13374
+ }
13375
+ const Tag = `h${headingLevel}`;
13376
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
13377
+ "section",
13378
+ {
13379
+ "data-slot": "course-description",
13380
+ "aria-labelledby": headingId,
13381
+ className: (0, import_utils2.cn)("space-y-3", className),
13382
+ children: [
13383
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Tag, { id: headingId, className: (0, import_utils2.cn)("text-xl font-semibold", headingClassName), children: heading }),
13384
+ body3
13385
+ ]
13386
+ }
13387
+ );
13388
+ }
13389
+
13283
13390
  // src/components/treatment.tsx
13284
- var import_utils3 = require("@reblu/site-ui/utils");
13391
+ var import_utils4 = require("@reblu/site-ui/utils");
13285
13392
 
13286
13393
  // src/components/_page-parts.tsx
13287
- var import_utils2 = require("@reblu/site-ui/utils");
13394
+ var import_utils3 = require("@reblu/site-ui/utils");
13288
13395
  var import_button_variants = require("@reblu/site-ui/button-variants");
13289
- var import_jsx_runtime2 = require("react/jsx-runtime");
13396
+ var import_jsx_runtime3 = require("react/jsx-runtime");
13290
13397
  var KNOWN_BUTTON_VARIANTS = /* @__PURE__ */ new Set([
13291
13398
  "default",
13292
13399
  "destructive",
@@ -13299,11 +13406,11 @@ function toButtonVariant(variant) {
13299
13406
  return variant && KNOWN_BUTTON_VARIANTS.has(variant) ? variant : "default";
13300
13407
  }
13301
13408
  function PageHero({ page }) {
13302
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("header", { className: "space-y-4", children: [
13303
- page.category && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "inline-flex items-center rounded-full bg-secondary px-3 py-1 text-sm font-medium text-secondary-foreground", children: page.category.name }),
13304
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { className: "text-4xl font-bold tracking-tight", children: page.title }),
13305
- page.subtitle && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-lg text-muted-foreground", children: page.subtitle }),
13306
- page.coverImageUrl && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "relative aspect-[21/9] w-full overflow-hidden rounded-xl bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
13409
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("header", { className: "space-y-4", children: [
13410
+ page.category && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "inline-flex items-center rounded-full bg-secondary px-3 py-1 text-sm font-medium text-secondary-foreground", children: page.category.name }),
13411
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { className: "text-4xl font-bold tracking-tight", children: page.title }),
13412
+ page.subtitle && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-lg text-muted-foreground", children: page.subtitle }),
13413
+ page.coverImageUrl && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "relative aspect-[21/9] w-full overflow-hidden rounded-xl bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
13307
13414
  "img",
13308
13415
  {
13309
13416
  src: page.coverImageUrl,
@@ -13317,14 +13424,14 @@ function PageHero({ page }) {
13317
13424
  function SectionCta({ section }) {
13318
13425
  if (!section.ctaLabel || !section.ctaUrl) return null;
13319
13426
  const variant = toButtonVariant(section.ctaVariant);
13320
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
13427
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
13321
13428
  "a",
13322
13429
  {
13323
13430
  href: section.ctaUrl,
13324
13431
  "data-slot": "button",
13325
13432
  "data-variant": variant,
13326
13433
  "data-size": "default",
13327
- className: (0, import_utils2.cn)((0, import_button_variants.buttonVariants)({ variant, size: "default" })),
13434
+ className: (0, import_utils3.cn)((0, import_button_variants.buttonVariants)({ variant, size: "default" })),
13328
13435
  ...section.ctaIsExternal ? { target: "_blank", rel: "noopener noreferrer" } : {},
13329
13436
  children: section.ctaLabel
13330
13437
  }
@@ -13332,59 +13439,59 @@ function SectionCta({ section }) {
13332
13439
  }
13333
13440
  function SectionImages({ section }) {
13334
13441
  if (section.images.length === 0) return null;
13335
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: (0, import_utils2.cn)("grid gap-4", section.images.length > 1 ? "sm:grid-cols-2" : "grid-cols-1"), children: section.images.map((img) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("figure", { className: "space-y-1", children: [
13336
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "relative aspect-video w-full overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("img", { src: img.url, alt: img.alt, loading: "lazy", className: "h-full w-full object-cover" }) }),
13337
- img.caption && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("figcaption", { className: "text-sm text-muted-foreground", children: img.caption })
13442
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: (0, import_utils3.cn)("grid gap-4", section.images.length > 1 ? "sm:grid-cols-2" : "grid-cols-1"), children: section.images.map((img) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("figure", { className: "space-y-1", children: [
13443
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "relative aspect-video w-full overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("img", { src: img.url, alt: img.alt, loading: "lazy", className: "h-full w-full object-cover" }) }),
13444
+ img.caption && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("figcaption", { className: "text-sm text-muted-foreground", children: img.caption })
13338
13445
  ] }, `${img.url}-${img.order}`)) });
13339
13446
  }
13340
13447
  function PageSectionBlock({ section }) {
13341
13448
  const imageFirst = section.layout === "IMAGE_TEXT";
13342
13449
  const sideBySide = section.layout === "TEXT_IMAGE" || section.layout === "IMAGE_TEXT";
13343
13450
  const hasImages = section.images.length > 0;
13344
- const body3 = /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "space-y-4", children: [
13345
- section.heading && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: "text-2xl font-bold", children: section.heading }),
13346
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SafeHtml, { html: sanitizeHtml(section.contentHtml), headingOffset: 2 }),
13347
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SectionCta, { section })
13451
+ const body3 = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-4", children: [
13452
+ section.heading && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h2", { className: "text-2xl font-bold", children: section.heading }),
13453
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SafeHtml, { html: sanitizeHtml(section.contentHtml), headingOffset: 2 }),
13454
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SectionCta, { section })
13348
13455
  ] });
13349
13456
  if (sideBySide && hasImages) {
13350
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("section", { className: "grid items-center gap-8 md:grid-cols-2", children: imageFirst ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
13351
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SectionImages, { section }),
13457
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("section", { className: "grid items-center gap-8 md:grid-cols-2", children: imageFirst ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
13458
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SectionImages, { section }),
13352
13459
  body3
13353
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
13460
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
13354
13461
  body3,
13355
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SectionImages, { section })
13462
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SectionImages, { section })
13356
13463
  ] }) });
13357
13464
  }
13358
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("section", { className: "space-y-4", children: [
13465
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("section", { className: "space-y-4", children: [
13359
13466
  body3,
13360
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SectionImages, { section })
13467
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SectionImages, { section })
13361
13468
  ] });
13362
13469
  }
13363
13470
  function PageSectionList({ sections }) {
13364
13471
  if (sections.length === 0) return null;
13365
13472
  const ordered = sections.slice().sort((a, b2) => a.order - b2.order);
13366
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "space-y-12", children: ordered.map((section) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(PageSectionBlock, { section }, section.id)) });
13473
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "space-y-12", children: ordered.map((section) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PageSectionBlock, { section }, section.id)) });
13367
13474
  }
13368
13475
 
13369
13476
  // src/components/treatment.tsx
13370
- var import_jsx_runtime3 = require("react/jsx-runtime");
13477
+ var import_jsx_runtime4 = require("react/jsx-runtime");
13371
13478
  function Treatment({ page, className }) {
13372
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("article", { className: (0, import_utils3.cn)("space-y-12", className), "data-slot": "treatment", children: [
13373
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PageHero, { page }),
13374
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PageSectionList, { sections: page.sections })
13479
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("article", { className: (0, import_utils4.cn)("space-y-12", className), "data-slot": "treatment", children: [
13480
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PageHero, { page }),
13481
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PageSectionList, { sections: page.sections })
13375
13482
  ] });
13376
13483
  }
13377
13484
 
13378
13485
  // src/components/parent-page.tsx
13379
- var import_utils5 = require("@reblu/site-ui/utils");
13486
+ var import_utils6 = require("@reblu/site-ui/utils");
13380
13487
 
13381
13488
  // src/components/page-card-grid.tsx
13382
- var import_utils4 = require("@reblu/site-ui/utils");
13383
- var import_jsx_runtime4 = require("react/jsx-runtime");
13489
+ var import_utils5 = require("@reblu/site-ui/utils");
13490
+ var import_jsx_runtime5 = require("react/jsx-runtime");
13384
13491
  var defaultPageHref = (page) => `/${page.slug}`;
13385
13492
  var pageKey = (page) => `${page.category?.slug ?? ""}/${page.slug}`;
13386
13493
  function PageCardGrid(props) {
13387
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(PageCardGridSection, { ...props });
13494
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PageCardGridSection, { ...props });
13388
13495
  }
13389
13496
  function PageCardGridSection({
13390
13497
  pages,
@@ -13395,15 +13502,15 @@ function PageCardGridSection({
13395
13502
  }) {
13396
13503
  if (pages.length === 0) return null;
13397
13504
  const showHeading = keepEmptyHeading ? heading !== void 0 : !!heading;
13398
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: (0, import_utils4.cn)("space-y-6", className), children: [
13399
- showHeading && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { className: "text-2xl font-bold", children: heading }),
13400
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "grid list-none grid-cols-1 gap-6 p-0 sm:grid-cols-2 lg:grid-cols-3", children: pages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
13505
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("section", { className: (0, import_utils5.cn)("space-y-6", className), children: [
13506
+ showHeading && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h2", { className: "text-2xl font-bold", children: heading }),
13507
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { className: "grid list-none grid-cols-1 gap-6 p-0 sm:grid-cols-2 lg:grid-cols-3", children: pages.map((page) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
13401
13508
  "a",
13402
13509
  {
13403
13510
  href: pageHref(page),
13404
13511
  className: "group flex h-full flex-col overflow-hidden rounded-lg border bg-card transition-shadow hover:shadow-lg",
13405
13512
  children: [
13406
- page.coverImageUrl && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "relative aspect-video overflow-hidden bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
13513
+ page.coverImageUrl && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "relative aspect-video overflow-hidden bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
13407
13514
  "img",
13408
13515
  {
13409
13516
  src: page.coverImageUrl,
@@ -13412,9 +13519,9 @@ function PageCardGridSection({
13412
13519
  className: "h-full w-full object-cover transition-transform group-hover:scale-105"
13413
13520
  }
13414
13521
  ) }),
13415
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-1 flex-col gap-2 p-4", children: [
13416
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "font-semibold leading-tight transition-colors group-hover:text-primary", children: page.title }),
13417
- page.excerpt && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "line-clamp-2 text-sm text-muted-foreground", children: page.excerpt })
13522
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex flex-1 flex-col gap-2 p-4", children: [
13523
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { className: "font-semibold leading-tight transition-colors group-hover:text-primary", children: page.title }),
13524
+ page.excerpt && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "line-clamp-2 text-sm text-muted-foreground", children: page.excerpt })
13418
13525
  ] })
13419
13526
  ]
13420
13527
  }
@@ -13423,7 +13530,7 @@ function PageCardGridSection({
13423
13530
  }
13424
13531
 
13425
13532
  // src/components/parent-page.tsx
13426
- var import_jsx_runtime5 = require("react/jsx-runtime");
13533
+ var import_jsx_runtime6 = require("react/jsx-runtime");
13427
13534
  var defaultChildPageHref = (slug) => `/${slug}`;
13428
13535
  function ParentPage({
13429
13536
  page,
@@ -13438,10 +13545,10 @@ function ParentPage({
13438
13545
  const pages = childPages ?? treatments ?? [];
13439
13546
  const hrefFor = childPageHref ?? treatmentHref ?? defaultChildPageHref;
13440
13547
  const label = childPagesLabel ?? treatmentsLabel ?? "Treatments";
13441
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("article", { className: (0, import_utils5.cn)("space-y-12", className), "data-slot": "specialty", children: [
13442
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PageHero, { page }),
13443
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PageSectionList, { sections: page.sections }),
13444
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
13548
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("article", { className: (0, import_utils6.cn)("space-y-12", className), "data-slot": "specialty", children: [
13549
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PageHero, { page }),
13550
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PageSectionList, { sections: page.sections }),
13551
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
13445
13552
  PageCardGridSection,
13446
13553
  {
13447
13554
  pages,
@@ -13457,34 +13564,34 @@ function ParentPage({
13457
13564
  var Specialty = ParentPage;
13458
13565
 
13459
13566
  // src/components/profile-card.tsx
13460
- var import_utils6 = require("@reblu/site-ui/utils");
13461
- var import_jsx_runtime6 = require("react/jsx-runtime");
13567
+ var import_utils7 = require("@reblu/site-ui/utils");
13568
+ var import_jsx_runtime7 = require("react/jsx-runtime");
13462
13569
  function initials(name) {
13463
13570
  return name.split(/\s+/).filter(Boolean).slice(0, 2).map((part) => part[0]?.toUpperCase() ?? "").join("");
13464
13571
  }
13465
13572
  function ProfileCard({ name, role, imageUrl, specialties = [], bio, href, className }) {
13466
13573
  const NameTag = href ? "a" : "span";
13467
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
13574
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
13468
13575
  "article",
13469
13576
  {
13470
- className: (0, import_utils6.cn)(
13577
+ className: (0, import_utils7.cn)(
13471
13578
  "flex flex-col items-center gap-3 rounded-lg border bg-card p-6 text-center",
13472
13579
  className
13473
13580
  ),
13474
13581
  "data-slot": "profile-card",
13475
13582
  children: [
13476
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "relative h-24 w-24 overflow-hidden rounded-full bg-muted", children: imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("img", { src: imageUrl, alt: name, loading: "lazy", className: "h-full w-full object-cover" }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "flex h-full w-full items-center justify-center text-2xl font-semibold text-muted-foreground", "aria-hidden": "true", children: initials(name) }) }),
13477
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "space-y-1", children: [
13478
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { className: "text-lg font-semibold leading-tight", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
13583
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "relative h-24 w-24 overflow-hidden rounded-full bg-muted", children: imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("img", { src: imageUrl, alt: name, loading: "lazy", className: "h-full w-full object-cover" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "flex h-full w-full items-center justify-center text-2xl font-semibold text-muted-foreground", "aria-hidden": "true", children: initials(name) }) }),
13584
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "space-y-1", children: [
13585
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { className: "text-lg font-semibold leading-tight", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
13479
13586
  NameTag,
13480
13587
  {
13481
13588
  ...href ? { href, className: "transition-colors hover:text-primary" } : {},
13482
13589
  children: name
13483
13590
  }
13484
13591
  ) }),
13485
- role && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-sm text-muted-foreground", children: role })
13592
+ role && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-sm text-muted-foreground", children: role })
13486
13593
  ] }),
13487
- specialties.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { className: "flex flex-wrap justify-center gap-1.5 p-0", children: specialties.map((s2) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
13594
+ specialties.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { className: "flex flex-wrap justify-center gap-1.5 p-0", children: specialties.map((s2) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
13488
13595
  "li",
13489
13596
  {
13490
13597
  className: "inline-flex items-center rounded-full bg-secondary px-2.5 py-0.5 text-xs font-medium text-secondary-foreground",
@@ -13492,28 +13599,28 @@ function ProfileCard({ name, role, imageUrl, specialties = [], bio, href, classN
13492
13599
  },
13493
13600
  s2
13494
13601
  )) }),
13495
- bio && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-sm text-muted-foreground", children: bio })
13602
+ bio && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-sm text-muted-foreground", children: bio })
13496
13603
  ]
13497
13604
  }
13498
13605
  );
13499
13606
  }
13500
13607
 
13501
13608
  // src/components/product-card.tsx
13502
- var import_utils7 = require("@reblu/site-ui/utils");
13503
- var import_jsx_runtime7 = require("react/jsx-runtime");
13609
+ var import_utils8 = require("@reblu/site-ui/utils");
13610
+ var import_jsx_runtime8 = require("react/jsx-runtime");
13504
13611
  function ProductCard({ product, href, currencyCode = "EUR", locale, className }) {
13505
13612
  const image = product.images.find((i) => i.isPrimary) ?? product.images[0];
13506
13613
  const hasDiscount = product.comparePrice != null && product.comparePrice > product.price;
13507
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
13614
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
13508
13615
  "article",
13509
13616
  {
13510
- className: (0, import_utils7.cn)(
13617
+ className: (0, import_utils8.cn)(
13511
13618
  "group flex flex-col overflow-hidden rounded-lg border bg-card transition-shadow hover:shadow-lg",
13512
13619
  className
13513
13620
  ),
13514
13621
  "data-slot": "product-card",
13515
13622
  children: [
13516
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "relative aspect-square overflow-hidden bg-muted", children: image ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
13623
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "relative aspect-square overflow-hidden bg-muted", children: image ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
13517
13624
  "img",
13518
13625
  {
13519
13626
  src: image.url,
@@ -13521,14 +13628,14 @@ function ProductCard({ product, href, currencyCode = "EUR", locale, className })
13521
13628
  loading: "lazy",
13522
13629
  className: "h-full w-full object-cover transition-transform group-hover:scale-105"
13523
13630
  }
13524
- ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "flex h-full items-center justify-center text-4xl text-muted-foreground/30", "aria-hidden": "true", children: "\u{1F6CD}\uFE0F" }) }),
13525
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-1 flex-col gap-2 p-4", children: [
13526
- product.category && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "inline-flex w-fit items-center rounded-full bg-secondary px-2.5 py-0.5 text-xs font-medium text-secondary-foreground", children: product.category.name }),
13527
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { className: "text-base font-semibold leading-tight", children: href ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("a", { href, className: "transition-colors hover:text-primary", children: product.name }) : product.name }),
13528
- product.shortDescription && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "line-clamp-2 text-sm text-muted-foreground", children: product.shortDescription }),
13529
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "mt-auto flex items-baseline gap-2 pt-2", children: [
13530
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-lg font-bold text-foreground", children: formatPrice(product.price, currencyCode, locale) }),
13531
- hasDiscount && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-sm text-muted-foreground line-through", children: formatPrice(product.comparePrice, currencyCode, locale) })
13631
+ ) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "flex h-full items-center justify-center text-4xl text-muted-foreground/30", "aria-hidden": "true", children: "\u{1F6CD}\uFE0F" }) }),
13632
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex flex-1 flex-col gap-2 p-4", children: [
13633
+ product.category && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "inline-flex w-fit items-center rounded-full bg-secondary px-2.5 py-0.5 text-xs font-medium text-secondary-foreground", children: product.category.name }),
13634
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("h3", { className: "text-base font-semibold leading-tight", children: href ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("a", { href, className: "transition-colors hover:text-primary", children: product.name }) : product.name }),
13635
+ product.shortDescription && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "line-clamp-2 text-sm text-muted-foreground", children: product.shortDescription }),
13636
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "mt-auto flex items-baseline gap-2 pt-2", children: [
13637
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-lg font-bold text-foreground", children: formatPrice(product.price, currencyCode, locale) }),
13638
+ hasDiscount && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-sm text-muted-foreground line-through", children: formatPrice(product.comparePrice, currencyCode, locale) })
13532
13639
  ] })
13533
13640
  ] })
13534
13641
  ]
@@ -13730,8 +13837,8 @@ var __iconNode8 = [
13730
13837
  var Truck = createLucideIcon("truck", __iconNode8);
13731
13838
 
13732
13839
  // src/components/product-trust-items.tsx
13733
- var import_utils10 = require("@reblu/site-ui/utils");
13734
- var import_jsx_runtime8 = require("react/jsx-runtime");
13840
+ var import_utils11 = require("@reblu/site-ui/utils");
13841
+ var import_jsx_runtime9 = require("react/jsx-runtime");
13735
13842
  var DEFAULT_TRUST_ICONS = Object.freeze({
13736
13843
  shipping: Truck,
13737
13844
  returns: RotateCcw,
@@ -13765,17 +13872,17 @@ function ProductTrustItems({
13765
13872
  return [{ key: `${index}-${icon}`, Icon: Icon2, text: text3 }];
13766
13873
  });
13767
13874
  if (rows.length === 0) return null;
13768
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(List, { "data-slot": "product-trust-items", className: (0, import_utils10.cn)("space-y-2.5", className), children: rows.map(({ key: key2, Icon: Icon2, text: text3 }) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("li", { className: (0, import_utils10.cn)("flex items-center gap-3 text-sm text-muted-foreground", itemClassName), children: [
13769
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Icon2, { "aria-hidden": "true", className: "h-4 w-4 shrink-0 text-foreground/60" }),
13770
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { children: text3 })
13875
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(List, { "data-slot": "product-trust-items", className: (0, import_utils11.cn)("space-y-2.5", className), children: rows.map(({ key: key2, Icon: Icon2, text: text3 }) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("li", { className: (0, import_utils11.cn)("flex items-center gap-3 text-sm text-muted-foreground", itemClassName), children: [
13876
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Icon2, { "aria-hidden": "true", className: "h-4 w-4 shrink-0 text-foreground/60" }),
13877
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { children: text3 })
13771
13878
  ] }, key2)) });
13772
13879
  }
13773
13880
 
13774
13881
  // src/components/faq-accordion.tsx
13775
- var import_utils11 = require("@reblu/site-ui/utils");
13882
+ var import_utils12 = require("@reblu/site-ui/utils");
13776
13883
 
13777
13884
  // src/components/_heading.tsx
13778
- var import_jsx_runtime9 = require("react/jsx-runtime");
13885
+ var import_jsx_runtime10 = require("react/jsx-runtime");
13779
13886
  function nextHeadingLevel(level) {
13780
13887
  return Math.min(level + 1, 6);
13781
13888
  }
@@ -13785,11 +13892,11 @@ function Heading({
13785
13892
  children: children2
13786
13893
  }) {
13787
13894
  const Tag = `h${level}`;
13788
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Tag, { className, children: children2 });
13895
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Tag, { className, children: children2 });
13789
13896
  }
13790
13897
 
13791
13898
  // src/components/faq-accordion.tsx
13792
- var import_jsx_runtime10 = require("react/jsx-runtime");
13899
+ var import_jsx_runtime11 = require("react/jsx-runtime");
13793
13900
  function FaqAccordion({
13794
13901
  items,
13795
13902
  heading,
@@ -13800,18 +13907,18 @@ function FaqAccordion({
13800
13907
  }) {
13801
13908
  const visible = items.map((item, index) => ({ item, index })).filter(({ item }) => item.q.trim() !== "");
13802
13909
  if (visible.length === 0) return null;
13803
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: (0, import_utils11.cn)("space-y-4", className), "data-slot": "faq-accordion", children: [
13804
- heading && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Heading, { level: headingLevel, className: "text-2xl font-semibold tracking-tight", children: heading }),
13805
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "divide-y divide-border rounded-xl border border-border", children: visible.map(({ item, index }) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
13910
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: (0, import_utils12.cn)("space-y-4", className), "data-slot": "faq-accordion", children: [
13911
+ heading && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Heading, { level: headingLevel, className: "text-2xl font-semibold tracking-tight", children: heading }),
13912
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "divide-y divide-border rounded-xl border border-border", children: visible.map(({ item, index }) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
13806
13913
  "details",
13807
13914
  {
13808
13915
  className: "group px-4",
13809
13916
  "data-slot": "faq-item",
13810
13917
  ...defaultOpen.includes(index) ? { open: true } : {},
13811
13918
  children: [
13812
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("summary", { className: "flex cursor-pointer list-none items-center justify-between gap-4 py-4 font-medium focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring [&::-webkit-details-marker]:hidden", children: [
13813
- questionHeadingLevel ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Heading, { level: questionHeadingLevel, className: "text-base font-medium", children: item.q }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: item.q }),
13814
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
13919
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("summary", { className: "flex cursor-pointer list-none items-center justify-between gap-4 py-4 font-medium focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring [&::-webkit-details-marker]:hidden", children: [
13920
+ questionHeadingLevel ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Heading, { level: questionHeadingLevel, className: "text-base font-medium", children: item.q }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { children: item.q }),
13921
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
13815
13922
  "span",
13816
13923
  {
13817
13924
  "aria-hidden": "true",
@@ -13820,7 +13927,7 @@ function FaqAccordion({
13820
13927
  }
13821
13928
  )
13822
13929
  ] }),
13823
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: "whitespace-pre-line pb-4 text-muted-foreground", children: item.a })
13930
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "whitespace-pre-line pb-4 text-muted-foreground", children: item.a })
13824
13931
  ]
13825
13932
  },
13826
13933
  index
@@ -13829,40 +13936,40 @@ function FaqAccordion({
13829
13936
  }
13830
13937
 
13831
13938
  // src/components/page-blocks.tsx
13832
- var import_utils12 = require("@reblu/site-ui/utils");
13939
+ var import_utils13 = require("@reblu/site-ui/utils");
13833
13940
  var import_button_variants2 = require("@reblu/site-ui/button-variants");
13834
- var import_jsx_runtime11 = require("react/jsx-runtime");
13941
+ var import_jsx_runtime12 = require("react/jsx-runtime");
13835
13942
  var ALIASES = {
13836
13943
  doctor_embed: "profile_embed",
13837
13944
  specialty_embed: "page_embed"
13838
13945
  };
13839
13946
  function HeroBlock({ block, headingLevel }) {
13840
13947
  const { title, subtitle, imageUrl } = block.data;
13841
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-4", children: [
13842
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Heading, { level: headingLevel, className: "text-3xl font-bold tracking-tight md:text-4xl", children: title }),
13843
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-lg opacity-80", children: subtitle }),
13844
- imageUrl && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "relative aspect-[21/9] w-full overflow-hidden rounded-xl bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("img", { src: imageUrl, alt: "", loading: "lazy", className: "h-full w-full object-cover" }) })
13948
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-4", children: [
13949
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Heading, { level: headingLevel, className: "text-3xl font-bold tracking-tight md:text-4xl", children: title }),
13950
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-lg opacity-80", children: subtitle }),
13951
+ imageUrl && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "relative aspect-[21/9] w-full overflow-hidden rounded-xl bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("img", { src: imageUrl, alt: "", loading: "lazy", className: "h-full w-full object-cover" }) })
13845
13952
  ] });
13846
13953
  }
13847
13954
  function RichtextBlock({ block, headingLevel }) {
13848
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SafeHtml, { html: sanitizeHtml(block.data.html), headingOffset: headingLevel - 1 });
13955
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SafeHtml, { html: sanitizeHtml(block.data.html), headingOffset: headingLevel - 1 });
13849
13956
  }
13850
13957
  function FaqBlock({ block }) {
13851
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(FaqAccordion, { items: block.data.items });
13958
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FaqAccordion, { items: block.data.items });
13852
13959
  }
13853
13960
  function StatsBlock({ block }) {
13854
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dl", { className: "grid gap-6 sm:grid-cols-2 lg:grid-cols-4", children: block.data.items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "flex flex-col-reverse gap-1", children: [
13855
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dt", { className: "text-sm opacity-80", children: item.label }),
13856
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dd", { className: "text-3xl font-bold", children: item.value })
13961
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dl", { className: "grid gap-6 sm:grid-cols-2 lg:grid-cols-4", children: block.data.items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "flex flex-col-reverse gap-1", children: [
13962
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dt", { className: "text-sm opacity-80", children: item.label }),
13963
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("dd", { className: "text-3xl font-bold", children: item.value })
13857
13964
  ] }, i)) });
13858
13965
  }
13859
13966
  function TestimonialBlock({ block }) {
13860
13967
  const { quote, author, role, avatarUrl } = block.data;
13861
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("figure", { className: "space-y-4", children: [
13862
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("blockquote", { className: "text-xl italic", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { children: quote }) }),
13863
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("figcaption", { className: "flex items-center gap-3", children: [
13968
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "space-y-4", children: [
13969
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("blockquote", { className: "text-xl italic", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { children: quote }) }),
13970
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figcaption", { className: "flex items-center gap-3", children: [
13864
13971
  avatarUrl && // eslint-disable-next-line @next/next/no-img-element
13865
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
13972
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
13866
13973
  "img",
13867
13974
  {
13868
13975
  src: avatarUrl,
@@ -13871,9 +13978,9 @@ function TestimonialBlock({ block }) {
13871
13978
  className: "h-10 w-10 rounded-full object-cover"
13872
13979
  }
13873
13980
  ),
13874
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { children: [
13875
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "font-semibold", children: author }),
13876
- role && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "block text-sm opacity-80", children: role })
13981
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { children: [
13982
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "font-semibold", children: author }),
13983
+ role && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "block text-sm opacity-80", children: role })
13877
13984
  ] })
13878
13985
  ] })
13879
13986
  ] });
@@ -13882,19 +13989,19 @@ function CtaSlotBlock(_props) {
13882
13989
  return null;
13883
13990
  }
13884
13991
  function FeatureListBlock({ block }) {
13885
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ul", { className: "grid list-disc gap-2 pl-5 sm:grid-cols-2", children: block.data.items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("li", { children: item.text }, i)) });
13992
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ul", { className: "grid list-disc gap-2 pl-5 sm:grid-cols-2", children: block.data.items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("li", { children: item.text }, i)) });
13886
13993
  }
13887
13994
  function GalleryBlock({ block }) {
13888
13995
  const { images } = block.data;
13889
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
13996
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
13890
13997
  "div",
13891
13998
  {
13892
- className: (0, import_utils12.cn)(
13999
+ className: (0, import_utils13.cn)(
13893
14000
  "grid gap-4",
13894
14001
  images.length > 1 ? "sm:grid-cols-2 lg:grid-cols-3" : "grid-cols-1"
13895
14002
  ),
13896
- children: images.map((img, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("figure", { className: "space-y-1", children: [
13897
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "relative aspect-video w-full overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14003
+ children: images.map((img, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("figure", { className: "space-y-1", children: [
14004
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "relative aspect-video w-full overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
13898
14005
  "img",
13899
14006
  {
13900
14007
  src: img.url,
@@ -13903,7 +14010,7 @@ function GalleryBlock({ block }) {
13903
14010
  className: "h-full w-full object-cover"
13904
14011
  }
13905
14012
  ) }),
13906
- img.caption && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("figcaption", { className: "text-sm opacity-80", children: img.caption })
14013
+ img.caption && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("figcaption", { className: "text-sm opacity-80", children: img.caption })
13907
14014
  ] }, `${img.url}-${i}`))
13908
14015
  }
13909
14016
  );
@@ -13913,13 +14020,13 @@ function EmbedCard({
13913
14020
  headingLevel,
13914
14021
  embedHref
13915
14022
  }) {
13916
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
14023
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
13917
14024
  "a",
13918
14025
  {
13919
14026
  href: embedHref(resolved),
13920
14027
  className: "group block overflow-hidden rounded-xl border border-border bg-card text-card-foreground transition-shadow hover:shadow-md focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
13921
14028
  children: [
13922
- resolved.coverImageUrl && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "aspect-video w-full overflow-hidden bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14029
+ resolved.coverImageUrl && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "aspect-video w-full overflow-hidden bg-muted", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
13923
14030
  "img",
13924
14031
  {
13925
14032
  src: resolved.coverImageUrl,
@@ -13928,24 +14035,24 @@ function EmbedCard({
13928
14035
  className: "h-full w-full object-cover"
13929
14036
  }
13930
14037
  ) }),
13931
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "space-y-1 p-4", children: [
13932
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Heading, { level: headingLevel, className: "text-lg font-semibold", children: resolved.title }),
13933
- resolved.role && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-sm text-muted-foreground", children: resolved.role }),
13934
- resolved.excerpt && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "text-muted-foreground", children: resolved.excerpt })
14038
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: "space-y-1 p-4", children: [
14039
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Heading, { level: headingLevel, className: "text-lg font-semibold", children: resolved.title }),
14040
+ resolved.role && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm text-muted-foreground", children: resolved.role }),
14041
+ resolved.excerpt && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-muted-foreground", children: resolved.excerpt })
13935
14042
  ] })
13936
14043
  ]
13937
14044
  }
13938
14045
  );
13939
14046
  }
13940
14047
  function PageEmbedBlock({ block, headingLevel, embedHref }) {
13941
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(EmbedCard, { resolved: block.resolved, headingLevel, embedHref });
14048
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(EmbedCard, { resolved: block.resolved, headingLevel, embedHref });
13942
14049
  }
13943
14050
  function ProfileEmbedBlock({
13944
14051
  block,
13945
14052
  headingLevel,
13946
14053
  embedHref
13947
14054
  }) {
13948
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(EmbedCard, { resolved: block.resolved, headingLevel, embedHref });
14055
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(EmbedCard, { resolved: block.resolved, headingLevel, embedHref });
13949
14056
  }
13950
14057
  var DEFAULT_RENDERERS = {
13951
14058
  hero: HeroBlock,
@@ -14002,14 +14109,14 @@ function toIdFragment(value) {
14002
14109
  function SectionCta2({ cta }) {
14003
14110
  if (!hasUsableCta(cta)) return null;
14004
14111
  const variant = toButtonVariant(cta.variant);
14005
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14112
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "pt-2", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14006
14113
  "a",
14007
14114
  {
14008
14115
  href: cta.url,
14009
14116
  "data-slot": "button",
14010
14117
  "data-variant": variant,
14011
14118
  "data-size": "default",
14012
- className: (0, import_utils12.cn)((0, import_button_variants2.buttonVariants)({ variant, size: "default" })),
14119
+ className: (0, import_utils13.cn)((0, import_button_variants2.buttonVariants)({ variant, size: "default" })),
14013
14120
  ...cta.isExternal ? { target: "_blank", rel: "noopener noreferrer" } : {},
14014
14121
  children: cta.label
14015
14122
  }
@@ -14035,17 +14142,17 @@ function PageBlocks({
14035
14142
  const headingId = block.heading ? `${safePrefix}-${toIdFragment(block.id)}-heading` : void 0;
14036
14143
  const background = block.backgroundColor;
14037
14144
  return [
14038
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
14145
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
14039
14146
  "section",
14040
14147
  {
14041
14148
  "data-slot": "page-block",
14042
14149
  "data-block-type": type,
14043
14150
  "aria-labelledby": headingId,
14044
14151
  style: surfaceStyle(background),
14045
- className: (0, import_utils12.cn)("space-y-6", background && "rounded-xl px-6 py-10", sectionClassName),
14152
+ className: (0, import_utils13.cn)("space-y-6", background && "rounded-xl px-6 py-10", sectionClassName),
14046
14153
  children: [
14047
- block.heading && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Heading, { level: headingLevel, className: "text-2xl font-bold tracking-tight", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { id: headingId, children: block.heading }) }),
14048
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
14154
+ block.heading && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Heading, { level: headingLevel, className: "text-2xl font-bold tracking-tight", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { id: headingId, children: block.heading }) }),
14155
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14049
14156
  Renderer,
14050
14157
  {
14051
14158
  block,
@@ -14053,7 +14160,7 @@ function PageBlocks({
14053
14160
  embedHref
14054
14161
  }
14055
14162
  ),
14056
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(SectionCta2, { cta: block.cta })
14163
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SectionCta2, { cta: block.cta })
14057
14164
  ]
14058
14165
  },
14059
14166
  block.id
@@ -14061,12 +14168,12 @@ function PageBlocks({
14061
14168
  ];
14062
14169
  });
14063
14170
  if (sections.length === 0) return null;
14064
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: (0, import_utils12.cn)("space-y-12", className), "data-slot": "page-blocks", children: sections });
14171
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: (0, import_utils13.cn)("space-y-12", className), "data-slot": "page-blocks", children: sections });
14065
14172
  }
14066
14173
 
14067
14174
  // src/components/shop-filters.tsx
14068
- var import_utils13 = require("@reblu/site-ui/utils");
14069
- var import_jsx_runtime12 = require("react/jsx-runtime");
14175
+ var import_utils14 = require("@reblu/site-ui/utils");
14176
+ var import_jsx_runtime13 = require("react/jsx-runtime");
14070
14177
  var DEFAULT_SHOP_PRICE_BANDS = [
14071
14178
  { max: 2500 },
14072
14179
  { min: 2500, max: 5e3 },
@@ -14110,7 +14217,7 @@ function priceBandLabel(band, t, currencyCode, locale) {
14110
14217
  return "";
14111
14218
  }
14112
14219
  function OptionLink({ href, active, label, onActivate }) {
14113
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14220
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14114
14221
  "a",
14115
14222
  {
14116
14223
  href,
@@ -14119,7 +14226,7 @@ function OptionLink({ href, active, label, onActivate }) {
14119
14226
  event.preventDefault();
14120
14227
  onActivate();
14121
14228
  } : void 0,
14122
- className: (0, import_utils13.cn)(
14229
+ className: (0, import_utils14.cn)(
14123
14230
  "inline-flex items-center rounded-full border px-3 py-1 text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
14124
14231
  active ? "border-transparent bg-primary text-primary-foreground" : "border-border text-muted-foreground hover:bg-muted hover:text-foreground"
14125
14232
  ),
@@ -14128,9 +14235,9 @@ function OptionLink({ href, active, label, onActivate }) {
14128
14235
  );
14129
14236
  }
14130
14237
  function FilterFieldset({ legend, children: children2 }) {
14131
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("fieldset", { className: "space-y-2", children: [
14132
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("legend", { className: "text-sm font-medium text-foreground", children: legend }),
14133
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "flex flex-wrap gap-2", children: children2 })
14238
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("fieldset", { className: "space-y-2", children: [
14239
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("legend", { className: "text-sm font-medium text-foreground", children: legend }),
14240
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex flex-wrap gap-2", children: children2 })
14134
14241
  ] });
14135
14242
  }
14136
14243
  function ShopFilters({
@@ -14153,11 +14260,11 @@ function ShopFilters({
14153
14260
  if (!shouldRenderShopFilters(facets, active)) {
14154
14261
  return null;
14155
14262
  }
14156
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: (0, import_utils13.cn)("space-y-6", className), "data-slot": "shop-filters", children: [
14263
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: (0, import_utils14.cn)("space-y-6", className), "data-slot": "shop-filters", children: [
14157
14264
  visibleTaxonomies.map((axis) => {
14158
14265
  const activeSlug = active.taxonomy?.[axis.key];
14159
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(FilterFieldset, { legend: axis.label, children: [
14160
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14266
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(FilterFieldset, { legend: axis.label, children: [
14267
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14161
14268
  OptionLink,
14162
14269
  {
14163
14270
  href: hrefs.taxonomy(axis.key, void 0),
@@ -14172,7 +14279,7 @@ function ShopFilters({
14172
14279
  ),
14173
14280
  axis.terms.map((term) => {
14174
14281
  const isActive = activeSlug === term.slug;
14175
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14282
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14176
14283
  OptionLink,
14177
14284
  {
14178
14285
  href: hrefs.taxonomy(axis.key, isActive ? void 0 : term.slug),
@@ -14192,9 +14299,9 @@ function ShopFilters({
14192
14299
  }),
14193
14300
  visibleAttributes.map((attr) => {
14194
14301
  const activeValues = toValueArray(active.attr?.[attr.key]);
14195
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FilterFieldset, { legend: attr.label, children: attr.options.map((opt) => {
14302
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FilterFieldset, { legend: attr.label, children: attr.options.map((opt) => {
14196
14303
  const isActive = activeValues.includes(opt.value);
14197
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14304
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14198
14305
  OptionLink,
14199
14306
  {
14200
14307
  href: hrefs.attr(attr.key, opt.value),
@@ -14212,11 +14319,11 @@ function ShopFilters({
14212
14319
  );
14213
14320
  }) }, attr.key);
14214
14321
  }),
14215
- showPriceGroup && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(FilterFieldset, { legend: t.price, children: priceBands.map((band, i) => {
14322
+ showPriceGroup && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FilterFieldset, { legend: t.price, children: priceBands.map((band, i) => {
14216
14323
  const isActive = active.priceMin === band.min && active.priceMax === band.max;
14217
14324
  const nextMin = isActive ? void 0 : band.min;
14218
14325
  const nextMax = isActive ? void 0 : band.max;
14219
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14326
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14220
14327
  OptionLink,
14221
14328
  {
14222
14329
  href: hrefs.price(nextMin, nextMax),
@@ -14227,7 +14334,7 @@ function ShopFilters({
14227
14334
  i
14228
14335
  );
14229
14336
  }) }),
14230
- hasOnSale && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14337
+ hasOnSale && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14231
14338
  OptionLink,
14232
14339
  {
14233
14340
  href: hrefs.onSale(!active.onSale),
@@ -14236,7 +14343,7 @@ function ShopFilters({
14236
14343
  onActivate: onChange ? () => onChange({ onSale: !active.onSale }) : void 0
14237
14344
  }
14238
14345
  ),
14239
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
14346
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14240
14347
  "a",
14241
14348
  {
14242
14349
  href: hrefs.clearAll(),
@@ -14252,8 +14359,8 @@ function ShopFilters({
14252
14359
  }
14253
14360
 
14254
14361
  // src/components/cart-line-list.tsx
14255
- var import_utils14 = require("@reblu/site-ui/utils");
14256
- var import_jsx_runtime13 = require("react/jsx-runtime");
14362
+ var import_utils15 = require("@reblu/site-ui/utils");
14363
+ var import_jsx_runtime14 = require("react/jsx-runtime");
14257
14364
  var DEFAULT_LABELS2 = {
14258
14365
  quantityLabel: "Cantidad",
14259
14366
  decrease: "Reducir cantidad",
@@ -14271,6 +14378,7 @@ function CartLineList({
14271
14378
  onRemove,
14272
14379
  liveMessage,
14273
14380
  notice,
14381
+ lineMessage,
14274
14382
  labels,
14275
14383
  currencyCode,
14276
14384
  locale,
@@ -14278,9 +14386,9 @@ function CartLineList({
14278
14386
  }) {
14279
14387
  const t = { ...DEFAULT_LABELS2, ...labels };
14280
14388
  const noticeContent = notice === true ? t.cancelledNotice : notice;
14281
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: (0, import_utils14.cn)("space-y-4", className), "data-slot": "cart-line-list", children: [
14282
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { "aria-live": "polite", className: "sr-only", children: liveMessage }),
14283
- noticeContent != null && noticeContent !== false && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14389
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: (0, import_utils15.cn)("space-y-4", className), "data-slot": "cart-line-list", children: [
14390
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { "aria-live": "polite", className: "sr-only", children: liveMessage }),
14391
+ noticeContent != null && noticeContent !== false && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
14284
14392
  "div",
14285
14393
  {
14286
14394
  role: "status",
@@ -14289,32 +14397,33 @@ function CartLineList({
14289
14397
  children: noticeContent
14290
14398
  }
14291
14399
  ),
14292
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("ul", { className: "space-y-4", children: items.map((item) => {
14400
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("ul", { className: "space-y-4", children: items.map((item) => {
14293
14401
  const maxQty = item.maxStock ?? Infinity;
14294
14402
  const atMax = item.quantity >= maxQty;
14295
14403
  const atMin = item.quantity <= 1;
14296
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
14404
+ const message = lineMessage?.(item);
14405
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
14297
14406
  "li",
14298
14407
  {
14299
14408
  className: "flex gap-4 rounded-xl border border-border bg-card p-4",
14300
14409
  children: [
14301
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "h-20 w-20 flex-shrink-0 overflow-hidden rounded-lg bg-muted", children: item.imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("img", { src: item.imageUrl, alt: item.name, className: "h-full w-full object-cover" }) : null }),
14302
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "min-w-0 flex-1", children: [
14303
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "truncate text-sm font-semibold leading-tight", children: item.name }),
14304
- item.variantName && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground", children: item.variantName }),
14305
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("p", { className: "mt-1 text-sm text-muted-foreground", children: [
14410
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "h-20 w-20 flex-shrink-0 overflow-hidden rounded-lg bg-muted", children: item.imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("img", { src: item.imageUrl, alt: item.name, className: "h-full w-full object-cover" }) : null }),
14411
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "min-w-0 flex-1", children: [
14412
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "truncate text-sm font-semibold leading-tight", children: item.name }),
14413
+ item.variantName && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "mt-0.5 text-xs text-muted-foreground", children: item.variantName }),
14414
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { className: "mt-1 text-sm text-muted-foreground", children: [
14306
14415
  formatPrice(item.unitPrice, currencyCode, locale),
14307
14416
  " ",
14308
14417
  t.unitPriceSuffix
14309
14418
  ] }),
14310
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
14419
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
14311
14420
  "div",
14312
14421
  {
14313
14422
  role: "group",
14314
14423
  "aria-label": t.quantityLabel,
14315
14424
  className: "mt-3 flex items-center gap-3",
14316
14425
  children: [
14317
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14426
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
14318
14427
  "button",
14319
14428
  {
14320
14429
  type: "button",
@@ -14325,8 +14434,8 @@ function CartLineList({
14325
14434
  children: "\u2212"
14326
14435
  }
14327
14436
  ),
14328
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "w-8 text-center text-sm font-semibold tabular-nums", children: item.quantity }),
14329
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14437
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "w-8 text-center text-sm font-semibold tabular-nums", children: item.quantity }),
14438
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
14330
14439
  "button",
14331
14440
  {
14332
14441
  type: "button",
@@ -14337,7 +14446,7 @@ function CartLineList({
14337
14446
  children: "+"
14338
14447
  }
14339
14448
  ),
14340
- onRemove && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
14449
+ onRemove && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
14341
14450
  "button",
14342
14451
  {
14343
14452
  type: "button",
@@ -14349,9 +14458,17 @@ function CartLineList({
14349
14458
  )
14350
14459
  ]
14351
14460
  }
14461
+ ),
14462
+ message != null && message !== false && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
14463
+ "p",
14464
+ {
14465
+ className: "mt-2 text-sm text-destructive",
14466
+ "data-slot": "cart-line-list-line-message",
14467
+ children: message
14468
+ }
14352
14469
  )
14353
14470
  ] }),
14354
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "flex-shrink-0 text-right", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "text-base font-bold", children: formatPrice(item.unitPrice * item.quantity, currencyCode, locale) }) })
14471
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: "flex-shrink-0 text-right", children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("p", { className: "text-base font-bold", children: formatPrice(item.unitPrice * item.quantity, currencyCode, locale) }) })
14355
14472
  ]
14356
14473
  },
14357
14474
  lineKey(item.productId, item.variantId)
@@ -14361,8 +14478,8 @@ function CartLineList({
14361
14478
  }
14362
14479
 
14363
14480
  // src/components/cart-summary.tsx
14364
- var import_utils15 = require("@reblu/site-ui/utils");
14365
- var import_jsx_runtime14 = require("react/jsx-runtime");
14481
+ var import_utils16 = require("@reblu/site-ui/utils");
14482
+ var import_jsx_runtime15 = require("react/jsx-runtime");
14366
14483
  var DEFAULT_LABELS3 = {
14367
14484
  subtotal: "Subtotal",
14368
14485
  discountPrefix: "Descuento",
@@ -14389,40 +14506,40 @@ function CartSummary({
14389
14506
  const hasDiscount = Boolean(discount && discount > 0);
14390
14507
  const noticeContent = notice === true ? t.cancelledNotice : notice;
14391
14508
  const hasNotice = noticeContent != null && noticeContent !== false;
14392
- const breakdown = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
14509
+ const breakdown = /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
14393
14510
  "dl",
14394
14511
  {
14395
- className: (0, import_utils15.cn)("space-y-2 text-sm", !hasNotice && className),
14512
+ className: (0, import_utils16.cn)("space-y-2 text-sm", !hasNotice && className),
14396
14513
  "data-slot": "cart-summary",
14397
14514
  children: [
14398
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-muted-foreground", children: [
14399
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dt", { children: t.subtotal }),
14400
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dd", { children: formatPrice(subtotal, currencyCode, locale) })
14515
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex justify-between text-muted-foreground", children: [
14516
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dt", { children: t.subtotal }),
14517
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dd", { children: formatPrice(subtotal, currencyCode, locale) })
14401
14518
  ] }),
14402
- hasDiscount && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-green-600 dark:text-green-400", children: [
14403
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("dt", { children: [
14519
+ hasDiscount && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex justify-between text-green-600 dark:text-green-400", children: [
14520
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("dt", { children: [
14404
14521
  t.discountPrefix,
14405
14522
  discountCode ? ` (${discountCode})` : ""
14406
14523
  ] }),
14407
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("dd", { children: [
14524
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("dd", { children: [
14408
14525
  "-",
14409
14526
  formatPrice(discount, currencyCode, locale)
14410
14527
  ] })
14411
14528
  ] }),
14412
- shippingEnabled && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between text-muted-foreground", children: [
14413
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dt", { children: t.shipping }),
14414
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dd", { children: shipping == null || !Number.isFinite(shipping) ? t.shippingCalculated : shipping === 0 ? t.freeShipping : formatPrice(shipping, currencyCode, locale) })
14529
+ shippingEnabled && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex justify-between text-muted-foreground", children: [
14530
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dt", { children: t.shipping }),
14531
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dd", { children: shipping == null || !Number.isFinite(shipping) ? t.shippingCalculated : shipping === 0 ? t.freeShipping : formatPrice(shipping, currencyCode, locale) })
14415
14532
  ] }),
14416
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex justify-between border-t border-border pt-2 text-base font-bold", children: [
14417
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dt", { children: t.total }),
14418
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("dd", { children: formatPrice(total, currencyCode, locale) })
14533
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex justify-between border-t border-border pt-2 text-base font-bold", children: [
14534
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dt", { children: t.total }),
14535
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("dd", { children: formatPrice(total, currencyCode, locale) })
14419
14536
  ] })
14420
14537
  ]
14421
14538
  }
14422
14539
  );
14423
14540
  if (!hasNotice) return breakdown;
14424
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: (0, import_utils15.cn)("space-y-3", className), "data-slot": "cart-summary-wrapper", children: [
14425
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
14541
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: (0, import_utils16.cn)("space-y-3", className), "data-slot": "cart-summary-wrapper", children: [
14542
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
14426
14543
  "div",
14427
14544
  {
14428
14545
  role: "status",
@@ -14435,13 +14552,60 @@ function CartSummary({
14435
14552
  ] });
14436
14553
  }
14437
14554
 
14555
+ // src/components/cart-adjustments-notice.tsx
14556
+ var import_utils17 = require("@reblu/site-ui/utils");
14557
+ var import_jsx_runtime16 = require("react/jsx-runtime");
14558
+ var DEFAULT_LABELS4 = {
14559
+ removed: (names) => names.length === 1 ? `Hemos quitado del carrito: ${names[0]}, ya no est\xE1 disponible.` : `Hemos quitado del carrito: ${names.join(", ")}, ya no est\xE1n disponibles.`,
14560
+ quantityChanged: (name, quantity) => `Hemos ajustado la cantidad de ${name} a ${quantity} por el stock disponible.`,
14561
+ priceChanged: (name, from, to) => `El precio de ${name} ha cambiado: antes ${from}, ahora ${to}.`
14562
+ };
14563
+ function displayName(line) {
14564
+ return line.variantName ? `${line.name} (${line.variantName})` : line.name;
14565
+ }
14566
+ function CartAdjustmentsNotice({
14567
+ removed = [],
14568
+ quantityChanges = [],
14569
+ priceChanges = [],
14570
+ labels,
14571
+ currencyCode,
14572
+ locale,
14573
+ className
14574
+ }) {
14575
+ const t = { ...DEFAULT_LABELS4, ...labels };
14576
+ const messages = [];
14577
+ if (removed.length > 0) messages.push(t.removed(removed.map(displayName)));
14578
+ for (const change of quantityChanges) {
14579
+ messages.push(t.quantityChanged(displayName(change), change.to));
14580
+ }
14581
+ for (const change of priceChanges) {
14582
+ messages.push(
14583
+ t.priceChanged(
14584
+ displayName(change),
14585
+ formatPrice(change.from, currencyCode, locale),
14586
+ formatPrice(change.to, currencyCode, locale)
14587
+ )
14588
+ );
14589
+ }
14590
+ if (messages.length === 0) return null;
14591
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
14592
+ "div",
14593
+ {
14594
+ role: "status",
14595
+ className: (0, import_utils17.cn)("rounded-lg border border-border bg-muted px-3 py-2 text-sm", className),
14596
+ "data-slot": "cart-adjustments-notice",
14597
+ children: messages.length === 1 ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { children: messages[0] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("ul", { className: "list-disc space-y-1 pl-4", children: messages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("li", { children: message }, index)) })
14598
+ }
14599
+ );
14600
+ }
14601
+
14438
14602
  // src/components/added-to-cart-toast.tsx
14439
- var import_utils16 = require("@reblu/site-ui/utils");
14440
- var import_jsx_runtime15 = (
14603
+ var import_utils18 = require("@reblu/site-ui/utils");
14604
+ var import_jsx_runtime17 = (
14441
14605
  // eslint-disable-next-line @next/next/no-img-element -- toast content, not a Next <Image> layout context
14442
14606
  require("react/jsx-runtime")
14443
14607
  );
14444
- var DEFAULT_LABELS4 = {
14608
+ var DEFAULT_LABELS5 = {
14445
14609
  success: "A\xF1adido al carrito",
14446
14610
  error: "No se pudo a\xF1adir al carrito",
14447
14611
  outOfStock: "Producto agotado",
@@ -14456,37 +14620,37 @@ function AddedToCartToast({
14456
14620
  labels,
14457
14621
  className
14458
14622
  }) {
14459
- const t = { ...DEFAULT_LABELS4, ...labels };
14623
+ const t = { ...DEFAULT_LABELS5, ...labels };
14460
14624
  const message = status === "error" ? t.error : status === "outOfStock" ? t.outOfStock : t.success;
14461
14625
  const hasThumbnail = Boolean(imageUrl && imageUrl.trim().length > 0);
14462
14626
  const variant = status === "success" ? "success" : "error";
14463
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
14627
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
14464
14628
  "div",
14465
14629
  {
14466
14630
  "data-slot": "added-to-cart-toast",
14467
14631
  "data-variant": variant,
14468
- className: (0, import_utils16.cn)(
14632
+ className: (0, import_utils18.cn)(
14469
14633
  "flex items-center gap-3 rounded-xl border border-border bg-card p-3 text-sm shadow-lg",
14470
14634
  variant === "success" && "border-green-600/30 dark:border-green-400/30",
14471
14635
  variant === "error" && "border-destructive/30",
14472
14636
  className
14473
14637
  ),
14474
14638
  children: [
14475
- hasThumbnail && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("img", { src: imageUrl, alt: productName, className: "h-10 w-10 flex-shrink-0 rounded-lg object-cover" }),
14476
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "min-w-0 flex-1", children: [
14477
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "truncate font-semibold text-foreground", children: productName }),
14478
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "truncate text-muted-foreground", children: quantity && quantity > 1 ? `${message} \xB7 x${quantity}` : message })
14639
+ hasThumbnail && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("img", { src: imageUrl, alt: productName, className: "h-10 w-10 flex-shrink-0 rounded-lg object-cover" }),
14640
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "min-w-0 flex-1", children: [
14641
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "truncate font-semibold text-foreground", children: productName }),
14642
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "truncate text-muted-foreground", children: quantity && quantity > 1 ? `${message} \xB7 x${quantity}` : message })
14479
14643
  ] }),
14480
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("a", { href: cartHref, className: "text-sm font-semibold text-primary underline-offset-2 hover:underline", children: t.viewCart }) })
14644
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "flex-shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("a", { href: cartHref, className: "text-sm font-semibold text-primary underline-offset-2 hover:underline", children: t.viewCart }) })
14481
14645
  ]
14482
14646
  }
14483
14647
  );
14484
14648
  }
14485
14649
 
14486
14650
  // src/components/checkout-login-prompt.tsx
14487
- var import_utils17 = require("@reblu/site-ui/utils");
14488
- var import_jsx_runtime16 = require("react/jsx-runtime");
14489
- var DEFAULT_LABELS5 = {
14651
+ var import_utils19 = require("@reblu/site-ui/utils");
14652
+ var import_jsx_runtime18 = require("react/jsx-runtime");
14653
+ var DEFAULT_LABELS6 = {
14490
14654
  title: "Identificaci\xF3n",
14491
14655
  description: "Introduce tu email para agilizar el proceso o contin\xFAa como invitado.",
14492
14656
  emailLabel: "Email",
@@ -14510,28 +14674,28 @@ function CheckoutLoginPrompt({
14510
14674
  className
14511
14675
  }) {
14512
14676
  if (!open) return null;
14513
- const t = { ...DEFAULT_LABELS5, ...labels };
14677
+ const t = { ...DEFAULT_LABELS6, ...labels };
14514
14678
  const isValidEmail = EMAIL_PATTERN.test(email.trim());
14515
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
14516
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "fixed inset-0 z-50 bg-black/50", onClick: onClose, "aria-hidden": "true" }),
14517
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
14679
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
14680
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "fixed inset-0 z-50 bg-black/50", onClick: onClose, "aria-hidden": "true" }),
14681
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
14518
14682
  "div",
14519
14683
  {
14520
14684
  role: "dialog",
14521
14685
  "aria-modal": "true",
14522
14686
  "aria-labelledby": "checkout-login-prompt-title",
14523
14687
  "data-slot": "checkout-login-prompt",
14524
- className: (0, import_utils17.cn)(
14688
+ className: (0, import_utils19.cn)(
14525
14689
  "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",
14526
14690
  className
14527
14691
  ),
14528
14692
  children: [
14529
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
14530
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { children: [
14531
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h2", { id: "checkout-login-prompt-title", className: "text-xl font-bold", children: t.title }),
14532
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: t.description })
14693
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-start justify-between gap-3", children: [
14694
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
14695
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h2", { id: "checkout-login-prompt-title", className: "text-xl font-bold", children: t.title }),
14696
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "mt-1 text-sm text-muted-foreground", children: t.description })
14533
14697
  ] }),
14534
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
14698
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
14535
14699
  "button",
14536
14700
  {
14537
14701
  type: "button",
@@ -14542,9 +14706,9 @@ function CheckoutLoginPrompt({
14542
14706
  }
14543
14707
  )
14544
14708
  ] }),
14545
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "space-y-2", children: [
14546
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("label", { htmlFor: "checkout-login-prompt-email", className: "text-sm font-medium", children: t.emailLabel }),
14547
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
14709
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "space-y-2", children: [
14710
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { htmlFor: "checkout-login-prompt-email", className: "text-sm font-medium", children: t.emailLabel }),
14711
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
14548
14712
  "input",
14549
14713
  {
14550
14714
  id: "checkout-login-prompt-email",
@@ -14553,29 +14717,29 @@ function CheckoutLoginPrompt({
14553
14717
  value: email,
14554
14718
  onChange: (e) => onEmailChange(e.target.value),
14555
14719
  placeholder: t.emailPlaceholder,
14556
- className: (0, import_utils17.cn)(
14720
+ className: (0, import_utils19.cn)(
14557
14721
  "w-full rounded-lg border bg-background px-3 py-2 text-sm transition focus:outline-none focus:ring-2 focus:ring-primary/20",
14558
14722
  error ? "border-destructive" : "border-border focus:border-primary"
14559
14723
  )
14560
14724
  }
14561
14725
  ),
14562
- error && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-xs text-destructive", children: error })
14726
+ error && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-xs text-destructive", children: error })
14563
14727
  ] }),
14564
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "space-y-2", children: [
14565
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
14728
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "space-y-2", children: [
14729
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
14566
14730
  "button",
14567
14731
  {
14568
14732
  type: "button",
14569
14733
  onClick: onSubmitEmail,
14570
14734
  disabled: checking || !isValidEmail,
14571
- className: (0, import_utils17.cn)(
14735
+ className: (0, import_utils19.cn)(
14572
14736
  "flex w-full items-center justify-center gap-2 rounded-xl px-4 py-2.5 text-sm font-semibold transition-all",
14573
14737
  checking || !isValidEmail ? "cursor-not-allowed bg-muted text-muted-foreground" : "bg-primary text-primary-foreground hover:bg-primary/90"
14574
14738
  ),
14575
14739
  children: checking ? t.checking : t.continueWithEmail
14576
14740
  }
14577
14741
  ),
14578
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
14742
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
14579
14743
  "button",
14580
14744
  {
14581
14745
  type: "button",
@@ -14592,10 +14756,10 @@ function CheckoutLoginPrompt({
14592
14756
  }
14593
14757
 
14594
14758
  // src/components/checkout-form.tsx
14595
- var import_utils18 = require("@reblu/site-ui/utils");
14759
+ var import_utils20 = require("@reblu/site-ui/utils");
14596
14760
  var import_phone_input = require("@reblu/site-ui/phone-input");
14597
- var import_jsx_runtime17 = require("react/jsx-runtime");
14598
- var DEFAULT_LABELS6 = {
14761
+ var import_jsx_runtime19 = require("react/jsx-runtime");
14762
+ var DEFAULT_LABELS7 = {
14599
14763
  contactTitle: "Datos de contacto",
14600
14764
  nameLabel: "Nombre completo",
14601
14765
  namePlaceholder: "Tu nombre",
@@ -14634,7 +14798,7 @@ function CheckoutForm({
14634
14798
  locale,
14635
14799
  className
14636
14800
  }) {
14637
- const t = { ...DEFAULT_LABELS6, ...labels };
14801
+ const t = { ...DEFAULT_LABELS7, ...labels };
14638
14802
  const details = checkoutError?.details;
14639
14803
  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;
14640
14804
  const phoneError = contactErrors?.phone ?? (rejectedPhone ? checkoutError.error : void 0);
@@ -14648,22 +14812,22 @@ function CheckoutForm({
14648
14812
  event.preventDefault();
14649
14813
  if (discountCode.trim() && !discountApplying) onApplyDiscount();
14650
14814
  }
14651
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
14815
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
14652
14816
  loginPrompt,
14653
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
14817
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
14654
14818
  "form",
14655
14819
  {
14656
14820
  "data-testid": "checkout-form",
14657
14821
  onSubmit,
14658
- className: (0, import_utils18.cn)("space-y-8", className),
14822
+ className: (0, import_utils20.cn)("space-y-8", className),
14659
14823
  "data-slot": "checkout-form",
14660
14824
  children: [
14661
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("section", { className: "space-y-4", children: [
14662
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h2", { className: "border-b border-border pb-2 text-lg font-semibold", children: t.contactTitle }),
14663
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
14664
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "space-y-1", children: [
14665
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { htmlFor: "checkout-form-name", className: "text-sm font-medium", children: t.nameLabel }),
14666
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
14825
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("section", { className: "space-y-4", children: [
14826
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h2", { className: "border-b border-border pb-2 text-lg font-semibold", children: t.contactTitle }),
14827
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
14828
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-1", children: [
14829
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { htmlFor: "checkout-form-name", className: "text-sm font-medium", children: t.nameLabel }),
14830
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
14667
14831
  "input",
14668
14832
  {
14669
14833
  id: "checkout-form-name",
@@ -14672,17 +14836,17 @@ function CheckoutForm({
14672
14836
  value: contact.name,
14673
14837
  onChange: (e) => patchContact({ name: e.target.value }),
14674
14838
  placeholder: t.namePlaceholder,
14675
- className: (0, import_utils18.cn)(
14839
+ className: (0, import_utils20.cn)(
14676
14840
  "w-full rounded-lg border bg-background px-3 py-2 text-sm transition focus:outline-none focus:ring-2 focus:ring-primary/20",
14677
14841
  contactErrors?.name ? "border-destructive" : "border-border focus:border-primary"
14678
14842
  )
14679
14843
  }
14680
14844
  ),
14681
- contactErrors?.name && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-xs text-destructive", children: contactErrors.name })
14845
+ contactErrors?.name && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-xs text-destructive", children: contactErrors.name })
14682
14846
  ] }),
14683
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "space-y-1", children: [
14684
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { htmlFor: "checkout-form-email", className: "text-sm font-medium", children: t.emailLabel }),
14685
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
14847
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "space-y-1", children: [
14848
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { htmlFor: "checkout-form-email", className: "text-sm font-medium", children: t.emailLabel }),
14849
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
14686
14850
  "input",
14687
14851
  {
14688
14852
  id: "checkout-form-email",
@@ -14691,15 +14855,15 @@ function CheckoutForm({
14691
14855
  value: contact.email,
14692
14856
  onChange: (e) => patchContact({ email: e.target.value }),
14693
14857
  placeholder: t.emailPlaceholder,
14694
- className: (0, import_utils18.cn)(
14858
+ className: (0, import_utils20.cn)(
14695
14859
  "w-full rounded-lg border bg-background px-3 py-2 text-sm transition focus:outline-none focus:ring-2 focus:ring-primary/20",
14696
14860
  contactErrors?.email ? "border-destructive" : "border-border focus:border-primary"
14697
14861
  )
14698
14862
  }
14699
14863
  ),
14700
- contactErrors?.email && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-xs text-destructive", children: contactErrors.email })
14864
+ contactErrors?.email && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-xs text-destructive", children: contactErrors.email })
14701
14865
  ] }),
14702
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
14866
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "space-y-1", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
14703
14867
  import_phone_input.PhoneInput,
14704
14868
  {
14705
14869
  id: "checkout-form-phone",
@@ -14713,15 +14877,15 @@ function CheckoutForm({
14713
14877
  ] })
14714
14878
  ] }),
14715
14879
  children2,
14716
- generalError ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { role: "alert", className: "text-sm text-destructive", children: generalError }) : null,
14717
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("section", { className: "space-y-3", children: [
14718
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("h2", { className: "border-b border-border pb-2 text-lg font-semibold", children: t.discountTitle }),
14719
- appliedDiscount ? /* @__PURE__ */ (0, import_jsx_runtime17.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: [
14720
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex items-center gap-2 text-sm text-green-700 dark:text-green-400", children: [
14721
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "font-semibold", children: appliedDiscount.code }),
14722
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: t.discountAppliedSuffix(formatPrice(appliedDiscount.amount, currencyCode, locale)) })
14880
+ generalError ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { role: "alert", className: "text-sm text-destructive", children: generalError }) : null,
14881
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("section", { className: "space-y-3", children: [
14882
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("h2", { className: "border-b border-border pb-2 text-lg font-semibold", children: t.discountTitle }),
14883
+ appliedDiscount ? /* @__PURE__ */ (0, import_jsx_runtime19.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: [
14884
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex items-center gap-2 text-sm text-green-700 dark:text-green-400", children: [
14885
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "font-semibold", children: appliedDiscount.code }),
14886
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: t.discountAppliedSuffix(formatPrice(appliedDiscount.amount, currencyCode, locale)) })
14723
14887
  ] }),
14724
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
14888
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
14725
14889
  "button",
14726
14890
  {
14727
14891
  type: "button",
@@ -14731,9 +14895,9 @@ function CheckoutForm({
14731
14895
  children: t.removeDiscount
14732
14896
  }
14733
14897
  )
14734
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { className: "flex gap-2", children: [
14735
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("label", { htmlFor: "checkout-form-discount-code", className: "sr-only", children: t.discountTitle }),
14736
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
14898
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex gap-2", children: [
14899
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("label", { htmlFor: "checkout-form-discount-code", className: "sr-only", children: t.discountTitle }),
14900
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
14737
14901
  "input",
14738
14902
  {
14739
14903
  id: "checkout-form-discount-code",
@@ -14745,7 +14909,7 @@ function CheckoutForm({
14745
14909
  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"
14746
14910
  }
14747
14911
  ),
14748
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
14912
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
14749
14913
  "button",
14750
14914
  {
14751
14915
  type: "button",
@@ -14756,14 +14920,14 @@ function CheckoutForm({
14756
14920
  }
14757
14921
  )
14758
14922
  ] }),
14759
- discountError && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("p", { className: "text-xs text-destructive", children: discountError })
14923
+ discountError && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-xs text-destructive", children: discountError })
14760
14924
  ] }),
14761
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
14925
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
14762
14926
  "button",
14763
14927
  {
14764
14928
  type: "submit",
14765
14929
  disabled: submitting || submitDisabled,
14766
- className: (0, import_utils18.cn)(
14930
+ className: (0, import_utils20.cn)(
14767
14931
  "flex w-full items-center justify-center gap-2 rounded-xl px-4 py-3 font-semibold transition-all",
14768
14932
  submitting || submitDisabled ? "cursor-not-allowed bg-muted text-muted-foreground" : "bg-primary text-primary-foreground hover:bg-primary/90"
14769
14933
  ),
@@ -14777,9 +14941,34 @@ function CheckoutForm({
14777
14941
  }
14778
14942
 
14779
14943
  // src/components/order-confirmation.tsx
14780
- var import_utils19 = require("@reblu/site-ui/utils");
14781
- var import_jsx_runtime18 = require("react/jsx-runtime");
14782
- var DEFAULT_LABELS7 = {
14944
+ var import_utils22 = require("@reblu/site-ui/utils");
14945
+
14946
+ // src/components/order-invoice-link.tsx
14947
+ var import_utils21 = require("@reblu/site-ui/utils");
14948
+ var import_jsx_runtime20 = require("react/jsx-runtime");
14949
+ var DEFAULT_LABELS8 = {
14950
+ linkLabel: "Descargar la factura {number}",
14951
+ signInHint: "Te pediremos que inicies sesi\xF3n para abrirla."
14952
+ };
14953
+ function OrderInvoiceLink({ invoice, labels, className }) {
14954
+ if (!invoice) return null;
14955
+ const t = { ...DEFAULT_LABELS8, ...labels };
14956
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: (0, import_utils21.cn)("space-y-1 text-sm", className), "data-slot": "order-invoice-link", children: [
14957
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
14958
+ "a",
14959
+ {
14960
+ href: invoice.url,
14961
+ className: "font-semibold text-primary underline-offset-2 hover:underline",
14962
+ children: t.linkLabel.replace("{number}", invoice.number)
14963
+ }
14964
+ ),
14965
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "text-muted-foreground", children: t.signInHint })
14966
+ ] });
14967
+ }
14968
+
14969
+ // src/components/order-confirmation.tsx
14970
+ var import_jsx_runtime21 = require("react/jsx-runtime");
14971
+ var DEFAULT_LABELS9 = {
14783
14972
  pollingTitle: "Confirmando tu pedido\u2026",
14784
14973
  pollingDescription: "Estamos procesando el pago, un momento\u2026",
14785
14974
  foundTitle: "\xA1Pedido confirmado!",
@@ -14805,7 +14994,9 @@ var DEFAULT_LABELS7 = {
14805
14994
  notFoundDescription: "Comprueba el enlace o contacta con nosotros si el problema persiste.",
14806
14995
  errorTitle: "Ha ocurrido un error",
14807
14996
  errorDescription: "No hemos podido comprobar el estado de tu pedido.",
14808
- orderReferenceLabel: "Referencia del pedido"
14997
+ orderReferenceLabel: "Referencia del pedido",
14998
+ invoiceLinkLabel: "Descargar la factura {number}",
14999
+ invoiceSignInHint: "Te pediremos que inicies sesi\xF3n para abrirla."
14809
15000
  };
14810
15001
  function OrderConfirmation({
14811
15002
  status,
@@ -14818,7 +15009,7 @@ function OrderConfirmation({
14818
15009
  locale,
14819
15010
  className
14820
15011
  }) {
14821
- const t = { ...DEFAULT_LABELS7, ...labels };
15012
+ const t = { ...DEFAULT_LABELS9, ...labels };
14822
15013
  const isPolling = status === "polling" || status === "loading";
14823
15014
  const isFound = status === "found" || status === "paid";
14824
15015
  const { title, description } = (() => {
@@ -14840,48 +15031,55 @@ function OrderConfirmation({
14840
15031
  const showOrderReference = Boolean(order) && !showFullOrderSummary && (status === "refunded" || status === "partially_refunded" || status === "pending_timeout");
14841
15032
  const showSessionReference = !order && sessionId && (status === "timeout" || status === "not_found" || status === "pending_timeout");
14842
15033
  const showRecheck = (status === "pending_timeout" || status === "error") && onRecheck;
14843
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: (0, import_utils19.cn)("space-y-6 text-center", className), "data-slot": "order-confirmation", children: [
14844
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h1", { className: "text-3xl font-bold", children: title }),
14845
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-lg text-muted-foreground", children: description }),
14846
- showFullOrderSummary && order && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "space-y-6", children: [
14847
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14848
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.orderNumberLabel }),
14849
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "font-mono text-lg font-semibold", children: order.orderNumber })
15034
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: (0, import_utils22.cn)("space-y-6 text-center", className), "data-slot": "order-confirmation", children: [
15035
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h1", { className: "text-3xl font-bold", children: title }),
15036
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-lg text-muted-foreground", children: description }),
15037
+ showFullOrderSummary && order && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "space-y-6", children: [
15038
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
15039
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.orderNumberLabel }),
15040
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "font-mono text-lg font-semibold", children: order.orderNumber })
14850
15041
  ] }),
14851
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "mx-auto max-w-sm space-y-3 rounded-xl border border-border bg-card p-5 text-left", children: [
14852
- order.items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
15042
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "mx-auto max-w-sm space-y-3 rounded-xl border border-border bg-card p-5 text-left", children: [
15043
+ order.items.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
14853
15044
  "div",
14854
15045
  {
14855
15046
  className: "flex justify-between gap-4 text-sm",
14856
15047
  children: [
14857
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "max-w-[60%] truncate text-muted-foreground", children: [
15048
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "max-w-[60%] truncate text-muted-foreground", children: [
14858
15049
  item.product.name,
14859
15050
  item.variant ? ` (${item.variant.name})` : "",
14860
15051
  " x",
14861
15052
  item.quantity
14862
15053
  ] }),
14863
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: formatPrice(item.total, currencyCode, locale) })
15054
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: formatPrice(item.total, currencyCode, locale) })
14864
15055
  ]
14865
15056
  },
14866
15057
  idx
14867
15058
  )),
14868
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "space-y-1 border-t border-border pt-3 text-sm", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex justify-between pt-1 text-base font-bold", children: [
14869
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: t.totalLabel }),
14870
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: formatPrice(order.total, currencyCode, locale) })
15059
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "space-y-1 border-t border-border pt-3 text-sm", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex justify-between pt-1 text-base font-bold", children: [
15060
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: t.totalLabel }),
15061
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: formatPrice(order.total, currencyCode, locale) })
14871
15062
  ] }) })
14872
15063
  ] }),
14873
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("p", { className: "mx-auto max-w-sm text-sm text-muted-foreground", children: [
15064
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: "mx-auto max-w-sm text-sm text-muted-foreground", children: [
14874
15065
  t.confirmationEmailPrefix,
14875
15066
  " ",
14876
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "font-medium text-foreground", children: order.customerEmail }),
15067
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "font-medium text-foreground", children: order.customerEmail }),
14877
15068
  "."
14878
- ] })
15069
+ ] }),
15070
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
15071
+ OrderInvoiceLink,
15072
+ {
15073
+ invoice: order.invoice,
15074
+ labels: { linkLabel: t.invoiceLinkLabel, signInHint: t.invoiceSignInHint }
15075
+ }
15076
+ )
14879
15077
  ] }),
14880
- showOrderReference && order && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14881
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.orderReferenceLabel }),
14882
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "font-mono text-lg font-semibold", children: order.orderNumber })
15078
+ showOrderReference && order && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
15079
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.orderReferenceLabel }),
15080
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "font-mono text-lg font-semibold", children: order.orderNumber })
14883
15081
  ] }),
14884
- status === "failed" && cartHref && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
15082
+ status === "failed" && cartHref && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14885
15083
  "a",
14886
15084
  {
14887
15085
  href: cartHref,
@@ -14889,7 +15087,7 @@ function OrderConfirmation({
14889
15087
  children: t.backToCartLabel
14890
15088
  }
14891
15089
  ),
14892
- showRecheck && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
15090
+ showRecheck && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
14893
15091
  "button",
14894
15092
  {
14895
15093
  type: "button",
@@ -14898,9 +15096,270 @@ function OrderConfirmation({
14898
15096
  children: t.recheckLabel
14899
15097
  }
14900
15098
  ),
14901
- showSessionReference && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14902
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.sessionReferenceLabel }),
14903
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "break-all font-mono text-sm font-semibold", children: sessionId })
15099
+ showSessionReference && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
15100
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.sessionReferenceLabel }),
15101
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "break-all font-mono text-sm font-semibold", children: sessionId })
15102
+ ] })
15103
+ ] });
15104
+ }
15105
+
15106
+ // src/components/full-invoice-fields.tsx
15107
+ var import_utils23 = require("@reblu/site-ui/utils");
15108
+ var import_jsx_runtime22 = require("react/jsx-runtime");
15109
+ var EMPTY_FULL_INVOICE_VALUE = {
15110
+ wantsFullInvoice: false,
15111
+ billingIdType: "NIF",
15112
+ billingIdCountry: "",
15113
+ billingNif: "",
15114
+ billingName: "",
15115
+ street: "",
15116
+ postalCode: "",
15117
+ city: "",
15118
+ country: "ES"
15119
+ };
15120
+ var DEFAULT_LABELS10 = {
15121
+ toggle: "\xBFQuieres factura completa?",
15122
+ underCapNotice: "Para una factura completa necesitas tu NIF/NIE o un documento de identificaci\xF3n. Si no, recibir\xE1s una factura simplificada.",
15123
+ overCapNotice: "El importe del pedido supera el m\xE1ximo de la factura simplificada: para completar la compra, indica tu NIF/NIE o un documento de identificaci\xF3n, tu nombre y tu direcci\xF3n de facturaci\xF3n.",
15124
+ idType: "Tipo de documento",
15125
+ idCountry: "Pa\xEDs que expidi\xF3 el documento",
15126
+ chooseCountry: "Elige un pa\xEDs",
15127
+ spanishNif: "NIF / NIE / CIF",
15128
+ documentNumber: "N\xFAmero de documento",
15129
+ name: "Nombre o raz\xF3n social",
15130
+ street: "Direcci\xF3n",
15131
+ postalCode: "C\xF3digo postal",
15132
+ city: "Ciudad",
15133
+ country: "Pa\xEDs",
15134
+ idTypeOptions: {
15135
+ NIF: "NIF / NIE / CIF (Espa\xF1a)",
15136
+ "02": "NIF-IVA intracomunitario (otro pa\xEDs de la UE)",
15137
+ "03": "Pasaporte",
15138
+ "04": "Documento oficial de identidad de tu pa\xEDs de residencia",
15139
+ "05": "Certificado de residencia",
15140
+ "06": "Otro documento acreditativo"
15141
+ }
15142
+ };
15143
+ var ID_TYPES = ["NIF", "02", "03", "04", "05", "06"];
15144
+ var DEFAULT_INVOICE_COUNTRIES = [
15145
+ { code: "ES", name: "Espa\xF1a" },
15146
+ { code: "DE", name: "Alemania" },
15147
+ { code: "AD", name: "Andorra" },
15148
+ { code: "AR", name: "Argentina" },
15149
+ { code: "AT", name: "Austria" },
15150
+ { code: "BE", name: "B\xE9lgica" },
15151
+ { code: "BG", name: "Bulgaria" },
15152
+ { code: "CY", name: "Chipre" },
15153
+ { code: "CO", name: "Colombia" },
15154
+ { code: "HR", name: "Croacia" },
15155
+ { code: "DK", name: "Dinamarca" },
15156
+ { code: "SK", name: "Eslovaquia" },
15157
+ { code: "SI", name: "Eslovenia" },
15158
+ { code: "US", name: "Estados Unidos" },
15159
+ { code: "EE", name: "Estonia" },
15160
+ { code: "FI", name: "Finlandia" },
15161
+ { code: "FR", name: "Francia" },
15162
+ { code: "GR", name: "Grecia" },
15163
+ { code: "HU", name: "Hungr\xEDa" },
15164
+ { code: "IE", name: "Irlanda" },
15165
+ { code: "IT", name: "Italia" },
15166
+ { code: "LV", name: "Letonia" },
15167
+ { code: "LT", name: "Lituania" },
15168
+ { code: "LU", name: "Luxemburgo" },
15169
+ { code: "MT", name: "Malta" },
15170
+ { code: "MA", name: "Marruecos" },
15171
+ { code: "MX", name: "M\xE9xico" },
15172
+ { code: "NL", name: "Pa\xEDses Bajos" },
15173
+ { code: "PL", name: "Polonia" },
15174
+ { code: "PT", name: "Portugal" },
15175
+ { code: "GB", name: "Reino Unido" },
15176
+ { code: "CZ", name: "Rep\xFAblica Checa" },
15177
+ { code: "RO", name: "Ruman\xEDa" },
15178
+ { code: "SE", name: "Suecia" },
15179
+ { code: "CH", name: "Suiza" },
15180
+ { code: "VE", name: "Venezuela" }
15181
+ ];
15182
+ function shopIssuesInvoices(config) {
15183
+ return config.simplifiedInvoiceCapCents != null;
15184
+ }
15185
+ function isOverSimplifiedInvoiceCap(totalCents, capCents) {
15186
+ return capCents != null && totalCents > capCents;
15187
+ }
15188
+ function toCheckoutInvoiceFields(value, overCap, issuesInvoices = true) {
15189
+ if (!issuesInvoices) return {};
15190
+ if (!value.wantsFullInvoice && !overCap) return {};
15191
+ const name = value.billingName.trim();
15192
+ const [first = "", ...rest] = name.split(/\s+/);
15193
+ const billing = {
15194
+ billingName: name,
15195
+ billingNif: value.billingNif.trim(),
15196
+ billingIdType: value.billingIdType,
15197
+ ...value.billingIdType === "NIF" ? {} : { billingIdCountry: value.billingIdCountry },
15198
+ billingAddress: {
15199
+ firstName: first,
15200
+ lastName: rest.join(" ") || first,
15201
+ street: value.street.trim(),
15202
+ city: value.city.trim(),
15203
+ postalCode: value.postalCode.trim(),
15204
+ country: value.country
15205
+ }
15206
+ };
15207
+ return { ...value.wantsFullInvoice ? { wantsFullInvoice: true } : {}, billing };
15208
+ }
15209
+ var FIELD_CLASS = "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20";
15210
+ function FullInvoiceFields({
15211
+ value,
15212
+ onChange,
15213
+ overCap,
15214
+ issuesInvoices = true,
15215
+ errors = {},
15216
+ countries = DEFAULT_INVOICE_COUNTRIES,
15217
+ labels,
15218
+ className
15219
+ }) {
15220
+ if (!issuesInvoices) return null;
15221
+ const t = { ...DEFAULT_LABELS10, ...labels };
15222
+ const showFields = value.wantsFullInvoice || overCap;
15223
+ const isSpanishNif = value.billingIdType === "NIF";
15224
+ const set = (key2, next2) => onChange({ ...value, [key2]: next2 });
15225
+ const error = (key2) => errors[key2] ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { id: `full-invoice-${key2}-error`, className: "text-sm text-destructive", children: errors[key2] }) : null;
15226
+ const invalid2 = (key2) => errors[key2] ? { "aria-invalid": true, "aria-describedby": `full-invoice-${key2}-error` } : {};
15227
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("section", { className: (0, import_utils23.cn)("space-y-4", className), "data-slot": "full-invoice-fields", children: [
15228
+ overCap ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { role: "note", className: "rounded-lg border border-border p-4 text-sm", children: t.overCapNotice }) : /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
15229
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { className: "flex items-center gap-2 text-sm font-medium", children: [
15230
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
15231
+ "input",
15232
+ {
15233
+ type: "checkbox",
15234
+ checked: value.wantsFullInvoice,
15235
+ onChange: (e) => set("wantsFullInvoice", e.target.checked)
15236
+ }
15237
+ ),
15238
+ t.toggle
15239
+ ] }),
15240
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("p", { className: "text-sm text-muted-foreground", children: t.underCapNotice })
15241
+ ] }),
15242
+ showFields && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
15243
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
15244
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { htmlFor: "full-invoice-id-type", className: "text-sm font-medium", children: t.idType }),
15245
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
15246
+ "select",
15247
+ {
15248
+ id: "full-invoice-id-type",
15249
+ className: FIELD_CLASS,
15250
+ required: true,
15251
+ value: value.billingIdType,
15252
+ onChange: (e) => set("billingIdType", e.target.value),
15253
+ ...invalid2("billingIdType"),
15254
+ children: ID_TYPES.map((type) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("option", { value: type, children: t.idTypeOptions[type] }, type))
15255
+ }
15256
+ ),
15257
+ error("billingIdType")
15258
+ ] }),
15259
+ !isSpanishNif && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
15260
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { htmlFor: "full-invoice-id-country", className: "text-sm font-medium", children: t.idCountry }),
15261
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
15262
+ "select",
15263
+ {
15264
+ id: "full-invoice-id-country",
15265
+ className: FIELD_CLASS,
15266
+ required: true,
15267
+ value: value.billingIdCountry,
15268
+ onChange: (e) => set("billingIdCountry", e.target.value),
15269
+ ...invalid2("billingIdCountry"),
15270
+ children: [
15271
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("option", { value: "", disabled: true, children: t.chooseCountry }),
15272
+ countries.map((c) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("option", { value: c.code, children: c.name }, c.code))
15273
+ ]
15274
+ }
15275
+ ),
15276
+ error("billingIdCountry")
15277
+ ] }),
15278
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
15279
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { htmlFor: "full-invoice-nif", className: "text-sm font-medium", children: isSpanishNif ? t.spanishNif : t.documentNumber }),
15280
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
15281
+ "input",
15282
+ {
15283
+ id: "full-invoice-nif",
15284
+ className: FIELD_CLASS,
15285
+ required: true,
15286
+ value: value.billingNif,
15287
+ onChange: (e) => set("billingNif", e.target.value),
15288
+ ...invalid2("billingNif")
15289
+ }
15290
+ ),
15291
+ error("billingNif")
15292
+ ] }),
15293
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
15294
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { htmlFor: "full-invoice-name", className: "text-sm font-medium", children: t.name }),
15295
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
15296
+ "input",
15297
+ {
15298
+ id: "full-invoice-name",
15299
+ className: FIELD_CLASS,
15300
+ required: true,
15301
+ value: value.billingName,
15302
+ onChange: (e) => set("billingName", e.target.value),
15303
+ ...invalid2("billingName")
15304
+ }
15305
+ ),
15306
+ error("billingName")
15307
+ ] }),
15308
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1 sm:col-span-2", children: [
15309
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { htmlFor: "full-invoice-street", className: "text-sm font-medium", children: t.street }),
15310
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
15311
+ "input",
15312
+ {
15313
+ id: "full-invoice-street",
15314
+ className: FIELD_CLASS,
15315
+ required: true,
15316
+ value: value.street,
15317
+ onChange: (e) => set("street", e.target.value),
15318
+ ...invalid2("address")
15319
+ }
15320
+ )
15321
+ ] }),
15322
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
15323
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { htmlFor: "full-invoice-postal-code", className: "text-sm font-medium", children: t.postalCode }),
15324
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
15325
+ "input",
15326
+ {
15327
+ id: "full-invoice-postal-code",
15328
+ className: FIELD_CLASS,
15329
+ required: true,
15330
+ value: value.postalCode,
15331
+ onChange: (e) => set("postalCode", e.target.value)
15332
+ }
15333
+ )
15334
+ ] }),
15335
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
15336
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { htmlFor: "full-invoice-city", className: "text-sm font-medium", children: t.city }),
15337
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
15338
+ "input",
15339
+ {
15340
+ id: "full-invoice-city",
15341
+ className: FIELD_CLASS,
15342
+ required: true,
15343
+ value: value.city,
15344
+ onChange: (e) => set("city", e.target.value)
15345
+ }
15346
+ )
15347
+ ] }),
15348
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "space-y-1", children: [
15349
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("label", { htmlFor: "full-invoice-country", className: "text-sm font-medium", children: t.country }),
15350
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
15351
+ "select",
15352
+ {
15353
+ id: "full-invoice-country",
15354
+ className: FIELD_CLASS,
15355
+ required: true,
15356
+ value: value.country,
15357
+ onChange: (e) => set("country", e.target.value),
15358
+ children: countries.map((c) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("option", { value: c.code, children: c.name }, c.code))
15359
+ }
15360
+ )
15361
+ ] }),
15362
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "sm:col-span-2", children: error("address") })
14904
15363
  ] })
14905
15364
  ] });
14906
15365
  }
@@ -14908,17 +15367,23 @@ function OrderConfirmation({
14908
15367
  0 && (module.exports = {
14909
15368
  ALLOWED_YOUTUBE_HOSTS,
14910
15369
  AddedToCartToast,
15370
+ CartAdjustmentsNotice,
14911
15371
  CartLineList,
14912
15372
  CartSummary,
14913
15373
  CheckoutForm,
14914
15374
  CheckoutLoginPrompt,
15375
+ CourseDescription,
15376
+ DEFAULT_INVOICE_COUNTRIES,
14915
15377
  DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE,
14916
15378
  DEFAULT_SHOP_ERROR_MESSAGES,
14917
15379
  DEFAULT_SHOP_PRICE_BANDS,
14918
15380
  DEFAULT_TRUST_ICONS,
15381
+ EMPTY_FULL_INVOICE_VALUE,
14919
15382
  FaqAccordion,
15383
+ FullInvoiceFields,
14920
15384
  MarkdownRenderer,
14921
15385
  OrderConfirmation,
15386
+ OrderInvoiceLink,
14922
15387
  PageBlocks,
14923
15388
  PageCardGrid,
14924
15389
  ParentPage,
@@ -14935,10 +15400,14 @@ function OrderConfirmation({
14935
15400
  formatPrice,
14936
15401
  getShopErrorMessage,
14937
15402
  isAllowedYouTubeHost,
15403
+ isOverSimplifiedInvoiceCap,
15404
+ markdownToPlainText,
14938
15405
  markdownToSafeHtml,
14939
15406
  readingTime,
14940
15407
  sanitizeHtml,
14941
- shouldRenderShopFilters
15408
+ shopIssuesInvoices,
15409
+ shouldRenderShopFilters,
15410
+ toCheckoutInvoiceFields
14942
15411
  });
14943
15412
  /*! Bundled license information:
14944
15413