// Root onboarding app — owns the route state and the answers dict. // Routes: fork → → build → ready. A floating debug navigator (toggle // in the lower-right) lets reviewers jump between any screen without // filling out the form. function OnboardingApp() { const initialName = React.useMemo(() => { try { return localStorage.getItem("vibn:firstName") || ""; } catch { return ""; } }, []); const [stage, setStage] = React.useState("fork"); // fork | path | build | ready const [path, setPath] = React.useState(null); // entrepreneur | owner | consultant const [forkChoice, setForkChoice] = React.useState(null); const [step, setStep] = React.useState(0); const [data, setData] = React.useState({}); const [debugOpen, setDebugOpen] = React.useState(false); const update = (patch) => setData((d) => ({ ...d, ...patch })); // ── transitions ────────────────────────────────────────────────────── const confirmFork = () => { if (!forkChoice) return; setPath(forkChoice); setStep(0); setStage("path"); }; const backToFork = () => { setStage("fork"); setStep(0); }; const completePath = () => setStage("build"); const openWorkspace = () => setStage("ready"); const close = () => { window.location.href = "index.html"; }; const openChat = () => { window.location.href = "index.html"; }; // ⌘↵ advances on whatever the current primary action is React.useEffect(() => { const handler = (e) => { if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) { const btn = document.querySelector(".btn-primary:not([disabled])"); if (btn) btn.click(); } }; window.addEventListener("keydown", handler); return () => window.removeEventListener("keydown", handler); }, []); // ── render ─────────────────────────────────────────────────────────── let body; if (stage === "fork") { body = ( ); } else if (stage === "path") { const props = { data, onUpdate: update, onBack: backToFork, onClose: close, onComplete: completePath, onJumpToStep: setStep, step, }; if (path === "entrepreneur") body = ; else if (path === "owner") body = ; else body = ; } else if (stage === "build") { body = ( setStage("path")} onClose={close} onOpen={openWorkspace} /> ); } else { body = ; } return (
{body} { if (s === "fork") setStage("fork"); else if (s === "build") { setPath(p); setStage("build"); } else if (s === "ready") { setPath(p); setStage("ready"); } else { setPath(p); setStep(idx); setStage("path"); } }} />
); } // ── Debug navigator ────────────────────────────────────────────────────── function DebugNav({ open, setOpen, stage, path, step, onJump }) { const groups = [ { title: "Start", rows: [ { label: "01 · Fork", active: stage === "fork", go: () => onJump("fork") }, ]}, { title: "Entrepreneur", rows: [ { label: "02 · Idea", active: stage === "path" && path === "entrepreneur" && step === 0, go: () => onJump("path", "entrepreneur", 0) }, { label: "03 · Audience", active: stage === "path" && path === "entrepreneur" && step === 1, go: () => onJump("path", "entrepreneur", 1) }, { label: "04 · Goal", active: stage === "path" && path === "entrepreneur" && step === 2, go: () => onJump("path", "entrepreneur", 2) }, { label: "05 · Vibe", active: stage === "path" && path === "entrepreneur" && step === 3, go: () => onJump("path", "entrepreneur", 3) }, ]}, { title: "Owner", rows: [ { label: "02 · Business", active: stage === "path" && path === "owner" && step === 0, go: () => onJump("path", "owner", 0) }, { label: "03 · Stack", active: stage === "path" && path === "owner" && step === 1, go: () => onJump("path", "owner", 1) }, { label: "04 · First fix", active: stage === "path" && path === "owner" && step === 2, go: () => onJump("path", "owner", 2) }, { label: "05 · Scale", active: stage === "path" && path === "owner" && step === 3, go: () => onJump("path", "owner", 3) }, ]}, { title: "Consultant", rows: [ { label: "02 · Client", active: stage === "path" && path === "consultant" && step === 0, go: () => onJump("path", "consultant", 0) }, { label: "03 · Brief", active: stage === "path" && path === "consultant" && step === 1, go: () => onJump("path", "consultant", 1) }, { label: "04 · Scope", active: stage === "path" && path === "consultant" && step === 2, go: () => onJump("path", "consultant", 2) }, { label: "05 · Handoff", active: stage === "path" && path === "consultant" && step === 3, go: () => onJump("path", "consultant", 3) }, ]}, { title: "Finish", rows: [ { label: "Build · entrepreneur", active: stage === "build" && path === "entrepreneur", go: () => onJump("build", "entrepreneur") }, { label: "Build · owner", active: stage === "build" && path === "owner", go: () => onJump("build", "owner") }, { label: "Build · consultant", active: stage === "build" && path === "consultant", go: () => onJump("build", "consultant") }, { label: "Ready", active: stage === "ready", go: () => onJump("ready", path || "entrepreneur") }, ]}, ]; return (
{open && (
{groups.map((g) => (
{g.title}
{g.rows.map((r) => ( ))}
))}
)}
); } ReactDOM.createRoot(document.getElementById("root")).render();