@neowhale/storefront 0.2.57 → 0.2.59
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/landing.global.js +103 -9
- package/dist/react/index.cjs +103 -9
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +103 -9
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/landing.global.js
CHANGED
|
@@ -567,6 +567,8 @@ var WhaleStorefront = (function (exports) {
|
|
|
567
567
|
onSubmit: handleSubmit,
|
|
568
568
|
successHeading: c.inline_form.success_heading || "you're in.",
|
|
569
569
|
successMessage: c.inline_form.success_message || "check your inbox.",
|
|
570
|
+
successCtaText: c.inline_form.success_cta_text,
|
|
571
|
+
successCtaUrl: c.inline_form.success_cta_url,
|
|
570
572
|
submitText: c.inline_form.button_text || "send my code",
|
|
571
573
|
theme,
|
|
572
574
|
onEvent,
|
|
@@ -598,12 +600,36 @@ var WhaleStorefront = (function (exports) {
|
|
|
598
600
|
] })
|
|
599
601
|
] });
|
|
600
602
|
}
|
|
601
|
-
function HeroInlineForm({ ctaText, formOpen, setFormOpen, firstName, setFirstName, email, setEmail, status, errorMsg, onSubmit, successHeading, successMessage, submitText, theme, onEvent, tracking }) {
|
|
603
|
+
function HeroInlineForm({ ctaText, formOpen, setFormOpen, firstName, setFirstName, email, setEmail, status, errorMsg, onSubmit, successHeading, successMessage, successCtaText, successCtaUrl, submitText, theme, onEvent, tracking }) {
|
|
602
604
|
const formMaxW = "min(480px, 90vw)";
|
|
603
605
|
if (status === "success") {
|
|
604
606
|
return /* @__PURE__ */ jsx("div", { style: { maxWidth: formMaxW, margin: "0 auto", padding: "1.5rem 2rem", background: `${theme.fg}06`, border: `1px solid ${theme.fg}10` }, children: [
|
|
605
607
|
/* @__PURE__ */ jsx("p", { style: { fontSize: "clamp(1rem, 3vw, 1.25rem)", fontWeight: 300, color: theme.fg, margin: "0 0 0.375rem", fontFamily: theme.fontDisplay || "inherit" }, children: successHeading }),
|
|
606
|
-
/* @__PURE__ */ jsx("p", { style: { fontSize: "0.85rem", color: `${theme.fg}70`, margin: 0, lineHeight: 1.5 }, children: successMessage })
|
|
608
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: "0.85rem", color: `${theme.fg}70`, margin: 0, lineHeight: 1.5 }, children: successMessage }),
|
|
609
|
+
successCtaUrl && /* @__PURE__ */ jsx(
|
|
610
|
+
"button",
|
|
611
|
+
{
|
|
612
|
+
onClick: () => {
|
|
613
|
+
window.location.href = successCtaUrl;
|
|
614
|
+
onEvent?.("cta_click", { label: successCtaText || "shop now", url: successCtaUrl });
|
|
615
|
+
},
|
|
616
|
+
style: {
|
|
617
|
+
marginTop: "1rem",
|
|
618
|
+
width: "100%",
|
|
619
|
+
padding: "0.875rem",
|
|
620
|
+
background: theme.accent || theme.fg,
|
|
621
|
+
color: "#fff",
|
|
622
|
+
border: "none",
|
|
623
|
+
fontSize: "0.85rem",
|
|
624
|
+
fontWeight: 500,
|
|
625
|
+
cursor: "pointer",
|
|
626
|
+
letterSpacing: "0.08em",
|
|
627
|
+
textTransform: "uppercase",
|
|
628
|
+
fontFamily: "inherit"
|
|
629
|
+
},
|
|
630
|
+
children: successCtaText || "shop now"
|
|
631
|
+
}
|
|
632
|
+
)
|
|
607
633
|
] });
|
|
608
634
|
}
|
|
609
635
|
if (!formOpen) {
|
|
@@ -1130,6 +1156,25 @@ var WhaleStorefront = (function (exports) {
|
|
|
1130
1156
|
}
|
|
1131
1157
|
|
|
1132
1158
|
// src/react/components/sections/lead-capture-section.tsx
|
|
1159
|
+
var TURNSTILE_SITE_KEY = "0x4AAAAAACwmUPgmyfw6pWfT";
|
|
1160
|
+
var TURNSTILE_SCRIPT_URL = "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit";
|
|
1161
|
+
var turnstilePromise = null;
|
|
1162
|
+
function loadTurnstileScript() {
|
|
1163
|
+
if (turnstilePromise) return turnstilePromise;
|
|
1164
|
+
if (typeof window !== "undefined" && window.turnstile) {
|
|
1165
|
+
turnstilePromise = Promise.resolve();
|
|
1166
|
+
return turnstilePromise;
|
|
1167
|
+
}
|
|
1168
|
+
turnstilePromise = new Promise((resolve, reject) => {
|
|
1169
|
+
const script = document.createElement("script");
|
|
1170
|
+
script.src = TURNSTILE_SCRIPT_URL;
|
|
1171
|
+
script.async = true;
|
|
1172
|
+
script.onload = () => resolve();
|
|
1173
|
+
script.onerror = () => reject(new Error("Failed to load Turnstile script"));
|
|
1174
|
+
document.head.appendChild(script);
|
|
1175
|
+
});
|
|
1176
|
+
return turnstilePromise;
|
|
1177
|
+
}
|
|
1133
1178
|
function LeadCaptureSection({ section, data, theme, onEvent }) {
|
|
1134
1179
|
const c = section.content;
|
|
1135
1180
|
const [firstName, setFirstName] = useState("");
|
|
@@ -1138,6 +1183,41 @@ var WhaleStorefront = (function (exports) {
|
|
|
1138
1183
|
const [status, setStatus] = useState("idle");
|
|
1139
1184
|
const [errorMsg, setErrorMsg] = useState("");
|
|
1140
1185
|
const [serverMessage, setServerMessage] = useState(null);
|
|
1186
|
+
const turnstileRef = useRef(null);
|
|
1187
|
+
const turnstileToken = useRef(null);
|
|
1188
|
+
const turnstileWidgetId = useRef(null);
|
|
1189
|
+
const pendingSubmit = useRef(null);
|
|
1190
|
+
const onTurnstileToken = useCallback((token) => {
|
|
1191
|
+
turnstileToken.current = token;
|
|
1192
|
+
if (pendingSubmit.current) {
|
|
1193
|
+
const cb = pendingSubmit.current;
|
|
1194
|
+
pendingSubmit.current = null;
|
|
1195
|
+
cb();
|
|
1196
|
+
}
|
|
1197
|
+
}, []);
|
|
1198
|
+
useEffect(() => {
|
|
1199
|
+
if (typeof window === "undefined") return;
|
|
1200
|
+
let widgetId = null;
|
|
1201
|
+
loadTurnstileScript().then(() => {
|
|
1202
|
+
const el = turnstileRef.current;
|
|
1203
|
+
if (!el || !window.turnstile) return;
|
|
1204
|
+
widgetId = window.turnstile.render(el, {
|
|
1205
|
+
sitekey: TURNSTILE_SITE_KEY,
|
|
1206
|
+
callback: onTurnstileToken,
|
|
1207
|
+
"expired-callback": () => {
|
|
1208
|
+
turnstileToken.current = null;
|
|
1209
|
+
},
|
|
1210
|
+
size: "invisible"
|
|
1211
|
+
});
|
|
1212
|
+
turnstileWidgetId.current = widgetId;
|
|
1213
|
+
}).catch(() => {
|
|
1214
|
+
});
|
|
1215
|
+
return () => {
|
|
1216
|
+
if (widgetId != null && window.turnstile) {
|
|
1217
|
+
window.turnstile.remove(widgetId);
|
|
1218
|
+
}
|
|
1219
|
+
};
|
|
1220
|
+
}, [onTurnstileToken]);
|
|
1141
1221
|
const gatewayUrl = c.gateway_url || data.gatewayUrl || "https://whale-gateway.fly.dev";
|
|
1142
1222
|
const storeId = c.store_id || data.store?.id;
|
|
1143
1223
|
const slug = c.landing_page_slug || data.landing_page?.slug;
|
|
@@ -1146,11 +1226,7 @@ var WhaleStorefront = (function (exports) {
|
|
|
1146
1226
|
const buttonText = c.button_text || "Claim My Discount";
|
|
1147
1227
|
const successHeading = c.success_heading || "You\u2019re in!";
|
|
1148
1228
|
const successMessage = c.success_message || "Check your inbox for the discount code.";
|
|
1149
|
-
async function
|
|
1150
|
-
e.preventDefault();
|
|
1151
|
-
if (!email || !storeId) return;
|
|
1152
|
-
setStatus("loading");
|
|
1153
|
-
setErrorMsg("");
|
|
1229
|
+
async function submitLead(cfToken) {
|
|
1154
1230
|
const urlParams = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : null;
|
|
1155
1231
|
try {
|
|
1156
1232
|
const res = await fetch(`${gatewayUrl}/v1/stores/${storeId}/storefront/leads`, {
|
|
@@ -1172,7 +1248,8 @@ var WhaleStorefront = (function (exports) {
|
|
|
1172
1248
|
utm_source: urlParams?.get("utm_source") || void 0,
|
|
1173
1249
|
utm_medium: urlParams?.get("utm_medium") || void 0,
|
|
1174
1250
|
utm_campaign: urlParams?.get("utm_campaign") || void 0,
|
|
1175
|
-
utm_content: urlParams?.get("utm_content") || void 0
|
|
1251
|
+
utm_content: urlParams?.get("utm_content") || void 0,
|
|
1252
|
+
cf_turnstile_response: cfToken || void 0
|
|
1176
1253
|
})
|
|
1177
1254
|
});
|
|
1178
1255
|
if (!res.ok) {
|
|
@@ -1193,6 +1270,22 @@ var WhaleStorefront = (function (exports) {
|
|
|
1193
1270
|
setStatus("error");
|
|
1194
1271
|
}
|
|
1195
1272
|
}
|
|
1273
|
+
async function handleSubmit(e) {
|
|
1274
|
+
e.preventDefault();
|
|
1275
|
+
if (!email || !storeId) return;
|
|
1276
|
+
setStatus("loading");
|
|
1277
|
+
setErrorMsg("");
|
|
1278
|
+
if (turnstileToken.current) {
|
|
1279
|
+
return submitLead(turnstileToken.current);
|
|
1280
|
+
}
|
|
1281
|
+
const turnstile = window.turnstile;
|
|
1282
|
+
if (turnstile && turnstileWidgetId.current != null) {
|
|
1283
|
+
pendingSubmit.current = () => submitLead(turnstileToken.current);
|
|
1284
|
+
turnstile.execute(turnstileWidgetId.current);
|
|
1285
|
+
} else {
|
|
1286
|
+
return submitLead(null);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1196
1289
|
const inputStyle = {
|
|
1197
1290
|
flex: 1,
|
|
1198
1291
|
minWidth: 0,
|
|
@@ -1286,7 +1379,8 @@ var WhaleStorefront = (function (exports) {
|
|
|
1286
1379
|
animation: "lc-spin 0.8s linear infinite"
|
|
1287
1380
|
} }),
|
|
1288
1381
|
buttonText
|
|
1289
|
-
] })
|
|
1382
|
+
] }),
|
|
1383
|
+
/* @__PURE__ */ jsx("div", { ref: turnstileRef, style: { display: "none" } })
|
|
1290
1384
|
] })
|
|
1291
1385
|
] })
|
|
1292
1386
|
] });
|
package/dist/react/index.cjs
CHANGED
|
@@ -2306,6 +2306,8 @@ function HeroSection({ section, theme, tracking, onEvent, data }) {
|
|
|
2306
2306
|
onSubmit: handleSubmit,
|
|
2307
2307
|
successHeading: c.inline_form.success_heading || "you're in.",
|
|
2308
2308
|
successMessage: c.inline_form.success_message || "check your inbox.",
|
|
2309
|
+
successCtaText: c.inline_form.success_cta_text,
|
|
2310
|
+
successCtaUrl: c.inline_form.success_cta_url,
|
|
2309
2311
|
submitText: c.inline_form.button_text || "send my code",
|
|
2310
2312
|
theme,
|
|
2311
2313
|
onEvent,
|
|
@@ -2337,12 +2339,36 @@ function HeroSection({ section, theme, tracking, onEvent, data }) {
|
|
|
2337
2339
|
] })
|
|
2338
2340
|
] });
|
|
2339
2341
|
}
|
|
2340
|
-
function HeroInlineForm({ ctaText, formOpen, setFormOpen, firstName, setFirstName, email, setEmail, status, errorMsg, onSubmit, successHeading, successMessage, submitText, theme, onEvent, tracking }) {
|
|
2342
|
+
function HeroInlineForm({ ctaText, formOpen, setFormOpen, firstName, setFirstName, email, setEmail, status, errorMsg, onSubmit, successHeading, successMessage, successCtaText, successCtaUrl, submitText, theme, onEvent, tracking }) {
|
|
2341
2343
|
const formMaxW = "min(480px, 90vw)";
|
|
2342
2344
|
if (status === "success") {
|
|
2343
2345
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { maxWidth: formMaxW, margin: "0 auto", padding: "1.5rem 2rem", background: `${theme.fg}06`, border: `1px solid ${theme.fg}10` }, children: [
|
|
2344
2346
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "clamp(1rem, 3vw, 1.25rem)", fontWeight: 300, color: theme.fg, margin: "0 0 0.375rem", fontFamily: theme.fontDisplay || "inherit" }, children: successHeading }),
|
|
2345
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.85rem", color: `${theme.fg}70`, margin: 0, lineHeight: 1.5 }, children: successMessage })
|
|
2347
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { fontSize: "0.85rem", color: `${theme.fg}70`, margin: 0, lineHeight: 1.5 }, children: successMessage }),
|
|
2348
|
+
successCtaUrl && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2349
|
+
"button",
|
|
2350
|
+
{
|
|
2351
|
+
onClick: () => {
|
|
2352
|
+
window.location.href = successCtaUrl;
|
|
2353
|
+
onEvent?.("cta_click", { label: successCtaText || "shop now", url: successCtaUrl });
|
|
2354
|
+
},
|
|
2355
|
+
style: {
|
|
2356
|
+
marginTop: "1rem",
|
|
2357
|
+
width: "100%",
|
|
2358
|
+
padding: "0.875rem",
|
|
2359
|
+
background: theme.accent || theme.fg,
|
|
2360
|
+
color: "#fff",
|
|
2361
|
+
border: "none",
|
|
2362
|
+
fontSize: "0.85rem",
|
|
2363
|
+
fontWeight: 500,
|
|
2364
|
+
cursor: "pointer",
|
|
2365
|
+
letterSpacing: "0.08em",
|
|
2366
|
+
textTransform: "uppercase",
|
|
2367
|
+
fontFamily: "inherit"
|
|
2368
|
+
},
|
|
2369
|
+
children: successCtaText || "shop now"
|
|
2370
|
+
}
|
|
2371
|
+
)
|
|
2346
2372
|
] });
|
|
2347
2373
|
}
|
|
2348
2374
|
if (!formOpen) {
|
|
@@ -2865,6 +2891,25 @@ function COAModal({ coa, theme, onClose }) {
|
|
|
2865
2891
|
/* @__PURE__ */ jsxRuntime.jsx("iframe", { src: coa.url, style: { flex: 1, border: "none", background: "#fff" }, title: "Lab Results" })
|
|
2866
2892
|
] });
|
|
2867
2893
|
}
|
|
2894
|
+
var TURNSTILE_SITE_KEY = "0x4AAAAAACwmUPgmyfw6pWfT";
|
|
2895
|
+
var TURNSTILE_SCRIPT_URL = "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit";
|
|
2896
|
+
var turnstilePromise = null;
|
|
2897
|
+
function loadTurnstileScript() {
|
|
2898
|
+
if (turnstilePromise) return turnstilePromise;
|
|
2899
|
+
if (typeof window !== "undefined" && window.turnstile) {
|
|
2900
|
+
turnstilePromise = Promise.resolve();
|
|
2901
|
+
return turnstilePromise;
|
|
2902
|
+
}
|
|
2903
|
+
turnstilePromise = new Promise((resolve, reject) => {
|
|
2904
|
+
const script = document.createElement("script");
|
|
2905
|
+
script.src = TURNSTILE_SCRIPT_URL;
|
|
2906
|
+
script.async = true;
|
|
2907
|
+
script.onload = () => resolve();
|
|
2908
|
+
script.onerror = () => reject(new Error("Failed to load Turnstile script"));
|
|
2909
|
+
document.head.appendChild(script);
|
|
2910
|
+
});
|
|
2911
|
+
return turnstilePromise;
|
|
2912
|
+
}
|
|
2868
2913
|
function LeadCaptureSection({ section, data, theme, onEvent }) {
|
|
2869
2914
|
const c = section.content;
|
|
2870
2915
|
const [firstName, setFirstName] = react.useState("");
|
|
@@ -2873,6 +2918,41 @@ function LeadCaptureSection({ section, data, theme, onEvent }) {
|
|
|
2873
2918
|
const [status, setStatus] = react.useState("idle");
|
|
2874
2919
|
const [errorMsg, setErrorMsg] = react.useState("");
|
|
2875
2920
|
const [serverMessage, setServerMessage] = react.useState(null);
|
|
2921
|
+
const turnstileRef = react.useRef(null);
|
|
2922
|
+
const turnstileToken = react.useRef(null);
|
|
2923
|
+
const turnstileWidgetId = react.useRef(null);
|
|
2924
|
+
const pendingSubmit = react.useRef(null);
|
|
2925
|
+
const onTurnstileToken = react.useCallback((token) => {
|
|
2926
|
+
turnstileToken.current = token;
|
|
2927
|
+
if (pendingSubmit.current) {
|
|
2928
|
+
const cb = pendingSubmit.current;
|
|
2929
|
+
pendingSubmit.current = null;
|
|
2930
|
+
cb();
|
|
2931
|
+
}
|
|
2932
|
+
}, []);
|
|
2933
|
+
react.useEffect(() => {
|
|
2934
|
+
if (typeof window === "undefined") return;
|
|
2935
|
+
let widgetId = null;
|
|
2936
|
+
loadTurnstileScript().then(() => {
|
|
2937
|
+
const el = turnstileRef.current;
|
|
2938
|
+
if (!el || !window.turnstile) return;
|
|
2939
|
+
widgetId = window.turnstile.render(el, {
|
|
2940
|
+
sitekey: TURNSTILE_SITE_KEY,
|
|
2941
|
+
callback: onTurnstileToken,
|
|
2942
|
+
"expired-callback": () => {
|
|
2943
|
+
turnstileToken.current = null;
|
|
2944
|
+
},
|
|
2945
|
+
size: "invisible"
|
|
2946
|
+
});
|
|
2947
|
+
turnstileWidgetId.current = widgetId;
|
|
2948
|
+
}).catch(() => {
|
|
2949
|
+
});
|
|
2950
|
+
return () => {
|
|
2951
|
+
if (widgetId != null && window.turnstile) {
|
|
2952
|
+
window.turnstile.remove(widgetId);
|
|
2953
|
+
}
|
|
2954
|
+
};
|
|
2955
|
+
}, [onTurnstileToken]);
|
|
2876
2956
|
const gatewayUrl = c.gateway_url || data.gatewayUrl || "https://whale-gateway.fly.dev";
|
|
2877
2957
|
const storeId = c.store_id || data.store?.id;
|
|
2878
2958
|
const slug = c.landing_page_slug || data.landing_page?.slug;
|
|
@@ -2881,11 +2961,7 @@ function LeadCaptureSection({ section, data, theme, onEvent }) {
|
|
|
2881
2961
|
const buttonText = c.button_text || "Claim My Discount";
|
|
2882
2962
|
const successHeading = c.success_heading || "You\u2019re in!";
|
|
2883
2963
|
const successMessage = c.success_message || "Check your inbox for the discount code.";
|
|
2884
|
-
async function
|
|
2885
|
-
e.preventDefault();
|
|
2886
|
-
if (!email || !storeId) return;
|
|
2887
|
-
setStatus("loading");
|
|
2888
|
-
setErrorMsg("");
|
|
2964
|
+
async function submitLead(cfToken) {
|
|
2889
2965
|
const urlParams = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : null;
|
|
2890
2966
|
try {
|
|
2891
2967
|
const res = await fetch(`${gatewayUrl}/v1/stores/${storeId}/storefront/leads`, {
|
|
@@ -2907,7 +2983,8 @@ function LeadCaptureSection({ section, data, theme, onEvent }) {
|
|
|
2907
2983
|
utm_source: urlParams?.get("utm_source") || void 0,
|
|
2908
2984
|
utm_medium: urlParams?.get("utm_medium") || void 0,
|
|
2909
2985
|
utm_campaign: urlParams?.get("utm_campaign") || void 0,
|
|
2910
|
-
utm_content: urlParams?.get("utm_content") || void 0
|
|
2986
|
+
utm_content: urlParams?.get("utm_content") || void 0,
|
|
2987
|
+
cf_turnstile_response: cfToken || void 0
|
|
2911
2988
|
})
|
|
2912
2989
|
});
|
|
2913
2990
|
if (!res.ok) {
|
|
@@ -2928,6 +3005,22 @@ function LeadCaptureSection({ section, data, theme, onEvent }) {
|
|
|
2928
3005
|
setStatus("error");
|
|
2929
3006
|
}
|
|
2930
3007
|
}
|
|
3008
|
+
async function handleSubmit(e) {
|
|
3009
|
+
e.preventDefault();
|
|
3010
|
+
if (!email || !storeId) return;
|
|
3011
|
+
setStatus("loading");
|
|
3012
|
+
setErrorMsg("");
|
|
3013
|
+
if (turnstileToken.current) {
|
|
3014
|
+
return submitLead(turnstileToken.current);
|
|
3015
|
+
}
|
|
3016
|
+
const turnstile = window.turnstile;
|
|
3017
|
+
if (turnstile && turnstileWidgetId.current != null) {
|
|
3018
|
+
pendingSubmit.current = () => submitLead(turnstileToken.current);
|
|
3019
|
+
turnstile.execute(turnstileWidgetId.current);
|
|
3020
|
+
} else {
|
|
3021
|
+
return submitLead(null);
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
2931
3024
|
const inputStyle = {
|
|
2932
3025
|
flex: 1,
|
|
2933
3026
|
minWidth: 0,
|
|
@@ -3021,7 +3114,8 @@ function LeadCaptureSection({ section, data, theme, onEvent }) {
|
|
|
3021
3114
|
animation: "lc-spin 0.8s linear infinite"
|
|
3022
3115
|
} }),
|
|
3023
3116
|
buttonText
|
|
3024
|
-
] })
|
|
3117
|
+
] }),
|
|
3118
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: turnstileRef, style: { display: "none" } })
|
|
3025
3119
|
] })
|
|
3026
3120
|
] })
|
|
3027
3121
|
] });
|