Frontend : filtres

This commit is contained in:
2025-12-22 15:53:26 +01:00
parent b0ba1e886c
commit 6c47f0760e
5 changed files with 351 additions and 10 deletions

View File

@@ -1,9 +1,10 @@
"use client"
import { useState } from "react"
import { useState, useMemo } from "react"
import { useQuery } from "@tanstack/react-query"
import { getTracks, getStats } from "@/lib/api"
import type { FilterParams } from "@/lib/types"
import type { FilterParams, Track } from "@/lib/types"
import FilterPanel from "@/components/FilterPanel"
// Helper function to format Discogs genre labels (e.g., "Pop---Ballad" -> ["Pop", "Ballad"])
function formatGenre(genre: string): { category: string; subgenre: string } {
@@ -14,6 +15,42 @@ function formatGenre(genre: string): { category: string; subgenre: string } {
}
}
// Extract unique values for filter options
function extractFilterOptions(tracks: Track[]) {
const genres = new Set<string>()
const moods = new Set<string>()
const instruments = new Set<string>()
const keys = new Set<string>()
tracks.forEach(track => {
// Extract genre category (before "---")
const genreCategory = formatGenre(track.classification.genre.primary).category
genres.add(genreCategory)
// Extract primary mood
if (track.classification.mood.primary) {
moods.add(track.classification.mood.primary)
}
// Extract instruments
track.classification.instruments?.forEach(instrument => {
instruments.add(instrument)
})
// Extract key
if (track.features.key) {
keys.add(track.features.key)
}
})
return {
genres: Array.from(genres).sort(),
moods: Array.from(moods).sort(),
instruments: Array.from(instruments).sort(),
keys: Array.from(keys).sort(),
}
}
export default function Home() {
const [filters, setFilters] = useState<FilterParams>({})
const [page, setPage] = useState(0)
@@ -29,6 +66,16 @@ export default function Home() {
queryFn: getStats,
})
// Extract filter options from displayed tracks
// For better UX, we use the current page's tracks to populate filters
// TODO: Add a dedicated API endpoint to get all unique filter values
const filterOptions = useMemo(() => {
if (!tracksData?.tracks || tracksData.tracks.length === 0) {
return { genres: [], moods: [], instruments: [], keys: [] }
}
return extractFilterOptions(tracksData.tracks)
}, [tracksData])
return (
<div className="min-h-screen bg-gray-50">
{/* Header */}
@@ -63,6 +110,19 @@ export default function Home() {
</div>
)}
{/* Filter Panel */}
<FilterPanel
filters={filters}
onFiltersChange={(newFilters) => {
setFilters(newFilters)
setPage(0) // Reset to first page when filters change
}}
availableGenres={filterOptions.genres}
availableMoods={filterOptions.moods}
availableInstruments={filterOptions.instruments}
availableKeys={filterOptions.keys}
/>
{/* Tracks List */}
<div className="bg-white rounded-lg shadow">
<div className="p-4 border-b">