fix: conectar SearchDropdown com Header e passar searchValue corretamente
This commit is contained in:
@@ -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">
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user