fix: conectar SearchDropdown com Header e passar searchValue corretamente

This commit is contained in:
Erik
2025-12-01 16:46:47 -03:00
parent bee1af01ec
commit ef98075686
6 changed files with 348 additions and 14 deletions

View File

@@ -10,6 +10,7 @@ import SearchDropdown from './SearchDropdown';
export default function Header() {
const [isSearchOpen, setIsSearchOpen] = useState(false);
const [searchValue, setSearchValue] = useState('');
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [logo, setLogo] = useState<string | null>(null);
@@ -145,12 +146,19 @@ export default function Header() {
type="text"
placeholder={t('nav.search')}
autoFocus
onBlur={() => setIsSearchOpen(false)}
value={searchValue}
onChange={(e) => setSearchValue(e.target.value)}
onBlur={() => setTimeout(() => setIsSearchOpen(false), 200)}
className="bg-transparent border-none outline-none text-sm w-full text-gray-600 dark:text-gray-200 placeholder-gray-400"
/>
)}
</div>
<SearchDropdown isOpen={isSearchOpen} onClose={() => setIsSearchOpen(false)} />
<SearchDropdown
isOpen={isSearchOpen}
searchValue={searchValue}
onSearchChange={setSearchValue}
onClose={() => setIsSearchOpen(false)}
/>
</div>
<nav className="flex items-center gap-6 mr-4">

View File

@@ -15,10 +15,11 @@ interface Project {
interface SearchDropdownProps {
onClose?: () => void;
isOpen: boolean;
searchValue: string;
onSearchChange: (value: string) => void;
}
export default function SearchDropdown({ onClose, isOpen }: SearchDropdownProps) {
const [searchTerm, setSearchTerm] = useState('');
export default function SearchDropdown({ onClose, isOpen, searchValue, onSearchChange }: SearchDropdownProps) {
const [results, setResults] = useState<Project[]>([]);
const [allProjects, setAllProjects] = useState<Project[]>([]);
const [loading, setLoading] = useState(false);
@@ -48,7 +49,7 @@ export default function SearchDropdown({ onClose, isOpen }: SearchDropdownProps)
// Filtrar resultados conforme o usuário digita
useEffect(() => {
if (!searchTerm.trim()) {
if (!searchValue.trim()) {
setResults([]);
return;
}
@@ -58,21 +59,21 @@ export default function SearchDropdown({ onClose, isOpen }: SearchDropdownProps)
// Simular pequeno delay para evitar renderizações desnecessárias
const timer = setTimeout(() => {
const filtered = allProjects.filter(project =>
project.title.toLowerCase().includes(searchTerm.toLowerCase())
project.title.toLowerCase().includes(searchValue.toLowerCase())
);
setResults(filtered.slice(0, 5)); // Limitar a 5 resultados
setLoading(false);
}, 300);
return () => clearTimeout(timer);
}, [searchTerm, allProjects]);
}, [searchValue, allProjects]);
const defaultImage = 'https://images.unsplash.com/photo-1504307651254-35680f356dfd?q=80&w=200&auto=format&fit=crop';
return (
<>
{/* Dropdown Overlay */}
{isOpen && searchTerm && (
{isOpen && searchValue && (
<div className="absolute top-full left-0 right-0 mt-2 bg-white dark:bg-secondary rounded-lg shadow-xl border border-gray-200 dark:border-white/10 z-50 max-w-md w-full">
{loading && (
<div className="p-6 text-center">
@@ -82,10 +83,10 @@ export default function SearchDropdown({ onClose, isOpen }: SearchDropdownProps)
</div>
)}
{!loading && results.length === 0 && searchTerm && (
{!loading && results.length === 0 && searchValue && (
<div className="p-6 text-center text-gray-500 dark:text-gray-400">
<i className="ri-search-line text-3xl mb-3 block opacity-50"></i>
<p>Nenhum projeto encontrado com "{searchTerm}"</p>
<p>Nenhum projeto encontrado com "{searchValue}"</p>
</div>
)}
@@ -96,12 +97,12 @@ export default function SearchDropdown({ onClose, isOpen }: SearchDropdownProps)
key={project.id}
href={`${prefix}/projetos`}
onClick={() => {
setSearchTerm('');
onSearchChange('');
onClose?.();
}}
className="flex items-center gap-3 p-3 hover:bg-gray-50 dark:hover:bg-white/5 border-b border-gray-100 dark:border-white/10 last:border-b-0 transition-colors group"
>
<div className="relative w-16 h-16 flex-shrink-0 rounded-lg overflow-hidden bg-gray-200 dark:bg-white/5">
<div className="relative w-16 h-16 shrink-0 rounded-lg overflow-hidden bg-gray-200 dark:bg-white/5">
<Image
src={project.coverImage || defaultImage}
alt={project.title}
@@ -120,7 +121,7 @@ export default function SearchDropdown({ onClose, isOpen }: SearchDropdownProps)
</p>
)}
</div>
<i className="ri-arrow-right-line text-gray-400 group-hover:text-primary transition-colors flex-shrink-0 opacity-0 group-hover:opacity-100"></i>
<i className="ri-arrow-right-line text-gray-400 group-hover:text-primary transition-colors shrink-0 opacity-0 group-hover:opacity-100"></i>
</Link>
))}
@@ -128,7 +129,7 @@ export default function SearchDropdown({ onClose, isOpen }: SearchDropdownProps)
<Link
href={`${prefix}/projetos`}
onClick={() => {
setSearchTerm('');
onSearchChange('');
onClose?.();
}}
className="flex items-center justify-center gap-2 p-3 text-primary font-medium hover:bg-primary/10 border-t border-gray-100 dark:border-white/10 transition-colors group"