Files
ESPDocs/app/[locale]/not-found.jsx
T
Lucas RayanandAntigravity 47c55515bb
CI / Lint e auditorias (push) Successful in 50s
CI / Trivy (dependências e segredos) (push) Successful in 10s
CI / Imagem Docker (linux/arm64) (push) Successful in 2m31s
fix(i18n): eliminate portuguese text leaks across english routes
- Localize skip-to-content accessibility link and breadcrumb navigation
- Convert section layouts to dynamic generateMetadata with English titles, descriptions, and structured data
- Eliminate mixed language expressions and translate remaining SoC connection pin warnings and descriptions
- Translate component registry items, categories, tags, and IDF Component Manager guide
- Add strict identical string verification to scripts/check-i18n.mjs with technical allowlist

Co-Authored-By: Antigravity <noreply@google.com>
2026-11-01 17:17:33 -03:00

82 lines
3.2 KiB
React

import Header from "@/components/Header";
import Footer from "@/components/Footer";
import Link from "next/link";
import { ArrowRight, BookOpen, Compass, Scale, SlidersHorizontal } from "lucide-react";
import { getLocale } from "next-intl/server";
import { getLocalizedHref } from "@/i18n/links";
export const metadata = {
title: "404",
robots: { index: false, follow: false },
};
const CAMINHOS_PT = [
{ href: "/series", icon: Compass, titulo: "Séries ESP32", texto: "As 12 famílias, com pinagem e especificações." },
{ href: "/seletor", icon: SlidersHorizontal, titulo: "Seletor de chip", texto: "Responda a oito perguntas e receba os modelos indicados." },
{ href: "/comparacao", icon: Scale, titulo: "Comparador", texto: "Até quatro séries lado a lado." },
{ href: "/glossario", icon: BookOpen, titulo: "Glossário", texto: "Termos de hardware explicados em português." },
];
const CAMINHOS_EN = [
{ href: "/series", icon: Compass, titulo: "ESP32 Series", texto: "The 12 families, with pinouts and specifications." },
{ href: "/seletor", icon: SlidersHorizontal, titulo: "Chip selector", texto: "Answer eight questions and get recommended models." },
{ href: "/comparacao", icon: Scale, titulo: "Comparator", texto: "Up to four series side by side." },
{ href: "/glossario", icon: BookOpen, titulo: "Glossary", texto: "Hardware terms explained clearly." },
];
export default async function NotFound() {
let locale = "pt";
try {
locale = await getLocale();
} catch {
locale = "pt";
}
const isEn = locale === "en";
const caminhos = isEn ? CAMINHOS_EN : CAMINHOS_PT;
return (
<div className="site-canvas min-h-screen">
<Header />
<main id="conteudo" className="shell section">
<div className="mx-auto max-w-2xl text-center">
<p className="eyebrow justify-center">{isEn ? "Error 404" : "Erro 404"}</p>
<h1 className="page-title mt-4">{isEn ? "This page does not exist." : "Essa página não existe."}</h1>
<p className="lede mx-auto mt-5 max-w-xl">
{isEn
? "The address may have changed or was mistyped. Choose one of these paths to continue."
: "O endereço pode ter mudado ou estar digitado errado. Escolha um destes caminhos para continuar."}
</p>
<div className="mt-8 flex justify-center">
<Link href={isEn ? "/en" : "/"} className="btn btn-primary">
{isEn ? "Back to home" : "Voltar ao início"}
<ArrowRight className="h-4 w-4" aria-hidden="true" />
</Link>
</div>
</div>
<ul className="mx-auto mt-14 grid max-w-4xl gap-3 sm:grid-cols-2">
{caminhos.map(({ href, icon: Icon, titulo, texto }) => {
const targetHref = isEn ? getLocalizedHref(href, "en") : href;
return (
<li key={href}>
<Link href={targetHref} className="card card-interactive group flex h-full items-start gap-4 p-5">
<span className="grid h-10 w-10 shrink-0 place-items-center rounded-full bg-accent-soft text-accent">
<Icon className="h-5 w-5" aria-hidden="true" />
</span>
<span>
<span className="block font-semibold text-ink">{titulo}</span>
<span className="mt-0.5 block text-sm text-muted">{texto}</span>
</span>
</Link>
</li>
);
})}
</ul>
</main>
<Footer />
</div>
);
}