feat(web): weekly meal plan UI with regenerate + per-slot swap
apps/api:
- New PATCH /me/meal-plans/slots/:slotId — accepts { recipeId } and validates
ownership + that the new recipe is one of the slot's existing alternatives
(or already selected). Returns the updated slot with the new selected recipe.
apps/web — /plan route:
- Server component runs the same auth+disclaimer+profile guard chain as
/profile, then redirects to /profile if no profile exists yet (you can't
generate a plan without macros)
- actions.ts exposes three server actions: fetchCurrentPlan, regeneratePlan
and swapSlotRecipe; all proxy to api with the user's session cookie and
revalidatePath('/plan') after writes
- plan-week.tsx renders day-by-day sections (Lun→Dom) with a 4-card meal
row (1/2/4 columns at sm/lg breakpoints), recipe name + kcal, daily kcal
totals, expandable list of alternatives with one-click "Scegli"
- "Genera piano" CTA when there's no plan yet, "Rigenera" when there is one
- Italian copy under Plan.* with day, meal and kcal-total interpolations
- Home gains a "Vedi il piano settimanale" CTA next to "Completa profilo"
Verified end-to-end in Chrome:
- generate plan → 7 sections (Lun-Dom), each with 4 meal cards and per-day
kcal sum (e.g. Lunedì 1510 kcal = 360+540+150+460)
- recently-consumed penalty visible: Mon/Tue/Wed have different breakfasts
- swap: clicked "Vedi 3 alternative" on Mon Colazione → "Scegli" on
"Uova strapazzate" → card refreshed to that recipe and 410 kcal
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
e7158abbad
commit
f8eaf2f493
6 files changed
+311
-1
No files matched your search
@@ -7,7 +7,8 @@
|
||||
"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"
|
||||
"completeProfile": "Completa il tuo profilo",
|
||||
"viewPlan": "Vedi il piano settimanale"
|
||||
},
|
||||
"Welcome": {
|
||||
"title": "Prima di iniziare",
|
||||
@@ -61,6 +62,33 @@
|
||||
"disclaimer": "Procedendo accetti che i tuoi dati siano trattati come descritto nell'informativa sulla privacy. KetoPath non sostituisce il parere medico."
|
||||
}
|
||||
},
|
||||
"Plan": {
|
||||
"title": "Il tuo piano settimanale",
|
||||
"weekOf": "Settimana del {date}",
|
||||
"noPlan": "Non hai ancora un piano. Generalo per ricevere ricette adatte alla tua fase.",
|
||||
"generate": "Genera piano",
|
||||
"regenerate": "Rigenera",
|
||||
"noRecipe": "Nessuna ricetta selezionata",
|
||||
"showAlternatives": "Vedi {n} alternative",
|
||||
"hideAlternatives": "Nascondi alternative",
|
||||
"swap": "Scegli",
|
||||
"dayTotal": "{kcal} kcal totali",
|
||||
"meals": {
|
||||
"COLAZIONE": "Colazione",
|
||||
"PRANZO": "Pranzo",
|
||||
"SPUNTINO": "Spuntino",
|
||||
"CENA": "Cena"
|
||||
},
|
||||
"days": {
|
||||
"monday": "Lunedì",
|
||||
"tuesday": "Martedì",
|
||||
"wednesday": "Mercoledì",
|
||||
"thursday": "Giovedì",
|
||||
"friday": "Venerdì",
|
||||
"saturday": "Sabato",
|
||||
"sunday": "Domenica"
|
||||
}
|
||||
},
|
||||
"Profile": {
|
||||
"title": "Il tuo profilo",
|
||||
"subtitle": "Inserisci i tuoi dati per calcolare BMR e TDEE personalizzati.",
|
||||
|
||||
Reference in new issue
Block a user