diff options
Diffstat (limited to 'src/routes/categories')
| -rw-r--r-- | src/routes/categories/+page.server.ts | 53 | ||||
| -rw-r--r-- | src/routes/categories/+page.svelte | 164 |
2 files changed, 0 insertions, 217 deletions
diff --git a/src/routes/categories/+page.server.ts b/src/routes/categories/+page.server.ts deleted file mode 100644 index c97b619..0000000 --- a/src/routes/categories/+page.server.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { fail } from '@sveltejs/kit'; -import { - loadAll, - add, - deleteCategory, - reorder, -} from '$lib/server/services/categories'; -import { numericId, parseFormString } from '$lib/server/services/validation'; -import type { Category } from '$lib/server/services/types'; -import type { Actions, PageServerLoad } from './$types'; - -export interface CategoriesOutput { - categories: Category[]; -} - -export const load: PageServerLoad = async () => { - return { categories: await loadAll() }; -}; - -export const actions: Actions = { - add: async ({ request }) => { - const data = await request.formData(); - const name = parseFormString(data.get('name')); - - if (!name) { - return fail(400, { error: 'Le nom est requis' }); - } - - await add(name); - return { success: true }; - }, - - delete: async ({ request }) => { - const data = await request.formData(); - try { - const id = numericId(data.get('id')); - await deleteCategory(id); - } catch { - return fail(400, { error: 'ID invalide' }); - } - return { success: true }; - }, - - reorder: async ({ request }) => { - const data = await request.formData(); - const ids = data.getAll('orderedIds').map(numericId); - if (ids.length === 0) { - return fail(400, { error: 'Aucune catégorie' }); - } - await reorder(ids); - return { success: true }; - }, -}; diff --git a/src/routes/categories/+page.svelte b/src/routes/categories/+page.svelte deleted file mode 100644 index 267a287..0000000 --- a/src/routes/categories/+page.svelte +++ /dev/null @@ -1,164 +0,0 @@ -<script lang="ts"> - import { enhance } from '$app/forms'; - import type { Category } from '$lib/server/services/types'; - - let { data, form } = $props(); - let name = $state(''); - let draggedIndex = $state<number | null>(null); - // eslint-disable-next-line svelte/prefer-writable-derived - let localCategories = $state<Category[]>([]); - - // Sync with server data on navigation - $effect(() => { - localCategories = data?.categories ?? []; - }); - - let reorderFormRef: HTMLFormElement; - - function handleDragStart(index: number) { - draggedIndex = index; - } - - function handleDragOver(e: DragEvent, index: number) { - e.preventDefault(); - if (draggedIndex === null || draggedIndex === index) return; - - const next = [...localCategories]; - const [moved] = next.splice(draggedIndex, 1); - next.splice(index, 0, moved); - localCategories = next; - draggedIndex = index; - } - - function handleDrop() { - draggedIndex = null; - reorderFormRef?.requestSubmit(); - } -</script> - -<main> - <form class="cat-add-bar" method="POST" action="?/add" use:enhance> - <input - class="form-input" - type="text" - name="name" - bind:value={name} - placeholder="Nouvelle catégorie..." - autocomplete="off" - /> - <button class="btn-accent" type="submit" aria-label="Ajouter">+</button> - </form> - - {#if form?.error} - <p class="error">{form.error}</p> - {/if} - - <form - bind:this={reorderFormRef} - method="POST" - action="?/reorder" - use:enhance={() => { - return async ({ update }) => { - await update({ reset: false }); - }; - }} - > - {#each localCategories as cat (cat.id)} - <input type="hidden" name="orderedIds" value={cat.id} /> - {/each} - </form> - - <form method="POST" action="?/delete" use:enhance> - <ul class="item-list"> - {#each localCategories as cat, index (cat.id)} - <li - class="item-row item-row--card" - draggable="true" - ondragstart={() => handleDragStart(index)} - ondragover={(e) => handleDragOver(e, index)} - ondrop={handleDrop} - ondragend={() => (draggedIndex = null)} - > - <span class="drag-handle">⋮⋮</span> - <span class="cat-name">{cat.name}</span> - <button - class="btn-ghost" - name="id" - value={cat.id} - type="submit" - aria-label="Supprimer" - > - × - </button> - </li> - {/each} - </ul> - </form> - - {#if (localCategories.length ?? 0) === 0} - <p class="empty">Aucune catégorie</p> - {/if} -</main> - -<style> - .cat-name { - flex-grow: 1; - font-weight: 500; - color: var(--text); - } - - .drag-handle { - color: var(--text-secondary); - font-size: 0.875rem; - cursor: grab; - padding-right: 0.5rem; - user-select: none; - } - - .error { - margin-top: -0.25rem; - margin-bottom: 0.5rem; - } - - .cat-add-bar { - display: flex; - gap: 0.5rem; - padding: 0.75rem 0; - } - - .cat-add-bar input { - flex: 1; - background: var(--surface); - } - - .btn-accent { - width: 3rem; - height: 3rem; - flex-shrink: 0; - padding: 0; - border: none; - border-radius: 0.75rem; - background: var(--accent); - color: var(--white); - font-size: 1.25rem; - font-weight: 500; - font-family: inherit; - cursor: pointer; - display: flex; - align-items: center; - justify-content: center; - transition: all 0.2s ease; - box-shadow: 0 1px 2px var(--shadow); - } - - .btn-accent:hover { - background: var(--accent-hover); - transform: translateY(-1px); - box-shadow: 0 4px 8px var(--shadow-accent-lg); - } - - .empty { - margin-top: 1rem; - padding: 2rem; - } -</style> |
