From db2f142aaf98ba36d1e9b17ce8a4299268d1b69b Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Tue, 28 Jul 2026 15:29:32 +0200 Subject: feat: editable name and category in grocery detail page --- src/lib/server/services/groceries.ts | 12 ++++++++++++ src/routes/grocery/[id]/+page.server.ts | 23 +++++++++++++++++++++-- src/routes/grocery/[id]/+page.svelte | 30 ++++++++++++++++++------------ 3 files changed, 51 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/lib/server/services/groceries.ts b/src/lib/server/services/groceries.ts index fb42224..db9e736 100644 --- a/src/lib/server/services/groceries.ts +++ b/src/lib/server/services/groceries.ts @@ -97,6 +97,18 @@ export async function addOrUncheck( return { item: inserted, created: true }; } +export async function updateGrocery( + id: number, + name: string, + categoryId: number | null, + db = defaultDb, +): Promise { + await db + .update(groceries) + .set({ name, categoryId }) + .where(eq(groceries.id, id)); +} + export async function deleteGrocery(id: number, db = defaultDb): Promise { await db.delete(groceries).where(eq(groceries.id, id)); } diff --git a/src/routes/grocery/[id]/+page.server.ts b/src/routes/grocery/[id]/+page.server.ts index 3c3967a..cf8a949 100644 --- a/src/routes/grocery/[id]/+page.server.ts +++ b/src/routes/grocery/[id]/+page.server.ts @@ -2,23 +2,25 @@ import { error, fail, redirect } from '@sveltejs/kit'; import { db } from '$lib/server/db'; import { groceries, categories } from '$lib/server/db/schema'; import { eq } from 'drizzle-orm'; +import { loadAll as loadCategories } from '$lib/server/services/categories'; import { loadForGrocery, add as addRef, deleteReference, } from '$lib/server/services/references'; -import { deleteGrocery } from '$lib/server/services/groceries'; +import { updateGrocery, deleteGrocery } from '$lib/server/services/groceries'; import { numericId, parseFormString, parseOptionalNumber, } from '$lib/server/services/validation'; -import type { Grocery, Reference } from '$lib/server/services/types'; +import type { Category, Grocery, Reference } from '$lib/server/services/types'; import type { Actions, PageServerLoad } from './$types'; export interface GroceryDetailOutput { item: Grocery & { categoryName: string | null }; references: Reference[]; + categories: Category[]; } export const load: PageServerLoad = async ({ params }) => { @@ -35,6 +37,7 @@ export const load: PageServerLoad = async ({ params }) => { : [null]; const refs = await loadForGrocery(id); + const cats = await loadCategories(); return { item: { @@ -42,6 +45,7 @@ export const load: PageServerLoad = async ({ params }) => { categoryName: cat?.name ?? null, }, references: refs, + categories: cats, }; }; @@ -73,6 +77,21 @@ export const actions: Actions = { return { success: true }; }, + update: async ({ request, params }) => { + const data = await request.formData(); + const groceryId = numericId(params.id); + const name = parseFormString(data.get('name')); + const rawCategoryId = parseOptionalNumber(data.get('category_id')); + const categoryId = rawCategoryId === -1 ? null : rawCategoryId; + + if (!name) { + return fail(400, { error: 'Le nom est requis' }); + } + + await updateGrocery(groceryId, name, categoryId); + return { success: true }; + }, + deleteItem: async ({ params }) => { const groceryId = numericId(params.id); await deleteGrocery(groceryId); diff --git a/src/routes/grocery/[id]/+page.svelte b/src/routes/grocery/[id]/+page.svelte index a49d037..a7e0bc9 100644 --- a/src/routes/grocery/[id]/+page.svelte +++ b/src/routes/grocery/[id]/+page.svelte @@ -2,17 +2,30 @@ import { enhance } from '$app/forms'; let { data, form } = $props(); + let name = $state(data.item.name); + let categoryId = $state(data.item.categoryId ?? -1); let reference = $state(''); let price = $state(''); let unit = $state('€/kg'); let qualityScore = $state(''); -

{data.item.name}

- -{#if data.item.categoryName} -

{data.item.categoryName}

-{/if} +
+ + + +

@@ -110,13 +123,6 @@ ← Retour à la liste