13 KiB
Gestion des Productions - Documentation Staff
📋 Vue d'ensemble
La page Gestion des Productions (/staff/gestion-productions) est une interface complète permettant aux membres du staff de gérer l'ensemble des productions et spectacles de toutes les organisations.
✨ Fonctionnalités
🎬 CRUD Complet
- Créer : Ajouter de nouvelles productions avec nom, référence, date de déclaration et organisation
- Lire : Visualiser toutes les productions dans un tableau moderne avec filtres
- Mettre à jour : Modifier les informations d'une production existante
- Supprimer : Supprimer une production (avec vérification d'utilisation dans les contrats)
🔍 Recherche et Filtrage
- Recherche textuelle : Recherche en temps réel par nom ou référence
- Filtre par organisation : Filtrer les productions d'une organisation spécifique
- Effacement rapide : Bouton pour réinitialiser tous les filtres
📊 Interface Moderne
- Design ultra-moderne : Interface avec gradients, ombres et animations fluides
- Modales élégantes : Modales avec backdrop blur et animations d'entrée
- Badges et icônes : Affichage visuel clair avec icônes Lucide
- Responsive : Adaptation automatique mobile/tablette/desktop
- États de chargement : Spinners et messages informatifs
🎨 Interface Utilisateur
Header
┌────────────────────────────────────────────────────┐
│ Gestion des productions [+ Nouvelle] │
│ Gérez les productions et spectacles... │
└────────────────────────────────────────────────────┘
Barre de Filtres
- Recherche : Input avec icône de recherche et bouton de réinitialisation
- Filtres : Bouton avec badge indiquant le nombre de filtres actifs
- Organisation : Dropdown pour filtrer par organisation
Tableau des Productions
| Colonne | Description | Type |
|---|---|---|
| Nom | Nom de la production | Texte |
| Référence | Numéro d'objet/référence | Badge avec icône Hash |
| Date déclaration | Date de déclaration | Date avec icône Calendar |
| Organisation | Organisation liée | Texte |
| Actions | Éditer / Supprimer | Boutons icônes |
Modales
Modal Création/Édition
┌──────────────────────────────────────┐
│ 🏢 Nouvelle production ✕ │
├──────────────────────────────────────┤
│ │
│ 📄 Nom de la production * │
│ [Ex: Festival d'Avignon 2025] │
│ │
│ # Numéro d'objet / Référence │
│ [Ex: PROD-2025-001] │
│ │
│ 📅 Date de déclaration │
│ [Date picker] │
│ │
│ 🏢 Organisation * │
│ [Dropdown] │
│ │
│ [Annuler] [Créer ⟳] │
└──────────────────────────────────────┘
Modal Suppression
┌──────────────────────────────────────┐
│ 🗑️ Confirmer la suppression │
│ Cette action est irréversible │
├──────────────────────────────────────┤
│ │
│ Voulez-vous vraiment supprimer │
│ la production "Festival 2025" ? │
│ Référence : PROD-001 │
│ │
│ [Annuler] [Supprimer ⟳] │
└──────────────────────────────────────┘
🔧 Implémentation Technique
Architecture
app/(app)/staff/gestion-productions/
└── page.tsx (Client Component)
app/api/staff/productions/
├── route.ts (GET, POST)
└── [id]/
└── route.ts (GET, PATCH, DELETE)
components/
└── Sidebar.tsx (+ lien navigation)
Hooks React Query
useStaffCheck()
Vérifie si l'utilisateur connecté est staff.
const { data: staffCheck, isLoading } = useStaffCheck();
// Returns: { isStaff: boolean }
useOrganizations()
Récupère la liste de toutes les organisations.
const { data: organizations } = useOrganizations();
// Returns: Organization[]
useProductions(orgId?, searchQuery?)
Récupère les productions avec filtres optionnels.
const { data: productions, isLoading, error } = useProductions(orgId, searchQuery);
// Returns: Production[]
Types TypeScript
type Production = {
id: string;
name: string;
reference: string | null;
declaration_date: string | null;
org_id: string;
created_at?: string;
updated_at?: string;
};
type Organization = {
id: string;
name: string;
structure_api: string;
};
🌐 Routes API
GET /api/staff/productions
Description : Liste toutes les productions avec filtres optionnels
Query Parameters :
org_id(optional) : Filtrer par organisationq(optional) : Recherche textuelle (nom ou référence)
Response :
{
"productions": [
{
"id": "uuid",
"name": "Festival d'Avignon 2025",
"reference": "PROD-2025-001",
"declaration_date": "2025-01-15",
"org_id": "org-uuid",
"created_at": "2025-01-10T10:00:00Z",
"updated_at": "2025-01-10T10:00:00Z"
}
]
}
Codes d'erreur :
401: Non authentifié403: Accès refusé (non-staff)500: Erreur serveur
POST /api/staff/productions
Description : Créer une nouvelle production
Body :
{
"name": "Festival d'Avignon 2025",
"reference": "PROD-2025-001",
"declaration_date": "2025-01-15",
"org_id": "org-uuid"
}
Validation :
name: Requis, non videorg_id: Requis, doit exister dansorganizationsreference: Optionneldeclaration_date: Optionnel
Response :
{
"production": { /* Production créée */ }
}
Codes d'erreur :
400: Validation échouée401: Non authentifié403: Accès refusé (non-staff)500: Erreur serveur
GET /api/staff/productions/[id]
Description : Récupérer une production spécifique
Response :
{
"production": { /* Production */ }
}
Codes d'erreur :
401: Non authentifié403: Accès refusé (non-staff)404: Production introuvable500: Erreur serveur
PATCH /api/staff/productions/[id]
Description : Mettre à jour une production
Body (tous les champs optionnels) :
{
"name": "Nouveau nom",
"reference": "NEW-REF",
"declaration_date": "2025-02-01",
"org_id": "autre-org-uuid"
}
Response :
{
"production": { /* Production mise à jour */ }
}
Codes d'erreur :
400: Validation échouée401: Non authentifié403: Accès refusé (non-staff)404: Production introuvable500: Erreur serveur
DELETE /api/staff/productions/[id]
Description : Supprimer une production
Vérifications :
- La production existe
- La production n'est pas utilisée dans des contrats CDDU
Response :
{
"message": "Production supprimée avec succès",
"deleted_id": "uuid"
}
Codes d'erreur :
400: Production utilisée dans des contrats401: Non authentifié403: Accès refusé (non-staff)404: Production introuvable500: Erreur serveur
🔐 Sécurité
Vérifications
- Authentification : Session Supabase requise
- Autorisation : Vérification
staff_users.is_staff = true - Validation : Toutes les entrées utilisateur sont validées
- Protection suppression : Vérification des dépendances (contrats)
Permissions
- Staff uniquement : Toutes les opérations réservées au staff
- Aucune restriction par organisation : Le staff peut gérer toutes les organisations
📱 Responsive Design
Desktop (≥1024px)
- Tableau pleine largeur
- Filtres sur une ligne
- Modales centrées (max-width: 640px)
Tablet (768px - 1023px)
- Tableau scrollable horizontal
- Filtres sur deux lignes
- Modales adaptées
Mobile (<768px)
- Tableau scrollable
- Filtres empilés verticalement
- Modales plein écran avec padding
🎨 Design System
Couleurs
- Primary Gradient :
from-indigo-600 to-purple-600 - Hover Gradient :
from-indigo-700 to-purple-700 - Background :
bg-white,bg-slate-50 - Border :
border-slate-200 - Text :
text-slate-900,text-slate-600
Animations
- Modal entrée :
animate-in fade-in zoom-in-95 duration-200 - Backdrop :
backdrop-blur-sm - Transitions :
transition-all,transition-colors
Icônes (Lucide React)
Building2: OrganisationsFileText: Nom de productionHash: RéférenceCalendar: Date de déclarationPlus: CréerEdit2: ÉditerTrash2: SupprimerFilter: FiltresSearch: RechercheLoader2: ChargementClapperboard: Icône sidebar
🚀 Utilisation
Créer une production
- Cliquer sur "+ Nouvelle production"
- Remplir le formulaire :
- Nom (requis)
- Référence (optionnel)
- Date de déclaration (optionnel)
- Organisation (requis)
- Cliquer sur "Créer"
Modifier une production
- Cliquer sur l'icône ✏️ dans la colonne Actions
- Modifier les champs souhaités
- Cliquer sur "Enregistrer"
Supprimer une production
- Cliquer sur l'icône 🗑️ dans la colonne Actions
- Confirmer la suppression dans le modal
- La production est supprimée si elle n'est pas utilisée
Filtrer les productions
- Cliquer sur "Filtres"
- Sélectionner une organisation
- Les résultats sont filtrés automatiquement
Rechercher une production
- Saisir du texte dans la barre de recherche
- Les résultats sont filtrés en temps réel
- La recherche porte sur le nom et la référence
🐛 Gestion des Erreurs
Messages utilisateur
- Champ requis : "Le nom est requis"
- Organisation requise : "L'organisation est requise"
- Production utilisée : "Cette production est utilisée dans des contrats..."
- Erreur réseau : "Erreur lors du chargement des productions"
États
- Loading : Spinner avec message "Chargement..."
- Empty : Message "Aucune production trouvée"
- Error : Message d'erreur en rouge avec détails
📊 Performances
Optimisations
- React Query : Cache des requêtes API (15s)
- useMemo : Mémoïsation du filtrage local
- Invalidation sélective : Rafraîchissement uniquement des données modifiées
- Debouncing : Pas de debounce nécessaire (filtrage instant)
Stale Time
useStaffCheck(): 30 secondesuseOrganizations(): 60 secondesuseProductions(): 15 secondes
🔗 Intégration
Sidebar
La page est accessible via la sidebar staff :
<Link href="/staff/gestion-productions">
<Clapperboard className="w-4 h-4" />
Gestion des productions
</Link>
Navigation
- URL :
/staff/gestion-productions - Position : Entre "Virements salaires" et "Gestion des utilisateurs"
- Icône : 🎬 Clapperboard
🧪 Tests
Scénarios de test
- Accès non-staff : Vérifier refus d'accès
- Création : Créer une production valide
- Création invalide : Vérifier validation (nom vide, org manquante)
- Modification : Éditer une production existante
- Suppression : Supprimer une production non utilisée
- Suppression protection : Tenter de supprimer une production utilisée
- Filtres : Vérifier filtrage par organisation
- Recherche : Vérifier recherche textuelle
- Responsive : Tester sur mobile/tablet/desktop
Console logs
// Vérifier les requêtes API
// Réseau > Fetch/XHR
// GET /api/staff/productions
// POST /api/staff/productions
// PATCH /api/staff/productions/[id]
// DELETE /api/staff/productions/[id]
📝 Todo / Améliorations futures
- Export CSV/Excel des productions
- Tri des colonnes du tableau
- Pagination (si + de 100 productions)
- Filtre par date de déclaration (plage)
- Import CSV de productions en masse
- Historique des modifications
- Duplication de production
- Statistiques (nb productions par org, par période)
- Champ description/notes
- Tags/catégories de productions
- Lien direct vers les contrats associés