{isEn ? "Querying boards database…" : "Consultando o banco de placas…"}
"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 = (
{isEn ? "Querying boards database…" : "Consultando o banco de placas…"}
{isEn ? "Could not load boards" : "Não foi possível carregar as placas"}
{error}. {isEn ? "Check your connection and try again." : "Verifique a conexão e tente de novo."}
{filteredBoards.length}{" "} {isEn ? filteredBoards.length === 1 ? "board found" : "boards found" : filteredBoards.length === 1 ? "placa encontrada" : "placas encontradas"}
{filteredBoards.length === 0 ? ({isEn ? "Remove some filters or search by another name." : "Remova alguns filtros ou busque por outro nome."}