@neowhale/storefront 0.2.52 → 0.2.54
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 +204 -41
- package/dist/react/index.cjs +197 -39
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +197 -39
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -2206,8 +2206,52 @@ function AnimatedText({ text }) {
|
|
|
2206
2206
|
(part, i) => NUM_TEST.test(part) ? /* @__PURE__ */ jsx(AnimatedNumber, { raw: part }, i) : part
|
|
2207
2207
|
) });
|
|
2208
2208
|
}
|
|
2209
|
-
|
|
2210
|
-
|
|
2209
|
+
var GOOGLE_G = '<svg width="18" height="18" viewBox="0 0 48 48"><path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"/><path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"/><path fill="#FBBC05" d="M10.53 28.59a14.5 14.5 0 010-9.18l-7.98-6.19a24.03 24.03 0 000 21.56l7.98-6.19z"/><path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"/></svg>';
|
|
2210
|
+
function HeroSection({ section, theme, tracking, onEvent, data }) {
|
|
2211
|
+
const c = section.content;
|
|
2212
|
+
const [formOpen, setFormOpen] = useState(false);
|
|
2213
|
+
const [firstName, setFirstName] = useState("");
|
|
2214
|
+
const [email, setEmail] = useState("");
|
|
2215
|
+
const [status, setStatus] = useState("idle");
|
|
2216
|
+
const [errorMsg, setErrorMsg] = useState("");
|
|
2217
|
+
const gatewayUrl = data?.gatewayUrl || "https://whale-gateway.fly.dev";
|
|
2218
|
+
const storeId = data?.store?.id;
|
|
2219
|
+
const slug = data?.landing_page?.slug;
|
|
2220
|
+
async function handleSubmit(e) {
|
|
2221
|
+
e.preventDefault();
|
|
2222
|
+
if (!email || !storeId) return;
|
|
2223
|
+
setStatus("loading");
|
|
2224
|
+
setErrorMsg("");
|
|
2225
|
+
const urlParams = typeof window !== "undefined" ? new URLSearchParams(window.location.search) : null;
|
|
2226
|
+
try {
|
|
2227
|
+
const res = await fetch(`${gatewayUrl}/v1/stores/${storeId}/storefront/leads`, {
|
|
2228
|
+
method: "POST",
|
|
2229
|
+
headers: { "Content-Type": "application/json" },
|
|
2230
|
+
body: JSON.stringify({
|
|
2231
|
+
email,
|
|
2232
|
+
first_name: firstName || void 0,
|
|
2233
|
+
source: c.inline_form?.source || "landing_page",
|
|
2234
|
+
landing_page_slug: slug || void 0,
|
|
2235
|
+
tags: c.inline_form?.tags || void 0,
|
|
2236
|
+
visitor_id: data?.analyticsContext?.visitorId || void 0,
|
|
2237
|
+
session_id: data?.analyticsContext?.sessionId || void 0,
|
|
2238
|
+
utm_source: urlParams?.get("utm_source") || void 0,
|
|
2239
|
+
utm_medium: urlParams?.get("utm_medium") || void 0,
|
|
2240
|
+
utm_campaign: urlParams?.get("utm_campaign") || void 0
|
|
2241
|
+
})
|
|
2242
|
+
});
|
|
2243
|
+
if (!res.ok) {
|
|
2244
|
+
const body = await res.json().catch(() => ({}));
|
|
2245
|
+
throw new Error(body?.error?.message || "something went wrong.");
|
|
2246
|
+
}
|
|
2247
|
+
setStatus("success");
|
|
2248
|
+
onEvent?.("lead", { email, first_name: firstName || void 0, source: c.inline_form?.source || "landing_page" });
|
|
2249
|
+
} catch (err) {
|
|
2250
|
+
setErrorMsg(err instanceof Error ? err.message : "something went wrong.");
|
|
2251
|
+
setStatus("error");
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
const hasInlineForm = !!c.inline_form;
|
|
2211
2255
|
return /* @__PURE__ */ jsxs("div", { style: {
|
|
2212
2256
|
position: "relative",
|
|
2213
2257
|
minHeight: "60vh",
|
|
@@ -2217,36 +2261,56 @@ function HeroSection({ section, theme, tracking, onEvent }) {
|
|
|
2217
2261
|
alignItems: "center",
|
|
2218
2262
|
textAlign: "center",
|
|
2219
2263
|
padding: "3rem 1.5rem",
|
|
2220
|
-
backgroundImage: background_image ? `url(${background_image})` : void 0,
|
|
2264
|
+
backgroundImage: c.background_image ? `url(${c.background_image})` : void 0,
|
|
2221
2265
|
backgroundSize: "cover",
|
|
2222
2266
|
backgroundPosition: "center"
|
|
2223
2267
|
}, children: [
|
|
2224
|
-
background_image && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: "rgba(0,0,0,0.5)" } }),
|
|
2225
|
-
/* @__PURE__ */ jsxs("div", { style: { position: "relative", zIndex: 1, maxWidth: 640 }, children: [
|
|
2226
|
-
title && /* @__PURE__ */ jsx("h1", { style: {
|
|
2227
|
-
fontSize: "clamp(2rem,
|
|
2268
|
+
c.background_image && /* @__PURE__ */ jsx("div", { style: { position: "absolute", inset: 0, background: "rgba(0,0,0,0.5)" } }),
|
|
2269
|
+
/* @__PURE__ */ jsxs("div", { style: { position: "relative", zIndex: 1, maxWidth: 640, width: "100%" }, children: [
|
|
2270
|
+
c.title && /* @__PURE__ */ jsx("h1", { style: {
|
|
2271
|
+
fontSize: "clamp(2rem, 7vw, 3.25rem)",
|
|
2228
2272
|
fontWeight: 300,
|
|
2229
2273
|
fontFamily: theme.fontDisplay || "inherit",
|
|
2230
|
-
margin: "0 0
|
|
2231
|
-
lineHeight: 1.
|
|
2232
|
-
letterSpacing: "-0.
|
|
2274
|
+
margin: "0 0 1.25rem",
|
|
2275
|
+
lineHeight: 1.08,
|
|
2276
|
+
letterSpacing: "-0.03em",
|
|
2233
2277
|
color: theme.fg
|
|
2234
|
-
}, children: /* @__PURE__ */ jsx(AnimatedText, { text: title }) }),
|
|
2235
|
-
subtitle && /* @__PURE__ */ jsx("p", { style: {
|
|
2236
|
-
fontSize: "0.
|
|
2278
|
+
}, children: /* @__PURE__ */ jsx(AnimatedText, { text: c.title }) }),
|
|
2279
|
+
c.subtitle && /* @__PURE__ */ jsx("p", { style: {
|
|
2280
|
+
fontSize: "clamp(0.9rem, 2.5vw, 1.1rem)",
|
|
2237
2281
|
color: theme.accent,
|
|
2238
2282
|
margin: "0 0 2rem",
|
|
2239
2283
|
lineHeight: 1.6,
|
|
2240
2284
|
textTransform: "uppercase",
|
|
2241
|
-
letterSpacing: "0.
|
|
2242
|
-
}, children: subtitle }),
|
|
2243
|
-
|
|
2285
|
+
letterSpacing: "0.1em"
|
|
2286
|
+
}, children: c.subtitle }),
|
|
2287
|
+
hasInlineForm ? /* @__PURE__ */ jsx(
|
|
2288
|
+
HeroInlineForm,
|
|
2289
|
+
{
|
|
2290
|
+
ctaText: c.cta_text || "claim it",
|
|
2291
|
+
formOpen,
|
|
2292
|
+
setFormOpen,
|
|
2293
|
+
firstName,
|
|
2294
|
+
setFirstName,
|
|
2295
|
+
email,
|
|
2296
|
+
setEmail,
|
|
2297
|
+
status,
|
|
2298
|
+
errorMsg,
|
|
2299
|
+
onSubmit: handleSubmit,
|
|
2300
|
+
successHeading: c.inline_form.success_heading || "you're in.",
|
|
2301
|
+
successMessage: c.inline_form.success_message || "check your inbox.",
|
|
2302
|
+
submitText: c.inline_form.button_text || "send my code",
|
|
2303
|
+
theme,
|
|
2304
|
+
onEvent,
|
|
2305
|
+
tracking
|
|
2306
|
+
}
|
|
2307
|
+
) : c.cta_text && c.cta_url ? /* @__PURE__ */ jsx(
|
|
2244
2308
|
"a",
|
|
2245
2309
|
{
|
|
2246
|
-
href: cta_url,
|
|
2310
|
+
href: c.cta_url,
|
|
2247
2311
|
onClick: () => {
|
|
2248
|
-
trackClick(tracking, cta_text, cta_url);
|
|
2249
|
-
onEvent?.("cta_click", { label: cta_text, url: cta_url });
|
|
2312
|
+
trackClick(tracking, c.cta_text, c.cta_url);
|
|
2313
|
+
onEvent?.("cta_click", { label: c.cta_text, url: c.cta_url });
|
|
2250
2314
|
},
|
|
2251
2315
|
style: {
|
|
2252
2316
|
display: "inline-block",
|
|
@@ -2259,13 +2323,111 @@ function HeroSection({ section, theme, tracking, onEvent }) {
|
|
|
2259
2323
|
letterSpacing: "0.08em",
|
|
2260
2324
|
textTransform: "uppercase"
|
|
2261
2325
|
},
|
|
2262
|
-
children: cta_text
|
|
2326
|
+
children: c.cta_text
|
|
2263
2327
|
}
|
|
2264
|
-
),
|
|
2265
|
-
review_line && review_line.count > 0 && /* @__PURE__ */ jsx(ReviewLine, { rating: review_line.rating, count: review_line.count, source: review_line.source, url: review_line.url, accent: theme.accent, fg: theme.fg })
|
|
2328
|
+
) : null,
|
|
2329
|
+
c.review_line && c.review_line.count > 0 && /* @__PURE__ */ jsx(ReviewLine, { rating: c.review_line.rating, count: c.review_line.count, source: c.review_line.source, url: c.review_line.url, accent: theme.accent, fg: theme.fg })
|
|
2266
2330
|
] })
|
|
2267
2331
|
] });
|
|
2268
2332
|
}
|
|
2333
|
+
function HeroInlineForm({ ctaText, formOpen, setFormOpen, firstName, setFirstName, email, setEmail, status, errorMsg, onSubmit, successHeading, successMessage, submitText, theme, onEvent, tracking }) {
|
|
2334
|
+
if (status === "success") {
|
|
2335
|
+
return /* @__PURE__ */ jsxs("div", { style: { padding: "1.25rem 2rem", background: `${theme.fg}08`, border: `1px solid ${theme.fg}15`, maxWidth: 420, margin: "0 auto" }, children: [
|
|
2336
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: "1.1rem", fontWeight: 300, color: theme.fg, margin: "0 0 0.25rem", fontFamily: theme.fontDisplay || "inherit" }, children: successHeading }),
|
|
2337
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: "0.8rem", color: `${theme.fg}80`, margin: 0 }, children: successMessage })
|
|
2338
|
+
] });
|
|
2339
|
+
}
|
|
2340
|
+
if (!formOpen) {
|
|
2341
|
+
return /* @__PURE__ */ jsx(
|
|
2342
|
+
"button",
|
|
2343
|
+
{
|
|
2344
|
+
onClick: () => {
|
|
2345
|
+
setFormOpen(true);
|
|
2346
|
+
trackClick(tracking, ctaText, "#form");
|
|
2347
|
+
onEvent?.("cta_click", { label: ctaText });
|
|
2348
|
+
},
|
|
2349
|
+
style: {
|
|
2350
|
+
display: "inline-block",
|
|
2351
|
+
padding: "0.875rem 2rem",
|
|
2352
|
+
background: theme.fg,
|
|
2353
|
+
color: theme.bg,
|
|
2354
|
+
border: "none",
|
|
2355
|
+
cursor: "pointer",
|
|
2356
|
+
fontSize: "0.85rem",
|
|
2357
|
+
fontWeight: 500,
|
|
2358
|
+
letterSpacing: "0.08em",
|
|
2359
|
+
textTransform: "uppercase",
|
|
2360
|
+
fontFamily: "inherit",
|
|
2361
|
+
transition: "transform 0.2s"
|
|
2362
|
+
},
|
|
2363
|
+
children: ctaText
|
|
2364
|
+
}
|
|
2365
|
+
);
|
|
2366
|
+
}
|
|
2367
|
+
const inputStyle = {
|
|
2368
|
+
flex: 1,
|
|
2369
|
+
minWidth: 0,
|
|
2370
|
+
padding: "0.875rem 1rem",
|
|
2371
|
+
background: theme.surface,
|
|
2372
|
+
border: `1px solid ${theme.fg}25`,
|
|
2373
|
+
color: theme.fg,
|
|
2374
|
+
fontSize: "0.9rem",
|
|
2375
|
+
fontWeight: 300,
|
|
2376
|
+
outline: "none",
|
|
2377
|
+
fontFamily: "inherit",
|
|
2378
|
+
boxSizing: "border-box"
|
|
2379
|
+
};
|
|
2380
|
+
return /* @__PURE__ */ jsxs("form", { onSubmit, style: { maxWidth: 480, margin: "0 auto" }, children: [
|
|
2381
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 0 }, children: [
|
|
2382
|
+
/* @__PURE__ */ jsx(
|
|
2383
|
+
"input",
|
|
2384
|
+
{
|
|
2385
|
+
type: "text",
|
|
2386
|
+
placeholder: "first name",
|
|
2387
|
+
value: firstName,
|
|
2388
|
+
autoFocus: true,
|
|
2389
|
+
onChange: (e) => setFirstName(e.target.value),
|
|
2390
|
+
style: { ...inputStyle, borderRight: "none" }
|
|
2391
|
+
}
|
|
2392
|
+
),
|
|
2393
|
+
/* @__PURE__ */ jsx(
|
|
2394
|
+
"input",
|
|
2395
|
+
{
|
|
2396
|
+
type: "email",
|
|
2397
|
+
placeholder: "email",
|
|
2398
|
+
value: email,
|
|
2399
|
+
required: true,
|
|
2400
|
+
onChange: (e) => setEmail(e.target.value),
|
|
2401
|
+
style: { ...inputStyle, borderRight: "none" }
|
|
2402
|
+
}
|
|
2403
|
+
),
|
|
2404
|
+
/* @__PURE__ */ jsx(
|
|
2405
|
+
"button",
|
|
2406
|
+
{
|
|
2407
|
+
type: "submit",
|
|
2408
|
+
disabled: status === "loading",
|
|
2409
|
+
style: {
|
|
2410
|
+
padding: "0.875rem 1.25rem",
|
|
2411
|
+
background: theme.fg,
|
|
2412
|
+
color: theme.bg,
|
|
2413
|
+
border: "none",
|
|
2414
|
+
fontSize: "0.75rem",
|
|
2415
|
+
fontWeight: 600,
|
|
2416
|
+
letterSpacing: "0.08em",
|
|
2417
|
+
textTransform: "uppercase",
|
|
2418
|
+
cursor: status === "loading" ? "wait" : "pointer",
|
|
2419
|
+
fontFamily: "inherit",
|
|
2420
|
+
whiteSpace: "nowrap",
|
|
2421
|
+
flexShrink: 0,
|
|
2422
|
+
opacity: status === "loading" ? 0.7 : 1
|
|
2423
|
+
},
|
|
2424
|
+
children: status === "loading" ? "..." : submitText
|
|
2425
|
+
}
|
|
2426
|
+
)
|
|
2427
|
+
] }),
|
|
2428
|
+
status === "error" && errorMsg && /* @__PURE__ */ jsx("p", { style: { fontSize: "0.75rem", color: "#e55", margin: "0.5rem 0 0", textAlign: "left" }, children: errorMsg })
|
|
2429
|
+
] });
|
|
2430
|
+
}
|
|
2269
2431
|
function TextSection({ section, theme }) {
|
|
2270
2432
|
const { heading, body } = section.content;
|
|
2271
2433
|
const align = section.config?.align || "left";
|
|
@@ -2417,25 +2579,21 @@ function toEmbedUrl(url) {
|
|
|
2417
2579
|
}
|
|
2418
2580
|
function ReviewLine({ rating, count, source, url, accent, fg }) {
|
|
2419
2581
|
const label = `${rating.toFixed(1)} \xB7 ${count} ${source || "reviews"}`;
|
|
2420
|
-
const
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2582
|
+
const content = /* @__PURE__ */ jsxs("div", { style: {
|
|
2583
|
+
marginTop: "1.5rem",
|
|
2584
|
+
display: "flex",
|
|
2585
|
+
alignItems: "center",
|
|
2586
|
+
justifyContent: "center",
|
|
2587
|
+
gap: "0.625rem"
|
|
2588
|
+
}, children: [
|
|
2589
|
+
/* @__PURE__ */ jsx("span", { dangerouslySetInnerHTML: { __html: GOOGLE_G } }),
|
|
2590
|
+
/* @__PURE__ */ jsx("span", { style: { display: "inline-flex", gap: "2px" }, children: [1, 2, 3, 4, 5].map((s) => /* @__PURE__ */ jsx("svg", { width: 16, height: 16, viewBox: "0 0 20 20", fill: s <= Math.round(rating) ? "#FBBC05" : `${fg}20`, children: /* @__PURE__ */ jsx("path", { d: "M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" }) }, s)) }),
|
|
2591
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.9rem", color: `${fg}AA`, fontWeight: 500 }, children: label })
|
|
2425
2592
|
] });
|
|
2426
2593
|
if (url) {
|
|
2427
|
-
return /* @__PURE__ */ jsx("
|
|
2428
|
-
"a",
|
|
2429
|
-
{
|
|
2430
|
-
href: url,
|
|
2431
|
-
target: "_blank",
|
|
2432
|
-
rel: "noopener noreferrer",
|
|
2433
|
-
style: { textDecoration: "none", display: "inline-flex", alignItems: "center", gap: "0.5rem" },
|
|
2434
|
-
children: inner
|
|
2435
|
-
}
|
|
2436
|
-
) });
|
|
2594
|
+
return /* @__PURE__ */ jsx("a", { href: url, target: "_blank", rel: "noopener noreferrer", style: { textDecoration: "none", display: "block" }, children: content });
|
|
2437
2595
|
}
|
|
2438
|
-
return
|
|
2596
|
+
return content;
|
|
2439
2597
|
}
|
|
2440
2598
|
function CTASection({ section, theme, tracking, onEvent }) {
|
|
2441
2599
|
const { title, subtitle, buttons } = section.content;
|
|
@@ -3290,7 +3448,7 @@ function SectionRenderer({
|
|
|
3290
3448
|
const el = (() => {
|
|
3291
3449
|
switch (section.type) {
|
|
3292
3450
|
case "hero":
|
|
3293
|
-
return /* @__PURE__ */ jsx(HeroSection, { section, theme, tracking, onEvent });
|
|
3451
|
+
return /* @__PURE__ */ jsx(HeroSection, { section, theme, tracking, onEvent, data });
|
|
3294
3452
|
case "collage_hero":
|
|
3295
3453
|
return /* @__PURE__ */ jsx(CollageHeroSection, { section, theme, tracking, onEvent });
|
|
3296
3454
|
case "text":
|