import { useState, useEffect, useCallback } from 'react'; import { searchTracks, TrackSearchParams, TrackSearchError, } from '../services/trackSearchService'; import { Track } from '../types/track'; import { TrackSearchFilters } from './TrackSearchFilters'; import { TrackSearchResults } from './TrackSearchResults'; import { Input } from '@/components/ui/input'; import { Button } from '@/components/ui/button'; import { useDebounce } from '@/hooks/useDebounce'; import { Search } from 'lucide-react'; import { cn } from '@/lib/utils'; /** * TrackSearch Component * T0305: Composant principal pour la recherche avancée de tracks */ interface TrackSearchProps { className?: string; initialQuery?: string; } export function TrackSearch({ className, initialQuery = '', }: TrackSearchProps) { const [query, setQuery] = useState(initialQuery); const [filters, setFilters] = useState>({}); const [tracks, setTracks] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(1); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); // Debounce de la query pour éviter trop de requêtes const debouncedQuery = useDebounce(query, 500); // Fonction pour effectuer la recherche const performSearch = useCallback(async () => { setLoading(true); setError(null); try { const params: TrackSearchParams = { query: debouncedQuery.trim() || undefined, ...filters, page, limit: 20, }; const response = await searchTracks(params); setTracks(response.tracks); setTotal(response.pagination.total); } catch (err) { let errorMessage = 'Erreur lors de la recherche'; if (err instanceof TrackSearchError) { errorMessage = err.message; } else if (err instanceof Error) { errorMessage = err.message; } setError(errorMessage); setTracks([]); setTotal(0); } finally { setLoading(false); } }, [debouncedQuery, filters, page]); // Effectuer la recherche quand les paramètres changent useEffect(() => { performSearch(); }, [performSearch]); // Réinitialiser la page quand les filtres ou la query changent useEffect(() => { setPage(1); }, [ debouncedQuery, filters.genre, filters.musicalKey, filters.format, filters.tags, filters.minDuration, filters.maxDuration, filters.minBPM, filters.maxBPM, filters.minDate, filters.maxDate, ]); const handleSearch = () => { setPage(1); performSearch(); }; return (
{/* Search Bar */}
setQuery(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') { handleSearch(); } }} className="pl-10 rounded-md transition-[border-color,box-shadow] duration-[var(--sumi-duration-normal)]" />
{/* Filters */} {/* Results */}
); }