veza/apps/web/src/features/tracks
senke ede3546f4b
Some checks failed
Backend API CI / test-unit (push) Failing after 0s
Backend API CI / test-integration (push) Failing after 0s
Frontend CI / test (push) Failing after 0s
Storybook Audit / Build & audit Storybook (push) Failing after 0s
feat(release): v0.202 — Lots G, H, F, C, D
- Lot G: Recherche avancée (musical_key, tri pertinence, autocomplete, facettes, historique)
- Lot H: Analytics créateur (stats, charts, completion rate, export CSV/JSON)
- Lot F: Seller dashboard (GET /sell/stats, liste produits)
- Lot C: Player (crossfade, gapless preload, PiP)
- Lot D2: Autoplay (GET /tracks/recommendations, section À écouter ensuite)

Backend: GetRecommendations handler, route /tracks/recommendations
Frontend: PlayerQueue recommendations, fix TS errors (GlobalPlayer, AnalyticsViewKpiGrid, etc.)
Docs: FEATURE_STATUS, PROJECT_STATE, CHANGELOG, SCOPE_CONTROL
2026-02-20 18:16:17 +01:00
..
__tests__ incus deployement fully implemented, Makefile updated and make fmt ran 2026-01-13 19:47:57 +01:00
api feat(release): v0.202 — Lots G, H, F, C, D 2026-02-20 18:16:17 +01:00
components feat(search): add relevance sort option (G2) 2026-02-20 16:50:49 +01:00
docs incus deployement fully implemented, Makefile updated and make fmt ran 2026-01-13 19:47:57 +01:00
errors state-ownership: delete unused optimisticStoreUpdates.ts file 2026-01-15 19:26:53 +01:00
hooks chore: enable noUncheckedIndexedAccess, isolate ghost MSW handlers, document go-clamd tech debt 2026-02-12 23:12:35 +01:00
pages feat(tracks): add suggested tags endpoint and UI (E4) 2026-02-20 15:38:51 +01:00
services feat(search): add relevance sort option (G2) 2026-02-20 16:50:49 +01:00
types feat(tracks): add suggested tags endpoint and UI (E4) 2026-02-20 15:38:51 +01:00
index.ts api-contracts: replace ApiError interface with Zod-inferred type 2026-01-15 17:03:35 +01:00
README.md refonte: backend-api go first; phase 1 2025-12-12 21:34:34 -05:00
types.test.ts refonte: backend-api go first; phase 1 2025-12-12 21:34:34 -05:00
types.ts Phase 2 stabilisation: code mort, Modal→Dialog, feature flags, tests, router split, Rust legacy 2026-02-14 17:23:32 +01:00

Feature: Tracks

Cette feature fournit tous les composants et hooks nécessaires pour afficher et gérer des listes de pistes musicales.

Architecture

Composants

TrackListContainer

Composant principal qui assemble tous les sous-composants pour créer une interface complète de gestion de listes de pistes.

Utilisation :

import { TrackListContainer } from '@/features/tracks';

<TrackListContainer
  showFilters={true}
  showSort={true}
  showViewToggle={true}
  showPagination={true}
  availableGenres={['Rock', 'Pop', 'Jazz']}
  availableArtists={['Artist 1', 'Artist 2']}
  onTrackPlay={(track) => console.log('Play:', track)}
  onTrackLike={(track) => console.log('Like:', track)}
/>;

Props principales :

  • showFilters : Afficher les filtres (défaut: true)
  • showSort : Afficher les options de tri (défaut: true)
  • showViewToggle : Afficher le toggle liste/grille (défaut: true)
  • showPagination : Afficher la pagination (défaut: true)
  • useService : Utiliser le service API pour charger les données (défaut: true)
  • persistFilters : Persister les filtres dans localStorage (défaut: false)
  • persistSort : Persister le tri dans localStorage (défaut: false)
  • syncUrlParams : Synchroniser avec les paramètres URL (défaut: false)

TrackList

Affiche une liste de pistes en format liste (table) avec colonnes, actions et sélection.

TrackGrid

Affiche une grille de pistes avec layout responsive et options de densité.

TrackFilters

Composant de filtrage avec recherche, genre, artiste, année, durée.

