feat(admin): création de membre via dashboard
Nouvelle page /admin/members/new, jumeau de l'écran d'édition :
- Form complet : display_name, slug (auto), initials (auto), kind, bio,
email, website, avatar URL
- Avatar preview live (initiales / URL d'avatar mis à jour à la saisie)
- Slug auto-généré depuis display_name (NFD + lowercase + tirets)
tant que l'utilisateur n'a pas édité manuellement (flag slugDirty)
- Initiales auto-suggérées (1re lettre de chaque mot, max 3, upper),
flag initialsDirty distinct -> tu peux laisser le slug auto mais
forcer des initiales manuelles ou vice-versa
- Body construit en omettant les champs vides -> l'API génère ses propres
initiales si vides, slug auto-uniqueifie sur collision (-2/-3...)
- 201 -> redirige vers /admin/members/:slug/edit pour voir le résultat
- 422/409/401 gérés comme les autres écrans admin
UI
- AdminMembersPage : CTA "Nouveau membre" en haut à droite (à côté de
la recherche, justify-between sur le wrap parent)
- Router : route nommée admin-member-new avec guard admin
Backend
- Aucune nouvelle route : POST /api/members existait déjà
- Le contrôleur valide display_name (required), kind enum, email format,
URLs ; auto-génère initiales si non fournies (1res lettres de chaque mot)
- Slug auto avec suffixe en cas de collision (cf. Slugger::unique)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -62,13 +62,22 @@ const KIND_LABEL = {
|
||||
</header>
|
||||
<AdminSubNav />
|
||||
|
||||
<div class="mt-6 flex items-center gap-2">
|
||||
<div class="mt-6 flex items-center justify-between gap-2 flex-wrap">
|
||||
<input
|
||||
v-model="searchQ"
|
||||
type="search"
|
||||
placeholder="Rechercher un membre…"
|
||||
class="bg-donut-surface border border-donut-border rounded-lg px-3 py-2 text-sm outline-none focus:border-donut-text w-64"
|
||||
/>
|
||||
<RouterLink
|
||||
:to="{ name: 'admin-member-new' }"
|
||||
class="flex items-center gap-1.5 bg-donut-text text-white rounded-lg px-3.5 py-2 text-sm font-medium hover:bg-black transition-colors"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round">
|
||||
<path d="M12 5v14M5 12h14" />
|
||||
</svg>
|
||||
Nouveau membre
|
||||
</RouterLink>
|
||||
</div>
|
||||
|
||||
<LoadingState v-if="loading" class="mt-8" />
|
||||
|
||||
Reference in New Issue
Block a user