"use client"; import { ArrowRightIcon, CheckCircleIcon, ExclamationTriangleIcon, SparklesIcon, } from "@heroicons/react/24/outline"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import { useSession } from "@/lib/auth-client"; import { ActivityLevel, HealthGoal, HealthProfile, WeightLossPace, buildCoachRecommendations, buildGoalsFromProfile, loadHellthData, saveHellthData, } from "@/lib/hellth-data"; type FormState = { goal: HealthGoal; age: string; heightCm: string; currentWeightKg: string; targetWeightKg: string; activityLevel: ActivityLevel; pace: WeightLossPace; mealsPerDay: string; dietStyle: HealthProfile["dietStyle"]; cookingTime: HealthProfile["cookingTime"]; budgetFocus: boolean; excludedFoods: string; biggestChallenge: string; medicalNote: boolean; }; const initialForm: FormState = { goal: "lose_weight", age: "", heightCm: "", currentWeightKg: "", targetWeightKg: "", activityLevel: "moderate", pace: "normal", mealsPerDay: "3", dietStyle: "mixed", cookingTime: "medium", budgetFocus: false, excludedFoods: "", biggestChallenge: "", medicalNote: false, }; function numberFrom(value: string) { return Number(value.replace(",", ".")) || 0; } function OptionButton({ active, label, description, onClick, }: { active: boolean; label: string; description: string; onClick: () => void; }) { return ( ); } export default function OnboardingPage() { const router = useRouter(); const { data: session } = useSession(); const userKey = session?.user?.id ?? session?.user?.email ?? null; const [form, setForm] = useState(initialForm); const [savedProfile, setSavedProfile] = useState(null); const [error, setError] = useState(null); useEffect(() => { if (!userKey) return; const profile = loadHellthData(userKey).healthProfile; if (profile) { setSavedProfile(profile); setForm({ goal: profile.goal, age: String(profile.age), heightCm: String(profile.heightCm), currentWeightKg: String(profile.currentWeightKg), targetWeightKg: profile.targetWeightKg ? String(profile.targetWeightKg) : "", activityLevel: profile.activityLevel, pace: profile.pace, mealsPerDay: String(profile.mealsPerDay), dietStyle: profile.dietStyle, cookingTime: profile.cookingTime, budgetFocus: profile.budgetFocus, excludedFoods: profile.excludedFoods, biggestChallenge: profile.biggestChallenge, medicalNote: profile.medicalNote, }); } }, [userKey]); function saveProfile() { if (!userKey) return; const age = numberFrom(form.age); const heightCm = numberFrom(form.heightCm); const currentWeightKg = numberFrom(form.currentWeightKg); const targetWeightKg = numberFrom(form.targetWeightKg); if (age < 16 || heightCm < 120 || currentWeightKg < 35) { setError("Bitte Alter, Größe und aktuelles Gewicht plausibel ausfüllen."); return; } if (form.goal === "lose_weight" && targetWeightKg > 0 && targetWeightKg >= currentWeightKg) { setError("Für Abnehmen sollte das Zielgewicht unter dem aktuellen Gewicht liegen."); return; } const profile: HealthProfile = { completedAt: new Date().toISOString(), goal: form.goal, age, heightCm, currentWeightKg, targetWeightKg: targetWeightKg || undefined, activityLevel: form.activityLevel, pace: form.pace, mealsPerDay: Math.max(1, Math.min(6, numberFrom(form.mealsPerDay) || 3)), dietStyle: form.dietStyle, cookingTime: form.cookingTime, budgetFocus: form.budgetFocus, excludedFoods: form.excludedFoods.trim(), biggestChallenge: form.biggestChallenge.trim(), medicalNote: form.medicalNote, }; const goals = buildGoalsFromProfile(profile); const coachRecommendations = buildCoachRecommendations(profile, goals); const data = loadHellthData(userKey); saveHellthData({ ...data, healthProfile: profile, goals, coachRecommendations }, userKey); setSavedProfile(profile); setError(null); } const previewProfile: HealthProfile | null = numberFrom(form.age) >= 16 && numberFrom(form.heightCm) >= 120 && numberFrom(form.currentWeightKg) >= 35 ? { completedAt: new Date().toISOString(), goal: form.goal, age: numberFrom(form.age), heightCm: numberFrom(form.heightCm), currentWeightKg: numberFrom(form.currentWeightKg), targetWeightKg: numberFrom(form.targetWeightKg) || undefined, activityLevel: form.activityLevel, pace: form.pace, mealsPerDay: numberFrom(form.mealsPerDay) || 3, dietStyle: form.dietStyle, cookingTime: form.cookingTime, budgetFocus: form.budgetFocus, excludedFoods: form.excludedFoods, biggestChallenge: form.biggestChallenge, medicalNote: form.medicalNote, } : null; const previewGoals = previewProfile ? buildGoalsFromProfile(previewProfile) : null; const previewRecommendations = previewProfile && previewGoals ? buildCoachRecommendations(previewProfile, previewGoals) : []; return (

Erster Start

Dein Health-Profil

Hellth Hub nutzt diese Antworten, um alltagstaugliche Ziele und konkrete Vorschläge zu erzeugen. Die Werte sind Startpunkte und werden später über deinen echten Verlauf verbessert.

1. Ziel

setForm((current) => ({ ...current, goal: "lose_weight" }))} /> setForm((current) => ({ ...current, goal: "maintain" }))} /> setForm((current) => ({ ...current, goal: "healthier" }))} />

2. Ausgangslage

setForm((current) => ({ ...current, age: event.target.value }))} placeholder="Alter" className="rounded-2xl border border-gray-200 px-4 py-3 text-sm font-semibold" /> setForm((current) => ({ ...current, heightCm: event.target.value }))} placeholder="Größe cm" className="rounded-2xl border border-gray-200 px-4 py-3 text-sm font-semibold" /> setForm((current) => ({ ...current, currentWeightKg: event.target.value }))} placeholder="Aktuelles Gewicht kg" className="rounded-2xl border border-gray-200 px-4 py-3 text-sm font-semibold" /> setForm((current) => ({ ...current, targetWeightKg: event.target.value }))} placeholder="Zielgewicht kg" className="rounded-2xl border border-gray-200 px-4 py-3 text-sm font-semibold" />
setForm((current) => ({ ...current, activityLevel: "low" }))} /> setForm((current) => ({ ...current, activityLevel: "moderate" }))} /> setForm((current) => ({ ...current, activityLevel: "active" }))} />

3. Alltag

setForm((current) => ({ ...current, pace: "gentle" }))} /> setForm((current) => ({ ...current, pace: "normal" }))} /> setForm((current) => ({ ...current, pace: "ambitious" }))} />
setForm((current) => ({ ...current, mealsPerDay: event.target.value }))} placeholder="Mahlzeiten pro Tag" className="rounded-2xl border border-gray-200 px-4 py-3 text-sm font-semibold" />