TrackSort

Composant de tri avec sélection du champ et ordre (asc/desc).

ViewToggle

Toggle pour basculer entre vue liste et vue grille.

TrackListPagination

Composant de pagination avec navigation et informations.

TrackListEmpty

Affiche des états vides : aucun track, aucun résultat, erreur.

Hooks

useTrackList

Hook principal pour gérer l'état d'une liste de pistes avec tri, filtrage, pagination.

Utilisation :

import { useTrackList } from '@/features/tracks';

const trackList = useTrackList({
  useService: true,
  autoLoad: true,
  persistFilters: true,
  persistSort: true,
});

// Accéder aux données
trackList.filteredTracks; // Tracks filtrés et triés
trackList.isLoading; // État de chargement
trackList.error; // Erreur éventuelle

// Actions
trackList.setFilterOptions({ genre: 'Rock' });
trackList.setSortField('title');
trackList.setPage(2);

Services

trackListService

Service pour interagir avec l'API de listes de pistes.

Fonctions principales :

  • getTracks(options) : Récupérer les pistes avec pagination, filtres, tri
  • getTrackById(id) : Récupérer une piste par ID
  • getTracksByArtist(artist) : Récupérer les pistes d'un artiste

Exemples d'utilisation

Liste simple

import { TrackListContainer } from '@/features/tracks';

function MyTracksPage() {
  return (
    <TrackListContainer
      showFilters={false}
      showSort={true}
      showViewToggle={true}
    />
  );
}

Liste avec filtres personnalisés

import { TrackListContainer } from '@/features/tracks';

function FilteredTracksPage() {
  const genres = ['Rock', 'Pop', 'Jazz'];
  const artists = ['Artist 1', 'Artist 2'];

  return (
    <TrackListContainer
      showFilters={true}
      availableGenres={genres}
      availableArtists={artists}
      persistFilters={true}
      syncUrlParams={true}
    />
  );
}

Liste avec sélection

import { TrackListContainer } from '@/features/tracks';

function SelectableTracksPage() {
  const handleSelectedPlay = (trackIds: number[]) => {
    console.log('Play selected tracks:', trackIds);
  };

  return (
    <TrackListContainer
      showSelection={true}
      onSelectedPlay={handleSelectedPlay}
      onSelectedDelete={(ids) => console.log('Delete:', ids)}
      onSelectedLike={(ids) => console.log('Like:', ids)}
    />
  );
}

Liste avec callbacks personnalisés

import { TrackListContainer } from '@/features/tracks';
import { usePlayer } from '@/features/player';

function InteractiveTracksPage() {
  const player = usePlayer();

  const handleTrackPlay = (track) => {
    player.play(track);
  };

  const handleTrackLike = (track) => {
    // Appel API pour liker
    likeTrack(track.id);
  };

  const isLiked = (trackId: number) => {
    return likedTracks.includes(trackId);
  };

  const isPlaying = (trackId: number) => {
    return player.currentTrack?.id === trackId && player.isPlaying;
  };

  return (
    <TrackListContainer
      onTrackPlay={handleTrackPlay}
      onTrackLike={handleTrackLike}
      isLiked={isLiked}
      isPlaying={isPlaying}
      currentPlayingId={player.currentTrack?.id}
    />
  );
}

Persistance

localStorage

Les préférences peuvent être persistées dans localStorage :

  • Filtres : trackList_filters
  • Tri : trackList_sort
  • Mode d'affichage : trackList_viewMode
  • Densité de grille : trackList_gridDensity

URL Parameters

Les filtres et le tri peuvent être synchronisés avec les paramètres URL :

  • ?genre=Rock&artist=Artist1&sortField=title&sortOrder=asc

Tests

Tous les composants incluent des tests unitaires avec coverage ≥ 80%.

Exécuter les tests :

npm test -- features/tracks

Accessibilité

Tous les composants respectent les standards d'accessibilité :

  • Attributs ARIA appropriés
  • Navigation au clavier
  • Support des lecteurs d'écran
  • Contraste de couleurs conforme WCAG

Performance

  • Lazy loading des composants
  • Mémoïsation des calculs coûteux
  • Debouncing des recherches
  • Pagination côté serveur pour les grandes listes