@neowhale/storefront 0.2.19 → 0.2.20

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.
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var chunk7KXJLHGA_cjs = require('../chunk-7KXJLHGA.cjs');
4
- var chunkCQCCXDUS_cjs = require('../chunk-CQCCXDUS.cjs');
4
+ var chunkVAA2KKCH_cjs = require('../chunk-VAA2KKCH.cjs');
5
5
  var react = require('react');
6
6
  var navigation = require('next/navigation');
7
7
  var vanilla = require('zustand/vanilla');
@@ -1027,7 +1027,7 @@ function BehavioralTrackerComponent({ pathname }) {
1027
1027
  const baseUrl = config.proxyPath;
1028
1028
  const endpoint = `${baseUrl}/v1/stores/${config.storeId}/storefront/behavioral`;
1029
1029
  const sendBatch = async (batch) => {
1030
- await chunkCQCCXDUS_cjs.resilientSend(endpoint, batch, {
1030
+ await chunkVAA2KKCH_cjs.resilientSend(endpoint, batch, {
1031
1031
  "Content-Type": "application/json",
1032
1032
  "x-api-key": config.apiKey
1033
1033
  });
@@ -1213,7 +1213,7 @@ function FingerprintCollector() {
1213
1213
  collectFingerprint().then(async (fp) => {
1214
1214
  const baseUrl = config.proxyPath;
1215
1215
  const url = `${baseUrl}/v1/stores/${config.storeId}/storefront/fingerprints`;
1216
- await chunkCQCCXDUS_cjs.resilientSend(url, fp, {
1216
+ await chunkVAA2KKCH_cjs.resilientSend(url, fp, {
1217
1217
  "Content-Type": "application/json",
1218
1218
  "x-api-key": config.apiKey
1219
1219
  }).catch(() => {
@@ -1594,7 +1594,7 @@ function SessionRecorderComponent() {
1594
1594
  const sid = sessionId;
1595
1595
  const recorder = new SessionRecorder({
1596
1596
  sendChunk: async (events, sequence) => {
1597
- await chunkCQCCXDUS_cjs.resilientSend(url, {
1597
+ await chunkVAA2KKCH_cjs.resilientSend(url, {
1598
1598
  session_id: sid,
1599
1599
  visitor_id: visitorId,
1600
1600
  events,
@@ -1673,7 +1673,7 @@ function WhaleProvider({
1673
1673
  trackingEnabled: trackingEnabled ?? envBool("NEXT_PUBLIC_TRACKING_ENABLED") ?? true,
1674
1674
  recordingRate: recordingRate ?? envNumber("NEXT_PUBLIC_RECORDING_RATE") ?? 0.1
1675
1675
  };
1676
- const client = new chunkCQCCXDUS_cjs.WhaleClient({
1676
+ const client = new chunkVAA2KKCH_cjs.WhaleClient({
1677
1677
  storeId,
1678
1678
  apiKey,
1679
1679
  gatewayUrl: resolvedConfig.gatewayUrl,
@@ -1861,12 +1861,12 @@ function useCheckout() {
1861
1861
  setLoading(false);
1862
1862
  }
1863
1863
  }, [ctx.client, session]);
1864
- const complete = react.useCallback(async (payment) => {
1864
+ const complete = react.useCallback(async (payment, opts) => {
1865
1865
  if (!session) throw new Error("No active checkout session");
1866
1866
  setLoading(true);
1867
1867
  setError(null);
1868
1868
  try {
1869
- const order = await ctx.client.completeCheckout(session.id, payment);
1869
+ const order = await ctx.client.completeCheckout(session.id, payment, opts);
1870
1870
  setSession(null);
1871
1871
  return order;
1872
1872
  } catch (err) {
@@ -2020,7 +2020,11 @@ function useLoyalty() {
2020
2020
  await refresh();
2021
2021
  return result;
2022
2022
  }, [customer?.id, ctx.client, refresh]);
2023
- return { account, rewards, transactions, loading, error, refresh, redeemReward };
2023
+ const fetchProductsByCategory = react.useCallback(async (category, locationId, tier) => {
2024
+ const res = await ctx.client.listLoyaltyProducts({ category, location_id: locationId, tier });
2025
+ return res.data;
2026
+ }, [ctx.client]);
2027
+ return { account, rewards, transactions, loading, error, refresh, redeemReward, fetchProductsByCategory };
2024
2028
  }
2025
2029
  function useReviews(productId) {
2026
2030
  const ctx = react.useContext(WhaleContext);
@@ -2411,16 +2415,27 @@ function useReferral() {
2411
2415
  referredBy: status?.referred_by ?? null
2412
2416
  };
2413
2417
  }
2418
+ function trackClick(tracking, label, url, position) {
2419
+ if (!tracking?.gatewayUrl || !tracking?.code) return;
2420
+ const body = JSON.stringify({ label, url, position });
2421
+ if (typeof navigator !== "undefined" && navigator.sendBeacon) {
2422
+ navigator.sendBeacon(
2423
+ `${tracking.gatewayUrl}/q/${encodeURIComponent(tracking.code)}/click`,
2424
+ new Blob([body], { type: "application/json" })
2425
+ );
2426
+ }
2427
+ }
2414
2428
  function SectionRenderer({
2415
2429
  section,
2416
2430
  data,
2417
- theme
2431
+ theme,
2432
+ tracking
2418
2433
  }) {
2419
2434
  const [showCOA, setShowCOA] = react.useState(false);
2420
2435
  const el = (() => {
2421
2436
  switch (section.type) {
2422
2437
  case "hero":
2423
- return /* @__PURE__ */ jsxRuntime.jsx(HeroSection, { section, theme });
2438
+ return /* @__PURE__ */ jsxRuntime.jsx(HeroSection, { section, theme, tracking });
2424
2439
  case "text":
2425
2440
  return /* @__PURE__ */ jsxRuntime.jsx(TextSection, { section, theme });
2426
2441
  case "image":
@@ -2430,15 +2445,17 @@ function SectionRenderer({
2430
2445
  case "gallery":
2431
2446
  return /* @__PURE__ */ jsxRuntime.jsx(GallerySection, { section, theme });
2432
2447
  case "cta":
2433
- return /* @__PURE__ */ jsxRuntime.jsx(CTASection, { section, theme });
2448
+ return /* @__PURE__ */ jsxRuntime.jsx(CTASection, { section, theme, tracking });
2434
2449
  case "stats":
2435
2450
  return /* @__PURE__ */ jsxRuntime.jsx(StatsSection, { section, theme });
2436
2451
  case "product_card":
2437
- return /* @__PURE__ */ jsxRuntime.jsx(ProductCardSection, { section, data, theme });
2452
+ return /* @__PURE__ */ jsxRuntime.jsx(ProductCardSection, { section, data, theme, tracking });
2438
2453
  case "coa_viewer":
2439
- return /* @__PURE__ */ jsxRuntime.jsx(COAViewerSection, { section, data, theme, onShowCOA: () => setShowCOA(true) });
2454
+ return /* @__PURE__ */ jsxRuntime.jsx(COAViewerSection, { section, data, theme, onShowCOA: () => setShowCOA(true), tracking });
2440
2455
  case "social_links":
2441
2456
  return /* @__PURE__ */ jsxRuntime.jsx(SocialLinksSection, { section, theme });
2457
+ case "lead_capture":
2458
+ return /* @__PURE__ */ jsxRuntime.jsx(LeadCaptureSection, { section, data, theme });
2442
2459
  case "divider":
2443
2460
  return /* @__PURE__ */ jsxRuntime.jsx(DividerSection, { theme });
2444
2461
  default:
@@ -2450,7 +2467,7 @@ function SectionRenderer({
2450
2467
  showCOA && data?.coa && /* @__PURE__ */ jsxRuntime.jsx(COAModal, { coa: data.coa, theme, onClose: () => setShowCOA(false) })
2451
2468
  ] });
2452
2469
  }
2453
- function HeroSection({ section, theme }) {
2470
+ function HeroSection({ section, theme, tracking }) {
2454
2471
  const { title, subtitle, background_image, cta_text, cta_url } = section.content;
2455
2472
  return /* @__PURE__ */ jsxRuntime.jsxs(
2456
2473
  "div",
@@ -2492,6 +2509,7 @@ function HeroSection({ section, theme }) {
2492
2509
  "a",
2493
2510
  {
2494
2511
  href: cta_url,
2512
+ onClick: () => trackClick(tracking, cta_text, cta_url),
2495
2513
  style: {
2496
2514
  display: "inline-block",
2497
2515
  padding: "0.875rem 2rem",
@@ -2577,7 +2595,7 @@ function GallerySection({ section, theme }) {
2577
2595
  }
2578
2596
  ) }, i)) }) });
2579
2597
  }
2580
- function CTASection({ section, theme }) {
2598
+ function CTASection({ section, theme, tracking }) {
2581
2599
  const { buttons } = section.content;
2582
2600
  if (!buttons || buttons.length === 0) return null;
2583
2601
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "2rem 1.5rem", maxWidth: 480, margin: "0 auto", display: "flex", flexDirection: "column", gap: "0.75rem" }, children: buttons.map((btn, i) => {
@@ -2586,6 +2604,7 @@ function CTASection({ section, theme }) {
2586
2604
  "a",
2587
2605
  {
2588
2606
  href: btn.url,
2607
+ onClick: () => trackClick(tracking, btn.text, btn.url, i),
2589
2608
  style: {
2590
2609
  display: "block",
2591
2610
  width: "100%",
@@ -2657,7 +2676,7 @@ function StatsSection({ section, theme }) {
2657
2676
  }, children: stat.label })
2658
2677
  ] }, i)) }) });
2659
2678
  }
2660
- function ProductCardSection({ section, data, theme }) {
2679
+ function ProductCardSection({ section, data, theme, tracking }) {
2661
2680
  const product = data?.product;
2662
2681
  const c = section.content;
2663
2682
  const name = c.name || product?.name || "";
@@ -2673,6 +2692,7 @@ function ProductCardSection({ section, data, theme }) {
2673
2692
  "a",
2674
2693
  {
2675
2694
  href: url,
2695
+ onClick: () => trackClick(tracking, "View Product", url),
2676
2696
  style: {
2677
2697
  display: "block",
2678
2698
  width: "100%",
@@ -2697,7 +2717,8 @@ function COAViewerSection({
2697
2717
  section,
2698
2718
  data,
2699
2719
  theme,
2700
- onShowCOA
2720
+ onShowCOA,
2721
+ tracking
2701
2722
  }) {
2702
2723
  const coa = data?.coa;
2703
2724
  const c = section.content;
@@ -2718,10 +2739,200 @@ function COAViewerSection({
2718
2739
  display: "block",
2719
2740
  boxSizing: "border-box"
2720
2741
  };
2742
+ const buttonLabel = c.button_text || "View Lab Results";
2721
2743
  if (coa.viewer_url) {
2722
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "1.5rem", maxWidth: 480, margin: "0 auto" }, children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: coa.viewer_url, target: "_blank", rel: "noopener noreferrer", style: buttonStyle, children: c.button_text || "View Lab Results" }) });
2744
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "1.5rem", maxWidth: 480, margin: "0 auto" }, children: /* @__PURE__ */ jsxRuntime.jsx(
2745
+ "a",
2746
+ {
2747
+ href: coa.viewer_url,
2748
+ target: "_blank",
2749
+ rel: "noopener noreferrer",
2750
+ onClick: () => trackClick(tracking, buttonLabel, coa.viewer_url),
2751
+ style: buttonStyle,
2752
+ children: buttonLabel
2753
+ }
2754
+ ) });
2723
2755
  }
2724
- return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "1.5rem", maxWidth: 480, margin: "0 auto" }, children: /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: onShowCOA, style: buttonStyle, children: c.button_text || "View Lab Results" }) });
2756
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "1.5rem", maxWidth: 480, margin: "0 auto" }, children: /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => {
2757
+ trackClick(tracking, buttonLabel, coa.url);
2758
+ onShowCOA();
2759
+ }, style: buttonStyle, children: buttonLabel }) });
2760
+ }
2761
+ function LeadCaptureSection({ section, data, theme }) {
2762
+ const c = section.content;
2763
+ const [firstName, setFirstName] = react.useState("");
2764
+ const [email, setEmail] = react.useState("");
2765
+ const [status, setStatus] = react.useState("idle");
2766
+ const [errorMsg, setErrorMsg] = react.useState("");
2767
+ const gatewayUrl = c.gateway_url || data.gatewayUrl || "https://whale-gateway.fly.dev";
2768
+ const storeId = c.store_id || data.store?.id;
2769
+ const slug = c.landing_page_slug || data.landing_page?.slug;
2770
+ async function handleSubmit(e) {
2771
+ e.preventDefault();
2772
+ if (!email || !storeId) return;
2773
+ setStatus("loading");
2774
+ setErrorMsg("");
2775
+ try {
2776
+ const res = await fetch(`${gatewayUrl}/v1/stores/${storeId}/storefront/leads`, {
2777
+ method: "POST",
2778
+ headers: { "Content-Type": "application/json" },
2779
+ body: JSON.stringify({
2780
+ email,
2781
+ first_name: firstName || void 0,
2782
+ source: c.source || "landing_page",
2783
+ landing_page_slug: slug || void 0,
2784
+ tags: c.tags || void 0
2785
+ })
2786
+ });
2787
+ if (!res.ok) {
2788
+ const body = await res.json().catch(() => ({}));
2789
+ throw new Error(body?.error?.message || "Something went wrong. Please try again.");
2790
+ }
2791
+ setStatus("success");
2792
+ } catch (err) {
2793
+ setErrorMsg(err instanceof Error ? err.message : "Something went wrong. Please try again.");
2794
+ setStatus("error");
2795
+ }
2796
+ }
2797
+ const heading = c.heading || "get 10% off your first visit.";
2798
+ const subtitle = c.subtitle || "drop your email and we will send you the code.";
2799
+ const buttonText = c.button_text || "Claim My Discount";
2800
+ const successHeading = c.success_heading || "You\u2019re in!";
2801
+ const successMessage = c.success_message || "Check your inbox for the discount code.";
2802
+ const inputStyle = {
2803
+ flex: 1,
2804
+ minWidth: 0,
2805
+ padding: "0.875rem 1rem",
2806
+ background: theme.surface,
2807
+ border: `1px solid ${theme.fg}15`,
2808
+ color: theme.fg,
2809
+ fontSize: "0.95rem",
2810
+ fontWeight: 300,
2811
+ outline: "none",
2812
+ boxSizing: "border-box",
2813
+ fontFamily: "inherit",
2814
+ transition: "border-color 0.2s"
2815
+ };
2816
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "3.5rem 1.5rem", maxWidth: 560, margin: "0 auto" }, children: [
2817
+ /* @__PURE__ */ jsxRuntime.jsx("style", { children: `@keyframes lc-spin { to { transform: rotate(360deg) } }` }),
2818
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
2819
+ background: theme.surface,
2820
+ border: `1px solid ${theme.fg}12`,
2821
+ padding: "clamp(2rem, 6vw, 3rem)"
2822
+ }, children: status === "success" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center" }, children: [
2823
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: {
2824
+ fontSize: "clamp(1.5rem, 5vw, 2rem)",
2825
+ fontWeight: 300,
2826
+ fontFamily: theme.fontDisplay || "inherit",
2827
+ margin: "0 0 0.75rem",
2828
+ lineHeight: 1.2,
2829
+ letterSpacing: "-0.02em",
2830
+ color: theme.fg
2831
+ }, children: successHeading }),
2832
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: {
2833
+ fontSize: "0.9rem",
2834
+ color: `${theme.fg}99`,
2835
+ margin: "0 0 1.5rem",
2836
+ lineHeight: 1.6,
2837
+ fontWeight: 300
2838
+ }, children: successMessage }),
2839
+ c.coupon_code && /* @__PURE__ */ jsxRuntime.jsx("div", { style: {
2840
+ display: "inline-block",
2841
+ padding: "0.75rem 2rem",
2842
+ background: `${theme.fg}08`,
2843
+ border: `1px dashed ${theme.fg}30`,
2844
+ fontSize: "clamp(1.25rem, 4vw, 1.75rem)",
2845
+ fontWeight: 500,
2846
+ fontFamily: "monospace",
2847
+ letterSpacing: "0.12em",
2848
+ color: theme.accent
2849
+ }, children: c.coupon_code })
2850
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2851
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", marginBottom: "clamp(1.5rem, 4vw, 2rem)" }, children: [
2852
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { style: {
2853
+ fontSize: "clamp(1.5rem, 5vw, 2.25rem)",
2854
+ fontWeight: 300,
2855
+ fontFamily: theme.fontDisplay || "inherit",
2856
+ margin: "0 0 0.5rem",
2857
+ lineHeight: 1.15,
2858
+ letterSpacing: "-0.02em",
2859
+ color: theme.fg
2860
+ }, children: heading }),
2861
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: {
2862
+ fontSize: "0.85rem",
2863
+ color: theme.accent,
2864
+ margin: 0,
2865
+ lineHeight: 1.6,
2866
+ textTransform: "uppercase",
2867
+ letterSpacing: "0.15em"
2868
+ }, children: subtitle })
2869
+ ] }),
2870
+ /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, style: { display: "flex", flexDirection: "column", gap: "0.75rem" }, children: [
2871
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "0.75rem", flexWrap: "wrap" }, children: [
2872
+ /* @__PURE__ */ jsxRuntime.jsx(
2873
+ "input",
2874
+ {
2875
+ type: "text",
2876
+ placeholder: "First name",
2877
+ value: firstName,
2878
+ onChange: (e) => setFirstName(e.target.value),
2879
+ style: inputStyle
2880
+ }
2881
+ ),
2882
+ /* @__PURE__ */ jsxRuntime.jsx(
2883
+ "input",
2884
+ {
2885
+ type: "email",
2886
+ placeholder: "Email address",
2887
+ value: email,
2888
+ onChange: (e) => setEmail(e.target.value),
2889
+ required: true,
2890
+ style: inputStyle
2891
+ }
2892
+ )
2893
+ ] }),
2894
+ status === "error" && errorMsg && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.8rem", color: "#e55", margin: 0, fontWeight: 400 }, children: errorMsg }),
2895
+ /* @__PURE__ */ jsxRuntime.jsxs(
2896
+ "button",
2897
+ {
2898
+ type: "submit",
2899
+ disabled: status === "loading",
2900
+ style: {
2901
+ width: "100%",
2902
+ padding: "0.875rem",
2903
+ background: theme.fg,
2904
+ color: theme.bg,
2905
+ border: "none",
2906
+ fontSize: "0.85rem",
2907
+ fontWeight: 500,
2908
+ cursor: status === "loading" ? "wait" : "pointer",
2909
+ letterSpacing: "0.08em",
2910
+ textTransform: "uppercase",
2911
+ fontFamily: "inherit",
2912
+ display: "flex",
2913
+ alignItems: "center",
2914
+ justifyContent: "center",
2915
+ gap: "0.5rem",
2916
+ opacity: status === "loading" ? 0.7 : 1,
2917
+ transition: "opacity 0.2s"
2918
+ },
2919
+ children: [
2920
+ status === "loading" && /* @__PURE__ */ jsxRuntime.jsx("span", { style: {
2921
+ display: "inline-block",
2922
+ width: 16,
2923
+ height: 16,
2924
+ border: `2px solid ${theme.bg}40`,
2925
+ borderTopColor: theme.bg,
2926
+ borderRadius: "50%",
2927
+ animation: "lc-spin 0.8s linear infinite"
2928
+ } }),
2929
+ buttonText
2930
+ ]
2931
+ }
2932
+ )
2933
+ ] })
2934
+ ] }) })
2935
+ ] });
2725
2936
  }
