"use client"; import { useState, useEffect, useMemo } from "react"; import { createPortal } from "react-dom"; import { Search, X, Grid, List, Filter, AlertTriangle, Info, Tag, Zap, Sliders, CheckCircle, ExternalLink } from "lucide-react"; const FILTER_CATEGORIES = [ { id: "All", name: "Todos", color: "#8b5cf6" }, // purple { id: "GND", name: "Terra (GND)", color: "#64748b" }, // slate { id: "Power", name: "Alimentação", color: "#ef4444" }, // red { id: "GPIO", name: "GPIO", color: "#22c55e" }, // green { id: "Low Power", name: "GPIO LP", color: "#f59e0b" }, // amber { id: "ADC", name: "ADC", color: "#ec4899" }, // pink { id: "DAC", name: "DAC", color: "#a855f7" }, // purple { id: "Touch", name: "Touch", color: "#06b6d4" }, // cyan { id: "UART", name: "UART", color: "#3b82f6" }, // blue { id: "SPI", name: "SPI", color: "#f43f5e" }, // rose { id: "USB", name: "USB", color: "#a855f7" }, // purple { id: "Clock", name: "Clock", color: "#eab308" }, // yellow { id: "JTAG", name: "JTAG", color: "#6366f1" }, // indigo { id: "Strapping", name: "Inicialização", color: "#dc2626" }, // red { id: "DSI", name: "Display (DSI)", color: "#f97316" }, // orange { id: "CSI", name: "Câmera (CSI)", color: "#14b8a6" }, // teal { id: "Ethernet", name: "Ethernet", color: "#0284c7" }, // sky { id: "SD", name: "Cartão SD", color: "#10b981" }, // emerald { id: "I2C", name: "I2C", color: "#f59e0b" }, // amber { id: "Antena", name: "Antena", color: "#06b6d4" }, // cyan ]; const type_colors = { power: "#ef4444", // high-voltage red ground: "#64748b", // slate gray io: "#22c55e", // laser green analog: "#ec4899", // dynamic pink dedicated: "#3b82f6", // electric blue nc: "#94a3b8", // muted gray }; export default function ConnectionsDiagram({ connections, serie }) { const [activeFilter, setActiveFilter] = useState("All"); const [selectedConnection, setSelectedConnection] = useState(null); const [hoveredConnection, setHoveredConnection] = useState(null); const [searchQuery, setSearchQuery] = useState(""); const [viewMode, setViewMode] = useState("grid"); const [showTooltip, setShowTooltip] = useState(null); const [mounted, setMounted] = useState(false); useEffect(() => { setMounted(true); }, []); const isConnectionVisible = (connection) => { const matchesFilter = activeFilter === "All" || connection.categorias.includes(activeFilter); const matchesSearch = searchQuery === "" || connection.nome.toLowerCase().includes(searchQuery.toLowerCase()) || connection.numero.toString().toLowerCase().includes(searchQuery.toLowerCase()); return matchesFilter && matchesSearch; }; const getCategoryColor = (category) => { const filter = FILTER_CATEGORIES.find((f) => f.id === category); return filter?.color || "#64748b"; }; const visibleConnections = useMemo(() => { return connections.filter(isConnectionVisible); }, [connections, activeFilter, searchQuery]); const activeCategories = useMemo(() => { if (activeFilter === "All") return []; return FILTER_CATEGORIES.filter(cat => visibleConnections.some(conn => conn.categorias.includes(cat.id)) ); }, [visibleConnections, activeFilter]); useEffect(() => { const handleEscape = (e) => { if (e.key === "Escape") { setSelectedConnection(null); setShowTooltip(null); } }; if (selectedConnection) { document.addEventListener("keydown", handleEscape); document.body.style.overflow = "hidden"; } return () => { document.removeEventListener("keydown", handleEscape); document.body.style.overflow = "unset"; }; }, [selectedConnection]); useEffect(() => { const handleKeyDown = (e) => { if (selectedConnection) return; if (e.key === "Tab") { const buttons = document.querySelectorAll('[data-connection-button]'); const currentIndex = Array.from(buttons).findIndex(btn => btn === document.activeElement); if (e.shiftKey && currentIndex > 0) { e.preventDefault(); buttons[currentIndex - 1].focus(); } else if (!e.shiftKey && currentIndex < buttons.length - 1) { e.preventDefault(); buttons[currentIndex + 1].focus(); } } }; document.addEventListener("keydown", handleKeyDown); return () => document.removeEventListener("keydown", handleKeyDown); }, [selectedConnection]); if (!connections || connections.length === 0) { return (

Diagrama de conexões indisponível

Este modelo ainda não possui um mapa detalhado de conexões e barramentos.

); } return (
{/* Header info */}

Diagrama de Conexões Interativo

Explore todas as conexões e multiplexação do SoC do {serie.nome_completo}. Utilize o painel de busca rápida ou filtre por categoria para acender conexões específicas e ver mapas de barramentos.

{/* Search Panel */}
setSearchQuery(e.target.value)} className="w-full pl-12 pr-10 py-3 rounded-xl border border-slate-300 dark:border-slate-800 bg-white dark:bg-slate-950/40 focus:border-purple-500/80 focus:ring-4 focus:ring-purple-500/10 text-slate-800 dark:text-slate-200 transition-all outline-none text-sm font-semibold" aria-label="Search connections" /> {searchQuery && ( )}
{/* View Mode Toggle */}
{/* Filters Panel */}

