Refactor: padroniza schema de conexões e atualiza UI do diagrama + melhorias na página de série
- Padroniza JSON de conexões (vários chips): normaliza "numero", unifica categorias, substitui "restricoes" por "avisos" (array), adiciona "alimentacao" e revisa campos de tipo/funcões/avisos. - Atualiza large conjunto de arquivos em public/conexoes (ESP32, ESP32-S2/S3/C3/C5/C6/H2/P4) para o novo formato e dados mais completos. - Adapta ConnectionsDiagram.jsx ao novo schema: - atualiza FILTER_CATEGORIES e type_colors; - usa cores por tipo (type_colors) para background/bordas/indicadores; - renomeia/exibe avisos, altera labels (ex: "Conexão" → "Pino"), melhora renderização de badges e contadores; - refina modal (overlay, classes, exibição de categorias, seção de alimentação e lista de avisos). - Altera page de série (app/series/[key]/page.jsx): - adiciona bloco "Sobre a Matriz de Conexões Flexível"; - adiciona links rápidos: Datasheet, Guia de Programação e (condicional) Manual Técnico; - ajusta estilos de botões/grades e espaçamento (md:mx-8); - simplifica previous/next (retorna null em vez de placeholders vazios). - Atualiza public/series.json com links de manual/guia, correções de specs (GPIO, temperaturas, descrições) e outras metadatas. Resultados: dados de conexões padronizados, componente de diagrama consistente com o novo schema, melhor UX na página de série e acesso direto a documentação.
This commit is contained in:
1 parent
941dd266a0
commit
e169e29d0d
11 files changed
+5139
-3433
No files matched your search
@@ -3,30 +3,43 @@
|
||||
import { useState, useEffect, useMemo } from "react";
|
||||
|
||||
const FILTER_CATEGORIES = [
|
||||
{ id: "All", name: "Todos", color: "#64748b" },
|
||||
{ id: "Ground", name: "Terra (GND)", color: "#64748b" },
|
||||
{ id: "All", name: "Todos", color: "#374151" },
|
||||
{ id: "GND", name: "Terra (GND)", color: "#64748b" },
|
||||
{ id: "Power", name: "Alimentação", color: "#ef4444" },
|
||||
{ id: "RTC", name: "RTC", color: "#f59e0b" },
|
||||
{ id: "GPIO", name: "GPIO", color: "#22c55e" },
|
||||
{ id: "Low Power", name: "GPIO LP", color: "#f59e0b" },
|
||||
{ id: "ADC", name: "ADC", color: "#ec4899" },
|
||||
{ id: "DAC", name: "DAC", color: "#a855f7" },
|
||||
{ id: "Touch", name: "Touch", color: "#06b6d4" },
|
||||
{ id: "UART", name: "UART", color: "#3b82f6" },
|
||||
{ id: "SPI", name: "SPI", color: "#ef4444" },
|
||||
{ id: "I2C", name: "I2C", color: "#10b981" },
|
||||
{ id: "PWM", name: "PWM", color: "#f97316" },
|
||||
{ id: "USB", name: "USB", color: "#8b5cf6" },
|
||||
{ id: "Clock", name: "Clock", color: "#eab308" },
|
||||
{ id: "JTAG", name: "JTAG", color: "#8b5cf6" },
|
||||
{ id: "Strapping", name: "Inicialização", color: "#dc2626" },
|
||||
{ id: "DSI", name: "Display (DSI)", color: "#f97316" },
|
||||
{ id: "CSI", name: "Câmera (CSI)", color: "#14b8a6" },
|
||||
{ id: "Ethernet", name: "Ethernet", color: "#3b82f6" },
|
||||
{ id: "SD", name: "Cartão SD", color: "#10b981" },
|
||||
{ id: "I2C", name: "I2C", color: "#f59e0b" },
|
||||
{ id: "Antena", name: "Antena", color: "#22d3ee" },
|
||||
];
|
||||
|
||||
const type_colors = {
|
||||
power: "#ef4444",
|
||||
ground: "#64748b",
|
||||
io: "#22c55e",
|
||||
analog: "#ec4899",
|
||||
dedicated: "#3b82f6",
|
||||
nc: "#9ca3af",
|
||||
};
|
||||
|
||||
export default function ConnectionsDiagram({ connections, color }) {
|
||||
const [activeFilter, setActiveFilter] = useState("All");
|
||||
const [selectedConnection, setSelectedConnection] = useState(null);
|
||||
const [hoveredConnection, setHoveredConnection] = useState(null);
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [viewMode, setViewMode] = useState("grid"); // 'grid' or 'list'
|
||||
const [viewMode, setViewMode] = useState("grid");
|
||||
const [showTooltip, setShowTooltip] = useState(null);
|
||||
|
||||
const isConnectionVisible = (connection) => {
|
||||
@@ -326,17 +339,17 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
onBlur={() => setHoveredConnection(null)}
|
||||
aria-label={`Connection ${connection.nome}, number ${connection.numero}`}
|
||||
aria-describedby={showTooltip === index ? `tooltip-${index}` : undefined}
|
||||
className="relative w-full flex flex-col items-center justify-center p-3 rounded-2xl border-2 transition-all duration-300 opacity-100 hover:scale-110 hover:shadow-2xl hover:z-10 cursor-pointer active:scale-95 focus:outline-none focus:ring-4 focus:ring-offset-2"
|
||||
className="relative w-full flex flex-col items-center justify-center p-3 rounded-2xl border-2 transition-all duration-300 opacity-100 hover:scale-110 hover:shadow-2xl hover:z-10 cursor-pointer active:scale-95 focus:outline-none focus:border-4"
|
||||
style={{
|
||||
backgroundColor: connection.cor + "15",
|
||||
borderColor: isHovered ? connection.cor : connection.cor + "60",
|
||||
backgroundColor: type_colors[connection.tipo] + (isHovered ? "20" : "10"),
|
||||
borderColor: isHovered ? type_colors[connection.tipo] : type_colors[connection.tipo] + "60",
|
||||
transform: isHovered ? "translateY(-2px)" : undefined,
|
||||
focusRingColor: connection.cor,
|
||||
focusRingColor: type_colors[connection.tipo],
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="w-14 h-14 rounded-full flex items-center justify-center text-white font-bold text-sm mb-3 shadow-lg ring-2 ring-white"
|
||||
style={{ backgroundColor: connection.cor }}
|
||||
className="w-14 h-14 rounded-full flex items-center justify-center text-white font-bold text-sm mb-3 shadow-lg"
|
||||
style={{ backgroundColor: type_colors[connection.tipo] }}
|
||||
>
|
||||
{typeof connection.numero === "number"
|
||||
? connection.numero
|
||||
@@ -347,23 +360,23 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
{connection.nome}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap gap-1 justify-center">
|
||||
<div className="flex flex-wrap gap-1 justify-center leading-2">
|
||||
{connection.categorias.slice(0, 5).map((cat) => (
|
||||
<span
|
||||
key={cat}
|
||||
className="w-1.5 h-1.5 rounded-full"
|
||||
className="w-1.5 h-1.5 my-auto rounded-full"
|
||||
style={{ backgroundColor: getCategoryColor(cat) }}
|
||||
title={cat}
|
||||
/>
|
||||
))}
|
||||
{connection.categorias.length > 5 && (
|
||||
<span className="text-[10px] text-gray-500 font-medium">
|
||||
<span className="text-[10px] text-gray-500 font-medium leading-2">
|
||||
+{connection.categorias.length - 5}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{connection.restricoes && (
|
||||
{connection.avisos && (
|
||||
<div
|
||||
className="absolute -top-2 -right-2 bg-red-500 rounded-full p-1.5 shadow-lg ring-2 ring-white"
|
||||
aria-label="Has restrictions"
|
||||
@@ -391,7 +404,7 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
style={{ minWidth: "200px" }}
|
||||
>
|
||||
<div className="font-bold mb-1">{connection.nome}</div>
|
||||
<div className="text-gray-300 mb-2">{connection.numero}</div>
|
||||
<div className="text-gray-300 mb-2">Pino {connection.numero}</div>
|
||||
<div className="flex flex-wrap gap-1 mb-2">
|
||||
{connection.categorias.map((cat) => (
|
||||
<span
|
||||
@@ -425,7 +438,7 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
<th className="px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">Nome</th>
|
||||
<th className="px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">Categorias</th>
|
||||
<th className="px-6 py-4 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">Funções</th>
|
||||
<th className="px-6 py-4 text-center text-xs font-bold text-gray-700 uppercase tracking-wider">Status</th>
|
||||
<th className="px-6 py-4 text-center text-xs font-bold text-gray-700 uppercase tracking-wider">Avisos</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-gray-200">
|
||||
@@ -438,7 +451,7 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
<td className="px-6 py-4 whitespace-nowrap">
|
||||
<div
|
||||
className="w-10 h-10 rounded-full flex items-center justify-center text-white font-bold text-sm shadow-md"
|
||||
style={{ backgroundColor: connection.cor }}
|
||||
style={{ backgroundColor: type_colors[connection.tipo] }}
|
||||
>
|
||||
{typeof connection.numero === "number"
|
||||
? connection.numero
|
||||
@@ -469,19 +482,19 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
</div>
|
||||
</td>
|
||||
<td className="px-6 py-4 text-center">
|
||||
{connection.restricoes ? (
|
||||
{connection.avisos ? (
|
||||
<span className="inline-flex items-center gap-1 px-2 py-1 rounded-full bg-red-100 text-red-700 text-xs font-medium">
|
||||
<svg className="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
|
||||
</svg>
|
||||
Atenção
|
||||
Sim
|
||||
</span>
|
||||
) : (
|
||||
<span className="inline-flex items-center gap-1 px-2 py-1 rounded-full bg-green-100 text-green-700 text-xs font-medium">
|
||||
<svg className="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
|
||||
</svg>
|
||||
OK
|
||||
Não
|
||||
</span>
|
||||
)}
|
||||
</td>
|
||||
@@ -493,7 +506,7 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{connections.some(c => c.restricoes) && (
|
||||
{connections.some(c => c.avisos) && (
|
||||
<div className="bg-linear-to-r from-amber-50 to-yellow-50 border-2 border-amber-200 rounded-2xl p-6 shadow-sm">
|
||||
<div className="flex gap-4">
|
||||
<div className="shrink-0">
|
||||
@@ -537,7 +550,7 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
|
||||
{selectedConnection && (
|
||||
<div
|
||||
className="fixed inset-0 bg-black bg-opacity-80 backdrop-blur-sm flex items-center justify-center p-4 z-50 animate-fadeIn"
|
||||
className="fixed inset-0 bg-opacity-80 backdrop-blur-xs flex items-center justify-center p-4 z-50 animate-fadeIn"
|
||||
onClick={() => setSelectedConnection(null)}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
@@ -552,7 +565,7 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
<div className="flex items-center gap-5 flex-1">
|
||||
<div
|
||||
className="w-16 h-16 rounded-2xl flex items-center justify-center text-white font-bold text-xl shadow-xl ring-4 ring-white shrink-0"
|
||||
style={{ backgroundColor: selectedConnection.cor }}
|
||||
style={{ backgroundColor: type_colors[selectedConnection.tipo] }}
|
||||
>
|
||||
{typeof selectedConnection.numero === "number"
|
||||
? selectedConnection.numero
|
||||
@@ -563,7 +576,7 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
{selectedConnection.nome}
|
||||
</h3>
|
||||
<p className="text-base text-gray-600">
|
||||
Conexão {selectedConnection.numero}
|
||||
Pino {selectedConnection.numero}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -589,7 +602,7 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
</div>
|
||||
|
||||
<div className="flex-1 overflow-y-auto p-8 space-y-8">
|
||||
<div>
|
||||
{selectedConnection.categorias.length > 0 && (<div>
|
||||
<h4 className="text-lg font-bold text-gray-900 mb-4 flex items-center gap-2">
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path d="M7 3a1 1 0 000 2h6a1 1 0 100-2H7zM4 7a1 1 0 011-1h10a1 1 0 110 2H5a1 1 0 01-1-1zM2 11a2 2 0 012-2h12a2 2 0 012 2v4a2 2 0 01-2 2H4a2 2 0 01-2-2v-4z" />
|
||||
@@ -601,19 +614,43 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
{selectedConnection.categorias.map((cat) => (
|
||||
<span
|
||||
key={cat}
|
||||
className="px-4 py-2 rounded-xl text-sm font-bold text-white shadow-md ring-2 ring-white"
|
||||
className="px-4 py-2 rounded-xl text-sm font-bold text-white shadow-md"
|
||||
style={{ backgroundColor: getCategoryColor(cat) }}
|
||||
>
|
||||
{cat === "Strapping" ? "Inicialização" : cat}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>)}
|
||||
|
||||
{selectedConnection.alimentacao && (
|
||||
<div>
|
||||
<h4 className="text-lg font-bold text-gray-900 mb-4 flex items-center gap-2">
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z" clipRule="evenodd" />
|
||||
</svg>
|
||||
Alimentado por:
|
||||
</h4>
|
||||
<div className="bg-linear-to-br from-blue-50 to-indigo-50 rounded-2xl p-6 border border-blue-200">
|
||||
<ul className="space-y-3">
|
||||
{selectedConnection.alimentacao.map((source, index) => (
|
||||
<li key={index} className="flex items-start gap-4 text-sm group">
|
||||
<span
|
||||
className="mt-1.5 shrink-0 w-2 h-2 rounded-full"
|
||||
style={{ backgroundColor: type_colors["power"] }}
|
||||
/>
|
||||
<span className="text-gray-800 font-medium leading-relaxed">{source}</span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<h4 className="text-lg font-bold text-gray-900 mb-4 flex items-center gap-2">
|
||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z" clipRule="evenodd" />
|
||||
<path d="M13 7H7v6h6V7zM5 3a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2V5a2 2 0 00-2-2H5z" />
|
||||
</svg>
|
||||
Funções da Conexão
|
||||
</h4>
|
||||
@@ -623,8 +660,8 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
{selectedConnection.funcoes.map((func, index) => (
|
||||
<li key={index} className="flex items-start gap-4 text-sm group">
|
||||
<span
|
||||
className="mt-1 shrink-0 w-2 h-2 rounded-full group-hover:scale-125 transition-transform"
|
||||
style={{ backgroundColor: color }}
|
||||
className="mt-1.5 shrink-0 w-2 h-2 rounded-full"
|
||||
style={{ backgroundColor: type_colors[selectedConnection.tipo] }}
|
||||
/>
|
||||
<span className="text-gray-800 font-medium leading-relaxed">{func}</span>
|
||||
</li>
|
||||
@@ -633,7 +670,7 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{selectedConnection.restricoes && (
|
||||
{selectedConnection.avisos && (
|
||||
<div className="bg-linear-to-br from-red-50 to-rose-50 border-2 border-red-200 rounded-2xl p-6 shadow-sm">
|
||||
<div className="flex gap-4">
|
||||
<div className="shrink-0">
|
||||
@@ -653,11 +690,16 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<p className="text-lg font-bold text-red-900 mb-3">
|
||||
Alertas Importantes
|
||||
</p>
|
||||
<p className="text-sm text-red-800 leading-relaxed">
|
||||
{selectedConnection.restricoes}
|
||||
Avisos Importantes
|
||||
</p>
|
||||
{selectedConnection.avisos.map((aviso, index) => (
|
||||
<div key={index} className="flex items-start gap-3 mb-2">
|
||||
<span className="text-red-600 font-bold">•</span>
|
||||
<span className="text-sm text-red-800 leading-relaxed">
|
||||
{aviso}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -678,20 +720,6 @@ export default function ConnectionsDiagram({ connections, color }) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="bg-white rounded-2xl shadow-lg p-6 border-2 border-gray-100">
|
||||
<h3 className="text-lg font-bold text-gray-800 mb-3 flex items-center gap-2">
|
||||
<svg className="w-5 h-5 text-blue-600" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
|
||||
</svg>
|
||||
Sobre a Matriz de Conexões Flexível
|
||||
</h3>
|
||||
<p className="text-gray-700 leading-relaxed">
|
||||
O ESP32 possui uma matriz de conexões flexível que permite mapear diversas funções para múltiplos pinos.
|
||||
Isso significa que muitas conexões podem ser configuradas para desempenhar diferentes papéis, dependendo das necessidades do seu projeto.
|
||||
Consulte a documentação oficial para entender como aproveitar ao máximo essa flexibilidade.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<style jsx>{`
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
|
||||
Reference in new issue
Block a user