import { useState } from 'react' import { useNavigate } from 'react-router-dom' import { api } from '../api' /* === Tooltip Component === */ function Tip({ text, children }) { const [show, setShow] = useState(false) return ( {children} setShow(true)} onMouseLeave={() => setShow(false)} onClick={(e) => { e.stopPropagation(); setShow(s => !s) }} style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: '18px', height: '18px', borderRadius: '50%', marginLeft: '6px', background: 'rgba(0,0,0,0.06)', color: 'var(--text-3)', cursor: 'help', fontSize: '0.7rem', fontWeight: 800, flexShrink: 0, }}>? {show && ( {text} )} ) } const GOALS = [ { value: 'lose_weight', label: 'Lose Weight', icon: '⚖️', tip: 'Focus on caloric deficit through cardio and portion-controlled nutrition.' }, { value: 'build_strength', label: 'Build Strength', icon: '💪', tip: 'Progressive overload training — gradually increasing weight or resistance.' }, { value: 'get_active', label: 'Get More Active', icon: '🏃', tip: 'Building a consistent movement habit. Walking counts!' }, { value: 'feel_better', label: 'Feel Better Overall', icon: '😊', tip: 'Mind-body balance — stress relief, sleep quality, energy levels.' }, ] const TTM_STAGES = [ { value: 'precontemplation', label: "I'm not exercising and haven't thought about starting", tip: 'Pre-contemplation: No intention to act. We\'ll start with awareness and gentle nudges.' }, { value: 'contemplation', label: "I've been thinking about getting more active but haven't started", tip: 'Contemplation: Weighing pros and cons. We\'ll help tip the balance toward action.' }, { value: 'preparation', label: 'I do some exercise but not consistently', tip: 'Preparation: Ready to commit. We\'ll help you build a sustainable routine.' }, { value: 'action', label: "I've been exercising regularly for a few months", tip: 'Action: Building the habit. We\'ll help you stay consistent and avoid burnout.' }, { value: 'maintenance', label: "I've been exercising regularly for 6+ months", tip: 'Maintenance: Solid habit. We\'ll help you progress and keep things interesting.' }, ] const ACTIVITIES = [ 'Walking', 'Hiking', 'Running', 'Cycling', 'Swimming', 'Bodyweight', 'Weights', 'Yoga', 'Martial Arts', 'Dance', 'Team Sports', 'Pilates', 'Rowing', 'Jump Rope', 'Stretching', ] const EQUIPMENT_OPTIONS = [ { value: 'bicycle', label: '🚲 Bicycle' }, { value: 'pool', label: '🏊 Pool' }, { value: 'free_weights', label: '🏋️ Free Weights' }, { value: 'squat_rack', label: '🦵 Squat Rack' }, { value: 'bench_press', label: '💺 Bench Press' }, { value: 'machines', label: '⚙️ Machines' }, { value: 'resistance_bands', label: '🔗 Resistance Bands' }, { value: 'pull_up_bar', label: '🔩 Pull-up Bar' }, { value: 'kettlebell', label: '🔔 Kettlebell' }, { value: 'jump_rope', label: '⏩ Jump Rope' }, { value: 'yoga_mat', label: '🧘 Yoga Mat' }, { value: 'treadmill', label: '🏃 Treadmill' }, { value: 'stationary_bike', label: '🚴 Stationary Bike' }, { value: 'rowing_machine', label: '🚣 Rowing Machine' }, ] const BREQ2_ITEMS = [ { key: 'ext', label: '"People important to me say I should exercise"', tip: 'External regulation: exercising because others push you to. Least self-determined motivation.' }, { key: 'intro', label: '"I feel bad about myself when I skip exercise"', tip: 'Introjected regulation: guilt or obligation as a driver. Better than external, but still fragile.' }, { key: 'ident', label: '"I value what exercise does for my health"', tip: 'Identified regulation: you see exercise as personally important. A strong, durable motivator.' }, { key: 'intr', label: '"I find exercise enjoyable and satisfying"', tip: 'Intrinsic motivation: you exercise because it\'s fun. The most sustainable form of motivation.' }, { key: 'amot', label: '"I don\'t really see why I should bother"', tip: 'Amotivation: no perceived reason to exercise. If this is high, we\'ll start with very small wins.' }, ] export default function Onboarding() { const [step, setStep] = useState(0) const [goal, setGoal] = useState('') const [ttm, setTtm] = useState('') const [age, setAge] = useState('') const [heightCm, setHeightCm] = useState('') const [weightKg, setWeightKg] = useState('') const [gender, setGender] = useState('') const [parq, setParq] = useState({ heart: false, joints: false, meds: false }) const [motivation, setMotivation] = useState({ ext: 0, intro: 0, ident: 0, intr: 0, amot: 0 }) const [activities, setActivities] = useState([]) const [equipmentList, setEquipmentList] = useState([]) const [daysPerWeek, setDaysPerWeek] = useState(3) const [minsPerSession, setMinsPerSession] = useState(30) const [rewards, setRewards] = useState([{ name: '', cost: 100 }]) const [recommendations, setRecommendations] = useState([]) const [loading, setLoading] = useState(false) const navigate = useNavigate() const totalSteps = 8 function Likert({ label, value, onChange, tip }) { return (
Pick one — you can change this anytime.
Be honest — there's no wrong answer.
{TTM_STAGES.map(s => (For your safety — this takes 10 seconds.
{[ { key: 'heart', label: 'I have a heart condition or high blood pressure' }, { key: 'joints', label: 'I have bone or joint problems that could worsen with exercise' }, { key: 'meds', label: 'I take prescription medications for a chronic condition' }, ].map(q => ( ))} {(parq.heart || parq.joints || parq.meds) && (Optional — helps estimate nutrition needs.
Rate each honestly — helps us calibrate your experience.
{BREQ2_ITEMS.map(item => (Pick all that interest you.
No selection = bodyweight only. That's perfectly fine!
)}What guilty pleasures do you want to earn?
{rewards.map((r, i) => (Pick a program and commit to 90 days.
{recommendations.map(rec => ({rec.description}