import { useEffect, useRef, useState, useCallback } from 'react'; import { api } from '../lib/api'; interface GifImage { url: string; } interface Gif { id: string; title: string; url: string; images: { fixed_height: GifImage; original: GifImage; }; username: string; } interface GiphyPickerProps { onSelect: (gif: Gif) => void; onClose: () => void; } export function GiphyPicker({ onSelect, onClose }: GiphyPickerProps) { const [query, setQuery] = useState(''); const [results, setResults] = useState([]); const [loading, setLoading] = useState(false); const inputRef = useRef(null); const debounceRef = useRef>(); // Fetch trending on mount useEffect(() => { const fetchTrending = async () => { setLoading(true); try { const gifs = await api.get('/gifs/trending'); setResults(gifs); } catch { setResults([]); } finally { setLoading(false); } }; fetchTrending(); inputRef.current?.focus(); }, []); // Debounced search useEffect(() => { if (debounceRef.current) { clearTimeout(debounceRef.current); } if (!query.trim()) { // If query cleared, reload trending const fetchTrending = async () => { setLoading(true); try { const gifs = await api.get('/gifs/trending'); setResults(gifs); } catch { setResults([]); } finally { setLoading(false); } }; fetchTrending(); return; } debounceRef.current = setTimeout(async () => { setLoading(true); try { const gifs = await api.get( `/gifs/search?q=${encodeURIComponent(query.trim())}` ); setResults(gifs); } catch { setResults([]); } finally { setLoading(false); } }, 300); return () => { if (debounceRef.current) { clearTimeout(debounceRef.current); } }; }, [query]); const handleClick = useCallback( (gif: Gif) => { onSelect(gif); }, [onSelect] ); return (
{/* Header with search */}
{'>'} search: setQuery(e.target.value)} placeholder="_" className="bg-transparent text-gb-fg outline-none flex-1 caret-gb-orange" />
{/* Results grid */}
{loading && (

[loading...]

)} {!loading && results.length === 0 && (

[no results]

)} {!loading && results.length > 0 && (
{results.map((gif) => ( ))}
)}
); } export type { Gif };