Files
ESPDocs/components/PageHero.jsx
T
Lucas RayanandClaude Sonnet 5.5 5a9fe676fc
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
feat(i18n): Simplified Chinese (zh-CN), search answers per locale, fr/de/es data fixes
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-01 23:28:39 -03:00

105 lines
3.2 KiB
React

import Link from "next/link";
/**
* Abertura padrão das páginas internas: trilha, rótulo, título, frase de apoio
* e ações. Mesma voz da /livro e da home, para que nenhuma página pareça
* de outro produto.
*/
export default function PageHero({
trail = [],
icon: Icon,
label,
title,
lede,
align = "left",
children,
isEn: isEnProp,
isEs: isEsProp,
isFr: isFrProp,
isDe: isDeProp,
isZh: isZhProp,
locale: localeProp,
}) {
const center = align === "center";
const isEn =
isEnProp !== undefined
? isEnProp
: localeProp
? localeProp === "en"
: trail.some((t) => t.isEn || (t.href && t.href.startsWith("/en")));
const isEs =
isEsProp !== undefined
? isEsProp
: localeProp
? localeProp === "es"
: trail.some((t) => t.isEs || (t.href && t.href.startsWith("/es")));
const isFr =
isFrProp !== undefined
? isFrProp
: localeProp
? localeProp === "fr"
: trail.some((t) => t.isFr || (t.href && t.href.startsWith("/fr")));
const isDe =
isDeProp !== undefined
? isDeProp
: localeProp
? localeProp === "de"
: trail.some((t) => t.isDe || (t.href && t.href.startsWith("/de")));
const isZh =
isZhProp !== undefined
? isZhProp
: localeProp
? localeProp === "zh-CN"
: trail.some((t) => t.isZh || (t.href && t.href.startsWith("/zh-CN")));
const homeHref = isEn ? "/en" : isEs ? "/es" : isFr ? "/fr" : isZh ? "/zh-CN" : isDe ? "/de" : "/";
const homeLabel = isEn ? "Home" : isEs ? "Inicio" : isFr ? "Accueil" : isZh ? "首页" : isDe ? "Startseite" : "Início";
const breadcrumbAria = isEn
? "Breadcrumb navigation"
: isEs
? "Navegación por migas de pan"
: isFr
? "Fil d'Ariane"
: isZh ? "面包屑导航" : isDe
? "Brotkrumennavigation"
: "Trilha de navegação";
return (
<section className="shell pt-8 sm:pt-12">
{trail.length > 0 && (
<nav aria-label={breadcrumbAria} className="flex flex-wrap items-center gap-2 text-sm text-muted">
<Link href={homeHref} className="inline-flex min-h-11 min-w-11 items-center justify-center transition-colors hover:text-accent">
{homeLabel}
</Link>
{trail.map((item, i) => (
<span key={item.label} className="flex min-h-11 items-center gap-2">
<span aria-hidden="true" className="text-line-strong">/</span>
{item.href && i < trail.length - 1 ? (
<Link href={item.href} className="inline-flex min-h-11 min-w-11 items-center justify-center transition-colors hover:text-accent">
{item.label}
</Link>
) : (
<span aria-current="page" className="text-ink">
{item.label}
</span>
)}
</span>
))}
</nav>
)}
<div className={`${trail.length ? "mt-8 sm:mt-10" : ""} max-w-3xl ${center ? "mx-auto text-center" : ""}`}>
{label && (
<span className="chip chip-accent">
{Icon && <Icon className="h-3.5 w-3.5" aria-hidden="true" />}
{label}
</span>
)}
<h1 className={`page-title ${label ? "mt-5" : ""}`}>{title}</h1>
{lede && <p className={`lede mt-5 max-w-2xl ${center ? "mx-auto" : ""}`}>{lede}</p>}
{children && <div className={`mt-7 flex flex-wrap gap-3 ${center ? "justify-center" : ""}`}>{children}</div>}
</div>
</section>
);
}