'use client'; import { useState, useEffect, useCallback } from 'react'; import { getProducts, getProduct, getProductRecommendations, } from '@/services/shopify/catalog'; // Pure fetchers live in services/shopify/catalog so server code can use them // too; re-exported here so existing imports keep working. export { getProducts, getProductsPage, getProduct, getProductRecommendations, } from '@/services/shopify/catalog'; export type { Product, ProductOption, ProductOptionValue, ProductsPage, } from '@/services/shopify/catalog'; import type { Product } from '@/services/shopify/catalog'; interface UseProductsOptions { first?: number; after?: string | null; query?: string; sortKey?: 'BEST_SELLING' | 'CREATED_AT' | 'PRICE' | 'TITLE'; reverse?: boolean; } interface UseProductsReturn { products: Product[]; loading: boolean; error: string | null; refetch: () => Promise; } // Hook for fetching multiple products export function useProducts(options: UseProductsOptions = {}): UseProductsReturn { const [products, setProducts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const fetchProducts = useCallback(async () => { try { setLoading(true); setError(null); const data = await getProducts(options); setProducts(data); } catch (err) { console.error('Error fetching products:', err); setError(err instanceof Error ? err.message : 'Failed to load products'); } finally { setLoading(false); } }, [options.first, options.query, options.sortKey, options.reverse]); useEffect(() => { fetchProducts(); }, [fetchProducts]); return { products, loading, error, refetch: fetchProducts }; } // Hook for fetching a single product export function useProduct(handle: string | null) { const [product, setProduct] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const fetchProduct = useCallback(async () => { if (!handle) { setLoading(false); return; } try { setLoading(true); setError(null); const data = await getProduct(handle); setProduct(data); if (!data) { setError('Product not found'); } } catch (err) { console.error('Error fetching product:', err); setError(err instanceof Error ? err.message : 'Failed to load product'); } finally { setLoading(false); } }, [handle]); useEffect(() => { fetchProduct(); }, [fetchProduct]); return { product, loading, error, refetch: fetchProduct }; } // Hook for fetching product recommendations export function useProductRecommendations(productId: string | null) { const [recommendations, setRecommendations] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const fetchRecommendations = useCallback(async () => { if (!productId) { setLoading(false); return; } try { setLoading(true); setError(null); const data = await getProductRecommendations(productId); setRecommendations(data); } catch (err) { console.error('Error fetching recommendations:', err); setError(err instanceof Error ? err.message : 'Failed to load recommendations'); } finally { setLoading(false); } }, [productId]); useEffect(() => { fetchRecommendations(); }, [fetchRecommendations]); return { recommendations, loading, error, refetch: fetchRecommendations }; }