feat: i18n seam — typed t() + en dictionary

Nav and header wired as proof. Full string extraction deferred until a
second locale exists; CONTRIBUTING records the convention.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-09-21 19:45:46 +02:00
1 parent a89a81d46c
commit 88a8210bf8
5 files changed
+58 -15

No files matched your search

+27
View File
@@ -0,0 +1,27 @@
// English source strings. Flat keys, dot-separated namespaces.
// Add a locale by copying this file — keys must match exactly.
export const en = {
"nav.board": "Board",
"nav.monitors": "Monitors",
"nav.domains": "Domains",
"nav.systems": "Systems",
"nav.incidents": "Incidents",
"nav.status": "Status",
"header.search": "Search (⌘K)",
"header.settings": "Settings",
"header.theme": "Toggle theme",
"header.addWidget": "Add widget",
"header.addService": "Add service",
"header.widget": "Widget",
"common.add": "Add",
"common.edit": "Edit",
"common.delete": "Delete",
"common.cancel": "Cancel",
"common.save": "Save",
"common.test": "Test",
"common.loading": "Loading…",
} as const;
export type Key = keyof typeof en;
+13
View File
@@ -0,0 +1,13 @@
import { en, type Key } from "@/i18n/en";
export type { Key } from "@/i18n/en";
// i18n seam: dictionaries are plain objects keyed by dotted names. `t` is a
// typed lookup that falls back to the key itself, so a missing translation
// renders the key — loud in dev, never a crash. Locales beyond `en` plug in
// here later (settings key + lazy import); nothing else changes.
const dict: Record<Key, string> = en;
export function t(key: Key): string {
return dict[key] ?? key;
}