// game-plan-form.jsx — custom multi-step lead form for the Amazon Game Plan page.
// One question at a time (Typeform-style). Branches on "what brings you here".
// Emails the lead + their requested day/time to EMAIL_ENDPOINT; you confirm by hand.
// Exported to window.GamePlanForm and mounted by the page's inline script.
/* ====================================================================== *
* CONFIG — the one thing to wire up before going live. *
* ====================================================================== */
// Where lead answers + the requested slot are sent. This is your Formspree
// endpoint — every submission is emailed to you automatically.
const EMAIL_ENDPOINT = "https://formspree.io/f/xjgdpzab";
/* ====================================================================== *
* QUESTIONS — edit freely. {name} is replaced with their first name. *
* type: text | longtext | email | tel | select | booking *
* showIf: optional fn(answers) => bool (used for the new/existing fork) *
* ====================================================================== */
const STEPS = [
{ id: "name", type: "text", required: true,
q: "Hey there — what should we call you?",
help: "First name is perfect.", placeholder: "e.g. Jordan" },
{ id: "reason", type: "select", required: true,
q: "What brings you here, {name}?",
help: "So your game plan is built around the right thing.",
options: [
{ value: "start", label: "I want to start selling on Amazon" },
{ value: "grow", label: "I'm already selling and want to grow" },
] },
// ---- branch: brand-new sellers ----
{ id: "stage", type: "select", showIf: (a) => a.reason === "start",
q: "How far along are you?",
help: "No wrong answer — it just shapes the plan.",
options: [
{ value: "researching", label: "Just researching" },
{ value: "picked", label: "Picked a product" },
{ value: "sourcing", label: "Sourcing it now" },
{ value: "ready", label: "Ready to launch" },
] },
// ---- branch: existing sellers ----
{ id: "revenue", type: "select", showIf: (a) => a.reason === "grow",
q: "Roughly how much are you doing per month?",
help: "Ballpark is fine — it stays private.",
options: [
{ value: "<10k", label: "Under $10k / mo" },
{ value: "10-50k", label: "$10k – $50k / mo" },
{ value: "50-250k", label: "$50k – $250k / mo" },
{ value: "250k+", label: "$250k+ / mo" },
] },
{ id: "store", type: "text", showIf: (a) => a.reason === "grow", required: false,
q: "Got a store or product link?",
help: "Optional — your storefront or an ASIN link lets us look before we talk.",
placeholder: "amazon.com/…" },
{ id: "goal", type: "select",
q: "Where do you want to be in 12 months?",
help: "Your revenue goal.",
options: [
{ value: "<10k", label: "$0 – $10k / mo" },
{ value: "10-50k", label: "$10k – $50k / mo" },
{ value: "50-250k", label: "$50k – $250k / mo" },
{ value: "250k+", label: "$250k+ / mo" },
] },
{ id: "challenge", type: "longtext", required: false,
q: "What's the biggest thing in your way right now?",
help: "One line is plenty — this shapes your plan more than anything else.",
placeholder: "e.g. my listings get traffic but don't convert…" },
{ id: "budget", type: "select",
q: "Do you have budget set aside to invest in your Amazon?",
help: "No figure needed — this just tells us what to plan toward.",
options: [
{ value: "now", label: "Ready to invest now" },
{ value: "building", label: "Building toward it" },
{ value: "notyet", label: "Not yet" },
] },
{ id: "location", type: "text",
q: "Where are you based?",
help: "Just so we get your timezone right for the call.",
placeholder: "City, country" },
{ id: "email", type: "email", required: true,
q: "Where should we send your game plan, {name}?",
help: "For your plan and the call confirmation. No spam, ever.",
placeholder: "name@example.com" },
{ id: "whatsapp", type: "tel", required: false,
q: "WhatsApp number?",
help: "Optional — usually the quickest way to reach you.",
placeholder: "+1 555 000 0000" },
{ id: "source", type: "text", required: false,
q: "One last thing — how did you hear about us?",
help: "Optional, but it helps us a lot.",
placeholder: "e.g. Google, a friend, YouTube…" },
{ id: "booking", type: "booking",
q: "Last step, {name} — request your walkthrough",
help: "20 focused minutes where we walk you through your plan — what to do, in what order, what it's worth. Pick a preferred day and any times that suit you; we'll work around your calendar and confirm by email." },
];
/* ====================================================================== */
const { useState, useEffect, useRef, useMemo } = React;
const firstName = (a) => (a.name || "").trim().split(/\s+/)[0] || "there";
const fill = (str, a) => (str || "").replace(/\{name\}/g, firstName(a));
const isEmail = (v) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test((v || "").trim());
function submitLead(answers, stage) {
const payload = { ...answers, _stage: stage, _form: "Amazon Game Plan", _subject: "New Amazon Game Plan request", _ts: new Date().toISOString() };
if (!EMAIL_ENDPOINT) { console.log("[GamePlanForm] lead (" + stage + "):", payload); return; }
try {
fetch(EMAIL_ENDPOINT, {
method: "POST",
headers: { "Content-Type": "application/json", Accept: "application/json" },
body: JSON.stringify(payload),
keepalive: true,
}).catch(() => {});
} catch (e) { /* preview sandbox can't reach the network — fine */ }
}
function fireConversion() {
if (typeof window.gtag === "function") {
window.gtag("event", "conversion", { send_to: "AW-16798512866/JjupCLPRq7wcEOLtk8o-" });
}
}
function ProgressBar({ value }) {
return
Choose a weekday on the left, then pick the time that suits you best.
)}
);
}
function GamePlanForm() {
const [answers, setAnswers] = useState({});
const [idx, setIdx] = useState(0);
const [err, setErr] = useState("");
const [done, setDone] = useState(false);
const [leadSent, setLeadSent] = useState(false);
const inputRef = useRef(null);
const steps = useMemo(() => STEPS.filter((s) => !s.showIf || s.showIf(answers)), [answers]);
const step = steps[Math.min(idx, steps.length - 1)];
const progress = done ? 1 : (idx + 1) / steps.length;
useEffect(() => {
setErr("");
if (inputRef.current) inputRef.current.focus();
}, [idx, step && step.id]);
function setVal(v) { setAnswers((a) => ({ ...a, [step.id]: v })); setErr(""); }
function validate() {
const v = answers[step.id];
if (step.required && (!v || !String(v).trim())) {
setErr(step.type === "select" ? "Pick one to continue." : "This one's required."); return false;
}
if (step.type === "email" && v && !isEmail(v)) { setErr("That email doesn't look right."); return false; }
return true;
}
function captureLeadOnce() {
// fire the lead to email as soon as we have an email, so nothing is lost
if (!leadSent && answers.email) { submitLead(answers, "lead"); setLeadSent(true); }
}
function advance() {
if (!validate()) return;
if (step.id === "email") captureLeadOnce();
if (idx >= steps.length - 1) { finish(); return; }
setIdx((i) => i + 1);
}
function back() { if (idx > 0) setIdx((i) => i - 1); }
function pick(value) {
setAnswers((a) => ({ ...a, [step.id]: value }));
setErr("");
const isLast = idx >= steps.length - 1;
setTimeout(() => { isLast ? finish() : setIdx((i) => i + 1); }, 240);
}
function finish(extra) {
const merged = extra ? { ...answers, ...extra } : { ...answers };
if (!leadSent && merged.email) { submitLead(merged, "lead"); setLeadSent(true); }
submitLead(merged, "complete");
fireConversion();
setAnswers(merged);
setDone(true);
}
function onKey(e) {
if (e.key === "Enter" && step && step.type !== "longtext" && step.type !== "booking") {
e.preventDefault(); advance();
}
}
if (done) {
const slot = answers.booking_label;
return (
✓
Request received, {firstName(answers)}.
We've got your details and we're building your Amazon game plan by hand.
{slot ? <> You asked for {slot} — we'll confirm a time> : <> We'll confirm your walkthrough>}
{answers.email ? <> by email at {answers.email}> : <> by email>}, usually within a few hours.
Pending confirmation · No card charged · No obligation
);
}
const total = steps.length;
const num = String(idx + 1).padStart(2, "0");
return (