diff options
Diffstat (limited to 'src/routes')
| -rw-r--r-- | src/routes/+layout.svelte | 2 | ||||
| -rw-r--r-- | src/routes/+page.server.ts | 39 | ||||
| -rw-r--r-- | src/routes/+page.svelte | 74 |
3 files changed, 70 insertions, 45 deletions
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 8ba4f8f..5999926 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -18,6 +18,6 @@ .app { max-width: 48rem; margin: 0 auto; - padding: 1rem; + padding: 0 1rem; } </style> diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts index d548d09..55ac82d 100644 --- a/src/routes/+page.server.ts +++ b/src/routes/+page.server.ts @@ -1,4 +1,4 @@ -import { fail } from '@sveltejs/kit'; +import { fail, redirect } from '@sveltejs/kit'; import { db } from '$lib/server/db'; import { groceries, categories, references } from '$lib/server/db/schema'; import { eq, desc } from 'drizzle-orm'; @@ -87,4 +87,41 @@ export const actions: Actions = { return { success: true }; }, + + addAndEdit: async ({ request }) => { + const data = await request.formData(); + const name = data.get('name')?.toString().trim(); + const categoryId = data.get('category_id')?.toString() || null; + + if (!name) { + return fail(400, { error: 'Name is required' }); + } + + const [existing] = await db + .select() + .from(groceries) + .where(eq(groceries.name, name)) + .limit(1); + + if (existing) { + await db + .update(groceries) + .set({ + checked: false, + categoryId: categoryId ? Number(categoryId) : existing.categoryId, + }) + .where(eq(groceries.id, existing.id)); + throw redirect(303, `/grocery/${existing.id}`); + } else { + const [inserted] = await db + .insert(groceries) + .values({ + name, + categoryId: categoryId ? Number(categoryId) : null, + createdAt: new Date().toISOString(), + }) + .returning(); + throw redirect(303, `/grocery/${inserted.id}`); + } + }, }; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 57ce3d0..767c87e 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -17,27 +17,16 @@ } </script> -<form class="add-form" method="POST" action="?/add" use:enhance> - <label> - <span class="label">Item</span> - <input - type="text" - name="name" - bind:value={name} - placeholder="Add an item..." - autocomplete="off" - /> - </label> - <label> - <span class="label">Category</span> - <select name="category_id"> - <option value="">—</option> - {#each data?.categories ?? [] as cat (cat.id)} - <option value={cat.id}>{cat.name}</option> - {/each} - </select> - </label> +<form class="add-bar" method="POST" action="?/add" use:enhance> + <input + type="text" + name="name" + bind:value={name} + placeholder="Add an item..." + autocomplete="off" + /> <button type="submit">Add</button> + <button type="submit" formaction="?/addAndEdit">Edit</button> </form> {#if form?.error} @@ -75,49 +64,48 @@ {/if} <style> - .add-form { + .add-bar { display: flex; - flex-direction: column; gap: 0.5rem; - margin-bottom: 1rem; + padding: 0.5rem 1rem 0.5rem; + position: sticky; + top: 3rem; + background: #fafafa; + z-index: 10; } - .add-form label { - display: flex; - flex-direction: column; - gap: 0.25rem; - } - - .label { - font-size: 0.75rem; - font-weight: 600; - text-transform: uppercase; - color: #999; - } - - input, - select { + input { + flex: 1; padding: 0.75rem; border: 1px solid #ccc; border-radius: 0.5rem; font-size: 1rem; font-family: inherit; background: #fff; + min-width: 0; } - .add-form button[type='submit'] { - padding: 0.75rem 1.25rem; + .add-bar button { + padding: 0.75rem 1rem; border: none; border-radius: 0.5rem; + font-size: 1rem; + font-family: inherit; + cursor: pointer; + } + + .add-bar button[type='submit']:not([formaction]) { background: #333; color: #fff; - font-size: 1rem; - align-self: flex-start; + } + + .add-bar button[formaction] { + background: #e0e0e0; + color: #333; } .error { color: #d00; - margin-top: -0.5rem; margin-bottom: 1rem; } |
