diff options
| author | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-07-27 18:31:26 +0200 |
|---|---|---|
| committer | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-07-27 18:31:26 +0200 |
| commit | e14717b2e7853705469275d64023bb902b195ebb (patch) | |
| tree | 2e450f7b4e864e232d06df43ad1aba1b62be4f4c /src/routes/+page.svelte | |
| parent | 8224c7d6572db6ec76c4224eec1df8a538b47ad4 (diff) | |
feat: separate categories table + /categories management page
- Categories table (id, name unique) with FK from groceries.category_id
- /categories page for add/delete categories
- Main page uses native <select> dropdown for category
- Categories grouped by name in list/catalog views
- Regenerated drizzle migrations from scratch
Diffstat (limited to 'src/routes/+page.svelte')
| -rw-r--r-- | src/routes/+page.svelte | 136 |
1 files changed, 94 insertions, 42 deletions
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index a3e6d23..9490a51 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -7,18 +7,39 @@ let listItems = $derived(data?.items?.filter((i) => !i.checked) ?? []); let catalogItems = $derived(data?.items?.filter((i) => i.checked) ?? []); + + function groupByCategory(items: typeof listItems) { + const groups: Record<string, typeof listItems> = {}; + for (const item of items) { + const key = item.categoryName ?? 'Uncategorized'; + (groups[key] ??= []).push(item); + } + return Object.entries(groups); + } </script> <h1>Groceries</h1> <form class="add-form" method="POST" action="?/add" use:enhance> - <input - type="text" - name="name" - bind:value={name} - placeholder="Add an item..." - autocomplete="off" - /> + <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> <button type="submit">Add</button> </form> @@ -28,64 +49,86 @@ <h2>List</h2> -<form method="POST" action="?/toggle" use:enhance> - <ul class="item-list"> - {#each listItems as item (item.id)} - <li> - <button name="id" value={item.id} type="submit"> - {item.name} - </button> - </li> - {/each} - </ul> -</form> - {#if listItems.length === 0} <p class="empty">Nothing to buy</p> +{:else} + <form method="POST" action="?/toggle" use:enhance> + {#each groupByCategory(listItems) as [cat, items] (cat)} + <h3 class="category-name">{cat}</h3> + <ul class="item-list"> + {#each items as item (item.id)} + <li> + <button name="id" value={item.id} type="submit"> + {item.name} + </button> + </li> + {/each} + </ul> + {/each} + </form> {/if} <hr /> <h2>Catalog</h2> -<form method="POST" action="?/toggle" use:enhance> - <ul class="item-list"> - {#each catalogItems as item (item.id)} - <li class="catalog-item"> - <button name="id" value={item.id} type="submit"> - {item.name} - </button> - <button - class="delete-btn" - name="id" - value={item.id} - type="submit" - formaction="?/delete" - > - × - </button> - </li> - {/each} - </ul> -</form> - {#if catalogItems.length === 0} <p class="empty">No items yet</p> +{:else} + <form method="POST" action="?/toggle" use:enhance> + {#each groupByCategory(catalogItems) as [cat, items] (cat)} + <h3 class="category-name">{cat}</h3> + <ul class="item-list"> + {#each items as item (item.id)} + <li class="catalog-item"> + <button name="id" value={item.id} type="submit"> + {item.name} + </button> + <button + class="delete-btn" + name="id" + value={item.id} + type="submit" + formaction="?/delete" + > + × + </button> + </li> + {/each} + </ul> + {/each} + </form> {/if} <style> .add-form { display: flex; + flex-direction: column; gap: 0.5rem; margin-bottom: 1rem; } - input { - flex: 1; + .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 { padding: 0.75rem; border: 1px solid #ccc; border-radius: 0.5rem; font-size: 1rem; + font-family: inherit; + background: #fff; } .add-form button[type='submit'] { @@ -95,6 +138,7 @@ background: #333; color: #fff; font-size: 1rem; + align-self: flex-start; } .error { @@ -168,4 +212,12 @@ font-size: 0.875rem; margin-top: 0.5rem; } + + .category-name { + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + color: #999; + margin: 1rem 0 0.25rem; + } </style> |
