import { use, useEffect, useState, type ChangeEvent, type Dispatch, type FormEvent, type SetStateAction } from "react"; import type { SearchFilters } from "../../types/search"; import FilterButton from "../buttons/FilterButton"; import RecipeSearchFilterDropdown from "./RecipeSearchFilterDropdown"; import { SearchRecipes } from "../../services/RecipeService"; import { isApiError } from "../../types/api/error"; import type { Recipe } from "../../types/recipe"; import { useNavigate } from "react-router-dom"; import { FilterContext } from "../../context/FilterContext"; interface RecipeSearchBarProps { // filters: SearchFilters; // setFilters: React.Dispatch>; redirect: boolean; searchOnLoad: boolean; favorites: boolean; setRecipes: Dispatch> | null; // Loading is optional loading?: boolean; setLoading?: Dispatch>; }; export default function RecipeSearchBar({ redirect, searchOnLoad, favorites, setRecipes, loading, setLoading }: RecipeSearchBarProps) { const navigate = useNavigate(); const { filters, setFilters } = use(FilterContext); const [displayDropdown, setDisplayDropdown] = useState(false); // SERVER FUNCTIONS const fetchSearchResults = async () => { if (redirect) { await navigate("/v2/web/search"); return; } // Should not allow many queries, thought we should allow redirect through loading if (loading) return; if (setLoading) setLoading(true); try { const result = await SearchRecipes(filters); if (isApiError(result)) { console.error(result.message); return; } if (setRecipes) setRecipes(result); } finally { if (setLoading) setLoading(false); } } // HANDLERS const toggleDropdownHandler = () => setDisplayDropdown(!displayDropdown); // TODO: Store filters in a global state somewhere! const searchHandler = async (e: FormEvent): Promise => { e.preventDefault(); await fetchSearchResults(); }; const queryInputHandler = (e: ChangeEvent) => { const new_filters: SearchFilters = { ...filters, Search: e.target.value, }; setFilters(new_filters); } // EFFECTS // TODO: Learn how to use 'useCallback' here to prevent endless loading and fix warning useEffect(() => { if (searchOnLoad) void fetchSearchResults(); }, [searchOnLoad]); useEffect(() => { setFilters({ ...filters, Favorites: favorites }); }, [favorites]); return (
void searchHandler(e)}>
); }