Filtre por Função do Pino

{visibleConnections.length} de {connections.length} ativos
{FILTER_CATEGORIES.map((filter) => { const isActive = activeFilter === filter.id; const count = connections.filter(c => filter.id === "All" ? true : c.categorias.includes(filter.id) ).length; if (count === 0 && !isActive) return null; // Hide filters that don't apply to this chip return ( ); })}
{/* Active Categories badges */} {activeFilter !== "All" && activeCategories.length > 0 && (

Subcategorias ativadas por esse filtro:

{activeCategories.map(cat => ( {cat.name} ))}
)}
{/* Diagram Workspace */} {visibleConnections.length === 0 ? (

Nenhuma conexão encontrada

Tente ajustar seus termos de pesquisa ou limpe os filtros rápidos.

) : viewMode === "grid" ? ( /* Grid View Mode: Futuristic Electronic Chip Sockets */
{visibleConnections.map((connection, index) => { const isHovered = hoveredConnection === index; const connectionId = `connection-${index}`; const baseColor = type_colors[connection.tipo] || "#94a3b8"; return (
{/* Sleek Tooltip Popover */} {showTooltip === index && ( )}
); })}
) : ( /* List View Mode: Interactive Zebra Table */
{visibleConnections.map((connection, index) => { const baseColor = type_colors[connection.tipo] || "#94a3b8"; return ( setSelectedConnection(connection)} className="hover:bg-purple-500/5 dark:hover:bg-purple-400/5 cursor-pointer transition-colors group" > ); })}
Pino Nome do Pad Categorias Multiplexação de Funções Restrições
{typeof connection.numero === "number" ? connection.numero : connection.numero.substring(0, 4)}
{connection.nome}
{connection.categorias.map((cat) => ( {cat === "Strapping" ? "Inicialização" : cat} ))}
{connection.funcoes.join(", ")}
{connection.avisos ? ( Restrito ) : ( Livre )}
)} {/* Global Warning notice */} {connections.some(c => c.avisos) && (

Notas Importantes sobre a Pinagem

  • • Pinos contendo tags de Avisos/Restrições (cor vermelha) possuem papéis especiais de Strapping na inicialização, ou limitações analógicas. Clique neles para ver detalhes.
  • • Sempre garanta isolamento de circuitos capacitivos de toque em pinos com ruído de RF acoplado.
)} {/* Interactive Overlay Dialog Details Sheet */} {selectedConnection && mounted && createPortal(
setSelectedConnection(null)} role="dialog" aria-modal="true" aria-labelledby="modal-title" >
e.stopPropagation()} > {/* Dialog Header */}
{typeof selectedConnection.numero === "number" ? selectedConnection.numero : selectedConnection.numero.substring(0, 4)}

Pino Físico {selectedConnection.numero}

{/* Dialog Body Contents */}
{/* Categories */} {selectedConnection.categorias.length > 0 && (

Categorias de Multiplexação

{selectedConnection.categorias.map((cat) => ( {cat === "Strapping" ? "Inicialização" : cat} ))}
)} {/* Power Source */} {selectedConnection.alimentacao && (

Domínio de Alimentação Interna

    {selectedConnection.alimentacao.map((source, index) => (
  • {source}
  • ))}
)} {/* Function Multiplexation */}

Barramentos de Funções Disponíveis

    {selectedConnection.funcoes.map((func, index) => (
  • {func}
  • ))}
{/* Alerts/Warnings */} {selectedConnection.avisos && (

Avisos Importantes de Engenharia

{selectedConnection.avisos.map((aviso, index) => (
• {aviso}
))}
)}
{/* Dialog Footer */}
, document.body )}
); }