'use client'; import React, { useEffect, useState } from 'react'; import { useRouter } from 'next/navigation'; import { Command } from 'cmdk'; import { RiSearchLine } from '@remixicon/react'; import { Dialog, DialogContent, DialogTitle } from '@/components/ui/dialog'; import { Loader } from '@/components/ui/loader'; import { getProducts, type Product } from '@/hooks/use-shopify-products'; interface SearchDialogProps { open: boolean; onOpenChange: (open: boolean) => void; } const SearchDialog: React.FC = ({ open, onOpenChange }) => { const router = useRouter(); const [products, setProducts] = useState([]); const [loading, setLoading] = useState(false); const [query, setQuery] = useState(''); // Load the catalog once per open; cmdk filters it as the user types useEffect(() => { if (!open) { setQuery(''); return; } let cancelled = false; setLoading(true); getProducts({ first: 100, sortKey: 'TITLE' }) .then((data) => { if (!cancelled) setProducts(data); }) .catch((err) => { console.error('Failed to load products for search:', err); }) .finally(() => { if (!cancelled) setLoading(false); }); return () => { cancelled = true; }; }, [open]); const handleSelect = (handle: string) => { onOpenChange(false); router.push(`/products/${handle}`); }; return ( Search products
{loading ? (
) : ( <> No products found. {products.map((product) => { const image = product.images.edges[0]?.node; const price = product.priceRange.minVariantPrice; return ( handleSelect(product.handle)} className="flex cursor-pointer items-center gap-3 rounded-md px-2 py-2 text-sm data-[selected=true]:bg-gray-100" >
{image && ( {image.altText )}
{product.title} ${parseFloat(price.amount).toFixed(2)}
); })} )}
); }; export default SearchDialog;