"use client"; import { useState, useEffect } from "react"; import { usePathname } from "next/navigation"; import Header from "@/components/Header"; import Footer from "@/components/Footer"; import PageHero from "@/components/PageHero"; import BoardCard from "@/components/BoardCard"; import { AlertTriangle, RefreshCw, Search, ShoppingCart, SlidersHorizontal } from "lucide-react"; const HEADER_MAP_EN = { "Nome": "Name", "Descrição": "Description", "Série": "Series", "Loja Oficial": "Official Store", "Fabricante": "Manufacturer", "Processador": "Processor", "Memória Flash": "Flash Memory", "PSRAM": "PSRAM", "Conector USB": "USB Connector", "Interface USB": "USB Interface", "Antena": "Antenna", "Bateria": "Battery", "Display": "Display", "Sensores": "Sensors", "Botões": "Buttons", "LEDs": "LEDs", }; const VALUE_MAP_EN = { "Sim": "Yes", "Não": "No", "Opcional": "Optional", }; export default function PlacasPage() { const pathname = usePathname() || ""; const isEn = pathname === "/en" || pathname.startsWith("/en/"); const [boards, setBoards] = useState([]); const [filteredBoards, setFilteredBoards] = useState([]); const [headers, setHeaders] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [searchTerm, setSearchTerm] = useState(""); const [activeFilters, setActiveFilters] = useState({}); const [filterOptions, setFilterOptions] = useState({}); const [filtrosAbertos, setFiltrosAbertos] = useState(false); const excludedColumns = ["Nome", "Descrição", "Link", "Imagem", "Loja Oficial"]; useEffect(() => { fetchBoards(); setFiltrosAbertos(window.matchMedia("(min-width: 1024px)").matches); }, []); useEffect(() => { applyFilters(); }, [boards, searchTerm, activeFilters]); const fetchBoards = async () => { try { setLoading(true); const response = await fetch("/api/placas"); if (!response.ok) { throw new Error(isEn ? "Failed to load board data" : "Erro ao carregar dados das placas"); } const result = await response.json(); setBoards(result.data); setHeaders(result.headers); setFilteredBoards(result.data); generateFilterOptions(result.data, result.headers); } catch (err) { setError(err.message); } finally { setLoading(false); } }; const generateFilterOptions = (data, headers) => { const options = {}; const filterableColumns = headers.filter((h) => !excludedColumns.includes(h)); filterableColumns.forEach((column) => { const uniqueValues = new Set(); data.forEach((item) => { const value = item[column]; if (value && value.toString().trim()) { uniqueValues.add(value.toString().trim()); } }); const values = Array.from(uniqueValues).sort(); const binaryValues = ["Sim", "Não", "Opcional"]; const isBinaryFilter = values.every((v) => binaryValues.includes(v)); options[column] = { values: values, isBinary: isBinaryFilter, }; }); setFilterOptions(options); }; const applyFilters = () => { let filtered = [...boards]; if (searchTerm) { filtered = filtered.filter((board) => { const searchLower = searchTerm.toLowerCase(); return ( board.Nome?.toLowerCase().includes(searchLower) || board.Descrição?.toLowerCase().includes(searchLower) ); }); } Object.keys(activeFilters).forEach((column) => { if (activeFilters[column] && activeFilters[column].length > 0) { filtered = filtered.filter((board) => { const boardValue = board[column]?.toString().trim(); if (activeFilters[column].includes("binary-enabled")) { return boardValue === "Sim" || boardValue === "Opcional"; } return activeFilters[column].includes(boardValue); }); } }); setFilteredBoards(filtered); }; const handleFilterToggle = (column, value) => { setActiveFilters((prev) => { const newFilters = { ...prev }; if (!newFilters[column]) { newFilters[column] = [value]; } else { const index = newFilters[column].indexOf(value); if (index > -1) { newFilters[column] = newFilters[column].filter((v) => v !== value); if (newFilters[column].length === 0) { delete newFilters[column]; } } else { newFilters[column] = [...newFilters[column], value]; } } return newFilters; }); }; const clearFilters = () => { setActiveFilters({}); setSearchTerm(""); }; const activeFilterCount = Object.keys(activeFilters).length + (searchTerm ? 1 : 0); const filterableColumns = headers.filter((h) => !excludedColumns.includes(h)); const hero = ( ); if (loading) { return (
{hero}
{Array.from({ length: 6 }).map((_, i) => (
))}

{isEn ? "Querying boards database…" : "Consultando o banco de placas…"}

); } if (error) { return (
{hero}
); } const filtros = (
{filterableColumns.map((column) => { const filterData = filterOptions[column]; if (!filterData) return null; const colLabel = isEn ? (HEADER_MAP_EN[column] || column) : column; if (filterData.isBinary) { return ( ); } return (
{colLabel} {activeFilters[column]?.length > 0 && {activeFilters[column].length}}
{filterData.values.map((option) => { const optLabel = isEn ? (VALUE_MAP_EN[option] || option) : option; return ( ); })}
); })}
); return (
{hero}

{filteredBoards.length}{" "} {isEn ? filteredBoards.length === 1 ? "board found" : "boards found" : filteredBoards.length === 1 ? "placa encontrada" : "placas encontradas"}

{filteredBoards.length === 0 ? (
) : (
{filteredBoards.map((board, index) => ( ))}
)}
); }