feat(i18n): the interface speaks both languages
The account has had a `locale` since the beginning and it only chose which grammar quick add read a line with — so picking English changed nothing anybody could see, and the field said so honestly: "Sprog i hurtig tilføjelse". It says "Sprog" now, because it means it. Every component goes through `t()`. Danish is the source: a key missing from English falls through to Danish rather than to the key, because a Danish sentence in an English screen can be read and `settings.notifications.title` cannot. `tag()` is the single place `Intl` is asked. Before, `'da-DK'` was written into a dozen components, and that is the half of a translation that gets left behind — an English interface still saying "24. aug." is exactly the shape of a job half done. There is a smoke test that switches to English and refuses to see a Danish month name in the calendar's heading. Colour and theme names are keys now. `colors.js` keeps its ids untouched — they are what the database stores, and `internal/store` reads them out of that file — but `name` is `'color.tomato'`, resolved where it is drawn. The Inbox keeps its name. It is a project row the server creates at signup, not a string in the interface, and it can be renamed like any other project. Four copies of "3 hours ago" became one, in `web/src/lib/when.js`. They had already drifted: one said "aldrig logget ind", another "aldrig", and two stopped at days where the others carried on to a date. Routes stay Danish. `/indstillinger`, `/projekt`, `/uddelegeret` are bookmarks and they are in every smoke test; translating them buys nothing and costs both. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
e3c7fc792a
commit
4d8b70918b
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
import { page } from '$app/stores';
|
||||
import { app } from '$lib/stores.svelte.js';
|
||||
import { t } from '$lib/i18n.svelte.js';
|
||||
|
||||
let { children } = $props();
|
||||
|
||||
@@ -20,19 +21,19 @@
|
||||
// than disabled: this is not a feature to upsell, it is one that does not
|
||||
// apply to you.
|
||||
let sections = $derived([
|
||||
{ href: '/indstillinger', label: 'Konto' },
|
||||
{ href: '/indstillinger/notifikationer', label: 'Notifikationer' },
|
||||
{ href: '/indstillinger/integrationer', label: 'Integrationer' },
|
||||
{ href: '/indstillinger/ai', label: 'AI' },
|
||||
{ href: '/indstillinger/tokens', label: 'API-tokens' },
|
||||
{ href: '/indstillinger', label: t('settings.tab.account') },
|
||||
{ href: '/indstillinger/notifikationer', label: t('settings.tab.notifications') },
|
||||
{ href: '/indstillinger/integrationer', label: t('settings.tab.integrations') },
|
||||
{ href: '/indstillinger/ai', label: t('settings.tab.ai') },
|
||||
{ href: '/indstillinger/tokens', label: t('settings.tab.tokens') },
|
||||
...(app.user?.is_admin
|
||||
? [
|
||||
{ href: '/indstillinger/brugere', label: 'Brugere' },
|
||||
{ href: '/indstillinger/historik', label: 'Historik' },
|
||||
{ href: '/indstillinger/fejl', label: 'Fejl' }
|
||||
{ href: '/indstillinger/brugere', label: t('settings.tab.users') },
|
||||
{ href: '/indstillinger/historik', label: t('settings.tab.history') },
|
||||
{ href: '/indstillinger/fejl', label: t('settings.tab.errors') }
|
||||
]
|
||||
: []),
|
||||
{ href: '/indstillinger/data', label: 'Data og skabeloner' }
|
||||
{ href: '/indstillinger/data', label: t('settings.tab.data') }
|
||||
]);
|
||||
|
||||
let current = $derived($page.url.pathname.replace(/\/$/, '') || '/indstillinger');
|
||||
@@ -40,10 +41,10 @@
|
||||
|
||||
<div class="settings">
|
||||
<header>
|
||||
<h1>Indstillinger</h1>
|
||||
<h1>{t('settings.title')}</h1>
|
||||
</header>
|
||||
|
||||
<nav aria-label="Indstillinger">
|
||||
<nav aria-label={t('settings.title')}>
|
||||
{#each sections as section (section.href)}
|
||||
<a href={section.href} class:active={current === section.href}>{section.label}</a>
|
||||
{/each}
|
||||
|
||||
Reference in New Issue
Block a user