From 8854cfd1f9b431a80cead4eb3a11edefdc45aef0 Mon Sep 17 00:00:00 2001 From: elpatron Date: Mon, 12 Jan 2026 23:49:17 +0100 Subject: [PATCH] feat: add plan title and interval editing to settings - Add Settings button label i18n (de: Einstellungen) - Allow editing plan title, feeding per day, feeding interval, and litter interval - Update PlanSettings component with new form fields - Add German and English translations for new settings - Update Plan type to include title property --- .../[planId]/_components/plan-dashboard.tsx | 5 ++ app/actions/plan.ts | 14 ++- components/plan-settings.tsx | 86 ++++++++++++++++++- dictionaries/de.json | 5 ++ dictionaries/en.json | 5 ++ 5 files changed, 113 insertions(+), 2 deletions(-) diff --git a/app/[lang]/dashboard/[planId]/_components/plan-dashboard.tsx b/app/[lang]/dashboard/[planId]/_components/plan-dashboard.tsx index 29aca64..8506eed 100644 --- a/app/[lang]/dashboard/[planId]/_components/plan-dashboard.tsx +++ b/app/[lang]/dashboard/[planId]/_components/plan-dashboard.tsx @@ -32,6 +32,7 @@ type Booking = { type Plan = { id: string + title: string startDate: Date endDate: Date instructions: string | null @@ -161,9 +162,13 @@ export function PlanDashboard({ plan, dict, settingsDict, lang }: PlanDashboardP diff --git a/app/actions/plan.ts b/app/actions/plan.ts index 10a8879..35c7221 100644 --- a/app/actions/plan.ts +++ b/app/actions/plan.ts @@ -8,7 +8,15 @@ import { getDictionary } from "@/get-dictionary" export async function updatePlan( planId: string, - data: { instructions?: string; webhookUrl?: string; notifyAll?: boolean }, + data: { + instructions?: string; + webhookUrl?: string; + notifyAll?: boolean; + title?: string; + feedingPerDay?: number; + feedingInterval?: number; + litterInterval?: number; + }, lang: string = "en" ) { const dict = await getDictionary(lang as any) @@ -19,6 +27,10 @@ export async function updatePlan( instructions: data.instructions, webhookUrl: data.webhookUrl, notifyAll: data.notifyAll, + title: data.title, + feedingPerDay: data.feedingPerDay, + feedingInterval: data.feedingInterval, + litterInterval: data.litterInterval, } }) diff --git a/components/plan-settings.tsx b/components/plan-settings.tsx index 5b32b1c..de04e1a 100644 --- a/components/plan-settings.tsx +++ b/components/plan-settings.tsx @@ -33,18 +33,26 @@ import { updatePlan } from "@/app/actions/plan" interface PlanSettingsProps { planId: string + initialTitle: string initialInstructions: string | null initialWebhookUrl: string | null initialNotifyAll: boolean + initialFeedingPerDay: number + initialFeedingInterval: number + initialLitterInterval: number dict: any lang: string } export function PlanSettings({ planId, + initialTitle, initialInstructions, initialWebhookUrl, initialNotifyAll, + initialFeedingPerDay, + initialFeedingInterval, + initialLitterInterval, dict, lang }: PlanSettingsProps) { @@ -52,9 +60,13 @@ export function PlanSettings({ const [isPending, setIsPending] = useState(false) const formSchema = z.object({ + title: z.string().min(2), instructions: z.string().optional(), webhookUrl: z.string().url().optional().or(z.literal("")), notifyAll: z.boolean(), + feedingPerDay: z.number().min(1).max(10), + feedingInterval: z.number().min(1).max(30), + litterInterval: z.number().min(1).max(30), }) type FormValues = z.infer @@ -62,9 +74,13 @@ export function PlanSettings({ const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { + title: initialTitle, instructions: initialInstructions || "", webhookUrl: initialWebhookUrl || "", notifyAll: initialNotifyAll, + feedingPerDay: initialFeedingPerDay, + feedingInterval: initialFeedingInterval, + litterInterval: initialLitterInterval, }, }) @@ -86,7 +102,7 @@ export function PlanSettings({ @@ -98,6 +114,21 @@ export function PlanSettings({
+ ( + + {dict.titleLabel} + + + + + + )} + /> )} /> +
+ ( + + {dict.feedingPerDayLabel} + + field.onChange(parseInt(e.target.value))} + /> + + + + )} + /> + ( + + {dict.feedingIntervalLabel} + + field.onChange(parseInt(e.target.value))} + /> + + + + )} + /> +
+ ( + + {dict.litterIntervalLabel} + + field.onChange(parseInt(e.target.value))} + /> + + + + )} + />