User: "quero que o usuário possa escolher o idioma na navbar, e então leia
o site todo em seu idioma."
The locale infrastructure already existed (cookie + getLocale() + every
page renders bilingual). The toggle only lived as a subtle floating
control bottom-left. This surfaces it in the navbars where users expect
it, and confirms whole-site language switching.
locale-toggle-client.tsx
- New variant="navbar": gold-amber pill matching the magazine theme
(PT | EN, active = solid gold). Retro green variant kept for the
floating fallback.
- Guard: clicking the already-active language is a no-op.
- aria-pressed on each button for a11y.
locale-toggle.tsx: LocaleToggle gains variant passthrough.
site-header.tsx: <LocaleToggle variant="navbar"> added to the main nav
(homepage + /sightings /witnesses /objects /locations /operations
/documents).
bureau-nav.tsx: optional `locale` prop renders the same toggle pushed
to the right (ml-auto) on /bureau, /c/[slug], /h/[id], /jobs/[id].
All four callers now pass locale (getLocale added to h + jobs pages).
Cookie-based: switching sets `locale` cookie + router.refresh(); the
server re-renders every component through getLocale(), so the entire
page — headers, hero, summaries, case narratives, entity cards — flips
language in one click. The floating bottom-left toggle stays as a global
fallback for pages without a navbar (/d, /e, /search, /graph).
Also this session: Sun-Tzu smoke succeeded on the refreshed
CLAUDE_CODE_OAUTH_TOKEN — brief B-0001 written for the green fireballs
("bolas de fogo verdes confinadas ao corredor nuclear... cor espectral
e trajetória quase horizontal que os próprios analistas consideraram
irreconciliáveis com meteoros naturais", 3 pillars). Bulk entity
enrichment resumed in the background.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
/**
|
|
* BureauNav — top navigation bar present on every bureau page.
|
|
*
|
|
* Solves "I'm stuck on this page, there's no way back" UX. Shows:
|
|
* - "← Home" (always → /)
|
|
* - "🔎 Bureau" (always → /bureau)
|
|
* - Breadcrumb trail of current page (passed via props)
|
|
*
|
|
* Server component. No client-side history needed because the parent links
|
|
* are deterministic (every bureau page has a known parent in the hierarchy).
|
|
*/
|
|
import Link from "next/link";
|
|
import { ArrowLeft, Home } from "lucide-react";
|
|
import { LocaleToggle, type Locale } from "./locale-toggle";
|
|
|
|
export interface Crumb {
|
|
/** Display label. */
|
|
label: string;
|
|
/** When omitted the crumb is rendered as the current page (no link). */
|
|
href?: string;
|
|
}
|
|
|
|
export function BureauNav({ crumbs, locale }: { crumbs: Crumb[]; locale?: Locale }) {
|
|
return (
|
|
<nav className="sticky top-0 z-30 bg-[#0a0e1a]/95 backdrop-blur border-b border-[rgba(224,192,128,0.18)]">
|
|
<div className="mx-auto max-w-6xl px-4 py-2 flex items-center gap-3 flex-wrap text-[12px] font-mono">
|
|
<Link
|
|
href="/"
|
|
className="inline-flex items-center gap-1 px-2 py-1 rounded border border-[rgba(127,219,255,0.30)] text-[#7fdbff] hover:bg-[rgba(127,219,255,0.08)]"
|
|
aria-label="Voltar para a home"
|
|
>
|
|
<ArrowLeft size={12} />
|
|
<Home size={12} />
|
|
<span>home</span>
|
|
</Link>
|
|
|
|
<Link
|
|
href="/bureau"
|
|
className="inline-flex items-center gap-1 px-2 py-1 rounded border border-[#e0c080] text-[#e0c080] hover:bg-[rgba(224,192,128,0.08)]"
|
|
aria-label="Hub do bureau"
|
|
>
|
|
🔎 <span>bureau</span>
|
|
</Link>
|
|
|
|
{crumbs.length > 0 && (
|
|
<div className="text-[11px] text-[#5a6678] flex items-center gap-1.5 flex-wrap">
|
|
<span className="mx-1">/</span>
|
|
{crumbs.map((c, i) => (
|
|
<span key={`${c.label}-${i}`} className="inline-flex items-center gap-1.5">
|
|
{c.href ? (
|
|
<Link href={c.href} className="hover:text-[#7fdbff]">{c.label}</Link>
|
|
) : (
|
|
<span className="text-[#e7ecf3]">{c.label}</span>
|
|
)}
|
|
{i < crumbs.length - 1 && <span>/</span>}
|
|
</span>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
{locale && (
|
|
<span className="ml-auto">
|
|
<LocaleToggle current={locale} variant="navbar" />
|
|
</span>
|
|
)}
|
|
</div>
|
|
</nav>
|
|
);
|
|
}
|