2726
2937
  function SocialLinksSection({ section, theme }) {
2727
2938
  const { links } = section.content;
@@ -2844,15 +3055,16 @@ function QRLandingPage({
2844
3055
  const logoUrl = data.qr_code.logo_url || data.store?.logo_url;
2845
3056
  const storeName = data.store?.name;
2846
3057
  const sorted = [...sections].sort((a, b) => a.order - b.order);
3058
+ const tracking = { gatewayUrl, code };
2847
3059
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { minHeight: "100dvh", background: theme.bg, color: theme.fg, fontFamily }, children: [
2848
3060
  lp?.custom_css && /* @__PURE__ */ jsxRuntime.jsx("style", { children: lp.custom_css }),
2849
3061
  logoUrl && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "1.5rem", display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoUrl, alt: storeName || "Store", style: { height: 40, objectFit: "contain" } }) }),
2850
3062
  sorted.map((section) => {
2851
- const defaultRenderer = () => /* @__PURE__ */ jsxRuntime.jsx(SectionRenderer, { section, data, theme }, section.id);
3063
+ const defaultRenderer = () => /* @__PURE__ */ jsxRuntime.jsx(SectionRenderer, { section, data, theme, tracking }, section.id);
2852
3064
  if (renderSection) {
2853
3065
  return /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderSection(section, defaultRenderer) }, section.id);
2854
3066
  }
