Files
ketopath/apps/web/messages/it.json
T
lucianoandClaude Opus 4.7 1d904484e6 feat: profile flow — Zod schema, /me/profile API, /profile page with BMR/TDEE
@ketopath/shared — new module profile/schema:
- profileInputSchema (Zod): age 18-110, gender, height 120-230 cm, weights
  35-300 kg, activityLevel, optional targetDate
- GENDERS / ACTIVITY_LEVELS string-literal arrays for UI iteration
- Re-exported from @ketopath/shared

apps/api — new module modules/profile:
- PUT /me/profile: requireAuth, validates body via profileInputSchema, upserts
  the row, returns the saved profile + derived { bmr, tdee, activityMultiplier }
  (BMR/TDEE computed via @ketopath/shared)
- GET /me/profile: requireAuth, returns the same shape, 404 when missing
- Decimal columns serialised back as numbers

apps/web — new /profile page:
- src/app/[locale]/profile/page.tsx (server): redirects unauthenticated users
  to /sign-in, calls fetchProfile to hydrate the form
- profile-form.tsx (client): react-hook-form + zodResolver bound to the same
  shared schema, native styled selects for gender/activityLevel until shadcn
  Select arrives, post-submit panel showing BMR/TDEE/multiplier
- actions.ts: server actions saveProfile / fetchProfile that proxy the call
  to API_URL via cookie passthrough (no CORS, no exposed token)
- Home page gains a "Completa il tuo profilo" CTA when signed in
- API_URL env var added to .env.example
- Italian copy in messages/it.json under Profile

Verified end-to-end with the "Michele" PRD persona (49, M, 170cm, 76kg, SEDENTARY):
BMR = 1583 kcal, TDEE = 1899 kcal, multiplier 1.2 — matches the unit tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 14:20:07 +02:00

76 lines
3.0 KiB
JSON

{
"Home": {
"title": "KetoPath",
"tagline": "Il tuo percorso personalizzato verso uno stile di vita chetogenico sostenibile.",
"ctaPrimary": "Inizia gratis",
"ctaSecondary": "Scopri come funziona",
"disclaimer": "Le informazioni fornite da questa app non sostituiscono il parere di un medico.",
"signedInAs": "Accesso effettuato come {name}",
"signOut": "Esci",
"completeProfile": "Completa il tuo profilo"
},
"Metadata": {
"title": "KetoPath — Chetogenica e digiuno intermittente personalizzati",
"description": "Web app italiana per la gestione strutturata di chetogenica e digiuno intermittente, con piani adattivi, tracking e lista della spesa automatica."
},
"Auth": {
"SignIn": {
"title": "Accedi",
"subtitle": "Bentornato. Inserisci le tue credenziali per continuare.",
"emailLabel": "Email",
"passwordLabel": "Password",
"submit": "Accedi",
"submitting": "Accesso in corso…",
"google": "Accedi con Google",
"or": "oppure",
"noAccount": "Non hai un account? <link>Registrati</link>",
"error": "Credenziali non valide. Riprova."
},
"SignUp": {
"title": "Registrati",
"subtitle": "Crea il tuo profilo KetoPath in meno di un minuto.",
"nameLabel": "Nome",
"emailLabel": "Email",
"passwordLabel": "Password",
"passwordHint": "Almeno 8 caratteri.",
"submit": "Crea account",
"submitting": "Creazione in corso…",
"google": "Continua con Google",
"or": "oppure",
"haveAccount": "Hai già un account? <link>Accedi</link>",
"error": "Non è stato possibile completare la registrazione. Riprova.",
"disclaimer": "Procedendo accetti che i tuoi dati siano trattati come descritto nell'informativa sulla privacy. KetoPath non sostituisce il parere medico."
}
},
"Profile": {
"title": "Il tuo profilo",
"subtitle": "Inserisci i tuoi dati per calcolare BMR e TDEE personalizzati.",
"age": "Età",
"gender": "Sesso",
"heightCm": "Altezza (cm)",
"weightStartKg": "Peso iniziale (kg)",
"weightCurrentKg": "Peso attuale (kg)",
"weightGoalKg": "Peso obiettivo (kg)",
"activityLevel": "Livello di attività",
"selectPlaceholder": "Seleziona…",
"save": "Salva profilo",
"saving": "Salvataggio in corso…",
"summary": "Calcolo personalizzato",
"bmr": "Metabolismo basale (BMR)",
"tdee": "Fabbisogno totale (TDEE)",
"activityMultiplier": "Moltiplicatore attività",
"hint": "I valori sono stime basate sulla formula Mifflin-St Jeor. Non sostituiscono il parere di un nutrizionista.",
"genderOptions": {
"MALE": "Maschio",
"FEMALE": "Femmina",
"OTHER": "Altro / preferisco non specificare"
},
"activityOptions": {
"SEDENTARY": "Sedentario (lavoro d'ufficio)",
"LIGHT": "Leggero (sport 1-3 volte a settimana)",
"MODERATE": "Moderato (sport 3-5 volte a settimana)",
"INTENSE": "Intenso (sport 6+ volte a settimana)"
}
}
}