feat: Enhance Header component to improve active link detection

- Updated the `isActive` function in `Header.jsx` to handle root path and include logic for other paths.

chore: Update package-lock.json to remove peer dependencies

- Removed unnecessary peer dependencies from various packages in `package-lock.json`.

feat: Update frameworks.json to include example links

- Changed `exemplo_codigo` to `exemplo` and added `exemplos` links for various frameworks in `frameworks.json`.

feat: Add placa images to series.json

- Included image paths for different ESP32 series in `series.json`.

feat: Create CodeExample component for displaying code snippets

- Added a new `CodeExample.jsx` component to fetch and display code examples dynamically.

feat: Add example Arduino code for Wi-Fi connection

- Created `arduino.ino` example for connecting to Wi-Fi.

feat: Add example code for audio playback using ESP-ADF

- Created `esp-adf.c` example for audio playback using ESP-ADF.

feat: Add example code for DSP operations

- Created `esp-dsp.c` example demonstrating basic DSP operations.

feat: Add example code for ESP-IDF LED blinking

- Created `esp-idf.c` example for blinking an LED using ESP-IDF.

feat: Add example code for Matter integration

- Created `esp-matter.c` example for Matter device initialization and event handling.

feat: Add example code for neural network operations

- Created `esp-nn.c` example demonstrating basic neural network operations.

feat: Add example code for face detection using ESP-WHO

- Created `esp-who.c` example for face detection using ESP-WHO library.

feat: Add MicroPython example for LED blinking

- Created `micropython.py` example for blinking an LED using MicroPython.
This commit is contained in:
Lucas Rayan committed 2025-10-22 23:10:30 -03:00
1 parent 3a5608d1de
commit 2a6699bbfb
18 files changed
+641 -112

No files matched your search

