@reblu/site-blocks 0.7.0 → 0.9.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.js CHANGED
@@ -55,6 +55,33 @@ function getShopErrorMessage(code, overrides, fallback = DEFAULT_SHOP_ERROR_FALL
55
55
  return messages[code] ?? fallback;
56
56
  }
57
57
 
58
+ // src/lib/block-order.ts
59
+ function sortBlocksByOrder(blocks) {
60
+ return [...blocks].sort((a, b2) => a.order - b2.order);
61
+ }
62
+
63
+ // src/lib/faq-json-ld.ts
64
+ function normaliseText(value) {
65
+ return value.replace(/\s+/g, " ").trim();
66
+ }
67
+ function buildFaqPageJsonLd(items) {
68
+ const mainEntity = [];
69
+ for (const item of items) {
70
+ const name = normaliseText(item.q);
71
+ const text3 = normaliseText(item.a);
72
+ if (!name || !text3) continue;
73
+ mainEntity.push({ "@type": "Question", name, acceptedAnswer: { "@type": "Answer", text: text3 } });
74
+ }
75
+ if (mainEntity.length === 0) return null;
76
+ return { "@context": "https://schema.org", "@type": "FAQPage", mainEntity };
77
+ }
78
+ function collectFaqItems(blocks) {
79
+ if (!blocks) return [];
80
+ return sortBlocksByOrder(blocks).flatMap(
81
+ (block) => block.blockType === "faq" ? block.data.items : []
82
+ );
83
+ }
84
+
58
85
  // ../../node_modules/.pnpm/devlop@1.1.0/node_modules/devlop/lib/default.js
59
86
  function ok() {
60
87
  }
@@ -13421,9 +13448,302 @@ function ProductCard({ product, href, currencyCode = "EUR", locale, className })
13421
13448
  );
13422
13449
  }
13423
13450
 
13424
- // src/components/shop-filters.tsx
13451
+ // src/components/faq-accordion.tsx
13425
13452
  import { cn as cn7 } from "@reblu/site-ui/utils";
