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