"use client";
import { useState, useMemo, useRef } from "react";
import Header from "@/components/Header";
import Footer from "@/components/Footer";
import Link from "next/link";
import { categoriasGlossario } from "@/lib/glossarioData";
import {
BookOpen,
Search,
Cpu,
Database,
Wifi,
Sliders,
Sparkles,
BatteryCharging,
Code2,
Link2,
Check,
ArrowRight,
Lightbulb,
HelpCircle,
X,
SlidersHorizontal,
Filter,
RotateCcw,
Tag,
ShieldCheck,
} from "lucide-react";
export default function GlossarioPage() {
const [busca, setBusca] = useState("");
const [categoriaSelecionada, setCategoriaSelecionada] = useState("todas");
const [letraFiltro, setLetraFiltro] = useState(null);
const [copiadoSlug, setCopiadoSlug] = useState(null);
const searchInputRef = useRef(null);
// Sugestões populares para busca rápida
const buscasPopulares = [
{ rotulo: "GPIO", emoji: "🔌" },
{ rotulo: "ULP", emoji: "⚡" },
{ rotulo: "PSRAM", emoji: "💾" },
{ rotulo: "Strapping Pins", emoji: "🚀" },
{ rotulo: "Deep Sleep", emoji: "🔋" },
{ rotulo: "OTA", emoji: "📡" },
{ rotulo: "Matter", emoji: "🌐" },
{ rotulo: "Secure Boot", emoji: "🔒" },
{ rotulo: "Wi-Fi 6", emoji: "📶" },
{ rotulo: "MIPI", emoji: "✨" },
];
// Mapeamento de ícones por nome
const iconMap = {
Cpu: ,
Database: ,
Wifi: ,
Sliders: ,
Sparkles: ,
BatteryCharging: ,
Code2: ,
ShieldCheck: ,
};
// Lista de todos os termos com metadados de categoria
const todosOsTermos = useMemo(() => {
return categoriasGlossario.flatMap((cat) =>
cat.termos.map((t) => ({
...t,
categoriaId: cat.id,
categoriaNome: cat.nome,
categoriaCor: cat.cor,
categoriaIcone: cat.icone,
categoriaEmoji: cat.emoji,
slug: t.termo.toLowerCase().replace(/[\s()/²]+/g, "-"),
primeiraLetra: t.termo.charAt(0).toUpperCase(),
}))
);
}, []);
// Todas as letras do alfabeto de A a Z com indicador de existência de termos
const alfabeto = useMemo(() => {
const letras = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");
const setDisponivel = new Set(
todosOsTermos.map((t) => t.termo.charAt(0).toUpperCase())
);
return letras.map((letra) => ({
letra,
temTermos: setDisponivel.has(letra),
}));
}, [todosOsTermos]);
// Filtragem dinâmica
const termosFiltrados = useMemo(() => {
const termoBusca = busca.toLowerCase().trim();
return todosOsTermos.filter((item) => {
const matchCategoria =
categoriaSelecionada === "todas" ||
item.categoriaId === categoriaSelecionada;
const matchLetra = !letraFiltro || item.primeiraLetra === letraFiltro;
const matchBusca =
!termoBusca ||
item.termo.toLowerCase().includes(termoBusca) ||
item.definicao.toLowerCase().includes(termoBusca) ||
item.exemplo.toLowerCase().includes(termoBusca) ||
item.categoriaNome.toLowerCase().includes(termoBusca);
return matchCategoria && matchLetra && matchBusca;
});
}, [todosOsTermos, categoriaSelecionada, letraFiltro, busca]);
const temFiltroAtivo =
busca.trim() !== "" ||
categoriaSelecionada !== "todas" ||
letraFiltro !== null;
const limparTodosFiltros = () => {
setBusca("");
setCategoriaSelecionada("todas");
setLetraFiltro(null);
searchInputRef.current?.focus();
};
const copiarLinkTermo = (slug) => {
const url = `${window.location.origin}/glossario#${slug}`;
navigator.clipboard.writeText(url);
setCopiadoSlug(slug);
setTimeout(() => setCopiadoSlug(null), 2000);
};
const catAtivaInfo = categoriasGlossario.find(
(c) => c.id === categoriaSelecionada
);
return (
{/* Hero Section */}
Enciclopédia & Conceitos do ESP32
Glossário Técnico
Consulte definições diretas, parâmetros de hardware e exemplos práticos dos termos fundamentais do ecossistema ESP32.
{/* 1. PAINEL INTEGRADO DE BUSCA & FILTRAGEM (REDESIGN COMPLETO) */}
{/* Barra de Pesquisa Principal */}
setBusca(e.target.value)}
placeholder="Pesquisar por termo, sigla ou conceito (ex: GPIO, ULP, PSRAM, OTA, Deep Sleep)..."
className="w-full bg-slate-50 dark:bg-slate-950/70 pl-13 sm:pl-14 pr-24 sm:pr-28 py-3.5 sm:py-4 rounded-2xl border border-slate-250 dark:border-slate-800 text-sm sm:text-base font-medium placeholder:text-slate-400 dark:placeholder:text-slate-500 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent transition-all shadow-inner"
/>
{/* Lado Direito da Barra de Pesquisa: Botão Limpar ou Tag de Contagem */}
{busca ? (
{
setBusca("");
searchInputRef.current?.focus();
}}
className="text-xs px-2.5 py-1 rounded-xl bg-slate-200 dark:bg-slate-800 text-slate-600 dark:text-slate-300 hover:bg-slate-300 dark:hover:bg-slate-700 font-semibold flex items-center gap-1 transition-colors cursor-pointer"
>
Limpar
) : (
{termosFiltrados.length} {termosFiltrados.length === 1 ? "termo" : "termos"}
)}
{/* Atalhos de Pesquisa Rápida (Tags Populares) */}
Populares:
{buscasPopulares.map((item) => (
setBusca(item.rotulo)}
className={`px-2.5 py-1 rounded-lg font-medium transition-all shrink-0 cursor-pointer border ${
busca.toLowerCase() === item.rotulo.toLowerCase()
? "bg-purple-600 text-white border-purple-600 shadow-xs"
: "bg-slate-100/80 dark:bg-slate-800/60 text-slate-600 dark:text-slate-300 border-slate-200 dark:border-slate-750 hover:bg-purple-50 dark:hover:bg-purple-950/40 hover:border-purple-300 dark:hover:border-purple-800"
}`}
>
{item.emoji}
{item.rotulo}
))}
{/* Seletor de Categorias em Grid/Flex Moderno */}
Filtrar por Categoria
{categoriaSelecionada !== "todas" && (
setCategoriaSelecionada("todas")}
className="text-purple-600 dark:text-purple-400 hover:underline cursor-pointer lowercase first-letter:uppercase text-[11px]"
>
Ver todas ({todosOsTermos.length})
)}
{/* Botão Todas */}
setCategoriaSelecionada("todas")}
className={`p-2.5 rounded-xl text-xs font-bold transition-all text-left flex flex-col justify-between gap-1 cursor-pointer border ${
categoriaSelecionada === "todas"
? "bg-purple-600 text-white border-purple-600 shadow-sm ring-2 ring-purple-500/20"
: "bg-slate-50 dark:bg-slate-950/60 text-slate-700 dark:text-slate-300 border-slate-200 dark:border-slate-800 hover:border-purple-300 dark:hover:border-purple-700"
}`}
>
✨
Todas
{todosOsTermos.length}
{/* Categorias Individuais */}
{categoriasGlossario.map((cat) => {
const ativa = categoriaSelecionada === cat.id;
return (
setCategoriaSelecionada(cat.id)}
className={`p-2.5 rounded-xl text-xs font-bold transition-all text-left flex flex-col justify-between gap-1 cursor-pointer border ${
ativa
? "bg-purple-600 text-white border-purple-600 shadow-sm ring-2 ring-purple-500/20"
: "bg-slate-50 dark:bg-slate-950/60 text-slate-700 dark:text-slate-300 border-slate-200 dark:border-slate-800 hover:border-purple-300 dark:hover:border-purple-700"
}`}
>
{cat.emoji}
{cat.nome.split(" ")[0]}
{cat.termos.length}
);
})}
{/* Scrubber de Índice Alfabético (A-Z) */}
Índice A-Z:
setLetraFiltro(null)}
className={`px-2.5 py-1 rounded-lg text-[11px] font-bold cursor-pointer transition-all shrink-0 ${
letraFiltro === null
? "bg-purple-600 text-white shadow-xs"
: "text-slate-600 dark:text-slate-400 hover:bg-slate-100 dark:hover:bg-slate-800"
}`}
>
Todos
{alfabeto.map(({ letra, temTermos }) => {
const ativo = letraFiltro === letra;
if (!temTermos) {
return (
{letra}
);
}
return (
setLetraFiltro(ativo ? null : letra)}
className={`w-6 h-6 rounded-md flex items-center justify-center text-[11px] font-bold cursor-pointer transition-all shrink-0 ${
ativo
? "bg-purple-600 text-white scale-110 shadow-xs"
: "text-slate-700 dark:text-slate-300 hover:bg-purple-100 dark:hover:bg-purple-950/60"
}`}
>
{letra}
);
})}
{/* Fita de Filtros Ativos (Aparece quando algum filtro está ativo) */}
{temFiltroAtivo && (
Filtros ativos:
{busca && (
Busca: "{busca}"
setBusca("")}
className="hover:text-purple-900 dark:hover:text-purple-100"
>
)}
{categoriaSelecionada !== "todas" && (
Categoria: {catAtivaInfo?.nome}
setCategoriaSelecionada("todas")}
className="hover:text-purple-900 dark:hover:text-purple-100"
>
)}
{letraFiltro && (
Letra: {letraFiltro}
setLetraFiltro(null)}
className="hover:text-purple-900 dark:hover:text-purple-100"
>
)}
Redefinir filtros
)}
{/* 2. GRID DE CARDS DO GLOSSÁRIO */}
{termosFiltrados.length === 0 ? (
Nenhum termo encontrado
Não encontramos resultados para sua pesquisa com os filtros selecionados.
Limpar todos os filtros
) : (
{termosFiltrados.map((item) => {
return (
{/* Header do Card */}
{item.categoriaEmoji}
{item.categoriaNome}
copiarLinkTermo(item.slug)}
title="Copiar link direto para este termo"
className="text-xs text-slate-400 hover:text-purple-600 dark:hover:text-purple-400 inline-flex items-center gap-1 p-1 rounded hover:bg-slate-100 dark:hover:bg-slate-800 transition-colors cursor-pointer"
>
{copiadoSlug === item.slug ? (
<>
Copiado!
>
) : (
)}
{/* Título do Termo */}
{item.termo}
{/* Definição */}
{/* Caixa de Exemplo Prático */}
);
})}
)}
{/* 3. CTA & PRÓXIMOS PASSOS */}
Continue Explorando
Pronto para aplicar na prática?
Agora que você domina os conceitos técnicos, compare as especificações das séries ou use o seletor inteligente para encontrar o microcontrolador ideal para seu projeto.
Explorar Séries ESP32
Seletor Inteligente
Guia de Diagnóstico & Erros
);
}
/**
* Função utilitária que detecta nomes de séries do ESP32 dentro do texto e os converte em links clicáveis.
*/
function TextoComLinks({ texto }) {
if (!texto) return null;
const seriesKeys = [
"ESP32-S31",
"ESP32-C61",
"ESP32-S2",
"ESP32-S3",
"ESP32-C2",
"ESP32-C3",
"ESP32-C5",
"ESP32-C6",
"ESP32-P4",
"ESP32-H2",
"ESP32-H4",
"ESP32",
];
const regex = new RegExp(`\\b(${seriesKeys.join("|")})\\b`, "g");
const partes = texto.split(regex);
return (
<>
{partes.map((parte, i) => {
if (seriesKeys.includes(parte)) {
return (
{parte}
);
}
return parte;
})}
>
);
}