import { useEffect, useState } from 'react'; import { fetchCategories, fetchProducts, type Product } from '@/lib/api'; import ProductGallery from '@/components/ProductGallery'; const ProductsPage = () => { const [categories, setCategories] = useState(['All']); const [selectedCategory, setSelectedCategory] = useState('All'); const [products, setProducts] = useState([]); const [failed, setFailed] = useState(false); useEffect(() => { fetchCategories().then(setCategories).catch(() => setFailed(true)); }, []); // The filter is applied by the API, not in the browser — one source of truth for what's in a // category. `ignore` drops a slow response that lost the race to a newer click. useEffect(() => { let ignore = false; setFailed(false); fetchProducts(selectedCategory) .then((p) => { if (!ignore) setProducts(p); }) .catch(() => { if (!ignore) setFailed(true); }); return () => { ignore = true; }; }, [selectedCategory]); return (
{/* Page header */}

Our products

{/* Products Section */}
{/* Categories */}
{categories.map((category) => ( ))}
{failed && (

We could not load the menu just now. Please refresh, or call us on{' '} (309) 701-0660.

)} {/* Products Grid — deliberately unanimated. Filtering used to run a `layout` reflow plus an enter/exit fade on every card, which on a 40-card grid reads as the page lurching rather than responding. Swapping the list outright is instant, and the only motion left is the shadow on hover. */}
{products.map((product) => (
{/* Image Container */}
{/* Content */}

{product.name}

{product.category}
))}
); }; export default ProductsPage;