CampFireCritics/src/components/ui/SearchBar.jsx

116 lines
3.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useEffect, useRef } from 'react';
import { FiSearch, FiX } from 'react-icons/fi';
import { searchMedia } from '../../services/pocketbaseService';
import SearchResults from './SearchResults';
const SearchBar = ({ onClose, mobileMode = false }) => {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const inputRef = useRef(null);
// Фокус на инпут при монтировании
useEffect(() => {
const timer = setTimeout(() => {
if (inputRef.current) {
inputRef.current.focus();
}
}, 100);
return () => clearTimeout(timer);
}, []);
useEffect(() => {
const delayDebounceFn = setTimeout(() => {
if (query.length >= 2) {
setIsLoading(true);
searchMedia(query)
.then((data) => {
setResults(data);
setIsLoading(false);
})
.catch((error) => {
console.error('Search error:', error);
setIsLoading(false);
});
} else {
setResults([]);
}
}, 300);
return () => clearTimeout(delayDebounceFn);
}, [query]);
const handleInputChange = (e) => {
const value = e.target.value;
// Если это первый символ, делаем его заглавным
if (value.length === 1) {
setQuery(value.toUpperCase());
} else {
setQuery(value);
}
};
const handleResultClick = () => {
onClose(); // Закрываем поиск при клике на результат
};
return (
<div className="relative">
<div className="flex items-center gap-2">
<div className="relative flex-1">
<FiSearch className="absolute left-3 top-1/2 -translate-y-1/2 text-campfire-ash" />
<input
ref={inputRef}
type="text"
value={query}
onChange={handleInputChange}
placeholder="Че потерял?"
className="w-full pl-10 pr-4 py-2 bg-campfire-charcoal border border-campfire-ash/30 rounded-md text-campfire-light placeholder-campfire-ash focus:outline-none focus:ring-1 focus:ring-campfire-amber/100 focus:border-campfire-amber/50 transition-colors"
/>
{query && (
<button
onClick={() => setQuery('')}
className="absolute right-3 top-1/2 -translate-y-1/2 text-campfire-ash hover:text-campfire-light"
>
<FiX />
</button>
)}
</div>
<button
onClick={onClose}
className="px-4 py-2 text-campfire-light hover:text-campfire-amber transition-colors"
>
Отмена
</button>
</div>
{/* Search Results */}
{(query.length >= 2 || results.length > 0) && (
mobileMode ? (
<div className="mt-2 bg-campfire-charcoal/95 backdrop-blur-md border-b border-campfire-ash/30 shadow-lg rounded-lg">
<div className="container-custom mx-auto px-4 py-4">
{isLoading ? (
<div className="text-campfire-light text-center">Поиск...</div>
) : (
<SearchResults results={results} onResultClick={handleResultClick} />
)}
</div>
</div>
) : (
<div className="fixed left-0 right-0 top-[72px] bg-campfire-charcoal/95 backdrop-blur-md border-b border-campfire-ash/30 shadow-lg">
<div className="container-custom mx-auto px-4 py-4">
{isLoading ? (
<div className="text-campfire-light text-center">Поиск...</div>
) : (
<SearchResults results={results} onResultClick={handleResultClick} />
)}
</div>
</div>
)
)}
</div>
);
};
export default SearchBar;