"use client"; import { useEffect, useMemo, useRef, useState } from "react"; import { MarketplaceFilters } from "@/components/marketplace-filters"; import { ItemCard } from "@/components/item-card"; interface Item { id: string | number; name: string; category: string; image?: string; rarity?: string; npcPrice?: number; price?: { buy: number; sell: number }; priceHistory?: { highest: number; lowest: number; average: number }; level?: number; weight?: number; slots?: number; skill?: string; } interface InitialData { items: Item[]; total: number; page: number; pageSize: number; totalPages: number; } export default function LibraryClient({ initial }: { initial: InitialData }) { const [items, setItems] = useState(initial.items); const [total, setTotal] = useState(initial.total); const [page, setPage] = useState(initial.page || 1); const [pageSize] = useState(initial.pageSize || 24); const [totalPages, setTotalPages] = useState(initial.totalPages || 1); const [query, setQuery] = useState(""); const [categories, setCategories] = useState([]); const [rarities, setRarities] = useState([]); const [sort, setSort] = useState("name"); const [categoryOptions, setCategoryOptions] = useState<{ value: string; label: string }[] | undefined>(undefined); const debounceRef = useRef(undefined); const searchParams = useMemo(() => { const p = new URLSearchParams(); if (query) p.set("q", query); if (categories.length > 0) p.set("category", categories.join(",")); if (rarities.length > 0) p.set("rarity", rarities.join(",")); if (sort) p.set("sort", sort); p.set("page", String(page)); p.set("pageSize", String(pageSize)); return p; }, [query, categories, rarities, sort, page, pageSize]); useEffect(() => { // Debounce para evitar chamadas excessivas window.clearTimeout(debounceRef.current); debounceRef.current = window.setTimeout(async () => { const res = await fetch(`/api/items?${searchParams.toString()}`); if (!res.ok) return; const data = await res.json(); setItems(data.items); setTotal(data.total); setTotalPages(data.totalPages); }, 250); return () => window.clearTimeout(debounceRef.current); }, [searchParams]); // Carregar categorias dinâmicas a partir das tabelas do banco useEffect(() => { (async () => { try { const res = await fetch("/api/items/categories"); if (!res.ok) return; const data = await res.json(); if (Array.isArray(data.categories)) { const opts = (data.categories as string[]).map((c) => ({ value: c, label: c.charAt(0).toUpperCase() + c.slice(1) })); setCategoryOptions(opts); } } catch { // no-op } })(); }, []); const onSearch = (q: string) => { setPage(1); setQuery(q); }; const onFilter = (f: { rarity: string[]; category: string[]; priceRange?: { min: number; max: number } }) => { setPage(1); setCategories(f.category || []); setRarities(f.rarity || []); }; const onSort = (s: string) => { setPage(1); setSort(s); }; return (
{items.map((item) => ( ) )}
Página {page} de {totalPages}
); }