# 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.

```typescript
const { data: staffCheck, isLoading } = useStaffCheck();
// Returns: { isStaff: boolean }
```

#### `useOrganizations()`
Récupère la liste de toutes les organisations.

```typescript
const { data: organizations } = useOrganizations();
// Returns: Organization[]
```

#### `useProductions(orgId?, searchQuery?)`
Récupère les productions avec filtres optionnels.

```typescript
const { data: productions, isLoading, error } = useProductions(orgId, searchQuery);
// Returns: Production[]
```

### Types TypeScript

```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 organisation
- `q` (optional) : Recherche textuelle (nom ou référence)

**Response** :
```json
{
  "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** :
```json
{
  "name": "Festival d'Avignon 2025",
  "reference": "PROD-2025-001",
  "declaration_date": "2025-01-15",
  "org_id": "org-uuid"
}
```

**Validation** :
- `name` : Requis, non vide
- `org_id` : Requis, doit exister dans `organizations`
- `reference` : Optionnel
- `declaration_date` : Optionnel

**Response** :
```json
{
  "production": { /* Production créée */ }
}
```

**Codes d'erreur** :
- `400` : Validation échouée
- `401` : 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** :
```json
{
  "production": { /* Production */ }
}
```

**Codes d'erreur** :
- `401` : Non authentifié
- `403` : Accès refusé (non-staff)
- `404` : Production introuvable
- `500` : Erreur serveur

### PATCH `/api/staff/productions/[id]`

**Description** : Mettre à jour une production

**Body** (tous les champs optionnels) :
```json
{
  "name": "Nouveau nom",
  "reference": "NEW-REF",
  "declaration_date": "2025-02-01",
  "org_id": "autre-org-uuid"
}
```

**Response** :
```json
{
  "production": { /* Production mise à jour */ }
}
```

**Codes d'erreur** :
- `400` : Validation échouée
- `401` : Non authentifié
- `403` : Accès refusé (non-staff)
- `404` : Production introuvable
- `500` : 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** :
```json
{
  "message": "Production supprimée avec succès",
  "deleted_id": "uuid"
}
```

**Codes d'erreur** :
- `400` : Production utilisée dans des contrats
- `401` : Non authentifié
- `403` : Accès refusé (non-staff)
- `404` : Production introuvable
- `500` : 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` : Organisations
- `FileText` : Nom de production
- `Hash` : Référence
- `Calendar` : Date de déclaration
- `Plus` : Créer
- `Edit2` : Éditer
- `Trash2` : Supprimer
- `Filter` : Filtres
- `Search` : Recherche
- `Loader2` : Chargement
- `Clapperboard` : Icône sidebar

## 🚀 Utilisation

### Créer une production

1. Cliquer sur **"+ Nouvelle production"**
2. Remplir le formulaire :
   - Nom (requis)
   - Référence (optionnel)
   - Date de déclaration (optionnel)
   - Organisation (requis)
3. Cliquer sur **"Créer"**

### Modifier une production

1. Cliquer sur l'icône ✏️ dans la colonne Actions
2. Modifier les champs souhaités
3. Cliquer sur **"Enregistrer"**

### Supprimer une production

1. Cliquer sur l'icône 🗑️ dans la colonne Actions
2. Confirmer la suppression dans le modal
3. La production est supprimée si elle n'est pas utilisée

### Filtrer les productions

1. Cliquer sur **"Filtres"**
2. Sélectionner une organisation
3. Les résultats sont filtrés automatiquement

### Rechercher une production

1. Saisir du texte dans la barre de recherche
2. Les résultats sont filtrés en temps réel
3. 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 secondes
- `useOrganizations()` : 60 secondes
- `useProductions()` : 15 secondes

## 🔗 Intégration

### Sidebar

La page est accessible via la sidebar staff :

```tsx
<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

1. **Accès non-staff** : Vérifier refus d'accès
2. **Création** : Créer une production valide
3. **Création invalide** : Vérifier validation (nom vide, org manquante)
4. **Modification** : Éditer une production existante
5. **Suppression** : Supprimer une production non utilisée
6. **Suppression protection** : Tenter de supprimer une production utilisée
7. **Filtres** : Vérifier filtrage par organisation
8. **Recherche** : Vérifier recherche textuelle
9. **Responsive** : Tester sur mobile/tablet/desktop

### Console logs

```javascript
// 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

## 📚 Références

- [Lucide Icons](https://lucide.dev/)
- [TanStack Query (React Query)](https://tanstack.com/query/latest)
- [Tailwind CSS](https://tailwindcss.com/)
- [Next.js App Router](https://nextjs.org/docs/app)
- [Supabase Client](https://supabase.com/docs/reference/javascript)
