Frontend : filtres
This commit is contained in:
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user