feat(admin): création de catégorie via dashboard

Nouvelle page /admin/categories/new, jumeau de l'écran d'édition :
  - Form complet : name, slug (auto), description, color_hex, icon,
    dimension, sort_order
  - Preview live identique à l'éditeur (top border + folder tinté + badge)
  - Slug auto-généré depuis le nom (normalisation NFD + lowercase + dashes)
    tant que l'utilisateur n'a pas touché manuellement au champ. Flag
    slugDirty mis à true sur premier @input du slug -> on arrête l'auto.
  - Validation color_hex /^#RRGGBB$/ côté client + normalisation upper-case
  - Body construit en omettant les champs vides -> l'API applique ses
    défauts (color_hex='#888888', dimension='transversal', sort_order=0)
  - Sur 201 : redirige vers /admin/categories/:slug/edit pour que l'admin
    voie tout de suite sa nouvelle catégorie et puisse ajuster
  - 422/409/401 gérés comme sur les autres écrans admin

UI
  - AdminCategoriesPage : CTA "Nouvelle catégorie" en haut à droite
  - Router : route nommée admin-category-new avec guard admin

Backend
  - Aucune nouvelle route : POST /api/categories existait déjà
  - Le contrôleur valide name (required, max 128), dimension enum, color
    hex format, slug auto-unique

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-29 13:45:25 +02:00
parent dd7c3910f3
commit dcf99f011a
3 changed files with 263 additions and 3 deletions
+1
View File
@@ -40,6 +40,7 @@ const routes: RouteRecordRaw[] = [
{ path: 'admin/members', name: 'admin-members', component: () => import('@/pages/admin/AdminMembersPage.vue'), beforeEnter: requireAdmin },
{ path: 'admin/members/:slug/edit', name: 'admin-member-edit', component: () => import('@/pages/admin/AdminMemberEditPage.vue'), props: true, beforeEnter: requireAdmin },
{ path: 'admin/categories', name: 'admin-categories', component: () => import('@/pages/admin/AdminCategoriesPage.vue'), beforeEnter: requireAdmin },
{ path: 'admin/categories/new', name: 'admin-category-new', component: () => import('@/pages/admin/AdminCategoryNewPage.vue'), beforeEnter: requireAdmin },
{ path: 'admin/categories/:slug/edit', name: 'admin-category-edit', component: () => import('@/pages/admin/AdminCategoryEditPage.vue'), props: true, beforeEnter: requireAdmin },
{ path: 'admin/login', name: 'admin-login', component: () => import('@/pages/AdminLoginPage.vue'), meta: { hideForAuthed: true } },