- Translate content to English across messages/en.json, data/en, lib/data/en, and public/exemplos/en - Implement localized routing, slugs, and language negotiation with fallback to en - Build dedicated search index for English with strict book exclusion - Update components and pages to dynamically render localized strings and datasets - Verify full structural parity and exact 1:1 match on Portuguese pages via comparator Co-Authored-By: Antigravity <noreply@google.com>
196 lines
7.8 KiB
React
196 lines
7.8 KiB
React
import Header from "@/components/Header";
|
|
import Footer from "@/components/Footer";
|
|
import PageHero from "@/components/PageHero";
|
|
import SectionHead from "@/components/SectionHead";
|
|
import Link from "next/link";
|
|
import frameworksDataPt from "@/public/frameworks.json";
|
|
import frameworksDataEn from "@/data/en/frameworks.json";
|
|
import { paginaMeta } from "@/lib/seo";
|
|
import { getLocalizedHref } from "@/i18n/links";
|
|
import { ArrowRight, ArrowUpRight, Box, Brain, Cloud, GraduationCap, Layers, Mic, Music, Sparkles } from "lucide-react";
|
|
|
|
const GUIAS_PT = [
|
|
{
|
|
icon: GraduationCap,
|
|
titulo: "Estou começando",
|
|
texto: "Arduino ou MicroPython são os caminhos mais rápidos para testar sensores e APIs. Para produto, vá de ESP-IDF ou Rust.",
|
|
links: [
|
|
["Arduino", "/frameworks/Arduino"],
|
|
["MicroPython", "/frameworks/MicroPython"],
|
|
["Rust", "/frameworks/Rust-ESP"],
|
|
],
|
|
},
|
|
{
|
|
icon: Cloud,
|
|
titulo: "Nuvem e casa conectada",
|
|
texto: "ESP-Matter para interoperabilidade, ESP-RainMaker para nuvem pronta e Zigbee para redes locais de baixo consumo.",
|
|
links: [
|
|
["RainMaker", "/frameworks/ESP-RainMaker"],
|
|
["Matter", "/frameworks/ESP-Matter"],
|
|
["Zigbee", "/frameworks/ESP-Zigbee-SDK"],
|
|
],
|
|
},
|
|
{
|
|
icon: Sparkles,
|
|
titulo: "Áudio, voz e IA",
|
|
texto: "ESP-ADF para áudio, ESP-SR para reconhecimento de fala offline e ESP-NN para acelerar TinyML.",
|
|
links: [
|
|
["Áudio", "/frameworks/ESP-ADF", Music],
|
|
["Voz", "/frameworks/ESP-SR", Mic],
|
|
["IA", "/frameworks/ESP-NN", Brain],
|
|
],
|
|
},
|
|
];
|
|
|
|
const GUIAS_EN = [
|
|
{
|
|
icon: GraduationCap,
|
|
titulo: "Getting Started",
|
|
texto: "Arduino or MicroPython are the fastest routes to test sensors and APIs. For production, go with ESP-IDF or Rust.",
|
|
links: [
|
|
["Arduino", "/frameworks/Arduino"],
|
|
["MicroPython", "/frameworks/MicroPython"],
|
|
["Rust", "/frameworks/Rust-ESP"],
|
|
],
|
|
},
|
|
{
|
|
icon: Cloud,
|
|
titulo: "Cloud and Connected Home",
|
|
texto: "ESP-Matter for interoperability, ESP-RainMaker for ready-made cloud, and Zigbee for low-power local mesh networks.",
|
|
links: [
|
|
["RainMaker", "/frameworks/ESP-RainMaker"],
|
|
["Matter", "/frameworks/ESP-Matter"],
|
|
["Zigbee", "/frameworks/ESP-Zigbee-SDK"],
|
|
],
|
|
},
|
|
{
|
|
icon: Sparkles,
|
|
titulo: "Audio, Voice and AI",
|
|
texto: "ESP-ADF for audio processing, ESP-SR for offline speech recognition, and ESP-NN for accelerating TinyML.",
|
|
links: [
|
|
["Audio", "/frameworks/ESP-ADF", Music],
|
|
["Voice", "/frameworks/ESP-SR", Mic],
|
|
["AI", "/frameworks/ESP-NN", Brain],
|
|
],
|
|
},
|
|
];
|
|
|
|
export default async function Frameworks({ params }) {
|
|
const { locale } = await params;
|
|
const isEn = locale === "en";
|
|
const currentLocale = isEn ? "en" : "pt";
|
|
const frameworksData = isEn ? frameworksDataEn : frameworksDataPt;
|
|
const frameworks = Object.entries(frameworksData);
|
|
const guias = isEn ? GUIAS_EN : GUIAS_PT;
|
|
|
|
return (
|
|
<div className="site-canvas min-h-screen">
|
|
<Header />
|
|
|
|
<main id="conteudo">
|
|
<PageHero
|
|
trail={[{ label: isEn ? "Frameworks & SDKs" : "Frameworks e SDKs" }]}
|
|
icon={Layers}
|
|
label={isEn ? `${frameworks.length} frameworks and SDKs` : `${frameworks.length} frameworks e SDKs`}
|
|
title={isEn ? "ESP32 Frameworks and SDKs" : "Frameworks e SDKs do ESP32"}
|
|
lede={
|
|
isEn
|
|
? "From native C/C++ with FreeRTOS to Rust, IoT cloud, speech recognition, audio, and Matter. Choose by what you want to build."
|
|
: "Do C/C++ nativo com FreeRTOS ao Rust, passando por nuvem IoT, reconhecimento de voz, áudio e Matter. Escolha pelo que você quer construir."
|
|
}
|
|
/>
|
|
|
|
<section className="shell pt-10 sm:pt-12" aria-label={isEn ? "Where to begin" : "Por onde começar"}>
|
|
<div className="grid gap-4 md:grid-cols-3">
|
|
{guias.map(({ icon: Icon, titulo, texto, links }) => (
|
|
<div key={titulo} className="card flex flex-col p-5 sm:p-6">
|
|
<span className="grid h-10 w-10 place-items-center rounded-full bg-accent-soft text-accent">
|
|
<Icon className="h-5 w-5" aria-hidden="true" />
|
|
</span>
|
|
<h2 className="mt-4 font-display text-xl font-semibold tracking-[-0.03em] text-ink">{titulo}</h2>
|
|
<p className="mt-2 flex-1 text-sm leading-relaxed text-muted">{texto}</p>
|
|
<ul className="mt-5 flex flex-wrap gap-2 border-t border-line pt-4">
|
|
{links.map(([rotulo, href, Extra]) => (
|
|
<li key={rotulo}>
|
|
<Link href={getLocalizedHref(href, currentLocale)} className="chip-btn">
|
|
{Extra && <Extra className="h-4 w-4" aria-hidden="true" />}
|
|
{rotulo}
|
|
</Link>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</section>
|
|
|
|
<section className="shell mt-10">
|
|
<div className="panel flex flex-col items-start justify-between gap-6 p-7 sm:p-10 md:flex-row md:items-center">
|
|
<div className="max-w-2xl">
|
|
<span className="chip chip-accent">
|
|
<Box className="h-3.5 w-3.5" aria-hidden="true" />
|
|
{isEn ? "Modular architecture" : "Arquitetura modular"}
|
|
</span>
|
|
<h2 className="section-title mt-4">ESP Component Registry</h2>
|
|
<p className="mt-3 text-base leading-relaxed text-muted">
|
|
{isEn ? (
|
|
<>
|
|
Install display drivers (LVGL), industrial stacks (Modbus), cloud integrations, and board support packages
|
|
(BSPs) with a single line in your <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code> manifest.
|
|
</>
|
|
) : (
|
|
<>
|
|
Instale drivers de display (LVGL), pilhas industriais (Modbus), recursos de nuvem e pacotes de placa
|
|
(BSPs) com uma linha no manifesto <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code>.
|
|
</>
|
|
)}
|
|
</p>
|
|
</div>
|
|
<Link href={getLocalizedHref("/componentes", currentLocale)} className="btn btn-primary shrink-0">
|
|
{isEn ? "Explore components" : "Explorar componentes"}
|
|
<ArrowRight className="h-4 w-4" aria-hidden="true" />
|
|
</Link>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="shell section" aria-labelledby="todos-titulo">
|
|
<SectionHead
|
|
id="todos-titulo"
|
|
eyebrow={isEn ? "All" : "Todos"}
|
|
title={isEn ? "All frameworks" : "Todos os frameworks"}
|
|
lede={isEn ? "Each page provides features, ideal use cases, code examples, and official links." : "Cada ficha traz recursos, aplicações ideais, exemplo de código e links oficiais."}
|
|
/>
|
|
|
|
<div className="mt-8 grid gap-4 md:grid-cols-2 lg:grid-cols-3">
|
|
{frameworks.map(([key, framework]) => (
|
|
<Link key={key} href={getLocalizedHref(`/frameworks/${encodeURIComponent(key)}`, currentLocale)} className="card card-interactive group flex flex-col p-5 sm:p-6">
|
|
<div className="flex flex-wrap items-start justify-between gap-2">
|
|
<h3 className="font-display text-xl font-semibold tracking-[-0.03em] text-ink">{framework.nome}</h3>
|
|
<span className="chip max-w-full">{framework.linguagem}</span>
|
|
</div>
|
|
<p className="mt-1 text-sm text-muted">{framework.tipo}</p>
|
|
<p className="mt-3 line-clamp-3 text-sm leading-relaxed text-muted">{framework.descricao}</p>
|
|
|
|
<ul className="mt-5 flex flex-1 flex-wrap content-start gap-1.5">
|
|
{framework.casos_uso.slice(0, 3).map((caso) => (
|
|
<li key={caso} className="chip max-w-full">
|
|
<span className="truncate">{caso}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
|
|
<span className="mt-5 inline-flex items-center gap-1 border-t border-line pt-4 text-sm font-medium text-accent">
|
|
{isEn ? "View details and example" : "Ver detalhes e exemplo"}
|
|
<ArrowUpRight className="h-4 w-4 transition-transform group-hover:-translate-y-0.5 group-hover:translate-x-0.5" aria-hidden="true" />
|
|
</span>
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
<Footer />
|
|
</div>
|
|
);
|
|
}
|