/* BioReveal — Reveal page (v0.9 — analysis-first). * * Renders the AI's REAL analysis of the patient. No raw biomarker numbers * displayed — the AI interpreted them and wrote the read. Same render path * for both Claude and rules-engine output (they share schema). */ const PEPTIDE_PRICES = { "Sermorelin": 179, "NAD+": 189, "BPC-157": 149, "Glutathione": 119, "Ipamorelin": 169, "GHK-Cu": 159, "Selank": 139, "DSIP": 129, "B12 / MIC": 99, "CJC-1295": 169, "TB-500": 219, "Tesamorelin": 199, "Epitalon": 149, "Semax": 149, "PT-141": 119, }; const StepAnalysis = ({ onStart, error, onRetry }) => { const lines = [ "Reading what you said you want fixed", "Cross-checking your health background", "Reading the bioscan", "Picking the right peptides for you", "Cross-referencing 47,000+ outcomes", "Drafting your personal read", "Sequencing the protocol", "Adding lifestyle plays", "Finalizing the dose schedule", ]; const [i, setI] = React.useState(0); const [elapsed, setElapsed] = React.useState(0); const startedRef = React.useRef(false); React.useEffect(() => { if (!startedRef.current) { startedRef.current = true; onStart(); } }, []); // Keep cycling through the lines indefinitely until the parent flips to // reveal stage. Synth can take 30-60+ seconds when OAuth is contended, // so we never want a frozen "Writing your analysis…" with no movement. React.useEffect(() => { if (error) return; const t = setTimeout(() => setI((prev) => (prev + 1) % lines.length), 1100); return () => clearTimeout(t); }, [i, error]); // Elapsed-time counter so the user can see something is still moving React.useEffect(() => { if (error) return; const t = setInterval(() => setElapsed((s) => s + 1), 1000); return () => clearInterval(t); }, [error]); // Show "still working" hint after 15s. The OAuth backoff chain can take // 60s+ when our Claude credits are contended — be honest about it. const slowHint = elapsed >= 15; const verySlowHint = elapsed >= 45; return (
{error ? "Synthesis paused" : "Writing your analysis"}
{!error && ( <>
{lines.map((l, idx) => (
{l}
))}
● {String(Math.floor(elapsed / 60)).padStart(2, "0")}:{String(elapsed % 60).padStart(2, "0")} ELAPSED
{slowHint && !verySlowHint && (
Still going — deep reasoning on a busy day can take up to a minute. Don't refresh.
)} {verySlowHint && (
Almost there. The clinical model is queued behind other requests right now — usually finishes within another 30 seconds.
)} )} {error && (
ERROR
{error}
)}
); }; // Map peptide name → URL slug for deep-page links const PEPTIDE_SLUG = { "Sermorelin": "sermorelin", "NAD+": "nad-plus", "BPC-157": "bpc-157", "Ipamorelin": "ipamorelin", "GHK-Cu": "ghk-cu", "Glutathione": "glutathione", "Selank": "selank", "DSIP": "dsip", "B12 / MIC": "b12-mic", "CJC-1295": "cjc-1295", }; const Reveal = ({ profile, onRestart }) => { const { protocol } = profile; const peptides = (protocol.recommended_protocol || []).map(p => ({ ...p, price: PEPTIDE_PRICES[p.name] || 159 })); const total = peptides.reduce((s, p) => s + p.price, 0); const engine = protocol._meta?.engine || "fallback"; const { MDReviewer, ComplianceStrip, Testimonials, PressStrip } = window.BR_TRUST || {}; const { ChatSidekick } = window.BR_CHAT || {}; // Email auto-send. We captured email on funnel step 2 — fire /api/email-analysis // once on mount so the user sees their analysis in the inbox without having // to click anything. Confirmation rendered inline near the CTA. const userEmail = profile?.intake?.email || ""; const [autoSend, setAutoSend] = React.useState({ status: "idle", error: "" }); // idle | sending | sent | failed const autoSendFiredRef = React.useRef(false); // Stash protocol context so consult.html can pick it up React.useEffect(() => { try { sessionStorage.setItem("br_protocol_summary", JSON.stringify({ stackName: protocol.stack_name, peptides: peptides.map(p => p.name), total, sessionId: protocol.session_id || null, })); } catch {} }, [protocol.stack_name, total, protocol.session_id]); React.useEffect(() => { if (autoSendFiredRef.current) return; if (!userEmail || !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(userEmail)) return; autoSendFiredRef.current = true; setAutoSend({ status: "sending", error: "" }); fetch("/api/email-analysis", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ session_id: protocol.session_id || null, email: userEmail, protocol, }), }) .then(r => r.json()) .then(d => { if (d.ok) setAutoSend({ status: "sent", error: "" }); else setAutoSend({ status: "failed", error: d.message || "Send failed" }); }) .catch(err => setAutoSend({ status: "failed", error: err.message || "Network error" })); }, [userEmail, protocol.session_id]); // Split analysis paragraphs const analysisParas = (protocol.analysis || "").split(/\n\n+/).filter(Boolean); return (
{/* HERO — headline + engine tag */}
★ YOUR PERSONAL READ

