import { useState, useEffect, useRef, useCallback } from 'react'; interface SearchBarProps { onSearch: (query: string) => void; placeholder?: string; className?: string; initialValue?: string; } export const SearchBar = ({ onSearch, placeholder = "Rechercher...", className = "", initialValue = "" }: SearchBarProps) => { const [searchTerm, setSearchTerm] = useState(initialValue); const [isFocused, setIsFocused] = useState(false); const inputRef = useRef(null); const previousSearchTermRef = useRef(initialValue); // useCallback dans ce cas est utilisé pour éviter les boucles infinies : change l'état du composant parent qui change l'état de searchBar etc const regulatedSearch = useCallback( (term: string) => { // la recherche se fait si le terme a changé depuis la denrière recherche if (term !== previousSearchTermRef.current) { previousSearchTermRef.current = term; // déclenche uniquement à partir de deux caractères if (term.length >= 2 || term === '') { onSearch(term); } } }, [onSearch] ); // useEffect avec un délai pour limiter les appels d'API useEffect(() => { const timer = setTimeout(() => { regulatedSearch(searchTerm); }, 300); return () => { clearTimeout(timer); }; }, [searchTerm, regulatedSearch]); const handleSearch = (e: React.FormEvent) => { e.preventDefault(); if (searchTerm.length < 2 && searchTerm.length > 0) { // indication de la condition if (inputRef.current) { inputRef.current.classList.add('animate-shake'); setTimeout(() => { inputRef.current?.classList.remove('animate-shake'); }, 500); } return; } regulatedSearch(searchTerm); }; return (
setSearchTerm(e.target.value)} onFocus={() => setIsFocused(true)} onBlur={() => setIsFocused(false)} className="flex-1 pl-10 pr-4 py-2 bg-transparent outline-none text-foreground placeholder:text-muted-foreground w-full" /> {searchTerm && ( )}
{searchTerm.length === 1 && (

Veuillez saisir au moins 2 caractères

)}
); };