"use client"; import { BeakerIcon, ClockIcon, FireIcon, ScaleIcon } from "@heroicons/react/24/outline"; import { useEffect, useState } from "react"; import { trpc } from "@/lib/trpc"; type GoalsForm = { calories: number; proteinG: number; carbsG: number; fatG: number; drinkMl: number; weightKg: number; fastingHours: number; weeklyCalories: number; sportAddsCalories: boolean; }; const defaultGoals: GoalsForm = { calories: 2000, proteinG: 150, carbsG: 200, fatG: 67, drinkMl: 2500, weightKg: 120, fastingHours: 12, weeklyCalories: 14000, sportAddsCalories: true, }; const fields: Array<{ key: keyof Omit; label: string; unit: string; icon: typeof FireIcon }> = [ { key: "calories", label: "Kalorien", unit: "kcal", icon: FireIcon }, { key: "weeklyCalories", label: "Wochenbudget", unit: "kcal", icon: FireIcon }, { key: "proteinG", label: "Protein", unit: "g", icon: ScaleIcon }, { key: "carbsG", label: "Kohlenhydrate", unit: "g", icon: ScaleIcon }, { key: "fatG", label: "Fett", unit: "g", icon: ScaleIcon }, { key: "drinkMl", label: "Trinkziel", unit: "ml", icon: BeakerIcon }, { key: "weightKg", label: "Gewichtsziel", unit: "kg", icon: ScaleIcon }, { key: "fastingHours", label: "Fasten", unit: "h", icon: ClockIcon }, ]; function todayKey() { return new Date().toISOString().slice(0, 10); } export default function ZielePage() { const utils = trpc.useUtils(); const overviewQuery = trpc.health.overview.useQuery({ date: todayKey() }); const saveGoalsMutation = trpc.health.upsertGoals.useMutation({ onSuccess: async () => { await utils.health.overview.invalidate(); setSaved(true); window.setTimeout(() => setSaved(false), 1600); }, }); const [goals, setGoals] = useState(defaultGoals); const [saved, setSaved] = useState(false); useEffect(() => { const apiGoals = overviewQuery.data?.goals; if (!apiGoals) return; const calories = apiGoals.calories ?? defaultGoals.calories; setGoals({ calories, proteinG: apiGoals.proteinG ?? defaultGoals.proteinG, carbsG: apiGoals.carbsG ?? defaultGoals.carbsG, fatG: apiGoals.fatG ?? defaultGoals.fatG, drinkMl: apiGoals.drinkMl ?? defaultGoals.drinkMl, weightKg: Number(apiGoals.weightKg ?? defaultGoals.weightKg), fastingHours: apiGoals.fastingHours ?? defaultGoals.fastingHours, weeklyCalories: apiGoals.weeklyCalories ?? calories * 7, sportAddsCalories: apiGoals.sportAddsCalories ?? true, }); }, [overviewQuery.data?.goals]); function saveGoals() { saveGoalsMutation.mutate({ drinkMl: goals.drinkMl, calories: goals.calories, carbsG: goals.carbsG, fatG: goals.fatG, proteinG: goals.proteinG, weightKg: goals.weightKg || null, fastingHours: goals.fastingHours, weeklyCalories: goals.weeklyCalories || goals.calories * 7, sportAddsCalories: goals.sportAddsCalories, }); } return (

Health-API

Ziele

Alltagstaugliche Zielwerte statt perfekter Wissenschaft. Diese Werte werden jetzt serverseitig pro Benutzer gespeichert.

{overviewQuery.isLoading ? (
Ziele werden geladen...
) : null}
{fields.map((field) => ( ))}
{saved ?

Gespeichert.

: null} {saveGoalsMutation.error ?

{saveGoalsMutation.error.message}

: null}
); }