"use client"; import { ArrowPathIcon, CalendarDaysIcon, FireIcon, SparklesIcon } from "@heroicons/react/24/outline"; import { useEffect, useMemo, useState } from "react"; import { todayKey } from "@/lib/hellth-data"; import { trpc } from "@/lib/trpc"; function fmt(value: number) { return Math.round(value).toLocaleString("de-DE"); } function prognosis(balance: number) { if (balance >= 1000) return { label: "entspannt im Ziel", color: "text-emerald-700 bg-emerald-50" }; if (balance >= -300) return { label: "gut steuerbar", color: "text-blue-700 bg-blue-50" }; return { label: "leicht drüber - flexibel ausgleichen", color: "text-amber-700 bg-amber-50" }; } type ExtraDraft = { extraCalories: string; note: string }; export default function WochenbudgetPage() { const utils = trpc.useUtils(); const [selectedDate, setSelectedDate] = useState(todayKey()); const [saved, setSaved] = useState(false); // Pro Tag eingeplanter Mehrbedarf ("Blocker"), bevor er verteilt wird. const [drafts, setDrafts] = useState>({}); const summaryQuery = trpc.health.statsSummary.useQuery({ referenceDate: selectedDate }); const summary = summaryQuery.data?.week ?? null; const prediction = summary ? prognosis(summary.balance) : null; const setExtrasMutation = trpc.health.setWeeklyExtras.useMutation({ onSuccess: async () => { // Ohne Key-Filter invalidieren, damit Dashboard + Statistiken mitziehen. await utils.health.statsSummary.invalidate(); await utils.health.overview.invalidate(); setSaved(true); window.setTimeout(() => setSaved(false), 1500); }, }); // Entwurf aus den gespeicherten Tageswerten vorbefüllen, sobald die Woche geladen ist. useEffect(() => { if (!summary) return; setDrafts((current) => { const next: Record = {}; for (const day of summary.days) { next[day.date] = current[day.date] ?? { extraCalories: day.extraCalories ? String(day.extraCalories) : "", note: day.note ?? "", }; } return next; }); }, [summary]); const totalExtra = useMemo( () => Object.values(drafts).reduce((sum, draft) => sum + (Number(draft.extraCalories) || 0), 0), [drafts], ); function updateDraft(date: string, patch: Partial) { setDrafts((current) => ({ ...current, [date]: { ...current[date], ...patch } as ExtraDraft })); } function redistribute() { if (!summary) return; setExtrasMutation.mutate({ weekStart: summary.weekStart, days: summary.days.map((day) => ({ date: day.date, extraCalories: Math.max(0, Number(drafts[day.date]?.extraCalories) || 0), note: drafts[day.date]?.note?.trim() || null, })), }); } if (!summary || !prediction) { return (

Wochenbudget wird geladen.

); } return (

Flexible Planung

Wochenbudget

Trag pro Tag ein, wenn du mehr brauchst (z. B. Familienfeier +800). Mit „kcal neu verteilen" hebt Hellth Hub diese Tage an und gleicht den Rest der Woche gleichmäßig aus. Dein Wochenziel bleibt gleich.

setSelectedDate(event.target.value || todayKey())} className="rounded-full border border-gray-200 px-4 py-3 text-sm font-bold" />

{fmt(summary.baseBudget)}

Wochenziel

{fmt(summary.eatenCalories)}

gegessen/geplant

+{fmt(summary.activityCalories)}

Sportbonus (Woche)

{prediction.label}

{fmt(summary.availableCalories)}

noch verfügbar

Tagesverteilung

{totalExtra > 0 ? `${fmt(totalExtra)} kcal Mehrbedarf eingeplant – wird beim Verteilen auf die übrigen Tage ausgeglichen.` : "Trag bei einzelnen Tagen einen Mehrbedarf ein und verteile anschließend."}

{summary.days.map((day) => { const date = new Date(`${day.date}T12:00:00`); const over = day.eatenCalories > day.plannedCalories + day.activityCalories; const draft = drafts[day.date] ?? { extraCalories: "", note: "" }; const isBlocker = (Number(draft.extraCalories) || 0) > 0; return (

{date.toLocaleDateString("de-DE", { weekday: "short" })}

{date.toLocaleDateString("de-DE")}

{fmt(day.eatenCalories)} / {fmt(day.plannedCalories)} kcal {day.activityCalories ? ` + ${fmt(day.activityCalories)} Sport` : ""}

updateDraft(day.date, { note: event.target.value })} placeholder="Anlass" className="rounded-2xl border border-gray-200 px-3 py-3 text-sm font-bold" />

= 0 ? "text-emerald-700" : "text-amber-700"}`}> {day.balance >= 0 ? "+" : ""}{fmt(day.balance)} kcal

); })}
{saved ?
Gespeichert
: null}
); }