"use client"; import { CheckIcon } from "@heroicons/react/24/outline"; import { useEffect, useMemo, useState } from "react"; import { trpc } from "@/lib/trpc"; type TemplateDraft = { id: string; name: string; category: string; defaultMinutes: number; defaultCalories: number; defaultPoints: string; }; function numberInput(value: unknown) { return String(Number(value) || 0); } export default function PunkteEinstellungenPage() { const utils = trpc.useUtils(); const settingsQuery = trpc.health.pointSettings.useQuery(); const [recipeSubmissionPoints, setRecipeSubmissionPoints] = useState("25"); const [clubActivityDefaultPoints, setClubActivityDefaultPoints] = useState("100"); const [templates, setTemplates] = useState([]); const [saved, setSaved] = useState(false); const updateMutation = trpc.health.updatePointSettings.useMutation({ onSuccess: async () => { await Promise.all([ utils.health.pointSettings.invalidate(), utils.health.pointDefaults.invalidate(), utils.health.listActivityTemplates.invalidate(), ]); setSaved(true); window.setTimeout(() => setSaved(false), 1600); }, }); useEffect(() => { if (!settingsQuery.data) return; setRecipeSubmissionPoints(numberInput(settingsQuery.data.recipeSubmissionPoints)); setClubActivityDefaultPoints(numberInput(settingsQuery.data.clubActivityDefaultPoints)); setTemplates(settingsQuery.data.activityTemplates.map((template) => ({ id: template.id, name: template.name, category: template.category, defaultMinutes: template.defaultMinutes, defaultCalories: template.defaultCalories, defaultPoints: numberInput(template.defaultPoints), }))); }, [settingsQuery.data]); const groupedTemplates = useMemo(() => { const groups = new Map(); for (const template of templates) { const current = groups.get(template.category) ?? []; current.push(template); groups.set(template.category, current); } return [...groups.entries()].sort(([a], [b]) => a.localeCompare(b, "de-DE")); }, [templates]); function updateTemplate(id: string, value: string) { setTemplates((current) => current.map((template) => ( template.id === id ? { ...template, defaultPoints: value } : template ))); } function save() { updateMutation.mutate({ recipeSubmissionPoints: Number(recipeSubmissionPoints) || 0, clubActivityDefaultPoints: Number(clubActivityDefaultPoints) || 0, activityTemplates: templates.map((template) => ({ id: template.id, defaultPoints: Number(template.defaultPoints) || 0, })), }); } return (

Admin

Punktevergabe

Globale Punktwerte für Hellfireclub, Rezeptvorschläge und Aktivitätskatalog.

Systempunkte

Hinweis

Bestehende Punkte-Logs bleiben unverändert. Änderungen gelten für neue Aktivitäten, neue Rezeptvorschläge und neue Einträge aus dem Aktivitätskatalog.

{saved ?

Punkte gespeichert.

: null} {updateMutation.error ?

{updateMutation.error.message}

: null}

Aktivitätskatalog

{groupedTemplates.map(([category, entries]) => (

{category}

{entries.map((template) => (

{template.name}

{template.defaultMinutes} min · {template.defaultCalories} kcal

{template.id} {template.category} updateTemplate(template.id, event.target.value)} className="rounded-2xl border border-gray-200 bg-white px-4 py-3 text-sm font-semibold" />
))}
))} {!templates.length && !settingsQuery.isLoading ? (

Keine globalen Aktivitätsvorlagen gefunden.

) : null}
); }