feat: add plan title field with data migration

This commit is contained in:
2026-01-12 22:32:45 +01:00
parent 9db5466fb2
commit 3de2661f46
8 changed files with 72 additions and 7 deletions

View File

@@ -60,7 +60,7 @@ export default async function DashboardPage({
/> />
</div> </div>
<div> <div>
<h1 className="text-2xl font-bold">{dict.home.title}</h1> <h1 className="text-2xl font-bold">{plan.title}</h1>
<p className="text-muted-foreground text-sm"> <p className="text-muted-foreground text-sm">
{plan.startDate.toLocaleDateString(lang)} - {plan.endDate.toLocaleDateString(lang)} {plan.startDate.toLocaleDateString(lang)} - {plan.endDate.toLocaleDateString(lang)}
</p> </p>

View File

@@ -4,14 +4,15 @@ import prisma from '@/lib/prisma';
export async function POST(req: Request) { export async function POST(req: Request) {
try { try {
const body = await req.json(); const body = await req.json();
const { startDate, endDate, password, instructions } = body; const { title, startDate, endDate, password, instructions } = body;
if (!startDate || !endDate || !password) { if (!title || !startDate || !endDate || !password) {
return NextResponse.json({ error: 'Missing required fields' }, { status: 400 }); return NextResponse.json({ error: 'Missing required fields' }, { status: 400 });
} }
const plan = await prisma.plan.create({ const plan = await prisma.plan.create({
data: { data: {
title,
startDate: new Date(startDate), startDate: new Date(startDate),
endDate: new Date(endDate), endDate: new Date(endDate),
password, password,

View File

@@ -33,6 +33,9 @@ export function CreatePlanForm({ dict, lang }: CreatePlanFormProps) {
const router = useRouter() const router = useRouter()
const formSchema = z.object({ const formSchema = z.object({
title: z.string().min(2, {
message: dict.titleError,
}),
dateRange: z.object({ dateRange: z.object({
from: z.date(), from: z.date(),
to: z.date(), to: z.date(),
@@ -46,6 +49,7 @@ export function CreatePlanForm({ dict, lang }: CreatePlanFormProps) {
const form = useForm<z.infer<typeof formSchema>>({ const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema), resolver: zodResolver(formSchema),
defaultValues: { defaultValues: {
title: "",
password: "", password: "",
instructions: "", instructions: "",
}, },
@@ -59,6 +63,7 @@ export function CreatePlanForm({ dict, lang }: CreatePlanFormProps) {
method: "POST", method: "POST",
headers: { "Content-Type": "application/json" }, headers: { "Content-Type": "application/json" },
body: JSON.stringify({ body: JSON.stringify({
title: values.title,
startDate: values.dateRange.from, startDate: values.dateRange.from,
endDate: values.dateRange.to, endDate: values.dateRange.to,
password: values.password, password: values.password,
@@ -81,7 +86,21 @@ export function CreatePlanForm({ dict, lang }: CreatePlanFormProps) {
return ( return (
<Form {...form}> <Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8"> <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<FormField
control={form.control}
name="title"
render={({ field }) => (
<FormItem>
<FormLabel>{dict.title}</FormLabel>
<FormControl>
<Input placeholder={dict.titlePlaceholder} {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField <FormField
control={form.control} control={form.control}
name="dateRange" name="dateRange"
@@ -150,7 +169,7 @@ export function CreatePlanForm({ dict, lang }: CreatePlanFormProps) {
</FormItem> </FormItem>
)} )}
/> />
<Button type="submit">{dict.submit}</Button> <Button type="submit" className="w-full">{dict.submit}</Button>
</form> </form>
</Form> </Form>
) )

View File

@@ -3,9 +3,12 @@
"title": "Katzen-Sitting-Planer", "title": "Katzen-Sitting-Planer",
"description": "Koordiniere die Pflege deiner Vierbeiner, während du weg bist.", "description": "Koordiniere die Pflege deiner Vierbeiner, während du weg bist.",
"createPlan": "Neuen Plan erstellen", "createPlan": "Neuen Plan erstellen",
"createPlanDesc": "Wähle deine Reisedaten und setze ein Gruppen-Passwort." "createPlanDesc": "Gib deinem Plan einen Namen, wähle deine Reisedaten und setze ein Gruppen-Passwort."
}, },
"createPlanForm": { "createPlanForm": {
"title": "Titel des Plans",
"titlePlaceholder": "Lilly & Diego 🐈 🐈‍⬛",
"titleError": "Der Titel muss mindestens 2 Zeichen lang sein.",
"travelDates": "Reisedaten", "travelDates": "Reisedaten",
"pickDateRange": "Zeitraum wählen", "pickDateRange": "Zeitraum wählen",
"dateRangeDesc": "Wähle die Tage aus, an denen du weg bist.", "dateRangeDesc": "Wähle die Tage aus, an denen du weg bist.",

View File

@@ -3,9 +3,12 @@
"title": "Cat Sitting Planner", "title": "Cat Sitting Planner",
"description": "Coordinate care for your furry friends while you're away.", "description": "Coordinate care for your furry friends while you're away.",
"createPlan": "Create a New Plan", "createPlan": "Create a New Plan",
"createPlanDesc": "Select your travel dates and set a group password." "createPlanDesc": "Give your plan a title, select your travel dates and set a group password."
}, },
"createPlanForm": { "createPlanForm": {
"title": "Plan Title",
"titlePlaceholder": "Lilly & Diego 🐈 🐈‍⬛",
"titleError": "Title must be at least 2 characters.",
"travelDates": "Travel Dates", "travelDates": "Travel Dates",
"pickDateRange": "Pick a date range", "pickDateRange": "Pick a date range",
"dateRangeDesc": "Select the days you will be away.", "dateRangeDesc": "Select the days you will be away.",

View File

@@ -0,0 +1,19 @@
-- RedefineTables
PRAGMA defer_foreign_keys=ON;
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_Plan" (
"id" TEXT NOT NULL PRIMARY KEY,
"title" TEXT NOT NULL DEFAULT 'Cat Plan',
"password" TEXT NOT NULL,
"startDate" DATETIME NOT NULL,
"endDate" DATETIME NOT NULL,
"instructions" TEXT,
"webhookUrl" TEXT,
"notifyAll" BOOLEAN NOT NULL DEFAULT true,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO "new_Plan" ("createdAt", "endDate", "id", "instructions", "notifyAll", "password", "startDate", "webhookUrl") SELECT "createdAt", "endDate", "id", "instructions", "notifyAll", "password", "startDate", "webhookUrl" FROM "Plan";
DROP TABLE "Plan";
ALTER TABLE "new_Plan" RENAME TO "Plan";
PRAGMA foreign_keys=ON;
PRAGMA defer_foreign_keys=OFF;

View File

@@ -0,0 +1,19 @@
-- RedefineTables
PRAGMA defer_foreign_keys=ON;
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_Plan" (
"id" TEXT NOT NULL PRIMARY KEY,
"title" TEXT NOT NULL,
"password" TEXT NOT NULL,
"startDate" DATETIME NOT NULL,
"endDate" DATETIME NOT NULL,
"instructions" TEXT,
"webhookUrl" TEXT,
"notifyAll" BOOLEAN NOT NULL DEFAULT true,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO "new_Plan" ("createdAt", "endDate", "id", "instructions", "notifyAll", "password", "startDate", "title", "webhookUrl") SELECT "createdAt", "endDate", "id", "instructions", "notifyAll", "password", "startDate", "title", "webhookUrl" FROM "Plan";
DROP TABLE "Plan";
ALTER TABLE "new_Plan" RENAME TO "Plan";
PRAGMA foreign_keys=ON;
PRAGMA defer_foreign_keys=OFF;

View File

@@ -9,6 +9,7 @@ generator client {
model Plan { model Plan {
id String @id @default(cuid()) id String @id @default(cuid())
title String
password String password String
startDate DateTime startDate DateTime
endDate DateTime endDate DateTime