import { useCallback, useEffect, useState } from "react"; import { get } from "./api"; export interface Item { id: number; name: string; description: string | null; type: string; rarity: string; price: string | null; iconUrl: string; imageUrl: string; } export interface ItemFilters { search: string; type: string | null; rarity: string | null; } export function useItems() { const [items, setItems] = useState([]); const [total, setTotal] = useState(0); const [currentPage, setCurrentPage] = useState(1); const [limit, setLimit] = useState(50); const [filters, setFiltersState] = useState({ search: "", type: null, rarity: null, }); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const fetchItems = useCallback(async () => { try { setLoading(true); setError(null); const params = new URLSearchParams(); if (filters.search) params.set("search", filters.search); if (filters.type) params.set("type", filters.type); if (filters.rarity) params.set("rarity", filters.rarity); params.set("limit", String(limit)); params.set("offset", String((currentPage - 1) * limit)); const data = await get<{ items: Item[]; total: number }>( `/api/items?${params.toString()}` ); setItems(data.items); setTotal(data.total); } catch (e) { setError(e instanceof Error ? e.message : "Failed to load items"); } finally { setLoading(false); } }, [filters, currentPage, limit]); const setFilters = useCallback((newFilters: Partial) => { setFiltersState((prev) => ({ ...prev, ...newFilters })); setCurrentPage(1); }, []); const setSearchDebounced = useCallback( (() => { let timeoutId: NodeJS.Timeout; return (search: string) => { clearTimeout(timeoutId); timeoutId = setTimeout(() => { setFilters({ search }); }, 300); }; })(), [setFilters] ); const setPage = useCallback((page: number) => { setCurrentPage(page); }, []); useEffect(() => { fetchItems(); }, [fetchItems]); return { items, total, currentPage, limit, setLimit, filters, setFilters, setSearchDebounced, setPage, loading, error, refetch: fetchItems, }; }