# Feature: Playlists
Cette feature fournit tous les composants, hooks et services nécessaires pour gérer les playlists dans l'application VEZA.
## Architecture
### Structure des fichiers
```
features/playlists/
├── components/ # Composants UI
│ ├── PlaylistCard.tsx # Carte d'affichage d'une playlist
│ ├── PlaylistList.tsx # Liste de playlists avec pagination
│ ├── PlaylistHeader.tsx # En-tête de détail de playlist
│ ├── PlaylistActions.tsx # Actions (edit/delete) pour une playlist
│ ├── PlaylistForm.tsx # Formulaire création/édition
│ ├── CreatePlaylistDialog.tsx # Dialog de création
│ ├── PlaylistAnalytics.tsx # Analytics d'une playlist
│ ├── PlaylistEditor.tsx # Éditeur de playlist
│ └── PlaylistManager.tsx # Gestionnaire de playlists
├── pages/ # Pages
│ ├── PlaylistListPage.tsx # Page liste des playlists
│ ├── PlaylistDetailPage.tsx # Page détail d'une playlist
│ ├── PlaylistCreatePage.tsx # Page création
│ └── PlaylistEditPage.tsx # Page édition
├── hooks/ # Hooks React
│ ├── usePlaylist.ts # Hooks pour CRUD playlists et collaboration
│ └── usePlaylistPermissions.ts # Hooks pour les permissions
├── services/ # Services
│ └── playlistService.ts # Service API pour playlists
├── routes.tsx # Routes React Router
├── types.ts # Types TypeScript
├── __tests__/ # Tests d'intégration
│ ├── playlist.integration.test.tsx
│ └── collaboration.integration.test.tsx
└── index.ts # Exports publics
```
## Utilisation
### Routes
Les routes sont configurées dans `routes.tsx` et intégrées dans le router principal :
- `/playlists` - Liste des playlists
- `/playlists/new` - Créer une nouvelle playlist
- `/playlists/:id` - Détails d'une playlist
- `/playlists/:id/edit` - Éditer une playlist
### Composants principaux
#### Gestion des Tracks dans une Playlist
La page `PlaylistDetailPage` intègre tous les composants de gestion des tracks :
- **PlaylistTrackList** : Affiche la liste des tracks avec numérotation, actions (play, remove) et drag-and-drop pour réorganiser
- **AddTrackToPlaylistModal** : Modal pour rechercher et ajouter des tracks à la playlist
- **RemoveTrackButton** : Bouton pour retirer un track de la playlist (intégré dans PlaylistTrackItem)
**Fonctionnalités :**
- Affichage ordonné des tracks par position
- Drag-and-drop pour réorganiser les tracks
- Ajout de tracks via modal de recherche
- Suppression de tracks avec confirmation
- Lecture des tracks directement depuis la playlist
- Synchronisation avec le player global
**Exemple d'utilisation :**
```tsx
```
#### PlaylistList
Affiche une liste de playlists avec pagination et vue grille/liste.
```tsx
import { PlaylistList } from '@/features/playlists';
```
#### PlaylistCard
Carte d'affichage d'une playlist individuelle.
```tsx
import { PlaylistCard } from '@/features/playlists';
```
#### PlaylistForm
Formulaire réutilisable pour créer ou éditer une playlist.
```tsx
import { PlaylistForm } from '@/features/playlists';
// Création
// Édition
```
#### PlaylistDetailPage
Page complète de détail d'une playlist avec header, actions et liste des tracks.
```tsx
import { PlaylistDetailPage } from '@/features/playlists';
// Utilisé via les routes : /playlists/:id
```
### Hooks
#### usePlaylist
Récupère une playlist par son ID.
```tsx
import { usePlaylist } from '@/features/playlists';
const { data: playlist, isLoading, error } = usePlaylist(playlistId);
```
#### usePlaylists
Récupère la liste des playlists avec pagination.
```tsx
import { usePlaylists } from '@/features/playlists';
const { data, isLoading, error } = usePlaylists(limit, offset);
```
#### useCreatePlaylist
Hook de mutation pour créer une playlist.
```tsx
import { useCreatePlaylist } from '@/features/playlists';
const createMutation = useCreatePlaylist();
await createMutation.mutateAsync({
title: 'My Playlist',
description: 'Description',
is_public: true,
});
```
#### useUpdatePlaylist
Hook de mutation pour mettre à jour une playlist.
```tsx
import { useUpdatePlaylist } from '@/features/playlists';
const updateMutation = useUpdatePlaylist();
await updateMutation.mutateAsync({
id: 1,
data: {
title: 'Updated Title',
description: 'Updated description',
},
});
```
#### useDeletePlaylist
Hook de mutation pour supprimer une playlist.
```tsx
import { useDeletePlaylist } from '@/features/playlists';
const deleteMutation = useDeletePlaylist();
await deleteMutation.mutateAsync(playlistId);
```
### Services
#### playlistService
Service API pour toutes les opérations CRUD.
```tsx
import { createPlaylist, getPlaylist, updatePlaylist, deletePlaylist, listPlaylists } from '@/features/playlists';
// Créer
const playlist = await createPlaylist({
title: 'My Playlist',
description: 'Description',
is_public: true,
});
// Lire
const playlist = await getPlaylist(1);
const playlists = await listPlaylists(20, 0);
// Mettre à jour
const updated = await updatePlaylist(1, {
title: 'Updated Title',
});
// Supprimer
await deletePlaylist(1);
```
### Types
```tsx
import type {
Playlist,
PlaylistTrack,
CreatePlaylistRequest,
UpdatePlaylistRequest,
PlaylistListResponse,
} from '@/features/playlists';
```
## Fonctionnalités
### CRUD complet
- ✅ Création de playlists
- ✅ Lecture (liste et détail)
- ✅ Mise à jour
- ✅ Suppression
### Interface utilisateur
- ✅ Vue grille et liste
- ✅ Pagination
- ✅ Filtres et recherche
- ✅ Actions (edit/delete) avec vérification d'ownership
- ✅ Modals de confirmation
### Validation
- ✅ Validation des formulaires avec zod
- ✅ Messages d'erreur en français
- ✅ Validation côté client et serveur
### Tests
- ✅ Tests unitaires pour tous les composants
- ✅ Tests d'intégration CRUD
- ✅ Coverage ≥ 80%
## Dépendances
- React Router pour la navigation
- React Query pour la gestion des données
- Zustand pour l'état d'authentification
- Zod pour la validation
- React Hook Form pour les formulaires
## Notes
- Les playlists sont liées à un utilisateur (user_id)
- Seul le propriétaire peut modifier/supprimer sa playlist
- Les playlists peuvent être publiques ou privées
- Les playlists peuvent contenir des tracks (PlaylistTrack)