feat(i18n): Simplified Chinese (zh-CN), search answers per locale, fr/de/es data fixes
CI / Lint e auditorias (push) Successful in 1m10s
CI / Trivy (dependências e segredos) (push) Successful in 12s
CI / Imagem Docker (linux/arm64) (push) Successful in 2m39s
Release / Plano (reaproveitar a imagem?) (push) Successful in 6s
Release / ci (push) Skipped
Release / Publica a imagem (linux/arm64) (push) Successful in 18s
Release / Cria a release no Gitea (push) Successful in 5s

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Lucas RayanandClaude Sonnet 5.5 committed 2026-11-01 23:28:39 -03:00
1 parent ae61416468
commit 5a9fe676fc
61 files changed
+2517 -920

No files matched your search

+51 -15
View File
@@ -8,6 +8,7 @@ import frameworksDataEn from "@/data/en/frameworks.json";
import frameworksDataEs from "@/data/es/frameworks.json";
import frameworksDataFr from "@/data/fr/frameworks.json";
import frameworksDataDe from "@/data/de/frameworks.json";
import frameworksDataZh from "@/data/zh-CN/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";
@@ -176,6 +177,38 @@ const GUIAS_DE = [
],
},
];
const GUIAS_ZH = [
{
icon: GraduationCap,
titulo: "快速上手",
texto: "Arduino 或 MicroPython 是测试传感器和 API 最快的途径。量产请选择 ESP-IDF 或 Rust。",
links: [
["Arduino", "/frameworks/Arduino"],
["MicroPython", "/frameworks/MicroPython"],
["Rust", "/frameworks/Rust-ESP"],
],
},
{
icon: Cloud,
titulo: "云与智能家居",
texto: "需要互操作用 ESP-Matter,想要现成的云用 ESP-RainMaker,做低功耗本地 Mesh 网络用 Zigbee。",
links: [
["RainMaker", "/frameworks/ESP-RainMaker"],
["Matter", "/frameworks/ESP-Matter"],
["Zigbee", "/frameworks/ESP-Zigbee-SDK"],
],
},
{
icon: Sparkles,
titulo: "音频、语音与 AI",
texto: "音频处理用 ESP-ADF,离线语音识别用 ESP-SR,加速 TinyML 用 ESP-NN。",
links: [
["音频", "/frameworks/ESP-ADF", Music],
["语音", "/frameworks/ESP-SR", Mic],
["AI", "/frameworks/ESP-NN", Brain],
],
},
];
export default async function Frameworks({ params }) {
const { locale } = await params;
@@ -183,10 +216,11 @@ export default async function Frameworks({ params }) {
const isEs = locale === "es";
const isFr = locale === "fr";
const isDe = locale === "de";
const currentLocale = isEs ? "es" : isEn ? "en" : isFr ? "fr" : isDe ? "de" : "pt";
const frameworksData = isEs ? frameworksDataEs : isEn ? frameworksDataEn : isFr ? frameworksDataFr : isDe ? frameworksDataDe : frameworksDataPt;
const isZh = locale === "zh-CN";
const currentLocale = isEs ? "es" : isEn ? "en" : isFr ? "fr" : isZh ? "zh-CN" : isDe ? "de" : "pt";
const frameworksData = isEs ? frameworksDataEs : isEn ? frameworksDataEn : isFr ? frameworksDataFr : isZh ? frameworksDataZh : isDe ? frameworksDataDe : frameworksDataPt;
const frameworks = Object.entries(frameworksData);
const guias = isEs ? GUIAS_ES : isEn ? GUIAS_EN : isFr ? GUIAS_FR : isDe ? GUIAS_DE : GUIAS_PT;
const guias = isEs ? GUIAS_ES : isEn ? GUIAS_EN : isFr ? GUIAS_FR : isZh ? GUIAS_ZH : isDe ? GUIAS_DE : GUIAS_PT;
return (
<div className="site-canvas min-h-screen">
@@ -197,11 +231,11 @@ export default async function Frameworks({ params }) {
isEn={isEn}
isEs={isEs}
isFr={isFr}
isDe={isDe}
trail={[{ label: isEs ? "Frameworks y SDKs" : isEn ? "Frameworks & SDKs" : isFr ? "Frameworks et SDKs" : isDe ? "Frameworks & SDKs" : "Frameworks e SDKs" }]}
isDe={isDe} isZh={isZh}
trail={[{ label: isEs ? "Frameworks y SDKs" : isEn ? "Frameworks & SDKs" : isFr ? "Frameworks et SDKs" : isZh ? "框架与 SDK" : isDe ? "Frameworks & SDKs" : "Frameworks e SDKs" }]}
icon={Layers}
label={isEs ? `${frameworks.length} frameworks y SDKs` : isEn ? `${frameworks.length} frameworks and SDKs` : isFr ? `${frameworks.length} frameworks et SDKs` : isDe ? `${frameworks.length} Frameworks und SDKs` : `${frameworks.length} frameworks e SDKs`}
title={isEs ? "Frameworks y SDKs de ESP32" : isEn ? "ESP32 Frameworks and SDKs" : isFr ? "Frameworks et SDKs pour ESP32" : isDe ? "ESP32-Frameworks und SDKs" : "Frameworks e SDKs do ESP32"}
label={isEs ? `${frameworks.length} frameworks y SDKs` : isEn ? `${frameworks.length} frameworks and SDKs` : isFr ? `${frameworks.length} frameworks et SDKs` : isZh ? `${frameworks.length} 个框架与 SDK` : isDe ? `${frameworks.length} Frameworks und SDKs` : `${frameworks.length} frameworks e SDKs`}
title={isEs ? "Frameworks y SDKs de ESP32" : isEn ? "ESP32 Frameworks and SDKs" : isFr ? "Frameworks et SDKs pour ESP32" : isZh ? "ESP32 框架与 SDK" : isDe ? "ESP32-Frameworks und SDKs" : "Frameworks e SDKs do ESP32"}
lede={
isEs
? "Desde C/C++ nativo con FreeRTOS hasta Rust, nube IoT, reconocimiento de voz, audio y Matter. Elija según lo que desee construir."
@@ -209,13 +243,13 @@ export default async function Frameworks({ params }) {
? "From native C/C++ with FreeRTOS to Rust, IoT cloud, speech recognition, audio, and Matter. Choose by what you want to build."
: isFr
? "Du C/C++ natif avec FreeRTOS à Rust, en passant par le cloud IoT, la reconnaissance vocale, l'audio et Matter. Choisissez selon ce que vous souhaitez concevoir."
: isDe
: isZh ? "从原生 C/C++ 与 FreeRTOS,到 Rust,再到物联网云、语音识别、音频和 Matter。按你想构建的东西来选。" : isDe
? "Von nativem C/C++ mit FreeRTOS bis hin zu Rust, IoT-Cloud, Spracherkennung, Audio und Matter. Wählen Sie passend zu Ihrem Projekt."
: "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={isEs ? "Por dónde empezar" : isEn ? "Where to begin" : isFr ? "Par où commencer" : isDe ? "Wo anfangen" : "Por onde começar"}>
<section className="shell pt-10 sm:pt-12" aria-label={isEs ? "Por dónde empezar" : isEn ? "Where to begin" : isFr ? "Par où commencer" : isZh ? "从哪里开始" : isDe ? "Wo anfangen" : "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">
@@ -244,7 +278,7 @@ export default async function Frameworks({ params }) {
<div className="max-w-2xl">
<span className="chip chip-accent">
<Box className="h-3.5 w-3.5" aria-hidden="true" />
{isEs ? "Arquitectura modular" : isEn ? "Modular architecture" : isFr ? "Architecture modulaire" : isDe ? "Modulare Architektur" : "Arquitetura modular"}
{isEs ? "Arquitectura modular" : isEn ? "Modular architecture" : isFr ? "Architecture modulaire" : isZh ? "模块化架构" : isDe ? "Modulare Architektur" : "Arquitetura modular"}
</span>
<h2 className="section-title mt-4">ESP Component Registry</h2>
<p className="mt-3 text-base leading-relaxed text-muted">
@@ -263,7 +297,9 @@ export default async function Frameworks({ params }) {
Installez des pilotes d'écran (LVGL), des piles industrielles (Modbus), des fonctionnalités cloud et des paquets de support de cartes
(BSPs) avec une seule ligne dans votre manifeste <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code>.
</>
) : isDe ? (
) : isZh ? ( <>
通过 <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code> 清单中的一行,即可安装显示驱动(LVGL)、工业协议栈(Modbus)、云功能和开发板包(BSP)。
</> ) : isDe ? (
<>
Installieren Sie Display-Treiber (LVGL), Industrieprotokolle (Modbus), Cloud-Funktionen und Board-Support-Pakete
(BSPs) mit einer einzigen Zeile in Ihrem <code className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-sm">idf_component.yml</code>-Manifest.
@@ -277,7 +313,7 @@ export default async function Frameworks({ params }) {
</p>
</div>
<Link href={getLocalizedHref("/componentes", currentLocale)} className="btn btn-primary shrink-0">
{isEs ? "Explorar componentes" : isEn ? "Explore components" : isFr ? "Explorer les composants" : isDe ? "Komponenten erkunden" : "Explorar componentes"}
{isEs ? "Explorar componentes" : isEn ? "Explore components" : isFr ? "Explorer les composants" : isZh ? "探索组件" : isDe ? "Komponenten erkunden" : "Explorar componentes"}
<ArrowRight className="h-4 w-4" aria-hidden="true" />
</Link>
</div>
@@ -287,8 +323,8 @@ export default async function Frameworks({ params }) {
<SectionHead
id="todos-titulo"
eyebrow={isEs ? "Todos" : isEn ? "All" : "Todos"}
title={isEs ? "Todos los frameworks" : isEn ? "All frameworks" : isFr ? "Tous les frameworks" : isDe ? "Alle Frameworks" : "Todos os frameworks"}
lede={isEs ? "Cada ficha ofrece funciones, aplicaciones ideales, ejemplos de código y enlaces oficiales." : isEn ? "Each page provides features, ideal use cases, code examples, and official links." : isFr ? "Chaque fiche présente les fonctionnalités, les cas d'usage idéaux, des exemples de code et les liens officiels." : isDe ? "Jedes Datenblatt bietet Features, ideale Anwendungsbereiche, Codebeispiele und offizielle Links." : "Cada ficha traz recursos, aplicações ideais, exemplo de código e links oficiais."}
title={isEs ? "Todos los frameworks" : isEn ? "All frameworks" : isFr ? "Tous les frameworks" : isZh ? "全部框架" : isDe ? "Alle Frameworks" : "Todos os frameworks"}
lede={isEs ? "Cada ficha ofrece funciones, aplicaciones ideales, ejemplos de código y enlaces oficiales." : isEn ? "Each page provides features, ideal use cases, code examples, and official links." : isFr ? "Chaque fiche présente les fonctionnalités, les cas d'usage idéaux, des exemples de code et les liens officiels." : isZh ? "每张卡片包含功能、理想应用场景、代码示例和官方链接。" : isDe ? "Jedes Datenblatt bietet Features, ideale Anwendungsbereiche, Codebeispiele und offizielle 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">
@@ -310,7 +346,7 @@ export default async function Frameworks({ params }) {
</ul>
<span className="mt-5 inline-flex items-center gap-1 border-t border-line pt-4 text-sm font-medium text-accent">
{isEs ? "Ver detalles y ejemplo" : isEn ? "View details and example" : isFr ? "Voir les détails et l'exemple" : isDe ? "Details und Beispiel ansehen" : "Ver detalhes e exemplo"}
{isEs ? "Ver detalles y ejemplo" : isEn ? "View details and example" : isFr ? "Voir les détails et l'exemple" : isZh ? "查看详情与示例" : isDe ? "Details und Beispiel ansehen" : "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>