// onboarding.jsx — fluxo: welcome → nível → nome+objetivo → anamnese → plano → zenith → lembrete const { useState: useStateOb } = React; /* ---------- header com barra de progresso ---------- */ function OnboardHeader({ frac, onBack, showBack }) { return (
{showBack ? ( ) : }
); } function SelectCard({ active, onClick, children }) { return ( ); } /* ---------- slider de métrica com número grande ---------- */ function MetricSlider({ label, value, min, max, step = 1, unit, onChange }) { return (
{label} {value} {unit}
onChange(Number(e.target.value))} />
); } /* ---------- cartão de tipo de corpo (placeholder silhueta) ---------- */ function BodyCard({ active, label, onClick }) { return ( ); } function Onboarding({ onComplete }) { // fluxo linear de telas const STEPS = ['welcome','nivel','nome','objetivo','metrics','imc','corpoAtual','corpoAlvo','dias','plano','zenith','lembrete']; const [i, setI] = useStateOb(0); const key = STEPS[i]; // dados coletados const [level, setLevel] = useStateOb(null); const [name, setName] = useStateOb(''); const [objective, setObjective] = useStateOb(null); const [sex, setSex] = useStateOb(null); const [weight, setWeight] = useStateOb(75); const [height, setHeight] = useStateOb(172); const [birth, setBirth] = useStateOb('2000-01-01'); const [target, setTarget] = useStateOb(70); const [bodyNow, setBodyNow] = useStateOb(null); const [bodyTgt, setBodyTgt] = useStateOb(null); const [days, setDays] = useStateOb(4); const [reminder, setReminder] = useStateOb('07:00'); const imc = computeIMC(weight, height); const imcCat = imcCategory(imc); const plan = estimatePlan({ objective, weight, targetWeight: target, days }); const next = () => setI(s => Math.min(STEPS.length - 1, s + 1)); const back = () => setI(s => Math.max(0, s - 1)); const objLabel = (OBJECTIVES.find(o => o.id === objective) || {}).label || ''; const firstName = name.trim().split(' ')[0]; const footer = (label, disabled, onClick) => (
); return (
{key !== 'welcome' && 0} />}
{/* WELCOME */} {key === 'welcome' && (
HERO / ATLETA EM AÇÃO1080 × 1350
CALISTENIA · 30 DIAS

Domine o
seu corpo

Treinos guiados, sem equipamento. Evolua com o Zenith ao seu lado, um dia de cada vez.

)} {/* NÍVEL — PASSO 1 */} {key === 'nivel' && (
PASSO 1 · NÍVEL

Qual seu
nível?

Você pode mudar isso depois.

{LEVELS.map(l => ( setLevel(l.id)}>
{l.label}
{l.desc}
{l.meta}
))}
)} {/* NOME — PASSO 2 */} {key === 'nome' && (
PASSO 2 · IDENTIDADE

Como devo
te chamar?

O Zenith vai falar diretamente com você.

setName(e.target.value)} /> {firstName && (
ZENITH DIZ

Prazer, {firstName}. Vamos construir sua melhor versão.

)}
)} {/* OBJETIVO — PASSO 2 */} {key === 'objetivo' && (
PASSO 2 · OBJETIVO

Qual seu
objetivo?

{firstName ? `${firstName}, o que ` : 'O que '}você busca?

{OBJECTIVES.map(g => ( setObjective(g.id)}>
{g.label}
{g.desc}
))}
)} {/* MÉTRICAS — PASSO 3 */} {key === 'metrics' && (
PASSO 3 · ANAMNESE

Seus
dados

Usamos para calibrar seu plano. Fica só com você.

SEXO
{SEXES.map(s => ( ))}
DATA DE NASCIMENTO
setBirth(e.target.value)} />
)} {/* IMC RESULT */} {key === 'imc' && (
RESULTADO · IMC

Seu índice
de massa

{imc.toFixed(1)}
{imcCat.label}
{/* escala */}
ABAIXO NORMAL SOBREPESO OBESO

{firstName ? `${firstName}, ` : ''}vamos da sua marca de {weight}kg rumo aos {target}kg. Um passo de cada vez.

)} {/* CORPO ATUAL */} {key === 'corpoAtual' && (
PASSO 3 · CORPO ATUAL

Como você
está hoje?

Escolha o tipo mais próximo do seu.

{BODY_NOW.map(b => setBodyNow(b.id)} />)}
)} {/* CORPO ALVO */} {key === 'corpoAlvo' && (
PASSO 3 · CORPO ALVO

Onde quer
chegar?

Sua meta visual. Vamos mirar nela.

{BODY_TARGET.map(b => setBodyTgt(b.id)} />)}
)} {/* DIAS POR SEMANA */} {key === 'dias' && (
PASSO 3 · FREQUÊNCIA

Quantos dias
por semana?

Seja realista. Consistência vence intensidade.

{days}
DIAS / SEMANA
{[1,2,3,4,5,6,7].map(d => ( ))}
)} {/* PLANO — resumo */} {key === 'plano' && (
SEU PLANO ESTÁ PRONTO

{firstName ? `Vamos lá,\n${firstName}` : 'Vamos lá'}

Plano calibrado para o seu objetivo.

{/* destaque: estimativa */}
ESTIMATIVA PARA SUA META
{plan.text}
{objLabel.toUpperCase()} · {days}× POR SEMANA
{/* grid de resumo */}
{[ ['IMC ATUAL', imc.toFixed(1), imcCat.label], ['META DE PESO', `${target}kg`, `de ${weight}kg`], ['OBJETIVO', objLabel, (LEVELS.find(l => l.id === level) || {}).label || ''], ['FREQUÊNCIA', `${days}×`, 'por semana'], ].map(([k, v, s]) => (
{k}
{v}
{s}
))}
ZENITH DIZ

Tudo pronto{firstName ? `, ${firstName}` : ''}. Eu cuido do plano — você cuida da presença. Bora?

)} {/* ZENITH */} {key === 'zenith' && (
SEU MENTOR

Zenith

O Zenith evolui com você. A cada treino concluído, ele cresce — e desbloqueia novas habilidades para te guiar.

" Vamos começar?
)} {/* LEMBRETE */} {key === 'lembrete' && (
QUASE LÁ

Quando
treinar?

O Zenith vai te lembrar todo dia neste horário.

{reminder}
{['06:00','07:00','08:00','12:00','18:00','20:00'].map(t => ( ))}
)}
{/* footers */} {key === 'welcome' && footer('Começar', false, next)} {key === 'nivel' && footer('Continuar', !level, next)} {key === 'nome' && footer('Continuar', !name.trim(), next)} {key === 'objetivo' && footer('Continuar', !objective, next)} {key === 'metrics' && footer('Calcular meu IMC', !sex, next)} {key === 'imc' && footer('Continuar', false, next)} {key === 'corpoAtual' && footer('Continuar', !bodyNow, next)} {key === 'corpoAlvo' && footer('Continuar', !bodyTgt, next)} {key === 'dias' && footer('Gerar meu plano', false, next)} {key === 'plano' && footer('Conhecer o Zenith', false, next)} {key === 'zenith' && footer('Continuar', false, next)} {key === 'lembrete' && footer('Entrar no app', false, () => onComplete({ name: name.trim(), level, objective, sex, weight, height, birth, target, bodyNow, bodyTgt, days, reminder, imc, plan }))}
); } Object.assign(window, { Onboarding });