feat: bilingual website (DE/EN) with language switcher
CI / TypeScript — type-check (push) Successful in 8s
CI / Publish — build & push image (push) Successful in 8s
CI / Deploy — pull & restart on host (push) Successful in 2s

Add LangContext with localStorage persistence (default: DE).
DE/EN toggle in Nav (top-right, before CTA button).

All pages translated:
- Home: all 8 sections incl. NIS2 block
- Features: all 13 sections with full German bullet points
- Drivers: headings and descriptions
- Getting Started (coming soon)
- Roadmap: bilingual data arrays inline (Planned + Under consideration)
- NIS2: full Art. 21 mapping, evidence blocks, coming-soon list

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Manivong
2026-06-28 17:00:22 +02:00
co-authored by Claude Sonnet 4.6
parent f194c379e4
commit d48c7143aa
11 changed files with 1011 additions and 618 deletions
+10 -19
View File
@@ -1,3 +1,5 @@
import { useLang } from '../context/LangContext'
type Cap = '✓' | '—'
interface Driver {
@@ -29,13 +31,7 @@ const DRIVERS: Driver[] = [
{ name: 'zyxel', deviceType: 'Zyxel switches', facts: '✓', interfaces: '✓', lldp: '✓', vlans: '✓', ssids: '—', health: '—', docker: '—', reboot: '—', configPush: '—', status: 'beta' },
]
const NAPALM_BUILTIN = [
'Cisco IOS',
'Cisco IOS-XE',
'Cisco NX-OS',
'Arista EOS',
'Juniper JunOS',
]
const NAPALM_BUILTIN = ['Arista EOS', 'Cisco IOS', 'Cisco IOS-XE', 'Cisco NX-OS', 'Juniper JunOS']
const CAPS: { key: keyof Driver; label: string }[] = [
{ key: 'facts', label: 'Facts' },
@@ -62,20 +58,18 @@ function StatusBadge({ status }: { status: 'stable' | 'beta' }) {
}
export default function Drivers() {
const { t } = useLang()
return (
<div className="py-16 md:py-24">
<div className="max-w-7xl mx-auto px-6">
<div className="mb-12">
<h1 className="text-4xl md:text-5xl font-bold text-slate-100 mb-4">Supported Devices</h1>
<p className="text-base text-slate-400 leading-relaxed max-w-xl">
netOrk ships with custom NAPALM drivers for 11 device types and supports all built-in NAPALM
drivers. Capability availability varies by driver.
</p>
<h1 className="text-4xl md:text-5xl font-bold text-slate-100 mb-4">{t.drivers.heading}</h1>
<p className="text-base text-slate-400 leading-relaxed max-w-xl">{t.drivers.sub}</p>
</div>
{/* Custom drivers table */}
<div className="mb-16 overflow-x-auto">
<h2 className="text-xl font-semibold text-slate-200 mb-4">Custom Drivers</h2>
<h2 className="text-xl font-semibold text-slate-200 mb-4">{t.drivers.customHeading}</h2>
<div className="rounded-xl border border-slate-800 overflow-hidden">
<table className="w-full text-sm">
<thead>
@@ -110,12 +104,9 @@ export default function Drivers() {
</div>
</div>
{/* NAPALM built-ins */}
<div>
<h2 className="text-xl font-semibold text-slate-200 mb-4">Built-in NAPALM Drivers</h2>
<p className="text-sm text-slate-400 mb-6">
All standard NAPALM drivers are supported. Capabilities depend on the upstream NAPALM implementation.
</p>
<h2 className="text-xl font-semibold text-slate-200 mb-4">{t.drivers.napalmHeading}</h2>
<p className="text-sm text-slate-400 mb-6">{t.drivers.napalmSub}</p>
<div className="flex flex-wrap gap-3">
{NAPALM_BUILTIN.map((name) => (
<span