+141
View File
@@ -0,0 +1,141 @@
'use client'
import { useEffect, useState } from 'react'
export default function CodeExample({ framework }) {
const examplesUrl = framework?.exemplos;
const color = framework?.cor || '#6B7280';
const [sample, setSample] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [copied, setCopied] = useState(false);
useEffect(() => {
setSample('');
setError(null);
setLoading(false);
if (!framework) return;
const exemploPath = framework.exemplo;
if (!exemploPath) {
const msg = `// Exemplos completos: ${examplesUrl || 'Ver repositório'}\n// Abra o link acima para ver exemplos e código completo.\n`;
setSample(msg);
return;
}
const url = exemploPath.startsWith('/') ? exemploPath : `/${exemploPath}`;
let cancelled = false;
setLoading(true);
fetch(url)
.then((res) => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.text();
})
.then((text) => {
if (cancelled) return;
if (text && text.trim().length > 0) {
setSample(text);
} else {
setSample(`// Arquivo de exemplo está vazio. Consulte: ${examplesUrl || 'repositório'}\n`);
setError('Arquivo vazio');
}
})
.catch((err) => {
if (cancelled) return;
setSample(`// Não foi possível carregar o exemplo local. Consulte: ${examplesUrl || 'repositório'}\n`);
setError(err.message || 'Falha ao carregar exemplo');
})
.finally(() => {
if (!cancelled) setLoading(false);
});
return () => {
cancelled = true;
};
}, [framework?.exemplo, framework?.exemplos]);
const lines = (sample || '').split('\n');
async function handleCopy() {
try {
await navigator.clipboard.writeText(sample);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
} catch {}
}
return (
<div className="bg-white rounded-2xl shadow-lg p-6 border-2 border-gray-100 mb-8">
<div className="md:flex items-start justify-between gap-4 mb-4">
<div>
<h3 className="text-lg font-semibold text-gray-800 mb-1">Exemplo de Código</h3>
<p className="text-sm text-gray-600">Trecho rápido para começar — personalize conforme necessário.</p>
</div>
<div className="grid grid-cols-2 md:flex items-center gap-2">
<span
className="inline-flex items-center text-sm font-semibold px-3 py-1 rounded-full text-white"
style={{ backgroundColor: color }}
>
{framework?.linguagem || 'Código'}
</span>
<button
onClick={handleCopy}
className="inline-flex items-center gap-2 bg-white text-gray-800 px-3 py-2 rounded-lg font-medium shadow border-2 border-gray-100 hover:shadow-lg transition"
title="Copiar código"
>
{copied ? '✅ Copiado' : '📋 Copiar'}
</button>
{examplesUrl && (
<a
href={examplesUrl}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center gap-2 px-3 py-2 rounded-lg font-semibold text-white col-span-2"
style={{
background: `linear-gradient(90deg, ${color} 0%, rgba(124,58,237,1) 100%)`
}}
title="Abrir exemplos no GitHub"
>
🔗 Ver Outros no GitHub
</a>
)}
</div>
</div>
<div className="rounded-lg overflow-hidden border">
<div className="p-0">
<div className="flex items-center justify-between bg-gradient-to-r from-gray-900 to-gray-800 p-3">
<div className="text-xs text-gray-300 font-medium">{framework?.nome}</div>
<div className="text-xs text-gray-400">
{loading ? 'Carregando exemplo...' : (framework?.exemplo ? 'Exemplo do framework' : 'Abrir no GitHub')}
</div>
</div>
</div>
<div className="flex">
<pre
className="bg-gray-900 text-gray-100 p-4 w-full overflow-auto"
style={{ fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, "Roboto Mono", "Courier New", monospace' }}
>
{lines.map((line, idx) => (
<div key={idx} className="flex select-text">
<span className="text-gray-500 pr-4 text-right w-8 select-none">{idx + 1}</span>
<code className="whitespace-pre-wrap flex-1">{line === '' ? '\u00A0' : line}</code>
</div>
))}
</pre>
</div>
</div>
{error && <p className="text-xs text-red-500 mt-2">Não foi possível carregar o arquivo de exemplo: {error}. Usando instrução para o repositório.</p>}
<p className="text-xs text-gray-500 mt-3">Dica: personalize este trecho conforme o seu projeto. Os exemplos completos estão no repositório.</p>
</div>
);
}
+112 -24
View File
@@ -1,33 +1,121 @@
"use client";
export default function Footer() {
const year = new Date().getFullYear();
return (
<footer className="bg-white py-3 text-black border-t border-gray-300 space-y-2">
<div className="text-center leading-5 text-sm md:flex md:justify-between max-w-5xl mx-auto">
<div className="m-0 p-0">
© {new Date().getFullYear()}&nbsp;
<a
href="https://cienciaembarcada.com.br"
className="text-blue-700 font-semibold hover:underline"
target="_blank"
rel="noopener noreferrer"
>
Ciência Embarcada
</a>
. Todos os direitos reservados.
<footer role="contentinfo" aria-label="Rodapé do site ESPDocs" className="bg-linear-to-r from-blue-600 to-purple-600 text-white mt-12">
<div className="max-w-6xl mx-auto px-6 py-8 rounded-t-2xl shadow-inner border-t border-white/10">
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<div className="space-y-3">
<h3 className="text-2xl font-extrabold tracking-tight">ESPDocs</h3>
<p className="text-sm text-white/90 max-w-sm">
Documentação não oficial em português para ESP32 — focada em clareza, exemplos práticos e comunidade.
</p>
<div className="">
<a
href="https://github.com/lucasrguerra/ESPDocs"
target="_blank"
rel="noopener noreferrer"
aria-label="Ver repositório do ESPDocs no GitHub (abre em nova aba)"
className="inline-flex items-center gap-2 bg-white/10 hover:bg-white/20 px-3 py-2 rounded-md text-sm font-semibold focus:outline-none focus:ring-2 focus:ring-white/30 transition"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true" className="opacity-90">
<path d="M12 .5a12 12 0 00-3.8 23.4c.6.1.8-.3.8-.6v-2.1c-3.3.7-4-1.6-4-1.6-.5-1.2-1.2-1.5-1.2-1.5-1-.7.1-.7.1-.7 1.1.1 1.7 1.1 1.7 1.1 1 .1 1.6-.7 1.9-1 .1-.8.4-1.3.8-1.6-2.6-.3-5.3-1.3-5.3-5.8 0-1.3.5-2.3 1.2-3.1-.1-.3-.5-1.6.1-3.3 0 0 1-.3 3.3 1.2a11.4 11.4 0 016 0c2.3-1.5 3.3-1.2 3.3-1.2.6 1.7.2 3 .1 3.3.8.8 1.2 1.9 1.2 3.1 0 4.5-2.7 5.5-5.3 5.8.5.4.9 1.1.9 2.2v3.2c0 .3.2.7.8.6A12 12 0 0012 .5z" fill="currentColor"/>
</svg>
Ver no GitHub
</a>
</div>
</div>
<nav aria-label="Links úteis" className="text-sm">
<h4 className="text-sm font-semibold mb-2">Links úteis</h4>
<ul className="space-y-2">
<li>
<a
href="https://github.com/lucasrguerra/ESPDocs"
target="_blank"
rel="noopener noreferrer"
className="hover:underline text-white/95 focus:outline-none focus:ring-2 focus:ring-white/20 rounded"
aria-label="Abrir repositório no GitHub"
>
Repositório no GitHub
</a>
</li>
<li>
<a
href="https://github.com/lucasrguerra/ESPDocs/issues"
target="_blank"
rel="noopener noreferrer"
className="hover:underline text-white/90 focus:outline-none focus:ring-2 focus:ring-white/20 rounded"
aria-label="Abrir issues do repositório"
>
Reportar bug / Abrir issue
</a>
</li>
<li>
<a
href="https://cienciaembarcada.com.br"
target="_blank"
rel="noopener noreferrer"
className="hover:underline text-white/90 focus:outline-none focus:ring-2 focus:ring-white/20 rounded"
aria-label="Visitar Ciência Embarcada (abre em nova aba)"
>
Ciência Embarcada
</a>
</li>
</ul>
</nav>
<div className="space-y-3">
<h4 className="text-sm font-semibold">Créditos</h4>
<p className="text-sm text-white/90">
Desenvolvido por{' '}
<a
href="https://linkedin.com/in/lucasrguerra"
target="_blank"
rel="noopener noreferrer"
className="underline hover:text-white"
aria-label="Perfil LinkedIn de Lucas Rayan Guerra (abre em nova aba)"
>
Lucas Rayan Guerra
</a>
.
</p>
<div className="flex items-center gap-3 mt-2">
<a
href="https://github.com/lucasrguerra/ESPDocs"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center justify-center w-9 h-9 rounded-md bg-white/10 hover:bg-white/20 focus:outline-none focus:ring-2 focus:ring-white/20"
aria-label="GitHub do projeto"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M12 .5a12 12 0 00-3.8 23.4c.6.1.8-.3.8-.6v-2.1c-3.3.7-4-1.6-4-1.6-.5-1.2-1.2-1.5-1.2-1.5-1-.7.1-.7.1-.7 1.1.1 1.7 1.1 1.7 1.1 1 .1 1.6-.7 1.9-1 .1-.8.4-1.3.8-1.6-2.6-.3-5.3-1.3-5.3-5.8 0-1.3.5-2.3 1.2-3.1-.1-.3-.5-1.6.1-3.3 0 0 1-.3 3.3 1.2a11.4 11.4 0 016 0c2.3-1.5 3.3-1.2 3.3-1.2.6 1.7.2 3 .1 3.3.8.8 1.2 1.9 1.2 3.1 0 4.5-2.7 5.5-5.3 5.8.5.4.9 1.1.9 2.2v3.2c0 .3.2.7.8.6A12 12 0 0012 .5z" fill="currentColor"/>
</svg>
</a>
<a
href="https://linkedin.com/in/lucasrguerra"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center justify-center w-9 h-9 rounded-md bg-white/10 hover:bg-white/20 focus:outline-none focus:ring-2 focus:ring-white/20"
aria-label="LinkedIn do autor"
>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<path d="M4.98 3.5a2.5 2.5 0 11.001 5.001A2.5 2.5 0 014.98 3.5zM3 8.98h4v12H3v-12zM9.5 8.98h3.8v1.6h.1c.5-.9 1.8-1.9 3.6-1.9 3.8 0 4.5 2.5 4.5 5.8v6.5h-4v-5.8c0-1.4-.1-3.2-2-3.2-2 0-2.3 1.6-2.3 3.1v5.9h-4v-12z" fill="currentColor"/>
</svg>
</a>
</div>
</div>
</div>
<div className="m-0 p-0">
Desenvolvido por&nbsp;
<a
href="https://linkedin.com/in/lucasrguerra"
className="text-blue-700 font-semibold hover:underline"
target="_blank"
rel="noopener noreferrer"
>
Lucas Rayan Guerra
</a>
.
<div className="mt-6 pt-4 border-t border-white/10 text-sm text-white/80 text-center">
<div>
© {year} ESPDocs — Conteúdo não oficial. Consulte sempre datasheets e documentos oficiais para decisões críticas.
</div>
</div>
</div>
</footer>
+5 -1
View File
@@ -29,7 +29,11 @@ export default function Header() {
];
function isActive(href) {
return pathname === href;
if (href === "/") {
return pathname === "/";
}
return String(pathname).includes(href) && href !== "/";
}
return (