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>
119 lines
6.3 KiB
React
119 lines
6.3 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." },
|
|
];
|
|
|
|
const CAMINHOS_ES = [
|
|
{ href: "/series", icon: Compass, titulo: "Series ESP32", texto: "Las 12 familias, con patillaje y especificaciones." },
|
|
{ href: "/seletor", icon: SlidersHorizontal, titulo: "Selector de chip", texto: "Responda a ocho preguntas y reciba los modelos recomendados." },
|
|
{ href: "/comparacao", icon: Scale, titulo: "Comparador", texto: "Hasta cuatro series frente a frente." },
|
|
{ href: "/glossario", icon: BookOpen, titulo: "Glosario", texto: "Términos de hardware explicados con claridad." },
|
|
];
|
|
|
|
const CAMINHOS_FR = [
|
|
{ href: "/series", icon: Compass, titulo: "Séries ESP32", texto: "Les 12 familles, avec brochage et spécifications." },
|
|
{ href: "/seletor", icon: SlidersHorizontal, titulo: "Sélecteur de puce", texto: "Répondez à huit questions et obtenez les modèles recommandés." },
|
|
{ href: "/comparacao", icon: Scale, titulo: "Comparateur", texto: "Jusqu'à quatre séries côte à côte." },
|
|
{ href: "/glossario", icon: BookOpen, titulo: "Glossaire", texto: "Les termes matériels expliqués clairement." },
|
|
];
|
|
|
|
const CAMINHOS_DE = [
|
|
{ href: "/series", icon: Compass, titulo: "ESP32-Serien", texto: "Die 12 Familien mit Pinbelegung und Spezifikationen." },
|
|
{ href: "/seletor", icon: SlidersHorizontal, titulo: "Chip-Auswahl", texto: "Beantworten Sie acht Fragen und erhalten Sie passende Empfehlungen." },
|
|
{ href: "/comparacao", icon: Scale, titulo: "Vergleich", texto: "Bis zu vier Serien im direkten Vergleich." },
|
|
{ href: "/glossario", icon: BookOpen, titulo: "Glossar", texto: "Hardware-Begriffe verständlich erklärt." },
|
|
];
|
|
const CAMINHOS_ZH = [
|
|
{ href: "/series", icon: Compass, titulo: "ESP32 系列", texto: "12 个系列,含引脚与规格。" },
|
|
{ href: "/seletor", icon: SlidersHorizontal, titulo: "芯片选型", texto: "回答八个问题,获得推荐型号。" },
|
|
{ href: "/comparacao", icon: Scale, titulo: "对比工具", texto: "最多四个系列并排对比。" },
|
|
{ href: "/glossario", icon: BookOpen, titulo: "术语表", texto: "清晰解释硬件术语。" },
|
|
];
|
|
|
|
export default async function NotFound() {
|
|
let locale = "pt";
|
|
try {
|
|
locale = await getLocale();
|
|
} catch {
|
|
locale = "pt";
|
|
}
|
|
const isEn = locale === "en";
|
|
const isEs = locale === "es";
|
|
const isFr = locale === "fr";
|
|
const isDe = locale === "de";
|
|
const isZh = locale === "zh-CN";
|
|
const caminhos = isEn ? CAMINHOS_EN : isEs ? CAMINHOS_ES : isFr ? CAMINHOS_FR : isZh ? CAMINHOS_ZH : isDe ? CAMINHOS_DE : 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" : isFr ? "Erreur 404" : isZh ? "错误 404" : isDe ? "Fehler 404" : "Error 404"}</p>
|
|
<h1 className="page-title mt-4">{isEn ? "This page does not exist." : isEs ? "Esta página no existe." : isFr ? "Cette page n'existe pas." : isZh ? "该页面不存在。" : isDe ? "Diese Seite existiert nicht." : "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."
|
|
: isEs
|
|
? "La dirección puede haber cambiado o estar mal escrita. Elija uno de estos caminos para continuar."
|
|
: isFr
|
|
? "L'adresse a peut-être changé ou a été mal saisie. Choisissez l'un de ces chemins pour continuer."
|
|
: isZh ? "地址可能已更改或输入有误。请从以下入口继续浏览。" : isDe
|
|
? "Die Adresse wurde möglicherweise geändert oder falsch eingegeben. Wählen Sie einen dieser Wege, um fortzufahren."
|
|
: "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" : isEs ? "/es" : isFr ? "/fr" : isZh ? "/zh-CN" : isDe ? "/de" : "/"} className="btn btn-primary">
|
|
{isEn ? "Back to home" : isEs ? "Volver al inicio" : isFr ? "Retour à l'accueil" : isZh ? "返回首页" : isDe ? "Zur Startseite" : "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 = getLocalizedHref(href, locale);
|
|
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>
|
|
);
|
|
}
|