"use client"; import { useState, useMemo } from "react"; import { usePathname } from "next/navigation"; import Header from "@/components/Header"; import Footer from "@/components/Footer"; import PageHero from "@/components/PageHero"; import SectionHead from "@/components/SectionHead"; import * as componentesPt from "@/lib/componentRegistryData"; import * as componentesEn from "@/lib/data/en/componentes"; import * as componentesEs from "@/lib/data/es/componentes"; import * as componentesFr from "@/lib/data/fr/componentes"; import * as componentesDe from "@/lib/data/de/componentes"; import * as componentesZh from "@/lib/data/zh-CN/componentes"; import { ArrowUpRight, Box, Brain, Check, CircuitBoard, Cloud, Copy, Cpu, Download, HelpCircle, Home, Layers, Monitor, Plus, Search, ShieldCheck, Terminal, Trash2, Wrench, X, } from "lucide-react"; const ICONES_CATEGORIA = { ui_display: Monitor, cloud_conectividade: Cloud, audio_voz_ia: Brain, smart_home_mesh: Home, drivers_perifericos: Cpu, bsp_placas: CircuitBoard, sistema_utilitarios: Wrench, }; export default function ComponentRegistryPage() { const pathname = usePathname(); const isEn = pathname?.startsWith("/en"); const isEs = pathname?.startsWith("/es"); const isFr = pathname?.startsWith("/fr"); const isDe = pathname?.startsWith("/de"); const isZh = pathname?.startsWith("/zh-CN"); const { CATEGORIAS_COMPONENTES, COMPONENTES_REGISTRY, GUIA_COMPONENT_MANAGER } = isEs ? componentesEs : isEn ? componentesEn : isFr ? componentesFr : isZh ? componentesZh : isDe ? componentesDe : componentesPt; const [busca, setBusca] = useState(""); const [categoriaAtiva, setCategoriaAtiva] = useState("todos"); const [chipFiltro, setChipFiltro] = useState("todos"); const [copiadoId, setCopiadoId] = useState(null); const [manifestoCopiado, setManifestoCopiado] = useState(false); // Componentes selecionados no construtor de idf_component.yml const [componentesSelecionados, setComponentesSelecionados] = useState([ "espressif-esp_lvgl_port", "espressif-led_indicator" ]); // Lista de chips únicos para filtro const chipsDisponiveis = ["todos", "ESP32", "ESP32-S3", "ESP32-C6", "ESP32-P4", "ESP32-H2", "ESP32-C3"]; // Filtragem dos componentes const componentesFiltrados = useMemo(() => { return COMPONENTES_REGISTRY.filter((comp) => { const matchCategoria = categoriaAtiva === "todos" || comp.categoria === categoriaAtiva; const matchChip = chipFiltro === "todos" || (comp.chips && comp.chips.includes(chipFiltro)); const matchBusca = busca.trim() === "" || comp.name.toLowerCase().includes(busca.toLowerCase()) || comp.namespace.toLowerCase().includes(busca.toLowerCase()) || comp.titulo.toLowerCase().includes(busca.toLowerCase()) || comp.descricao.toLowerCase().includes(busca.toLowerCase()) || comp.tags.some((t) => t.toLowerCase().includes(busca.toLowerCase())); return matchCategoria && matchChip && matchBusca; }); }, [busca, categoriaAtiva, chipFiltro, COMPONENTES_REGISTRY]); // Manipuladores de cópia const copiarComando = (id, comando) => { navigator.clipboard.writeText(comando); setCopiadoId(id); setTimeout(() => setCopiadoId(null), 2000); }; const toggleSelecaoManifesto = (id) => { setComponentesSelecionados((prev) => prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id] ); }; // Geração dinâmica do manifesto YAML const manifestoYaml = useMemo(() => { const selecionados = COMPONENTES_REGISTRY.filter((c) => componentesSelecionados.includes(c.id) ); if (selecionados.length === 0) { return isEs ? `# No hay componentes seleccionados.\n# Haga clic en "+ Agregar al manifiesto" en las tarjetas de abajo.` : isEn ? `# No components selected.\n# Click "+ Add to Manifest" on the cards below.` : isFr ? `# Aucun composant sélectionné.\n# Cliquez sur "+ Ajouter au manifeste" sur les cartes ci-dessous.` : isZh ? `# 尚未选择组件。\n# 点击下方卡片中的“+ 添加到清单”。` : isDe ? `# Keine Komponenten ausgewählt.\n# Klicken Sie auf den Karten unten auf "+ Zum Manifest hinzufügen".` : `# Nenhum componente selecionado.\n# Clique em "+ Adicionar ao Manifesto" nos cards abaixo.`; } let yaml = isEs ? `# main/idf_component.yml\n# Generado mediante ESPDocs Component Hub (https://espdocs.cienciaembarcada.com.br/es/componentes)\n\ndependencies:\n` : isEn ? `# main/idf_component.yml\n# Generated via ESPDocs Component Hub (https://espdocs.cienciaembarcada.com.br/en/components)\n\ndependencies:\n` : isFr ? `# main/idf_component.yml\n# Généré via ESPDocs Component Hub (https://espdocs.cienciaembarcada.com.br/fr/composants)\n\ndependencies:\n` : isZh ? `# main/idf_component.yml\n# 由 ESPDocs Component Hub 生成(https://espdocs.cienciaembarcada.com.br/zh-CN/components)\n\ndependencies:\n` : isDe ? `# main/idf_component.yml\n# Erstellt über den ESPDocs Component Hub (https://espdocs.cienciaembarcada.com.br/de/komponenten)\n\ndependencies:\n` : `# main/idf_component.yml\n# Gerado via ESPDocs Component Hub (https://espdocs.cienciaembarcada.com.br/componentes)\n\ndependencies:\n`; selecionados.forEach((c) => { yaml += ` ${c.namespace}/${c.name}: "${c.versao}"\n`; }); return yaml; }, [componentesSelecionados, COMPONENTES_REGISTRY, isEn, isEs, isFr, isDe, isZh]); const copiarManifesto = () => { navigator.clipboard.writeText(manifestoYaml); setManifestoCopiado(true); setTimeout(() => setManifestoCopiado(false), 2000); }; const baixarManifesto = () => { const blob = new Blob([manifestoYaml], { type: "text/yaml;charset=utf-8" }); const url = URL.createObjectURL(blob); const link = document.createElement("a"); link.href = url; link.download = "idf_component.yml"; document.body.appendChild(link); link.click(); document.body.removeChild(link); URL.revokeObjectURL(url); }; const limparFiltros = () => { setBusca(""); setCategoriaAtiva("todos"); setChipFiltro("todos"); }; const totalFiltros = (busca.trim() ? 1 : 0) + (categoriaAtiva !== "todos" ? 1 : 0) + (chipFiltro !== "todos" ? 1 : 0); return (
{isEs ? "Abrir el registro oficial" : isEn ? "Open official registry" : isFr ? "Ouvrir le registre officiel" : isZh ? "打开官方注册中心" : isDe ? "Offizielles Repository öffnen" : "Abrir o registro oficial"} {isEs ? "Generar idf_component.yml" : isEn ? "Generate idf_component.yml" : isFr ? "Générer idf_component.yml" : isZh ? "生成 idf_component.yml" : isDe ? "idf_component.yml erstellen" : "Gerar idf_component.yml"}

{isEs ? "Categoría" : isEn ? "Category" : isFr ? "Catégorie" : isZh ? "类别" : isDe ? "Kategorie" : "Categoria"}

{CATEGORIAS_COMPONENTES.map((cat) => { const Icone = ICONES_CATEGORIA[cat.id] ?? Layers; const contagem = cat.id === "todos" ? COMPONENTES_REGISTRY.length : COMPONENTES_REGISTRY.filter((c) => c.categoria === cat.id).length; return ( ); })}

{isEs ? "Chip compatible" : isEn ? "Compatible chip" : isFr ? "Puce compatible" : isZh ? "兼容芯片" : isDe ? "Kompatibler Chip" : "Chip compatível"}

{chipsDisponiveis.map((chip) => ( ))}

{componentesFiltrados.length} {componentesFiltrados.length === 1 ? (isEs ? "componente" : isEn ? "component" : isFr ? "composant" : isZh ? "个组件" : isDe ? "Komponente" : "componente") : (isEs ? "componentes" : isEn ? "components" : isFr ? "composants" : isZh ? "个组件" : isDe ? "Komponenten" : "componentes")}

{componentesFiltrados.length === 0 ? (
) : (
{componentesFiltrados.map((comp) => { const selecionado = componentesSelecionados.includes(comp.id); const cliCmd = `idf.py add-dependency "${comp.namespace}/${comp.name}${comp.versao}"`; const foiCopiado = copiadoId === comp.id; return (

{comp.namespace}/ {comp.oficial && ( )}

{comp.name}

{comp.titulo}

{comp.versao}

{comp.descricao}

    {comp.tags.map((tag) => (
  • {tag}
  • ))}

{foiCopiado ? (isEs ? "Comando copiado" : isEn ? "Command copied" : isFr ? "Commande copiée" : isZh ? "命令已复制" : isDe ? "Befehl kopiert" : "Comando copiado") : ""}

Chips: {comp.chips.join(", ")}

); })}
)}

{isEs ? "Generador de manifiesto" : isEn ? "Manifest generator" : isFr ? "Générateur de manifeste" : isZh ? "清单生成器" : isDe ? "Manifest-Generator" : "Gerador de manifesto"}

{isEs ? "Su idf_component.yml" : isEn ? "Your idf_component.yml" : isFr ? "Votre idf_component.yml" : isZh ? "你的 idf_component.yml" : isDe ? "Ihre idf_component.yml" : "Seu idf_component.yml"}

{isEs ? ( <>Guarde el archivo en la carpeta main/ del proyecto y ESP-IDF descargará todas las bibliotecas durante la compilación. ) : isEn ? ( <>Save this file in your project's main/ folder and ESP-IDF will download all dependencies during build. ) : isFr ? ( <>Enregistrez le fichier dans le dossier main/ du projet et ESP-IDF téléchargera toutes les bibliothèques lors de la compilation. ) : isZh ? ( <>将文件保存到项目的 main/ 文件夹中,ESP-IDF 会在编译时下载所有库。 ) : isDe ? ( <>Speichern Sie die Datei im Ordner main/ Ihres Projekts, und ESP-IDF lädt beim Build alle Abhängigkeiten herunter. ) : ( <>Salve o arquivo na pasta main/ do projeto e o ESP-IDF baixa todas as bibliotecas na compilação. )}

{componentesSelecionados.length > 0 && ( )}
{manifestoYaml}
{componentesSelecionados.length > 0 && (
    {componentesSelecionados.map((id) => { const c = COMPONENTES_REGISTRY.find((item) => item.id === id); if (!c) return null; return (
  • {c.name}
  • ); })}
)}
    {GUIA_COMPONENT_MANAGER.vantagens.map((v) => (
  • {v.titulo}

    {v.descricao}

  • ))}

    {GUIA_COMPONENT_MANAGER.comandosCli.map((cmd, i) => (
  • $ {cmd.exemplo}

    {cmd.explicacao}

  • ))}

    {isEs ? ( <>
  • ^1.2.0: acepta actualizaciones menores y correcciones (1.2.1, 1.3.0), pero bloquea cambios importantes de API (2.0.0). Recomendado.
  • ~1.2.0: acepta solo correcciones de errores (1.2.1, 1.2.5).
  • 1.2.0: bloquea en esta versión exacta.
  • *: acepta cualquier versión. Evite en producción.
  • ) : isEn ? ( <>
  • ^1.2.0: accepts minor updates and bug fixes (1.2.1, 1.3.0), but blocks breaking API changes (2.0.0). Recommended.
  • ~1.2.0: accepts patch releases only (1.2.1, 1.2.5).
  • 1.2.0: locks to this exact version.
  • *: accepts any version. Avoid in production.
  • ) : isFr ? ( <>
  • ^1.2.0: accepte les mises à jour mineures et les correctifs (1.2.1, 1.3.0), mais bloque les changements majeurs d'API (2.0.0). Recommandé.
  • ~1.2.0: accepte uniquement les correctifs de bugs (1.2.1, 1.2.5).
  • 1.2.0: verrouille sur cette version exacte.
  • *: accepte n'importe quelle version. À éviter en production.
  • ) : isZh ? ( <>
  • ^1.2.0:接受次版本更新和修复(1.2.1、1.3.0),但会阻止重大 API 变更(2.0.0)。推荐。
  • ~1.2.0:只接受缺陷修复(1.2.1、1.2.5)。
  • 1.2.0:锁定到精确版本。
  • *:接受任意版本。生产环境请避免。
  • ) : isDe ? ( <>
  • ^1.2.0: akzeptiert Minor-Updates und Bugfixes (1.2.1, 1.3.0), blockiert aber Breaking Changes (2.0.0). Empfohlen.
  • ~1.2.0: akzeptiert nur Patch-Releases (1.2.1, 1.2.5).
  • 1.2.0: bindet fest an diese Version.
  • *: akzeptiert jede Version. In Produktion vermeiden.
  • ) : ( <>
  • ^1.2.0: aceita atualizações menores e correções (1.2.1, 1.3.0), mas bloqueia mudanças grandes de API (2.0.0). Recomendado.
  • ~1.2.0: aceita só correções de bugs (1.2.1, 1.2.5).
  • 1.2.0: trava na versão exata.
  • *: aceita qualquer versão. Evite em produção.
  • )}
); }