'use client'; import { zodResolver } from '@hookform/resolvers/zod'; import { ACTIVITY_LEVELS, GENDERS, profileInputSchema, type ProfileInput } from '@ketopath/shared'; import { useRouter } from 'next/navigation'; import { useTranslations } from 'next-intl'; import { useState } from 'react'; import { useForm } from 'react-hook-form'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { saveProfile } from './actions'; type Derived = { bmr: number; tdee: number; activityMultiplier: number }; type Profile = ProfileInput & { derived?: Derived }; export function ProfileForm({ initial }: { initial: Profile | null }) { const t = useTranslations('Profile'); const router = useRouter(); const [serverError, setServerError] = useState(null); const [saved, setSaved] = useState(initial?.derived ?? null); const { register, handleSubmit, formState: { errors, isSubmitting }, } = useForm({ resolver: zodResolver(profileInputSchema), ...(initial ? { defaultValues: { age: initial.age, gender: initial.gender, heightCm: initial.heightCm, weightStartKg: initial.weightStartKg, weightCurrentKg: initial.weightCurrentKg, weightGoalKg: initial.weightGoalKg, activityLevel: initial.activityLevel, }, } : {}), }); const onSubmit = handleSubmit(async (input) => { setServerError(null); const result = await saveProfile(input); if (!result.ok) { setServerError(result.error); return; } const profile = result.profile as Profile; if (profile.derived) setSaved(profile.derived); router.refresh(); }); return (
{serverError ? (

{serverError}

) : null} {saved ? (

{t('summary')}

  • {t('bmr')}: {saved.bmr} kcal
  • {t('tdee')}: {saved.tdee} kcal
  • {t('activityMultiplier')}:{' '} {saved.activityMultiplier}

{t('hint')}

) : null}
); } function Field({ label, error, children, }: { label: string; error?: string | undefined; children: React.ReactNode; }) { return (
{children} {error ?

{error}

: null}
); }