diff options
Diffstat (limited to 'src/routes/catalog/+page.svelte')
| -rw-r--r-- | src/routes/catalog/+page.svelte | 126 |
1 files changed, 80 insertions, 46 deletions
diff --git a/src/routes/catalog/+page.svelte b/src/routes/catalog/+page.svelte index aa02ef5..ebc1819 100644 --- a/src/routes/catalog/+page.svelte +++ b/src/routes/catalog/+page.svelte @@ -6,6 +6,15 @@ let catalogItems = $derived(data?.items ?? []); let selectedIds = new SvelteSet<number>(); + let searchQuery = $state(''); + + let filteredItems = $derived( + searchQuery.trim() === '' + ? catalogItems + : catalogItems.filter((item) => + item.name.toLowerCase().includes(searchQuery.toLowerCase()), + ), + ); function toggleId(id: number) { if (selectedIds.has(id)) selectedIds.delete(id); @@ -18,9 +27,12 @@ const key = item.categoryName ?? 'Non catégorisé'; (groups[key] ??= []).push(item); } - const result: [string, typeof catalogItems][] = data.categories.map( - (cat) => [cat.name, groups[cat.name] ?? []], - ); + const result: [string, typeof catalogItems][] = []; + for (const cat of data.categories) { + if (groups[cat.name]?.length > 0) { + result.push([cat.name, groups[cat.name]]); + } + } if (groups['Non catégorisé']?.length > 0) { result.unshift(['Non catégorisé', groups['Non catégorisé']]); } @@ -68,49 +80,60 @@ {#if catalogItems.length === 0} <p class="empty">Aucun article</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="item-row item-row--fixed"> - <input - type="checkbox" - class="item-check" - checked={selectedIds.has(item.id)} - onchange={() => toggleId(item.id)} - /> - <button - class="item-btn item-btn--grow" - name="id" - value={item.id} - type="submit" - aria-pressed={item.checked} - > - <span class="item-text"> - <span class:checked={item.checked}>{item.name}</span> - {#if item.bestRef} - <span class="best-ref" - >{item.bestRef.reference} - {#if item.bestRef.price && item.bestRef.unit} - {item.bestRef.price.toFixed(2)} - {item.bestRef.unit} - {/if} - {#if item.bestRef.qualityScore != null} - ({item.bestRef.qualityScore}/100) - {/if} - </span> - {/if} - </span> - </button> - <a class="ref-link" href="/grocery/{item.id}?from=/catalog" - >→</a - > - </li> - {/each} - </ul> - {/each} - </form> + <input + type="search" + bind:value={searchQuery} + placeholder="Rechercher un article..." + class="search-input" + /> + + {#if filteredItems.length === 0} + <p class="empty">Aucun résultat</p> + {:else} + <form method="POST" action="?/toggle" use:enhance> + {#each groupByCategory(filteredItems) as [cat, items] (cat)} + <h3 class="category-name">{cat}</h3> + <ul class="item-list"> + {#each items as item (item.id)} + <li class="item-row item-row--fixed"> + <input + type="checkbox" + class="item-check" + checked={selectedIds.has(item.id)} + onchange={() => toggleId(item.id)} + /> + <button + class="item-btn item-btn--grow" + name="id" + value={item.id} + type="submit" + aria-pressed={item.checked} + > + <span class="item-text"> + <span class:checked={item.checked}>{item.name}</span> + {#if item.bestRef} + <span class="best-ref" + >{item.bestRef.reference} + {#if item.bestRef.price && item.bestRef.unit} + {item.bestRef.price.toFixed(2)} + {item.bestRef.unit} + {/if} + {#if item.bestRef.qualityScore != null} + ({item.bestRef.qualityScore}/100) + {/if} + </span> + {/if} + </span> + </button> + <a class="ref-link" href="/grocery/{item.id}?from=/catalog" + >→</a + > + </li> + {/each} + </ul> + {/each} + </form> + {/if} {/if} </main> @@ -173,4 +196,15 @@ margin-top: 1rem; padding: 2rem; } + + .search-input { + width: 100%; + padding: 0.75rem 1rem; + border: 1px solid var(--border); + border-radius: 0.5rem; + background: var(--surface); + color: var(--text); + font-size: 1rem; + margin-top: 1rem; + } </style> |
