Session 12: i18n (10 languages, cookie-based), Africa tier .99, locale switcher, RTL Arabic (1305 tests)

This commit is contained in:
Kev
2026-06-10 22:24:40 -04:00
parent e5c45ecc8e
commit d957dee17b
27 changed files with 1834 additions and 29 deletions
+21 -11
View File
@@ -4,20 +4,26 @@ import { useState } from 'react';
import { useAuth } from '@/contexts/AuthContext';
import Wordmark from '@/components/Wordmark';
import NotificationBell from '@/components/NotificationBell';
const NAV_LINKS = [
{ label: 'Read', href: '/scan' },
{ label: 'Tracker', href: '/tracker' },
{ label: 'Ledger', href: '/ledger' },
{ label: 'Pricing', href: '/#pricing' },
{ label: 'Blog', href: '/blog' },
];
import LocaleSwitcher from '@/components/LocaleSwitcher';
import { useT } from '@/contexts/LocaleContext';
export default function Nav() {
const { user, tier, scansRemaining, signOut } = useAuth();
const t = useT();
const [mobileOpen, setMobileOpen] = useState(false);
const [menuOpen, setMenuOpen] = useState(false);
// Session 12 — translation labels resolved at render time so a
// locale switch flips the nav without a code change. Hrefs stay
// English (the [locale]/ refactor is a future session).
const NAV_LINKS = [
{ label: t('nav.scan'), href: '/scan' },
{ label: t('nav.tracker'), href: '/tracker' },
{ label: t('nav.ledger'), href: '/ledger' },
{ label: t('nav.pricing'), href: '/pricing' },
{ label: 'Blog', href: '/blog' },
];
return (
<nav
style={{
@@ -108,6 +114,7 @@ export default function Nav() {
</span>
)}
<NotificationBell />
<LocaleSwitcher />
<button
onClick={() => setMenuOpen((o) => !o)}
aria-haspopup="menu"
@@ -180,9 +187,12 @@ export default function Nav() {
)}
</div>
) : (
<a href="/login" className="btn-primary" style={{ padding: '8px 16px', fontSize: 13 }}>
Log In
</a>
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
<LocaleSwitcher />
<a href="/login" className="btn-primary" style={{ padding: '8px 16px', fontSize: 13 }}>
{t('nav.login')}
</a>
</div>
)}
</div>