{protocol.stack_name}

{protocol.headline}

{/* THE ANALYSIS — the new headline section */} {analysisParas.length > 0 && (
★ THE READ
{analysisParas.map((p, i) => (

$1") }}/> ))}

)} {/* PROTOCOL CARDS */} {peptides.length > 0 && (
★ THE PROTOCOL

What we'd recommend.

{peptides.length} peptide{peptides.length > 1 ? "s" : ""}, sequenced for your goals + signals. A licensed clinician reviews before anything ships.

{peptides.map((p, i) => (

{p.name}

{p.mechanism_short}

★ Why for you {p.match_reason}

Dose
{p.dose}
Week 1
{p.expected_week_1}
Week 12
{p.expected_week_12}
{(p.side_effects_likely?.length || p.contraindications?.length) ? (
{p.side_effects_likely?.length > 0 &&
SIDE EFFECTS · {p.side_effects_likely.join(" · ")}
} {p.contraindications?.length > 0 &&
⚠ AVOID IF · {p.contraindications.join(" · ")}
}
) : null}
${p.price}/mo
Read more →
))}
)} {/* LIFESTYLE PLAYS */} {protocol.lifestyle_plays?.length > 0 && (
★ FREE LEVERS

Lifestyle moves that compound the protocol.

These cost nothing and double the effect of every peptide we recommended.

{protocol.lifestyle_plays.map((l, i) => (
{String(i + 1).padStart(2, "0")}

{l.play}

{l.why}

))}
)} {/* WHAT TO WATCH */} {protocol.what_to_watch?.length > 0 && (
★ HOW YOU'LL KNOW IT'S WORKING

Track these week-to-week.

{protocol.what_to_watch.map((w, i) => (
Track
{w.signal}
If working
{w.if_improving}
If not
{w.if_not}
))}
)} {/* HONEST CAVEAT */} {protocol.if_im_being_honest && (
★ IF I'M BEING HONEST

{protocol.if_im_being_honest}

)} {/* MD REVIEW FLAGS */} {protocol.md_review_flags?.length > 0 && protocol.md_review_flags[0] !== "routine_review" && (
★ MD REVIEW FLAGS
{protocol.md_review_flags.map(f => ( ⚑ {f.replace(/_/g, " ")} ))}
)} {/* TRUST: MD reviewer */} {MDReviewer && } {/* TRUST: testimonials */} {Testimonials && } {/* TRUST: compliance + money-back */} {ComplianceStrip && } {/* TRUST: press */} {PressStrip && } {/* FINAL CTA */}

Book your $0 MD consult.

{peptides.length > 0 && (
Estimated stack · monthly ${total}/mo
)} {/* Auto-send confirmation (silent if no email captured) */} {userEmail && autoSend.status === "sending" && (
● Emailing your analysis to {userEmail}…
)} {userEmail && autoSend.status === "sent" && (
✓ Sent to {userEmail} · Check your inbox
)} {userEmail && autoSend.status === "failed" && (
✗ Couldn't email — we'll retry shortly
)}
{protocol.disclaimer || "DRAFT — pending licensed clinician review."}
); }; Object.assign(window, { Reveal, StepAnalysis });