2855
- return /* @__PURE__ */ jsxRuntime.jsx(SectionRenderer, { section, data, theme }, section.id);
3067
+ return /* @__PURE__ */ jsxRuntime.jsx(SectionRenderer, { section, data, theme, tracking }, section.id);
2856
3068
  }),
2857
3069
  storeName && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "2rem 1.5rem", borderTop: `1px solid ${theme.surface}`, textAlign: "center" }, children: /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: "0.75rem", color: theme.muted, margin: 0 }, children: [
2858
3070
  storeName,
@@ -3102,10 +3314,11 @@ function LandingPage({
3102
3314
  if (state === "expired") return /* @__PURE__ */ jsxRuntime.jsx(DefaultExpired2, {});
3103
3315
  if (state === "error") return /* @__PURE__ */ jsxRuntime.jsx(DefaultError2, { message: errorMsg });
3104
3316
  if (!data) return null;
3105
- return /* @__PURE__ */ jsxRuntime.jsx(PageLayout, { data, renderSection });
3317
+ return /* @__PURE__ */ jsxRuntime.jsx(PageLayout, { data, gatewayUrl, renderSection });
3106
3318
  }
3107
3319
  function PageLayout({
3108
3320
  data,
3321
+ gatewayUrl,
3109
3322
  renderSection
3110
3323
  }) {
3111
3324
  const { landing_page: lp, store } = data;
@@ -3121,15 +3334,16 @@ function PageLayout({
3121
3334
  const fontFamily = lp.font_family || theme.fontDisplay || "system-ui, -apple-system, sans-serif";
3122
3335
  const logoUrl = store?.logo_url;
3123
3336
  const sorted = [...lp.sections].sort((a, b) => a.order - b.order);
3337
+ const sectionData = { ...data, gatewayUrl, landing_page: { slug: lp.slug } };
3124
3338
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { minHeight: "100dvh", background: theme.bg, color: theme.fg, fontFamily }, children: [
3125
3339
  lp.custom_css && /* @__PURE__ */ jsxRuntime.jsx("style", { children: lp.custom_css }),
3126
3340
  logoUrl && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "1.5rem", display: "flex", justifyContent: "center" }, children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: logoUrl, alt: store?.name || "Store", style: { height: 40, objectFit: "contain" } }) }),
3127
3341
  sorted.map((section) => {
3128
- const defaultRenderer = () => /* @__PURE__ */ jsxRuntime.jsx(SectionRenderer, { section, data, theme }, section.id);
3342
+ const defaultRenderer = () => /* @__PURE__ */ jsxRuntime.jsx(SectionRenderer, { section, data: sectionData, theme }, section.id);
3129
3343
  if (renderSection) {
3130
3344
  return /* @__PURE__ */ jsxRuntime.jsx("div", { children: renderSection(section, defaultRenderer) }, section.id);
3131
3345
  }
3132
- return /* @__PURE__ */ jsxRuntime.jsx(SectionRenderer, { section, data, theme }, section.id);
3346
+ return /* @__PURE__ */ jsxRuntime.jsx(SectionRenderer, { section, data: sectionData, theme }, section.id);
3133
3347
  }),
3134
3348
  store?.name && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "2rem 1.5rem", borderTop: `1px solid ${theme.surface}`, textAlign: "center" }, children: /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { fontSize: "0.75rem", color: theme.muted, margin: 0 }, children: [
3135
3349
  "Powered by ",