aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--src/routes/grocery/[id]/+page.svelte49
2 files changed, 45 insertions, 6 deletions
diff --git a/README.md b/README.md
index 1eb4985..689e454 100644
--- a/README.md
+++ b/README.md
@@ -67,7 +67,7 @@ worker precaches assets; works offline after first visit.
- [ ] Live updates from server
- [ ] From catalog, multi-select and bulk-update category
-- [ ] Update item name/category on blur, no explicit save button
+- [x] Update item name/category on blur, no explicit save button
- [ ] Auto-categorize new items (LLM-assisted)
- [ ] Chores module (intro already promises "groceries, chores")
diff --git a/src/routes/grocery/[id]/+page.svelte b/src/routes/grocery/[id]/+page.svelte
index 50c2e0a..c0550fc 100644
--- a/src/routes/grocery/[id]/+page.svelte
+++ b/src/routes/grocery/[id]/+page.svelte
@@ -5,6 +5,8 @@
let name = $state(data.item.name);
let categoryId = $state(data.item.categoryId ?? -1);
let saved = $state(false);
+ let isSubmitting = $state(false);
+ let formRef: HTMLFormElement;
$effect(() => {
if (form?.success && form?.type === 'update') {
@@ -13,6 +15,17 @@
return () => clearTimeout(t);
}
});
+
+ function submitIfChanged() {
+ if (isSubmitting) return;
+ const currentCategoryId = data.item.categoryId ?? -1;
+ if (name === data.item.name && categoryId === currentCategoryId) return;
+ if (!name.trim()) return;
+
+ isSubmitting = true;
+ formRef.requestSubmit();
+ }
+
let reference = $state('');
let price = $state('');
let unit = $state('€/kg');
@@ -21,31 +34,50 @@
<main>
<form
+ bind:this={formRef}
class="form-card"
method="POST"
action="?/update"
use:enhance={() => {
return async ({ update }) => {
await update({ reset: false });
+ isSubmitting = false;
};
}}
>
<label>
<span class="form-label">Nom</span>
- <input class="form-input" type="text" name="name" bind:value={name} />
+ <input
+ class="form-input"
+ type="text"
+ name="name"
+ bind:value={name}
+ onblur={submitIfChanged}
+ onkeydown={(e) => {
+ if (e.key === 'Enter') {
+ e.preventDefault();
+ submitIfChanged();
+ }
+ }}
+ />
</label>
<label>
<span class="form-label">Catégorie</span>
- <select class="form-select" name="category_id" bind:value={categoryId}>
+ <select
+ class="form-select"
+ name="category_id"
+ bind:value={categoryId}
+ onblur={submitIfChanged}
+ >
<option value={-1}>—</option>
{#each data.categories as cat (cat.id)}
<option value={cat.id}>{cat.name}</option>
{/each}
</select>
</label>
- <button class="btn-primary" type="submit"
- >{saved ? '✓ Enregistré' : 'Enregistrer'}</button
- >
+ {#if saved}
+ <p class="save-status">✓ Enregistré</p>
+ {/if}
</form>
<hr />
@@ -223,4 +255,11 @@
background: var(--danger-bg);
transform: translateY(-1px);
}
+
+ .save-status {
+ font-size: 0.875rem;
+ color: var(--success);
+ font-weight: 500;
+ margin-top: -0.25rem;
+ }
</style>