13426
- import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
13453
+
13454
+ // src/components/_heading.tsx
13455
+ import { jsx as jsx7 } from "react/jsx-runtime";
13456
+ function nextHeadingLevel(level) {
13457
+ return Math.min(level + 1, 6);
13458
+ }
13459
+ function Heading({
13460
+ level,
13461
+ className,
13462
+ children: children2
13463
+ }) {
13464
+ const Tag = `h${level}`;
13465
+ return /* @__PURE__ */ jsx7(Tag, { className, children: children2 });
13466
+ }
13467
+
13468
+ // src/components/faq-accordion.tsx
13469
+ import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
13470
+ function FaqAccordion({
13471
+ items,
13472
+ heading,
13473
+ headingLevel = 2,
13474
+ questionHeadingLevel,
13475
+ defaultOpen = [],
13476
+ className
13477
+ }) {
13478
+ const visible = items.map((item, index) => ({ item, index })).filter(({ item }) => item.q.trim() !== "");
13479
+ if (visible.length === 0) return null;
13480
+ return /* @__PURE__ */ jsxs6("div", { className: cn7("space-y-4", className), "data-slot": "faq-accordion", children: [
13481
+ heading && /* @__PURE__ */ jsx8(Heading, { level: headingLevel, className: "text-2xl font-semibold tracking-tight", children: heading }),
13482
+ /* @__PURE__ */ jsx8("div", { className: "divide-y divide-border rounded-xl border border-border", children: visible.map(({ item, index }) => /* @__PURE__ */ jsxs6(
13483
+ "details",
13484
+ {
13485
+ className: "group px-4",
13486
+ "data-slot": "faq-item",
13487
+ ...defaultOpen.includes(index) ? { open: true } : {},
13488
+ children: [
13489
+ /* @__PURE__ */ jsxs6("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: [
13490
+ questionHeadingLevel ? /* @__PURE__ */ jsx8(Heading, { level: questionHeadingLevel, className: "text-base font-medium", children: item.q }) : /* @__PURE__ */ jsx8("span", { children: item.q }),
13491
+ /* @__PURE__ */ jsx8(
13492
+ "span",
13493
+ {
13494
+ "aria-hidden": "true",
13495
+ className: "shrink-0 text-muted-foreground transition-transform group-open:rotate-45",
13496
+ children: "+"
13497
+ }
13498
+ )
13499
+ ] }),
13500
+ /* @__PURE__ */ jsx8("p", { className: "whitespace-pre-line pb-4 text-muted-foreground", children: item.a })
13501
+ ]
13502
+ },
13503
+ index
13504
+ )) })
13505
+ ] });
13506
+ }
13507
+
13508
+ // src/components/page-blocks.tsx
13509
+ import { cn as cn8 } from "@reblu/site-ui/utils";
13510
+ import { buttonVariants as buttonVariants2 } from "@reblu/site-ui/button-variants";
13511
+ import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
13512
+ var ALIASES = {
13513
+ doctor_embed: "profile_embed",
13514
+ specialty_embed: "page_embed"
13515
+ };
13516
+ function HeroBlock({ block, headingLevel }) {
13517
+ const { title, subtitle, imageUrl } = block.data;
13518
+ return /* @__PURE__ */ jsxs7("div", { className: "space-y-4", children: [
13519
+ /* @__PURE__ */ jsx9(Heading, { level: headingLevel, className: "text-3xl font-bold tracking-tight md:text-4xl", children: title }),
13520
+ subtitle && /* @__PURE__ */ jsx9("p", { className: "text-lg opacity-80", children: subtitle }),
13521
+ imageUrl && /* @__PURE__ */ jsx9("div", { className: "relative aspect-[21/9] w-full overflow-hidden rounded-xl bg-muted", children: /* @__PURE__ */ jsx9("img", { src: imageUrl, alt: "", loading: "lazy", className: "h-full w-full object-cover" }) })
13522
+ ] });
13523
+ }
13524
+ function RichtextBlock({ block, headingLevel }) {
13525
+ return /* @__PURE__ */ jsx9(SafeHtml, { html: sanitizeHtml(block.data.html), headingOffset: headingLevel - 1 });
13526
+ }
13527
+ function FaqBlock({ block }) {
13528
+ return /* @__PURE__ */ jsx9(FaqAccordion, { items: block.data.items });
13529
+ }
13530
+ function StatsBlock({ block }) {
13531
+ return /* @__PURE__ */ jsx9("dl", { className: "grid gap-6 sm:grid-cols-2 lg:grid-cols-4", children: block.data.items.map((item, i) => /* @__PURE__ */ jsxs7("div", { className: "flex flex-col-reverse gap-1", children: [
13532
+ /* @__PURE__ */ jsx9("dt", { className: "text-sm opacity-80", children: item.label }),
13533
+ /* @__PURE__ */ jsx9("dd", { className: "text-3xl font-bold", children: item.value })
13534
+ ] }, i)) });
13535
+ }
13536
+ function TestimonialBlock({ block }) {
13537
+ const { quote, author, role, avatarUrl } = block.data;
13538
+ return /* @__PURE__ */ jsxs7("figure", { className: "space-y-4", children: [
13539
+ /* @__PURE__ */ jsx9("blockquote", { className: "text-xl italic", children: /* @__PURE__ */ jsx9("p", { children: quote }) }),
13540
+ /* @__PURE__ */ jsxs7("figcaption", { className: "flex items-center gap-3", children: [
13541
+ avatarUrl && // eslint-disable-next-line @next/next/no-img-element
13542
+ /* @__PURE__ */ jsx9(
13543
+ "img",
13544
+ {
13545
+ src: avatarUrl,
13546
+ alt: "",
13547
+ loading: "lazy",
13548
+ className: "h-10 w-10 rounded-full object-cover"
13549
+ }
13550
+ ),
13551
+ /* @__PURE__ */ jsxs7("span", { children: [
13552
+ /* @__PURE__ */ jsx9("span", { className: "font-semibold", children: author }),
13553
+ role && /* @__PURE__ */ jsx9("span", { className: "block text-sm opacity-80", children: role })
13554
+ ] })
13555
+ ] })
13556
+ ] });
13557
+ }
13558
+ function CtaSlotBlock(_props) {
13559
+ return null;
13560
+ }
13561
+ function FeatureListBlock({ block }) {
13562
+ return /* @__PURE__ */ jsx9("ul", { className: "grid list-disc gap-2 pl-5 sm:grid-cols-2", children: block.data.items.map((item, i) => /* @__PURE__ */ jsx9("li", { children: item.text }, i)) });
13563
+ }
13564
+ function GalleryBlock({ block }) {
13565
+ const { images } = block.data;
13566
+ return /* @__PURE__ */ jsx9(
13567
+ "div",
13568
+ {
13569
+ className: cn8(
13570
+ "grid gap-4",
13571
+ images.length > 1 ? "sm:grid-cols-2 lg:grid-cols-3" : "grid-cols-1"
13572
+ ),
13573
+ children: images.map((img, i) => /* @__PURE__ */ jsxs7("figure", { className: "space-y-1", children: [
13574
+ /* @__PURE__ */ jsx9("div", { className: "relative aspect-video w-full overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ jsx9(
13575
+ "img",
13576
+ {
13577
+ src: img.url,
13578
+ alt: img.alt ?? "",
13579
+ loading: "lazy",
13580
+ className: "h-full w-full object-cover"
13581
+ }
13582
+ ) }),
13583
+ img.caption && /* @__PURE__ */ jsx9("figcaption", { className: "text-sm opacity-80", children: img.caption })
13584
+ ] }, `${img.url}-${i}`))
13585
+ }
13586
+ );
13587
+ }
13588
+ function EmbedCard({
13589
+ resolved,
13590
+ headingLevel,
13591
+ embedHref
13592
+ }) {
13593
+ return /* @__PURE__ */ jsxs7(
13594
+ "a",
13595
+ {
13596
+ href: embedHref(resolved),
13597
+ 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",
13598
+ children: [
13599
+ resolved.coverImageUrl && /* @__PURE__ */ jsx9("div", { className: "aspect-video w-full overflow-hidden bg-muted", children: /* @__PURE__ */ jsx9(
13600
+ "img",
13601
+ {
13602
+ src: resolved.coverImageUrl,
13603
+ alt: "",
13604
+ loading: "lazy",
13605
+ className: "h-full w-full object-cover"
13606
+ }
13607
+ ) }),
13608
+ /* @__PURE__ */ jsxs7("div", { className: "space-y-1 p-4", children: [
13609
+ /* @__PURE__ */ jsx9(Heading, { level: headingLevel, className: "text-lg font-semibold", children: resolved.title }),
13610
+ resolved.role && /* @__PURE__ */ jsx9("p", { className: "text-sm text-muted-foreground", children: resolved.role }),
13611
+ resolved.excerpt && /* @__PURE__ */ jsx9("p", { className: "text-muted-foreground", children: resolved.excerpt })
13612
+ ] })
13613
+ ]
13614
+ }
13615
+ );
13616
+ }
13617
+ function PageEmbedBlock({ block, headingLevel, embedHref }) {
13618
+ return /* @__PURE__ */ jsx9(EmbedCard, { resolved: block.resolved, headingLevel, embedHref });
13619
+ }
13620
+ function ProfileEmbedBlock({
13621
+ block,
13622
+ headingLevel,
13623
+ embedHref
13624
+ }) {
13625
+ return /* @__PURE__ */ jsx9(EmbedCard, { resolved: block.resolved, headingLevel, embedHref });
13626
+ }
13627
+ var DEFAULT_RENDERERS = {
13628
+ hero: HeroBlock,
13629
+ richtext: RichtextBlock,
13630
+ faq: FaqBlock,
13631
+ stats: StatsBlock,
13632
+ testimonial: TestimonialBlock,
13633
+ cta: CtaSlotBlock,
13634
+ feature_list: FeatureListBlock,
13635
+ gallery: GalleryBlock,
13636
+ page_embed: PageEmbedBlock,
13637
+ profile_embed: ProfileEmbedBlock
13638
+ };
13639
+ var EMBED_TYPES = /* @__PURE__ */ new Set([
13640
+ "page_embed",
13641
+ "profile_embed"
13642
+ ]);
13643
+ function canonicalTypeOf(blockType) {
13644
+ if (Object.prototype.hasOwnProperty.call(ALIASES, blockType))
13645
+ return ALIASES[blockType];
13646
+ if (Object.prototype.hasOwnProperty.call(DEFAULT_RENDERERS, blockType))
13647
+ return blockType;
13648
+ return null;
13649
+ }
13650
+ var TOKEN_FOREGROUND = {
13651
+ "var(--primary)": "var(--primary-foreground)",
13652
+ "var(--secondary)": "var(--secondary-foreground)",
13653
+ "var(--accent)": "var(--accent-foreground)"
13654
+ };
13655
+ function hexLuminance(color2) {
13656
+ const match = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(color2.trim());
13657
+ if (!match) return null;
13658
+ const hex = match[1].length === 3 ? [...match[1]].map((c) => c + c).join("") : match[1];
13659
+ const [r, g, b2] = [0, 2, 4].map((i) => {
13660
+ const s2 = parseInt(hex.slice(i, i + 2), 16) / 255;
13661
+ return s2 <= 0.03928 ? s2 / 12.92 : Math.pow((s2 + 0.055) / 1.055, 2.4);
13662
+ });
13663
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b2;
13664
+ }
13665
+ function surfaceStyle(background) {
13666
+ if (!background) return void 0;
13667
+ const token = TOKEN_FOREGROUND[background];
13668
+ if (token) return { backgroundColor: background, color: token };
13669
+ const luminance = hexLuminance(background);
13670
+ if (luminance === null) return { backgroundColor: background };
13671
+ return { backgroundColor: background, color: luminance < 0.179 ? "#ffffff" : "#111827" };
13672
+ }
13673
+ function hasUsableCta(cta) {
13674
+ return !!cta && !!cta.label && !!cta.url;
13675
+ }
13676
+ function toIdFragment(value) {
13677
+ return value.replace(/[^A-Za-z0-9_-]/g, "-");
13678
+ }
13679
+ function SectionCta2({ cta }) {
13680
+ if (!hasUsableCta(cta)) return null;
13681
+ const variant = toButtonVariant(cta.variant);
13682
+ return /* @__PURE__ */ jsx9("div", { className: "pt-2", children: /* @__PURE__ */ jsx9(
13683
+ "a",
13684
+ {
13685
+ href: cta.url,
13686
+ "data-slot": "button",
13687
+ "data-variant": variant,
13688
+ "data-size": "default",
13689
+ className: cn8(buttonVariants2({ variant, size: "default" })),
13690
+ ...cta.isExternal ? { target: "_blank", rel: "noopener noreferrer" } : {},
13691
+ children: cta.label
13692
+ }
13693
+ ) });
13694
+ }
13695
+ function PageBlocks({
13696
+ blocks,
13697
+ components,
13698
+ headingLevel = 2,
13699
+ embedHref = (resolved) => `/${resolved.slug}`,
13700
+ idPrefix = "page-block",
13701
+ className,
13702
+ sectionClassName
13703
+ }) {
13704
+ if (!blocks || blocks.length === 0) return null;
13705
+ const safePrefix = `pb-${toIdFragment(idPrefix)}`;
13706
+ const sections = sortBlocksByOrder(blocks).flatMap((block) => {
13707
+ const type = canonicalTypeOf(block.blockType);
13708
+ if (type === null) return [];
13709
+ if (EMBED_TYPES.has(type) && !block.resolved) return [];
13710
+ if (type === "cta" && !components?.cta && !block.heading && !hasUsableCta(block.cta)) return [];
13711
+ const Renderer = components?.[type] ?? DEFAULT_RENDERERS[type];
13712
+ const headingId = block.heading ? `${safePrefix}-${toIdFragment(block.id)}-heading` : void 0;
13713
+ const background = block.backgroundColor;
13714
+ return [
13715
+ /* @__PURE__ */ jsxs7(
13716
+ "section",
13717
+ {
13718
+ "data-slot": "page-block",
13719
+ "data-block-type": type,
13720
+ "aria-labelledby": headingId,
13721
+ style: surfaceStyle(background),
13722
+ className: cn8("space-y-6", background && "rounded-xl px-6 py-10", sectionClassName),
13723
+ children: [
13724
+ block.heading && /* @__PURE__ */ jsx9(Heading, { level: headingLevel, className: "text-2xl font-bold tracking-tight", children: /* @__PURE__ */ jsx9("span", { id: headingId, children: block.heading }) }),
13725
+ /* @__PURE__ */ jsx9(
13726
+ Renderer,
13727
+ {
13728
+ block,
13729
+ headingLevel: block.heading ? nextHeadingLevel(headingLevel) : headingLevel,
13730
+ embedHref
13731
+ }
13732
+ ),
13733
+ /* @__PURE__ */ jsx9(SectionCta2, { cta: block.cta })
13734
+ ]
13735
+ },
13736
+ block.id
13737
+ )
13738
+ ];
13739
+ });
13740
+ if (sections.length === 0) return null;
13741
+ return /* @__PURE__ */ jsx9("div", { className: cn8("space-y-12", className), "data-slot": "page-blocks", children: sections });
13742
+ }
13743
+
13744
+ // src/components/shop-filters.tsx
13745
+ import { cn as cn9 } from "@reblu/site-ui/utils";
13746
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
13427
13747
  var DEFAULT_SHOP_PRICE_BANDS = [
13428
13748
  { max: 2500 },
13429
13749
  { min: 2500, max: 5e3 },
@@ -13467,7 +13787,7 @@ function priceBandLabel(band, t, currencyCode, locale) {
13467
13787
  return "";
13468
13788
  }
13469
13789
  function OptionLink({ href, active, label, onActivate }) {
13470
- return /* @__PURE__ */ jsx7(
13790
+ return /* @__PURE__ */ jsx10(
13471
13791
  "a",
13472
13792
  {
13473
13793
  href,
@@ -13476,7 +13796,7 @@ function OptionLink({ href, active, label, onActivate }) {
13476
13796
  event.preventDefault();
13477
13797
  onActivate();
13478
13798
  } : void 0,
13479
- className: cn7(
13799
+ className: cn9(
13480
13800
  "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",
13481
13801
  active ? "border-transparent bg-primary text-primary-foreground" : "border-border text-muted-foreground hover:bg-muted hover:text-foreground"
13482
13802
  ),
@@ -13485,9 +13805,9 @@ function OptionLink({ href, active, label, onActivate }) {
13485
13805
  );
13486
13806
  }
13487
13807
  function FilterFieldset({ legend, children: children2 }) {
13488
- return /* @__PURE__ */ jsxs6("fieldset", { className: "space-y-2", children: [
13489
- /* @__PURE__ */ jsx7("legend", { className: "text-sm font-medium text-foreground", children: legend }),
13490
- /* @__PURE__ */ jsx7("div", { className: "flex flex-wrap gap-2", children: children2 })
13808
+ return /* @__PURE__ */ jsxs8("fieldset", { className: "space-y-2", children: [
13809
+ /* @__PURE__ */ jsx10("legend", { className: "text-sm font-medium text-foreground", children: legend }),
13810
+ /* @__PURE__ */ jsx10("div", { className: "flex flex-wrap gap-2", children: children2 })
13491
13811
  ] });
13492
13812
  }
13493
13813
  function ShopFilters({
@@ -13510,11 +13830,11 @@ function ShopFilters({
13510
13830
  if (!shouldRenderShopFilters(facets, active)) {
13511
13831
  return null;
13512
13832
  }
13513
- return /* @__PURE__ */ jsxs6("div", { className: cn7("space-y-6", className), "data-slot": "shop-filters", children: [
13833
+ return /* @__PURE__ */ jsxs8("div", { className: cn9("space-y-6", className), "data-slot": "shop-filters", children: [
13514
13834
  visibleTaxonomies.map((axis) => {
13515
13835
  const activeSlug = active.taxonomy?.[axis.key];
13516
- return /* @__PURE__ */ jsxs6(FilterFieldset, { legend: axis.label, children: [
13517
- /* @__PURE__ */ jsx7(
13836
+ return /* @__PURE__ */ jsxs8(FilterFieldset, { legend: axis.label, children: [
13837
+ /* @__PURE__ */ jsx10(
13518
13838
  OptionLink,
13519
13839
  {
13520
13840
  href: hrefs.taxonomy(axis.key, void 0),
@@ -13529,7 +13849,7 @@ function ShopFilters({
13529
13849
  ),
13530
13850
  axis.terms.map((term) => {
13531
13851
  const isActive = activeSlug === term.slug;
13532
- return /* @__PURE__ */ jsx7(
13852
+ return /* @__PURE__ */ jsx10(
13533
13853
  OptionLink,
13534
13854
  {
13535
13855
  href: hrefs.taxonomy(axis.key, isActive ? void 0 : term.slug),
@@ -13549,9 +13869,9 @@ function ShopFilters({
13549
13869
  }),
13550
13870
  visibleAttributes.map((attr) => {
13551
13871
  const activeValues = toValueArray(active.attr?.[attr.key]);
13552
- return /* @__PURE__ */ jsx7(FilterFieldset, { legend: attr.label, children: attr.options.map((opt) => {
13872
+ return /* @__PURE__ */ jsx10(FilterFieldset, { legend: attr.label, children: attr.options.map((opt) => {
13553
13873
  const isActive = activeValues.includes(opt.value);
13554
- return /* @__PURE__ */ jsx7(
13874
+ return /* @__PURE__ */ jsx10(
13555
13875
  OptionLink,
13556
13876
  {
13557
13877
  href: hrefs.attr(attr.key, opt.value),
@@ -13569,11 +13889,11 @@ function ShopFilters({
13569
13889
  );
13570
13890
  }) }, attr.key);
13571
13891
  }),
13572
- showPriceGroup && /* @__PURE__ */ jsx7(FilterFieldset, { legend: t.price, children: priceBands.map((band, i) => {
13892
+ showPriceGroup && /* @__PURE__ */ jsx10(FilterFieldset, { legend: t.price, children: priceBands.map((band, i) => {
13573
13893
  const isActive = active.priceMin === band.min && active.priceMax === band.max;
13574
13894
  const nextMin = isActive ? void 0 : band.min;
13575
13895
  const nextMax = isActive ? void 0 : band.max;
13576
- return /* @__PURE__ */ jsx7(
13896
+ return /* @__PURE__ */ jsx10(
13577
13897
  OptionLink,
13578
13898
  {
13579
13899
  href: hrefs.price(nextMin, nextMax),
@@ -13584,7 +13904,7 @@ function ShopFilters({
13584
13904
  i
13585
13905
  );
13586
13906
  }) }),
13587
- hasOnSale && /* @__PURE__ */ jsx7(
13907
+ hasOnSale && /* @__PURE__ */ jsx10(
13588
13908
  OptionLink,
13589
13909
  {
13590
13910
  href: hrefs.onSale(!active.onSale),
@@ -13593,7 +13913,7 @@ function ShopFilters({
13593
13913
  onActivate: onChange ? () => onChange({ onSale: !active.onSale }) : void 0
13594
13914
  }
13595
13915
  ),
13596
- /* @__PURE__ */ jsx7(
13916
+ /* @__PURE__ */ jsx10(
13597
13917
  "a",
13598
13918
  {
13599
13919
  href: hrefs.clearAll(),
@@ -13609,8 +13929,8 @@ function ShopFilters({
13609
13929
  }
13610
13930
 
13611
13931
  // src/components/cart-line-list.tsx
13612
- import { cn as cn8 } from "@reblu/site-ui/utils";
13613
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
13932
+ import { cn as cn10 } from "@reblu/site-ui/utils";
13933
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
13614
13934
  var DEFAULT_LABELS2 = {
13615
13935
  quantityLabel: "Cantidad",
13616
13936
  decrease: "Reducir cantidad",
@@ -13635,9 +13955,9 @@ function CartLineList({
13635
13955
  }) {
13636
13956
  const t = { ...DEFAULT_LABELS2, ...labels };
13637
13957
  const noticeContent = notice === true ? t.cancelledNotice : notice;
13638
- return /* @__PURE__ */ jsxs7("div", { className: cn8("space-y-4", className), "data-slot": "cart-line-list", children: [
13639
- /* @__PURE__ */ jsx8("div", { "aria-live": "polite", className: "sr-only", children: liveMessage }),
13640
- noticeContent != null && noticeContent !== false && /* @__PURE__ */ jsx8(
13958
+ return /* @__PURE__ */ jsxs9("div", { className: cn10("space-y-4", className), "data-slot": "cart-line-list", children: [
13959
+ /* @__PURE__ */ jsx11("div", { "aria-live": "polite", className: "sr-only", children: liveMessage }),
13960
+ noticeContent != null && noticeContent !== false && /* @__PURE__ */ jsx11(
13641
13961
  "div",
13642
13962
  {
13643
13963
  role: "status",
@@ -13646,32 +13966,32 @@ function CartLineList({
13646
13966
  children: noticeContent
13647
13967
  }
13648
13968
  ),
13649
- /* @__PURE__ */ jsx8("ul", { className: "space-y-4", children: items.map((item) => {
13969
+ /* @__PURE__ */ jsx11("ul", { className: "space-y-4", children: items.map((item) => {
13650
13970
  const maxQty = item.maxStock ?? Infinity;
13651
13971
  const atMax = item.quantity >= maxQty;
13652
13972
  const atMin = item.quantity <= 1;
13653
- return /* @__PURE__ */ jsxs7(
13973
+ return /* @__PURE__ */ jsxs9(
13654
13974
  "li",
13655
13975
  {
13656
13976
  className: "flex gap-4 rounded-xl border border-border bg-card p-4",
13657
13977
  children: [
13658
- /* @__PURE__ */ jsx8("div", { className: "h-20 w-20 flex-shrink-0 overflow-hidden rounded-lg bg-muted", children: item.imageUrl ? /* @__PURE__ */ jsx8("img", { src: item.imageUrl, alt: item.name, className: "h-full w-full object-cover" }) : null }),
13659
- /* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
13660
- /* @__PURE__ */ jsx8("p", { className: "truncate text-sm font-semibold leading-tight", children: item.name }),
13661
- item.variantName && /* @__PURE__ */ jsx8("p", { className: "mt-0.5 text-xs text-muted-foreground", children: item.variantName }),
13662
- /* @__PURE__ */ jsxs7("p", { className: "mt-1 text-sm text-muted-foreground", children: [
13978
+ /* @__PURE__ */ jsx11("div", { className: "h-20 w-20 flex-shrink-0 overflow-hidden rounded-lg bg-muted", children: item.imageUrl ? /* @__PURE__ */ jsx11("img", { src: item.imageUrl, alt: item.name, className: "h-full w-full object-cover" }) : null }),
13979
+ /* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
13980
+ /* @__PURE__ */ jsx11("p", { className: "truncate text-sm font-semibold leading-tight", children: item.name }),
13981
+ item.variantName && /* @__PURE__ */ jsx11("p", { className: "mt-0.5 text-xs text-muted-foreground", children: item.variantName }),
13982
+ /* @__PURE__ */ jsxs9("p", { className: "mt-1 text-sm text-muted-foreground", children: [
13663
13983
  formatPrice(item.unitPrice, currencyCode, locale),
13664
13984
  " ",
13665
13985
  t.unitPriceSuffix
13666
13986
  ] }),
13667
- /* @__PURE__ */ jsxs7(
13987
+ /* @__PURE__ */ jsxs9(
13668
13988
  "div",
13669
13989
  {
13670
13990
  role: "group",
13671
13991
  "aria-label": t.quantityLabel,
13672
13992
  className: "mt-3 flex items-center gap-3",
13673
13993
  children: [
13674
- /* @__PURE__ */ jsx8(
13994
+ /* @__PURE__ */ jsx11(
13675
13995
  "button",
13676
13996
  {
13677
13997
  type: "button",
@@ -13682,8 +14002,8 @@ function CartLineList({
13682
14002
  children: "\u2212"
13683
14003
  }
13684
14004
  ),
13685
- /* @__PURE__ */ jsx8("span", { className: "w-8 text-center text-sm font-semibold tabular-nums", children: item.quantity }),
13686
- /* @__PURE__ */ jsx8(
14005
+ /* @__PURE__ */ jsx11("span", { className: "w-8 text-center text-sm font-semibold tabular-nums", children: item.quantity }),
14006
+ /* @__PURE__ */ jsx11(
13687
14007
  "button",
13688
14008
  {
13689
14009
  type: "button",
@@ -13694,7 +14014,7 @@ function CartLineList({
13694
14014
  children: "+"
13695
14015
  }
13696
14016
  ),
13697
- onRemove && /* @__PURE__ */ jsx8(
14017
+ onRemove && /* @__PURE__ */ jsx11(
13698
14018
  "button",
13699
14019
  {
13700
14020
  type: "button",
@@ -13708,7 +14028,7 @@ function CartLineList({
13708
14028
  }
13709
14029
  )
13710
14030
  ] }),
13711
- /* @__PURE__ */ jsx8("div", { className: "flex-shrink-0 text-right", children: /* @__PURE__ */ jsx8("p", { className: "text-base font-bold", children: formatPrice(item.unitPrice * item.quantity, currencyCode, locale) }) })
14031
+ /* @__PURE__ */ jsx11("div", { className: "flex-shrink-0 text-right", children: /* @__PURE__ */ jsx11("p", { className: "text-base font-bold", children: formatPrice(item.unitPrice * item.quantity, currencyCode, locale) }) })
13712
14032
  ]
13713
14033
  },
13714
14034
  lineKey(item.productId, item.variantId)
@@ -13718,8 +14038,8 @@ function CartLineList({
13718
14038
  }
13719
14039
 
13720
14040
  // src/components/cart-summary.tsx
13721
- import { cn as cn9 } from "@reblu/site-ui/utils";
13722
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
14041
+ import { cn as cn11 } from "@reblu/site-ui/utils";
14042
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
13723
14043
  var DEFAULT_LABELS3 = {
13724
14044
  subtotal: "Subtotal",
13725
14045
  discountPrefix: "Descuento",
@@ -13746,40 +14066,40 @@ function CartSummary({
13746
14066
  const hasDiscount = Boolean(discount && discount > 0);
13747
14067
  const noticeContent = notice === true ? t.cancelledNotice : notice;
13748
14068
  const hasNotice = noticeContent != null && noticeContent !== false;
13749
- const breakdown = /* @__PURE__ */ jsxs8(
14069
+ const breakdown = /* @__PURE__ */ jsxs10(
13750
14070
  "dl",
13751
14071
  {
13752
- className: cn9("space-y-2 text-sm", !hasNotice && className),
14072
+ className: cn11("space-y-2 text-sm", !hasNotice && className),
13753
14073
  "data-slot": "cart-summary",
13754
14074
  children: [
13755
- /* @__PURE__ */ jsxs8("div", { className: "flex justify-between text-muted-foreground", children: [
13756
- /* @__PURE__ */ jsx9("dt", { children: t.subtotal }),
13757
- /* @__PURE__ */ jsx9("dd", { children: formatPrice(subtotal, currencyCode, locale) })
14075
+ /* @__PURE__ */ jsxs10("div", { className: "flex justify-between text-muted-foreground", children: [
14076
+ /* @__PURE__ */ jsx12("dt", { children: t.subtotal }),
14077
+ /* @__PURE__ */ jsx12("dd", { children: formatPrice(subtotal, currencyCode, locale) })
13758
14078
  ] }),
13759
- hasDiscount && /* @__PURE__ */ jsxs8("div", { className: "flex justify-between text-green-600 dark:text-green-400", children: [
13760
- /* @__PURE__ */ jsxs8("dt", { children: [
14079
+ hasDiscount && /* @__PURE__ */ jsxs10("div", { className: "flex justify-between text-green-600 dark:text-green-400", children: [
14080
+ /* @__PURE__ */ jsxs10("dt", { children: [
13761
14081
  t.discountPrefix,
13762
14082
  discountCode ? ` (${discountCode})` : ""
13763
14083
  ] }),
13764
- /* @__PURE__ */ jsxs8("dd", { children: [
14084
+ /* @__PURE__ */ jsxs10("dd", { children: [
13765
14085
  "-",
13766
14086
  formatPrice(discount, currencyCode, locale)
13767
14087
  ] })
13768
14088
  ] }),
13769
- shippingEnabled && /* @__PURE__ */ jsxs8("div", { className: "flex justify-between text-muted-foreground", children: [
13770
- /* @__PURE__ */ jsx9("dt", { children: t.shipping }),
13771
- /* @__PURE__ */ jsx9("dd", { children: shipping == null || !Number.isFinite(shipping) ? t.shippingCalculated : shipping === 0 ? t.freeShipping : formatPrice(shipping, currencyCode, locale) })
14089
+ shippingEnabled && /* @__PURE__ */ jsxs10("div", { className: "flex justify-between text-muted-foreground", children: [
14090
+ /* @__PURE__ */ jsx12("dt", { children: t.shipping }),
14091
+ /* @__PURE__ */ jsx12("dd", { children: shipping == null || !Number.isFinite(shipping) ? t.shippingCalculated : shipping === 0 ? t.freeShipping : formatPrice(shipping, currencyCode, locale) })
13772
14092
  ] }),
13773
- /* @__PURE__ */ jsxs8("div", { className: "flex justify-between border-t border-border pt-2 text-base font-bold", children: [
13774
- /* @__PURE__ */ jsx9("dt", { children: t.total }),
13775
- /* @__PURE__ */ jsx9("dd", { children: formatPrice(total, currencyCode, locale) })
14093
+ /* @__PURE__ */ jsxs10("div", { className: "flex justify-between border-t border-border pt-2 text-base font-bold", children: [
14094
+ /* @__PURE__ */ jsx12("dt", { children: t.total }),
14095
+ /* @__PURE__ */ jsx12("dd", { children: formatPrice(total, currencyCode, locale) })
13776
14096
  ] })
13777
14097
  ]
13778
14098
  }
13779
14099
  );
13780
14100
  if (!hasNotice) return breakdown;
13781
- return /* @__PURE__ */ jsxs8("div", { className: cn9("space-y-3", className), "data-slot": "cart-summary-wrapper", children: [
13782
- /* @__PURE__ */ jsx9(
14101
+ return /* @__PURE__ */ jsxs10("div", { className: cn11("space-y-3", className), "data-slot": "cart-summary-wrapper", children: [
14102
+ /* @__PURE__ */ jsx12(
13783
14103
  "div",
13784
14104
  {
13785
14105
  role: "status",
@@ -13793,8 +14113,8 @@ function CartSummary({
13793
14113
  }
13794
14114
 
13795
14115
  // src/components/added-to-cart-toast.tsx
13796
- import { cn as cn10 } from "@reblu/site-ui/utils";
13797
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
14116
+ import { cn as cn12 } from "@reblu/site-ui/utils";
14117
+ import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
13798
14118
  var DEFAULT_LABELS4 = {
13799
14119
  success: "A\xF1adido al carrito",
13800
14120
  error: "No se pudo a\xF1adir al carrito",
@@ -13814,12 +14134,12 @@ function AddedToCartToast({
13814
14134
  const message = status === "error" ? t.error : status === "outOfStock" ? t.outOfStock : t.success;
13815
14135
  const hasThumbnail = Boolean(imageUrl && imageUrl.trim().length > 0);
13816
14136
  const variant = status === "success" ? "success" : "error";
13817
- return /* @__PURE__ */ jsxs9(
14137
+ return /* @__PURE__ */ jsxs11(
13818
14138
  "div",
13819
14139
  {
13820
14140
  "data-slot": "added-to-cart-toast",
13821
14141
  "data-variant": variant,
13822
- className: cn10(
14142
+ className: cn12(
13823
14143
  "flex items-center gap-3 rounded-xl border border-border bg-card p-3 text-sm shadow-lg",
13824
14144
  variant === "success" && "border-green-600/30 dark:border-green-400/30",
13825
14145
  variant === "error" && "border-destructive/30",
@@ -13827,20 +14147,20 @@ function AddedToCartToast({
13827
14147
  ),
13828
14148
  children: [
13829
14149
  hasThumbnail && // eslint-disable-next-line @next/next/no-img-element -- toast content, not a Next <Image> layout context
13830
- /* @__PURE__ */ jsx10("img", { src: imageUrl, alt: productName, className: "h-10 w-10 flex-shrink-0 rounded-lg object-cover" }),
13831
- /* @__PURE__ */ jsxs9("div", { className: "min-w-0 flex-1", children: [
13832
- /* @__PURE__ */ jsx10("p", { className: "truncate font-semibold text-foreground", children: productName }),
13833
- /* @__PURE__ */ jsx10("p", { className: "truncate text-muted-foreground", children: quantity && quantity > 1 ? `${message} \xB7 x${quantity}` : message })
14150
+ /* @__PURE__ */ jsx13("img", { src: imageUrl, alt: productName, className: "h-10 w-10 flex-shrink-0 rounded-lg object-cover" }),
14151
+ /* @__PURE__ */ jsxs11("div", { className: "min-w-0 flex-1", children: [
14152
+ /* @__PURE__ */ jsx13("p", { className: "truncate font-semibold text-foreground", children: productName }),
14153
+ /* @__PURE__ */ jsx13("p", { className: "truncate text-muted-foreground", children: quantity && quantity > 1 ? `${message} \xB7 x${quantity}` : message })
13834
14154
  ] }),
13835
- /* @__PURE__ */ jsx10("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx10("a", { href: cartHref, className: "text-sm font-semibold text-primary underline-offset-2 hover:underline", children: t.viewCart }) })
14155
+ /* @__PURE__ */ jsx13("div", { className: "flex-shrink-0", children: /* @__PURE__ */ jsx13("a", { href: cartHref, className: "text-sm font-semibold text-primary underline-offset-2 hover:underline", children: t.viewCart }) })
13836
14156
  ]
13837
14157
  }
13838
14158
  );
13839
14159
  }
13840
14160
 
13841
14161
  // src/components/checkout-login-prompt.tsx
13842
- import { cn as cn11 } from "@reblu/site-ui/utils";
13843
- import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
14162
+ import { cn as cn13 } from "@reblu/site-ui/utils";
14163
+ import { Fragment as Fragment3, jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
13844
14164
  var DEFAULT_LABELS5 = {
13845
14165
  title: "Identificaci\xF3n",
13846
14166
  description: "Introduce tu email para agilizar el proceso o contin\xFAa como invitado.",
@@ -13867,26 +14187,26 @@ function CheckoutLoginPrompt({
13867
14187
  if (!open) return null;
13868
14188
  const t = { ...DEFAULT_LABELS5, ...labels };
13869
14189
  const isValidEmail = EMAIL_PATTERN.test(email.trim());
13870
- return /* @__PURE__ */ jsxs10(Fragment3, { children: [
13871
- /* @__PURE__ */ jsx11("div", { className: "fixed inset-0 z-50 bg-black/50", onClick: onClose, "aria-hidden": "true" }),
13872
- /* @__PURE__ */ jsxs10(
14190
+ return /* @__PURE__ */ jsxs12(Fragment3, { children: [
14191
+ /* @__PURE__ */ jsx14("div", { className: "fixed inset-0 z-50 bg-black/50", onClick: onClose, "aria-hidden": "true" }),
14192
+ /* @__PURE__ */ jsxs12(
13873
14193
  "div",
13874
14194
  {
13875
14195
  role: "dialog",
13876
14196
  "aria-modal": "true",
13877
14197
  "aria-labelledby": "checkout-login-prompt-title",
13878
14198
  "data-slot": "checkout-login-prompt",
13879
- className: cn11(
14199
+ className: cn13(
13880
14200
  "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",
13881
14201
  className
13882
14202
  ),
13883
14203
  children: [
13884
- /* @__PURE__ */ jsxs10("div", { className: "flex items-start justify-between gap-3", children: [
13885
- /* @__PURE__ */ jsxs10("div", { children: [
13886
- /* @__PURE__ */ jsx11("h2", { id: "checkout-login-prompt-title", className: "text-xl font-bold", children: t.title }),
13887
- /* @__PURE__ */ jsx11("p", { className: "mt-1 text-sm text-muted-foreground", children: t.description })
14204
+ /* @__PURE__ */ jsxs12("div", { className: "flex items-start justify-between gap-3", children: [
14205
+ /* @__PURE__ */ jsxs12("div", { children: [
14206
+ /* @__PURE__ */ jsx14("h2", { id: "checkout-login-prompt-title", className: "text-xl font-bold", children: t.title }),
14207
+ /* @__PURE__ */ jsx14("p", { className: "mt-1 text-sm text-muted-foreground", children: t.description })
13888
14208
  ] }),
13889
- /* @__PURE__ */ jsx11(
14209
+ /* @__PURE__ */ jsx14(
13890
14210
  "button",
13891
14211
  {
13892
14212
  type: "button",
@@ -13897,9 +14217,9 @@ function CheckoutLoginPrompt({
13897
14217
  }
13898
14218
  )
13899
14219
  ] }),
13900
- /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
13901
- /* @__PURE__ */ jsx11("label", { htmlFor: "checkout-login-prompt-email", className: "text-sm font-medium", children: t.emailLabel }),
13902
- /* @__PURE__ */ jsx11(
14220
+ /* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
14221
+ /* @__PURE__ */ jsx14("label", { htmlFor: "checkout-login-prompt-email", className: "text-sm font-medium", children: t.emailLabel }),
14222
+ /* @__PURE__ */ jsx14(
13903
14223
  "input",
13904
14224
  {
13905
14225
  id: "checkout-login-prompt-email",
@@ -13908,29 +14228,29 @@ function CheckoutLoginPrompt({
13908
14228
  value: email,
13909
14229
  onChange: (e) => onEmailChange(e.target.value),
13910
14230
  placeholder: t.emailPlaceholder,
13911
- className: cn11(
14231
+ className: cn13(
13912
14232
  "w-full rounded-lg border bg-background px-3 py-2 text-sm transition focus:outline-none focus:ring-2 focus:ring-primary/20",
13913
14233
  error ? "border-destructive" : "border-border focus:border-primary"
13914
14234
  )
13915
14235
  }
13916
14236
  ),
13917
- error && /* @__PURE__ */ jsx11("p", { className: "text-xs text-destructive", children: error })
14237
+ error && /* @__PURE__ */ jsx14("p", { className: "text-xs text-destructive", children: error })
13918
14238
  ] }),
13919
- /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
13920
- /* @__PURE__ */ jsx11(
14239
+ /* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
14240
+ /* @__PURE__ */ jsx14(
13921
14241
  "button",
13922
14242
  {
13923
14243
  type: "button",
13924
14244
  onClick: onSubmitEmail,
13925
14245
  disabled: checking || !isValidEmail,
13926
- className: cn11(
14246
+ className: cn13(
13927
14247
  "flex w-full items-center justify-center gap-2 rounded-xl px-4 py-2.5 text-sm font-semibold transition-all",
13928
14248
  checking || !isValidEmail ? "cursor-not-allowed bg-muted text-muted-foreground" : "bg-primary text-primary-foreground hover:bg-primary/90"
13929
14249
  ),
13930
14250
  children: checking ? t.checking : t.continueWithEmail
13931
14251
  }
13932
14252
  ),
13933
- /* @__PURE__ */ jsx11(
14253
+ /* @__PURE__ */ jsx14(
13934
14254
  "button",
13935
14255
  {
13936
14256
  type: "button",
@@ -13947,8 +14267,9 @@ function CheckoutLoginPrompt({
13947
14267
  }
13948
14268
 
13949
14269
  // src/components/checkout-form.tsx
13950
- import { cn as cn12 } from "@reblu/site-ui/utils";
13951
- import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
14270
+ import { cn as cn14 } from "@reblu/site-ui/utils";
14271
+ import { PhoneInput } from "@reblu/site-ui/phone-input";
14272
+ import { Fragment as Fragment4, jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
13952
14273
  var DEFAULT_LABELS6 = {
13953
14274
  contactTitle: "Datos de contacto",
13954
14275
  nameLabel: "Nombre completo",
@@ -13969,6 +14290,8 @@ function CheckoutForm({
13969
14290
  contact,
13970
14291
  onContactChange,
13971
14292
  contactErrors,
14293
+ phoneRegion,
14294
+ checkoutError,
13972
14295
  discountCode,
13973
14296
  onDiscountCodeChange,
13974
14297
  onApplyDiscount,
@@ -13987,6 +14310,10 @@ function CheckoutForm({
13987
14310
  className
13988
14311
  }) {
13989
14312
  const t = { ...DEFAULT_LABELS6, ...labels };
14313
+ const details = checkoutError?.details;
14314
+ 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;
14315
+ const phoneError = contactErrors?.phone ?? (rejectedPhone ? checkoutError.error : void 0);
14316
+ const generalError = checkoutError && !rejectedPhone ? getShopErrorMessage(typeof checkoutError.code === "string" ? checkoutError.code : void 0) : null;
13990
14317
  function patchContact(patch3) {
13991
14318
  onContactChange({ ...contact, ...patch3 });
13992
14319
  }
@@ -13996,22 +14323,22 @@ function CheckoutForm({
13996
14323
  event.preventDefault();
13997
14324
  if (discountCode.trim() && !discountApplying) onApplyDiscount();
13998
14325
  }
13999
- return /* @__PURE__ */ jsxs11(Fragment4, { children: [
14326
+ return /* @__PURE__ */ jsxs13(Fragment4, { children: [
14000
14327
  loginPrompt,
14001
- /* @__PURE__ */ jsxs11(
14328
+ /* @__PURE__ */ jsxs13(
14002
14329
  "form",
14003
14330
  {
14004
14331
  "data-testid": "checkout-form",
14005
14332
  onSubmit,
14006
- className: cn12("space-y-8", className),
14333
+ className: cn14("space-y-8", className),
14007
14334
  "data-slot": "checkout-form",
14008
14335
  children: [
14009
- /* @__PURE__ */ jsxs11("section", { className: "space-y-4", children: [
14010
- /* @__PURE__ */ jsx12("h2", { className: "border-b border-border pb-2 text-lg font-semibold", children: t.contactTitle }),
14011
- /* @__PURE__ */ jsxs11("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
14012
- /* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
14013
- /* @__PURE__ */ jsx12("label", { htmlFor: "checkout-form-name", className: "text-sm font-medium", children: t.nameLabel }),
14014
- /* @__PURE__ */ jsx12(
14336
+ /* @__PURE__ */ jsxs13("section", { className: "space-y-4", children: [
14337
+ /* @__PURE__ */ jsx15("h2", { className: "border-b border-border pb-2 text-lg font-semibold", children: t.contactTitle }),
14338
+ /* @__PURE__ */ jsxs13("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
14339
+ /* @__PURE__ */ jsxs13("div", { className: "space-y-1", children: [
14340
+ /* @__PURE__ */ jsx15("label", { htmlFor: "checkout-form-name", className: "text-sm font-medium", children: t.nameLabel }),
14341
+ /* @__PURE__ */ jsx15(
14015
14342
  "input",
14016
14343
  {
14017
14344
  id: "checkout-form-name",
@@ -14020,17 +14347,17 @@ function CheckoutForm({
14020
14347
  value: contact.name,
14021
14348
  onChange: (e) => patchContact({ name: e.target.value }),
14022
14349
  placeholder: t.namePlaceholder,
14023
- className: cn12(
14350
+ className: cn14(
14024
14351
  "w-full rounded-lg border bg-background px-3 py-2 text-sm transition focus:outline-none focus:ring-2 focus:ring-primary/20",
14025
14352
  contactErrors?.name ? "border-destructive" : "border-border focus:border-primary"
14026
14353
  )
14027
14354
  }
14028
14355
  ),
14029
- contactErrors?.name && /* @__PURE__ */ jsx12("p", { className: "text-xs text-destructive", children: contactErrors.name })
14356
+ contactErrors?.name && /* @__PURE__ */ jsx15("p", { className: "text-xs text-destructive", children: contactErrors.name })
14030
14357
  ] }),
14031
- /* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
14032
- /* @__PURE__ */ jsx12("label", { htmlFor: "checkout-form-email", className: "text-sm font-medium", children: t.emailLabel }),
14033
- /* @__PURE__ */ jsx12(
14358
+ /* @__PURE__ */ jsxs13("div", { className: "space-y-1", children: [
14359
+ /* @__PURE__ */ jsx15("label", { htmlFor: "checkout-form-email", className: "text-sm font-medium", children: t.emailLabel }),
14360
+ /* @__PURE__ */ jsx15(
14034
14361
  "input",
14035
14362
  {
14036
14363
  id: "checkout-form-email",
@@ -14039,43 +14366,37 @@ function CheckoutForm({
14039
14366
  value: contact.email,
14040
14367
  onChange: (e) => patchContact({ email: e.target.value }),
14041
14368
  placeholder: t.emailPlaceholder,
14042
- className: cn12(
14369
+ className: cn14(
14043
14370
  "w-full rounded-lg border bg-background px-3 py-2 text-sm transition focus:outline-none focus:ring-2 focus:ring-primary/20",
14044
14371
  contactErrors?.email ? "border-destructive" : "border-border focus:border-primary"
14045
14372
  )
14046
14373
  }
14047
14374
  ),
14048
- contactErrors?.email && /* @__PURE__ */ jsx12("p", { className: "text-xs text-destructive", children: contactErrors.email })
14375
+ contactErrors?.email && /* @__PURE__ */ jsx15("p", { className: "text-xs text-destructive", children: contactErrors.email })
14049
14376
  ] }),
14050
- /* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
14051
- /* @__PURE__ */ jsx12("label", { htmlFor: "checkout-form-phone", className: "text-sm font-medium", children: t.phoneLabel }),
14052
- /* @__PURE__ */ jsx12(
14053
- "input",
14054
- {
14055
- id: "checkout-form-phone",
14056
- type: "tel",
14057
- autoComplete: "tel",
14058
- value: contact.phone ?? "",
14059
- onChange: (e) => patchContact({ phone: e.target.value }),
14060
- className: cn12(
14061
- "w-full rounded-lg border bg-background px-3 py-2 text-sm transition focus:outline-none focus:ring-2 focus:ring-primary/20",
14062
- contactErrors?.phone ? "border-destructive" : "border-border focus:border-primary"
14063
- )
14064
- }
14065
- ),
14066
- contactErrors?.phone && /* @__PURE__ */ jsx12("p", { className: "text-xs text-destructive", children: contactErrors.phone })
14067
- ] })
14377
+ /* @__PURE__ */ jsx15("div", { className: "space-y-1", children: /* @__PURE__ */ jsx15(
14378
+ PhoneInput,
14379
+ {
14380
+ id: "checkout-form-phone",
14381
+ label: t.phoneLabel,
14382
+ region: phoneRegion,
14383
+ value: contact.phone ?? "",
14384
+ onChange: (phone) => patchContact({ phone }),
14385
+ error: phoneError
14386
+ }
14387
+ ) })
14068
14388
  ] })
14069
14389
  ] }),
14070
14390
  children2,
14071
- /* @__PURE__ */ jsxs11("section", { className: "space-y-3", children: [
14072
- /* @__PURE__ */ jsx12("h2", { className: "border-b border-border pb-2 text-lg font-semibold", children: t.discountTitle }),
14073
- appliedDiscount ? /* @__PURE__ */ jsxs11("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: [
14074
- /* @__PURE__ */ jsxs11("div", { className: "flex items-center gap-2 text-sm text-green-700 dark:text-green-400", children: [
14075
- /* @__PURE__ */ jsx12("span", { className: "font-semibold", children: appliedDiscount.code }),
14076
- /* @__PURE__ */ jsx12("span", { children: t.discountAppliedSuffix(formatPrice(appliedDiscount.amount, currencyCode, locale)) })
14391
+ generalError ? /* @__PURE__ */ jsx15("p", { role: "alert", className: "text-sm text-destructive", children: generalError }) : null,
14392
+ /* @__PURE__ */ jsxs13("section", { className: "space-y-3", children: [
14393
+ /* @__PURE__ */ jsx15("h2", { className: "border-b border-border pb-2 text-lg font-semibold", children: t.discountTitle }),
14394
+ appliedDiscount ? /* @__PURE__ */ jsxs13("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: [
14395
+ /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2 text-sm text-green-700 dark:text-green-400", children: [
14396
+ /* @__PURE__ */ jsx15("span", { className: "font-semibold", children: appliedDiscount.code }),
14397
+ /* @__PURE__ */ jsx15("span", { children: t.discountAppliedSuffix(formatPrice(appliedDiscount.amount, currencyCode, locale)) })
14077
14398
  ] }),
14078
- /* @__PURE__ */ jsx12(
14399
+ /* @__PURE__ */ jsx15(
14079
14400
  "button",
14080
14401
  {
14081
14402
  type: "button",
@@ -14085,9 +14406,9 @@ function CheckoutForm({
14085
14406
  children: t.removeDiscount
14086
14407
  }
14087
14408
  )
14088
- ] }) : /* @__PURE__ */ jsxs11("div", { className: "flex gap-2", children: [
14089
- /* @__PURE__ */ jsx12("label", { htmlFor: "checkout-form-discount-code", className: "sr-only", children: t.discountTitle }),
14090
- /* @__PURE__ */ jsx12(
14409
+ ] }) : /* @__PURE__ */ jsxs13("div", { className: "flex gap-2", children: [
14410
+ /* @__PURE__ */ jsx15("label", { htmlFor: "checkout-form-discount-code", className: "sr-only", children: t.discountTitle }),
14411
+ /* @__PURE__ */ jsx15(
14091
14412
  "input",
14092
14413
  {
14093
14414
  id: "checkout-form-discount-code",
@@ -14099,7 +14420,7 @@ function CheckoutForm({
14099
14420
  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"
14100
14421
  }
14101
14422
  ),
14102
- /* @__PURE__ */ jsx12(
14423
+ /* @__PURE__ */ jsx15(
14103
14424
  "button",
14104
14425
  {
14105
14426
  type: "button",
@@ -14110,14 +14431,14 @@ function CheckoutForm({
14110
14431
  }
14111
14432
  )
14112
14433
  ] }),
14113
- discountError && /* @__PURE__ */ jsx12("p", { className: "text-xs text-destructive", children: discountError })
14434
+ discountError && /* @__PURE__ */ jsx15("p", { className: "text-xs text-destructive", children: discountError })
14114
14435
  ] }),
14115
- /* @__PURE__ */ jsx12(
14436
+ /* @__PURE__ */ jsx15(
14116
14437
  "button",
14117
14438
  {
14118
14439
  type: "submit",
14119
14440
  disabled: submitting || submitDisabled,
14120
- className: cn12(
14441
+ className: cn14(
14121
14442
  "flex w-full items-center justify-center gap-2 rounded-xl px-4 py-3 font-semibold transition-all",
14122
14443
  submitting || submitDisabled ? "cursor-not-allowed bg-muted text-muted-foreground" : "bg-primary text-primary-foreground hover:bg-primary/90"
14123
14444
  ),
@@ -14131,8 +14452,8 @@ function CheckoutForm({
14131
14452
  }
14132
14453
 
14133
14454
  // src/components/order-confirmation.tsx
14134
- import { cn as cn13 } from "@reblu/site-ui/utils";
14135
- import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
14455
+ import { cn as cn15 } from "@reblu/site-ui/utils";
14456
+ import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
14136
14457
  var DEFAULT_LABELS7 = {
14137
14458
  pollingTitle: "Confirmando tu pedido\u2026",
14138
14459
  pollingDescription: "Estamos procesando el pago, un momento\u2026",
@@ -14194,48 +14515,48 @@ function OrderConfirmation({
14194
14515
  const showOrderReference = Boolean(order) && !showFullOrderSummary && (status === "refunded" || status === "partially_refunded" || status === "pending_timeout");
14195
14516
  const showSessionReference = !order && sessionId && (status === "timeout" || status === "not_found" || status === "pending_timeout");
14196
14517
  const showRecheck = (status === "pending_timeout" || status === "error") && onRecheck;
14197
- return /* @__PURE__ */ jsxs12("div", { className: cn13("space-y-6 text-center", className), "data-slot": "order-confirmation", children: [
14198
- /* @__PURE__ */ jsx13("h1", { className: "text-3xl font-bold", children: title }),
14199
- /* @__PURE__ */ jsx13("p", { className: "text-lg text-muted-foreground", children: description }),
14200
- showFullOrderSummary && order && /* @__PURE__ */ jsxs12("div", { className: "space-y-6", children: [
14201
- /* @__PURE__ */ jsxs12("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14202
- /* @__PURE__ */ jsx13("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.orderNumberLabel }),
14203
- /* @__PURE__ */ jsx13("p", { className: "font-mono text-lg font-semibold", children: order.orderNumber })
14518
+ return /* @__PURE__ */ jsxs14("div", { className: cn15("space-y-6 text-center", className), "data-slot": "order-confirmation", children: [
14519
+ /* @__PURE__ */ jsx16("h1", { className: "text-3xl font-bold", children: title }),
14520
+ /* @__PURE__ */ jsx16("p", { className: "text-lg text-muted-foreground", children: description }),
14521
+ showFullOrderSummary && order && /* @__PURE__ */ jsxs14("div", { className: "space-y-6", children: [
14522
+ /* @__PURE__ */ jsxs14("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14523
+ /* @__PURE__ */ jsx16("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.orderNumberLabel }),
14524
+ /* @__PURE__ */ jsx16("p", { className: "font-mono text-lg font-semibold", children: order.orderNumber })
14204
14525
  ] }),
14205
- /* @__PURE__ */ jsxs12("div", { className: "mx-auto max-w-sm space-y-3 rounded-xl border border-border bg-card p-5 text-left", children: [
14206
- order.items.map((item, idx) => /* @__PURE__ */ jsxs12(
14526
+ /* @__PURE__ */ jsxs14("div", { className: "mx-auto max-w-sm space-y-3 rounded-xl border border-border bg-card p-5 text-left", children: [
14527
+ order.items.map((item, idx) => /* @__PURE__ */ jsxs14(
14207
14528
  "div",
14208
14529
  {
14209
14530
  className: "flex justify-between gap-4 text-sm",
14210
14531
  children: [
14211
- /* @__PURE__ */ jsxs12("span", { className: "max-w-[60%] truncate text-muted-foreground", children: [
14532
+ /* @__PURE__ */ jsxs14("span", { className: "max-w-[60%] truncate text-muted-foreground", children: [
14212
14533
  item.product.name,
14213
14534
  item.variant ? ` (${item.variant.name})` : "",
14214
14535
  " x",
14215
14536
  item.quantity
14216
14537
  ] }),
14217
- /* @__PURE__ */ jsx13("span", { children: formatPrice(item.total, currencyCode, locale) })
14538
+ /* @__PURE__ */ jsx16("span", { children: formatPrice(item.total, currencyCode, locale) })
14218
14539
  ]
14219
14540
  },
14220
14541
  idx
14221
14542
  )),
14222
- /* @__PURE__ */ jsx13("div", { className: "space-y-1 border-t border-border pt-3 text-sm", children: /* @__PURE__ */ jsxs12("div", { className: "flex justify-between pt-1 text-base font-bold", children: [
14223
- /* @__PURE__ */ jsx13("span", { children: t.totalLabel }),
14224
- /* @__PURE__ */ jsx13("span", { children: formatPrice(order.total, currencyCode, locale) })
14543
+ /* @__PURE__ */ jsx16("div", { className: "space-y-1 border-t border-border pt-3 text-sm", children: /* @__PURE__ */ jsxs14("div", { className: "flex justify-between pt-1 text-base font-bold", children: [
14544
+ /* @__PURE__ */ jsx16("span", { children: t.totalLabel }),
14545
+ /* @__PURE__ */ jsx16("span", { children: formatPrice(order.total, currencyCode, locale) })
14225
14546
  ] }) })
14226
14547
  ] }),
14227
- /* @__PURE__ */ jsxs12("p", { className: "mx-auto max-w-sm text-sm text-muted-foreground", children: [
14548
+ /* @__PURE__ */ jsxs14("p", { className: "mx-auto max-w-sm text-sm text-muted-foreground", children: [
14228
14549
  t.confirmationEmailPrefix,
14229
14550
  " ",
14230
- /* @__PURE__ */ jsx13("span", { className: "font-medium text-foreground", children: order.customerEmail }),
14551
+ /* @__PURE__ */ jsx16("span", { className: "font-medium text-foreground", children: order.customerEmail }),
14231
14552
  "."
14232
14553
  ] })
14233
14554
  ] }),
14234
- showOrderReference && order && /* @__PURE__ */ jsxs12("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14235
- /* @__PURE__ */ jsx13("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.orderReferenceLabel }),
14236
- /* @__PURE__ */ jsx13("p", { className: "font-mono text-lg font-semibold", children: order.orderNumber })
14555
+ showOrderReference && order && /* @__PURE__ */ jsxs14("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14556
+ /* @__PURE__ */ jsx16("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.orderReferenceLabel }),
14557
+ /* @__PURE__ */ jsx16("p", { className: "font-mono text-lg font-semibold", children: order.orderNumber })
14237
14558
  ] }),
14238
- status === "failed" && cartHref && /* @__PURE__ */ jsx13(
14559
+ status === "failed" && cartHref && /* @__PURE__ */ jsx16(
14239
14560
  "a",
14240
14561
  {
14241
14562
  href: cartHref,
@@ -14243,7 +14564,7 @@ function OrderConfirmation({
14243
14564
  children: t.backToCartLabel
14244
14565
  }
14245
14566
  ),
14246
- showRecheck && /* @__PURE__ */ jsx13(
14567
+ showRecheck && /* @__PURE__ */ jsx16(
14247
14568
  "button",
14248
14569
  {
14249
14570
  type: "button",
@@ -14252,9 +14573,9 @@ function OrderConfirmation({
14252
14573
  children: t.recheckLabel
14253
14574
  }
14254
14575
  ),
14255
- showSessionReference && /* @__PURE__ */ jsxs12("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14256
- /* @__PURE__ */ jsx13("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.sessionReferenceLabel }),
14257
- /* @__PURE__ */ jsx13("p", { className: "break-all font-mono text-sm font-semibold", children: sessionId })
14576
+ showSessionReference && /* @__PURE__ */ jsxs14("div", { className: "inline-block rounded-xl bg-muted px-6 py-4", children: [
14577
+ /* @__PURE__ */ jsx16("p", { className: "mb-1 text-xs uppercase tracking-widest text-muted-foreground", children: t.sessionReferenceLabel }),
14578
+ /* @__PURE__ */ jsx16("p", { className: "break-all font-mono text-sm font-semibold", children: sessionId })
14258
14579
  ] })
14259
14580
  ] });
14260
14581
  }
@@ -14268,15 +14589,19 @@ export {
14268
14589
  DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE,
14269
14590
  DEFAULT_SHOP_ERROR_MESSAGES,
14270
14591
  DEFAULT_SHOP_PRICE_BANDS,
14592
+ FaqAccordion,
14271
14593
  MarkdownRenderer,
14272
14594
  OrderConfirmation,
14595
+ PageBlocks,
14273
14596
  ProductCard,
14274
14597
  ProfileCard,
14275
14598
  SafeHtml,
14276
14599
  ShopFilters,
14277
14600
  Specialty,
14278
14601
  Treatment,
14602
+ buildFaqPageJsonLd,
14279
14603
  buildShareUrls,
14604
+ collectFaqItems,
14280
14605
  formatPrice,
14281
14606
  getShopErrorMessage,
14282
14607
  isAllowedYouTubeHost,