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>
435 lines
15 KiB
React
435 lines
15 KiB
React
"use client";
|
||
|
||
import Link from "next/link";
|
||
import { usePathname } from "next/navigation";
|
||
import Logo from "@/components/Logo";
|
||
import GiteaMark from "@/components/GiteaMark";
|
||
import { ArrowUpRight } from "lucide-react";
|
||
import { SITE } from "@/lib/seo";
|
||
import { LOCALES, getLocalizedHref } from "@/i18n/links";
|
||
|
||
const COLUMNS_PT = [
|
||
{
|
||
title: "Explorar",
|
||
links: [
|
||
{ href: "/series", label: "Séries ESP32" },
|
||
{ href: "/comparacao", label: "Comparador" },
|
||
{ href: "/catalogo", label: "Catálogo de placas" },
|
||
{ href: "/livro", label: "O livro" },
|
||
],
|
||
},
|
||
{
|
||
title: "Ferramentas",
|
||
links: [
|
||
{ href: "/seletor", label: "Seletor inteligente" },
|
||
{ href: "/diagnostico", label: "Diagnóstico" },
|
||
{ href: "/componentes", label: "Component Registry" },
|
||
{ href: "/frameworks", label: "Frameworks e SDKs" },
|
||
],
|
||
},
|
||
{
|
||
title: "Projeto",
|
||
links: [
|
||
{ href: "/sobre", label: "Sobre o ESPDocs" },
|
||
{ href: "/glossario", label: "Glossário" },
|
||
{ href: SITE.repositorio, label: "Repositório", external: true },
|
||
{ href: `${SITE.repositorio}/issues`, label: "Reportar um problema", external: true },
|
||
],
|
||
},
|
||
];
|
||
|
||
const COLUMNS_EN = [
|
||
{
|
||
title: "Explore",
|
||
links: [
|
||
{ href: "/series", label: "ESP32 Series" },
|
||
{ href: "/comparacao", label: "Comparator" },
|
||
{ href: "/catalogo", label: "Board Catalog" },
|
||
],
|
||
},
|
||
{
|
||
title: "Tools",
|
||
links: [
|
||
{ href: "/seletor", label: "Smart Selector" },
|
||
{ href: "/diagnostico", label: "Diagnostics" },
|
||
{ href: "/componentes", label: "Component Registry" },
|
||
{ href: "/frameworks", label: "Frameworks & SDKs" },
|
||
],
|
||
},
|
||
{
|
||
title: "Project",
|
||
links: [
|
||
{ href: "/sobre", label: "About ESPDocs" },
|
||
{ href: "/glossario", label: "Glossary" },
|
||
{ href: SITE.repositorio, label: "Repository", external: true },
|
||
{ href: `${SITE.repositorio}/issues`, label: "Report an issue", external: true },
|
||
],
|
||
},
|
||
];
|
||
|
||
const COLUMNS_ES = [
|
||
{
|
||
title: "Explorar",
|
||
links: [
|
||
{ href: "/series", label: "Series ESP32" },
|
||
{ href: "/comparacao", label: "Comparador" },
|
||
{ href: "/catalogo", label: "Catálogo de placas" },
|
||
],
|
||
},
|
||
{
|
||
title: "Herramientas",
|
||
links: [
|
||
{ href: "/seletor", label: "Selector inteligente" },
|
||
{ href: "/diagnostico", label: "Diagnóstico" },
|
||
{ href: "/componentes", label: "Component Registry" },
|
||
{ href: "/frameworks", label: "Frameworks y SDKs" },
|
||
],
|
||
},
|
||
{
|
||
title: "Proyecto",
|
||
links: [
|
||
{ href: "/sobre", label: "Acerca de ESPDocs" },
|
||
{ href: "/glossario", label: "Glosario" },
|
||
{ href: SITE.repositorio, label: "Repositorio", external: true },
|
||
{ href: `${SITE.repositorio}/issues`, label: "Reportar un problema", external: true },
|
||
],
|
||
},
|
||
];
|
||
|
||
const COLUMNS_FR = [
|
||
{
|
||
title: "Explorer",
|
||
links: [
|
||
{ href: "/series", label: "Séries ESP32" },
|
||
{ href: "/comparacao", label: "Comparateur" },
|
||
{ href: "/catalogo", label: "Catalogue de cartes" },
|
||
],
|
||
},
|
||
{
|
||
title: "Outils",
|
||
links: [
|
||
{ href: "/seletor", label: "Sélecteur intelligent" },
|
||
{ href: "/diagnostico", label: "Diagnostic" },
|
||
{ href: "/componentes", label: "Component Registry" },
|
||
{ href: "/frameworks", label: "Frameworks et SDKs" },
|
||
],
|
||
},
|
||
{
|
||
title: "Projet",
|
||
links: [
|
||
{ href: "/sobre", label: "À propos d'ESPDocs" },
|
||
{ href: "/glossario", label: "Glossaire" },
|
||
{ href: SITE.repositorio, label: "Dépôt", external: true },
|
||
{ href: `${SITE.repositorio}/issues`, label: "Signaler un problème", external: true },
|
||
],
|
||
},
|
||
];
|
||
|
||
const COLUMNS_DE = [
|
||
{
|
||
title: "Erkunden",
|
||
links: [
|
||
{ href: "/series", label: "ESP32-Serien" },
|
||
{ href: "/comparacao", label: "Vergleich" },
|
||
{ href: "/catalogo", label: "Board-Katalog" },
|
||
],
|
||
},
|
||
{
|
||
title: "Werkzeuge",
|
||
links: [
|
||
{ href: "/seletor", label: "Intelligente Auswahl" },
|
||
{ href: "/diagnostico", label: "Diagnose" },
|
||
{ href: "/componentes", label: "Component Registry" },
|
||
{ href: "/frameworks", label: "Frameworks & SDKs" },
|
||
],
|
||
},
|
||
{
|
||
title: "Projekt",
|
||
links: [
|
||
{ href: "/sobre", label: "Über ESPDocs" },
|
||
{ href: "/glossario", label: "Glossar" },
|
||
{ href: SITE.repositorio, label: "Repository", external: true },
|
||
{ href: `${SITE.repositorio}/issues`, label: "Problem melden", external: true },
|
||
],
|
||
},
|
||
];
|
||
const COLUMNS_ZH = [
|
||
{
|
||
title: "探索",
|
||
links: [
|
||
{ href: "/series", label: "ESP32 系列" },
|
||
{ href: "/comparacao", label: "对比工具" },
|
||
{ href: "/catalogo", label: "开发板目录" },
|
||
],
|
||
},
|
||
{
|
||
title: "工具",
|
||
links: [
|
||
{ href: "/seletor", label: "智能选型" },
|
||
{ href: "/diagnostico", label: "故障诊断" },
|
||
{ href: "/componentes", label: "Component Registry" },
|
||
{ href: "/frameworks", label: "框架与 SDK" },
|
||
],
|
||
},
|
||
{
|
||
title: "项目",
|
||
links: [
|
||
{ href: "/sobre", label: "关于 ESPDocs" },
|
||
{ href: "/glossario", label: "术语表" },
|
||
{ href: SITE.repositorio, label: "代码仓库", external: true },
|
||
{ href: `${SITE.repositorio}/issues`, label: "反馈问题", external: true },
|
||
],
|
||
},
|
||
];
|
||
|
||
export default function Footer() {
|
||
const pathname = usePathname() || "";
|
||
const year = new Date().getFullYear();
|
||
|
||
const currentLocale =
|
||
LOCALES.find((l) => pathname === `/${l.code}` || pathname.startsWith(`/${l.code}/`))?.code || "pt";
|
||
const isPt = currentLocale === "pt";
|
||
const isEn = currentLocale === "en";
|
||
const isEs = currentLocale === "es";
|
||
const isFr = currentLocale === "fr";
|
||
const isDe = currentLocale === "de";
|
||
const isZh = currentLocale === "zh-CN";
|
||
|
||
const getLinkHref = (href) => getLocalizedHref(`/${currentLocale}${href}`, currentLocale);
|
||
|
||
const columns = isPt
|
||
? COLUMNS_PT.map((column) => ({
|
||
...column,
|
||
links: column.links.filter((link) => link.href !== "/livro" || isPt),
|
||
}))
|
||
: isEs
|
||
? COLUMNS_ES
|
||
: isFr
|
||
? COLUMNS_FR
|
||
: isZh ? COLUMNS_ZH : isDe
|
||
? COLUMNS_DE
|
||
: COLUMNS_EN;
|
||
|
||
return (
|
||
<footer
|
||
className="mt-20 border-t border-line md:mt-28"
|
||
aria-label={
|
||
isPt
|
||
? "Rodapé do ESPDocs"
|
||
: isEs
|
||
? "Pie de página de ESPDocs"
|
||
: isFr
|
||
? "Pied de page d'ESPDocs"
|
||
: isZh ? "ESPDocs 页脚" : isDe
|
||
? "ESPDocs-Fußzeile"
|
||
: "ESPDocs footer"
|
||
}
|
||
>
|
||
<div className="shell py-14 md:py-20">
|
||
<div className="grid gap-12 lg:grid-cols-[1.1fr_2fr]">
|
||
<div>
|
||
<Link
|
||
href={getLinkHref("/")}
|
||
className="inline-flex min-h-11 items-center gap-2.5"
|
||
aria-label={
|
||
isPt
|
||
? "ESPDocs, página inicial"
|
||
: isEs
|
||
? "ESPDocs, página de inicio"
|
||
: isFr
|
||
? "ESPDocs, page d'accueil"
|
||
: isZh ? "ESPDocs,首页" : isDe
|
||
? "ESPDocs, Startseite"
|
||
: "ESPDocs, homepage"
|
||
}
|
||
>
|
||
<Logo className="h-7 w-7" />
|
||
<span className="font-display text-2xl font-semibold tracking-[-0.045em] text-ink">ESPDocs</span>
|
||
</Link>
|
||
<p className="mt-5 max-w-sm text-sm leading-relaxed text-muted">
|
||
{isPt ? (
|
||
<>
|
||
Documentação independente do ecossistema ESP32, escrita em português brasileiro.
|
||
Dados públicos, curadoria editorial e links para as fontes oficiais.
|
||
</>
|
||
) : isEs ? (
|
||
<>
|
||
Documentación independiente del ecosistema ESP32.
|
||
Datos públicos, curaduría editorial y enlaces a las fuentes oficiales.
|
||
</>
|
||
) : isFr ? (
|
||
<>
|
||
Documentation indépendante de l'écosystème ESP32.
|
||
Données publiques, sélection éditoriale et liens vers les sources officielles.
|
||
</>
|
||
) : isZh ? ( <>ESP32 生态的独立文档。公开数据、编辑整理,并链接到官方资料来源。</> ) : isDe ? (
|
||
<>
|
||
Unabhängige Dokumentation des ESP32-Ökosystems.
|
||
Öffentliche Daten, redaktionelle Betreuung und Links zu offiziellen Quellen.
|
||
</>
|
||
) : (
|
||
<>
|
||
Independent documentation of the ESP32 ecosystem.
|
||
Open data, editorial curation, and links to official sources.
|
||
</>
|
||
)}
|
||
</p>
|
||
|
||
{isPt && (
|
||
<>
|
||
<Link
|
||
href="/pt/livro"
|
||
className="group mt-7 grid grid-cols-[3rem_1fr_auto] items-center gap-3.5 rounded-2xl border border-line bg-surface p-3.5 transition-colors duration-300 hover:border-line-strong"
|
||
>
|
||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||
<img
|
||
src={SITE.livroCapa}
|
||
alt=""
|
||
aria-hidden="true"
|
||
width={48}
|
||
height={72}
|
||
className="h-[72px] w-12 rounded-md object-cover shadow-md"
|
||
/>
|
||
<span className="min-w-0">
|
||
<span className="text-xs font-semibold text-accent">Livro novo</span>
|
||
<span className="mt-0.5 block font-display text-base font-semibold leading-tight text-ink">Microcontroladores ESP32</span>
|
||
<span className="mt-1 block text-xs text-muted">Conectividade, eficiência e desempenho</span>
|
||
</span>
|
||
<ArrowUpRight className="h-4 w-4 text-faint transition-transform duration-300 group-hover:-translate-y-0.5 group-hover:translate-x-0.5 group-hover:text-accent" aria-hidden="true" />
|
||
</Link>
|
||
|
||
<div className="mt-4 flex flex-wrap gap-x-5 gap-y-2 text-sm">
|
||
<a href={SITE.livroAmazon} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center gap-1 text-muted transition-colors hover:text-accent">
|
||
Amazon
|
||
<ArrowUpRight className="h-3.5 w-3.5" aria-hidden="true" />
|
||
</a>
|
||
<a href={SITE.livroUiclap} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center gap-1 text-muted transition-colors hover:text-accent">
|
||
UICLAP
|
||
<ArrowUpRight className="h-3.5 w-3.5" aria-hidden="true" />
|
||
</a>
|
||
</div>
|
||
</>
|
||
)}
|
||
</div>
|
||
|
||
<div className="grid grid-cols-2 gap-8 sm:grid-cols-4">
|
||
{columns.map((column) => (
|
||
<nav key={column.title} aria-label={column.title}>
|
||
<h2 className="text-sm font-semibold text-ink">{column.title}</h2>
|
||
<ul className="mt-2 space-y-0">
|
||
{column.links.map((link) => (
|
||
<li key={link.href}>
|
||
{link.external ? (
|
||
<a
|
||
href={link.href}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
className="inline-flex min-h-11 items-center gap-1 text-sm text-muted transition-colors hover:text-accent"
|
||
>
|
||
{link.label}
|
||
<ArrowUpRight className="h-3 w-3" aria-hidden="true" />
|
||
</a>
|
||
) : (
|
||
<Link href={getLinkHref(link.href)} className="inline-flex min-h-11 min-w-11 items-center text-sm text-muted transition-colors hover:text-accent">
|
||
{link.label}
|
||
</Link>
|
||
)}
|
||
</li>
|
||
))}
|
||
</ul>
|
||
</nav>
|
||
))}
|
||
|
||
<div>
|
||
<h2 className="text-sm font-semibold text-ink">{isPt ? "Autor" : isEs ? "Autor" : isFr ? "Auteur" : isZh ? "作者" : isDe ? "Autor" : "Author"}</h2>
|
||
<p className="mt-4 text-sm leading-relaxed text-muted">
|
||
Lucas Rayan Guerra
|
||
<br />
|
||
<span className="text-xs text-faint">Ciência Embarcada</span>
|
||
</p>
|
||
<div className="mt-4 flex items-center gap-2">
|
||
<a
|
||
href={SITE.repositorio}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
aria-label={
|
||
isPt
|
||
? "Gitea do projeto (abre em nova aba)"
|
||
: isEs
|
||
? "Gitea del proyecto (abre en una pestaña nueva)"
|
||
: isFr
|
||
? "Gitea du projet (ouvre un nouvel onglet)"
|
||
: isZh ? "项目 Gitea(在新标签页打开)" : isDe
|
||
? "Projekt-Gitea (öffnet in neuem Tab)"
|
||
: "Project Gitea (opens in new tab)"
|
||
}
|
||
className="grid h-11 w-11 place-items-center rounded-full border border-line text-ink transition-colors hover:border-line-strong hover:bg-surface"
|
||
>
|
||
<GiteaMark className="h-4 w-4" />
|
||
</a>
|
||
<a
|
||
href={SITE.autorLinkedin}
|
||
target="_blank"
|
||
rel="noopener noreferrer"
|
||
aria-label={
|
||
isPt
|
||
? "LinkedIn do autor (abre em nova aba)"
|
||
: isEs
|
||
? "LinkedIn del autor (abre en una pestaña nueva)"
|
||
: isFr
|
||
? "LinkedIn de l'auteur (ouvre un nouvel onglet)"
|
||
: isZh ? "作者 LinkedIn(在新标签页打开)" : isDe
|
||
? "LinkedIn des Autors (öffnet in neuem Tab)"
|
||
: "Author LinkedIn (opens in new tab)"
|
||
}
|
||
className="grid h-11 w-11 place-items-center rounded-full border border-line text-ink transition-colors hover:border-line-strong hover:bg-surface"
|
||
>
|
||
<svg className="h-4 w-4" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||
<path d="M4.98 3.5a2.5 2.5 0 1 1 0 5.001 2.5 2.5 0 0 1 0-5zM3 8.98h4v12H3v-12zm6.5 0h3.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" />
|
||
</svg>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="mt-14 flex flex-col gap-4 border-t border-line pt-6 text-xs leading-relaxed text-faint md:flex-row md:items-center md:justify-between">
|
||
<p>
|
||
© {year}{" "}
|
||
{isPt
|
||
? "ESPDocs. Projeto independente, sem afiliação com a Espressif Systems."
|
||
: isEs
|
||
? "ESPDocs. Proyecto independiente, sin afiliación con Espressif Systems."
|
||
: isFr
|
||
? "ESPDocs. Projet indépendant, sans affiliation avec Espressif Systems."
|
||
: isZh ? "ESPDocs。独立项目,与乐鑫(Espressif Systems)无任何关联。" : isDe
|
||
? "ESPDocs. Unabhängiges Projekt, nicht verbunden mit Espressif Systems."
|
||
: "ESPDocs. Independent project, not affiliated with Espressif Systems."}
|
||
</p>
|
||
<p className="flex flex-wrap items-center gap-x-5 gap-y-2">
|
||
<a href={SITE.blog} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center gap-1 transition-colors hover:text-accent">
|
||
Ciência Embarcada
|
||
<ArrowUpRight className="h-3 w-3" aria-hidden="true" />
|
||
</a>
|
||
<a href={SITE.autorUrl} target="_blank" rel="noopener noreferrer" className="inline-flex min-h-11 items-center gap-1 transition-colors hover:text-accent">
|
||
lucasrguerra.dev.br
|
||
<ArrowUpRight className="h-3 w-3" aria-hidden="true" />
|
||
</a>
|
||
<span>
|
||
{isPt
|
||
? "Fontes oficiais: Espressif Systems."
|
||
: isEs
|
||
? "Fuentes oficiales: Espressif Systems."
|
||
: isFr
|
||
? "Sources officielles : Espressif Systems."
|
||
: isZh ? "官方资料来源:乐鑫(Espressif Systems)。" : isDe
|
||
? "Offizielle Quellen: Espressif Systems."
|
||
: "Official sources: Espressif Systems."}
|
||
</span>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
);
|
||
}
|