@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.
- package/dist/{chunk-XHWAUMWS.js → chunk-3Q7CPJBA.js} +18 -9
- package/dist/chunk-3Q7CPJBA.js.map +1 -0
- package/dist/{chunk-CQCCXDUS.cjs → chunk-VAA2KKCH.cjs} +18 -9
- package/dist/chunk-VAA2KKCH.cjs.map +1 -0
- package/dist/{client-D1XVKpFt.d.cts → client-BSO263Uv.d.cts} +15 -2
- package/dist/{client-D1XVKpFt.d.ts → client-BSO263Uv.d.ts} +15 -2
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/next/index.cjs +4 -4
- package/dist/next/index.d.cts +1 -1
- package/dist/next/index.d.ts +1 -1
- package/dist/next/index.js +1 -1
- package/dist/{pixel-manager-C6PAp7vQ.d.ts → pixel-manager-BcL95odX.d.ts} +1 -1
- package/dist/{pixel-manager-DZwpn_x2.d.cts → pixel-manager-DJ9m2FaQ.d.cts} +1 -1
- package/dist/react/index.cjs +238 -24
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +21 -5
- package/dist/react/index.d.ts +21 -5
- package/dist/react/index.js +234 -20
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-CQCCXDUS.cjs.map +0 -1
- package/dist/chunk-XHWAUMWS.js.map +0 -1
package/dist/react/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunk7KXJLHGA_cjs = require('../chunk-7KXJLHGA.cjs');
|
|
4
|
-
var
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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(
|
|
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:
|
|
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 ",
|