From f1f6f25574e1fa5c78221be6e591317bc1113ac3 Mon Sep 17 00:00:00 2001 From: Christian Johannesen Date: Sun, 18 Oct 2026 17:25:16 +0200 Subject: [PATCH] fix(i18n): localize topic metadata and footer --- apps/web/src/features/topic/TopicPage.tsx | 2 +- apps/web/src/store/preferences.ts | 4 ++-- apps/web/src/ui/AppLayout.tsx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/web/src/features/topic/TopicPage.tsx b/apps/web/src/features/topic/TopicPage.tsx index 973523a..3464672 100644 --- a/apps/web/src/features/topic/TopicPage.tsx +++ b/apps/web/src/features/topic/TopicPage.tsx @@ -17,7 +17,7 @@ export function TopicPage() { {t.library}
{topic.domains.join(' · ')}

{topic.title}

{topic.summary}

{session.data ? :

{t.loginHint}

}
-
Type
{topic.type}
Version
{topic.currentVersion ?? 'Living standard'}
Revision
#{topic.revisionNumber}
Verificeret
{new Date(topic.verifiedAt).toLocaleDateString('da-DK')}
+
{t.type}
{topic.type}
{t.version}
{topic.currentVersion ?? 'Living standard'}
{t.revision}
#{topic.revisionNumber}
{t.verified}
{new Date(topic.verifiedAt).toLocaleDateString(language === 'da' ? 'da-DK' : 'en-GB')}
{t.overview}{t.depth}{t.sources} {topic.sources.length} diff --git a/apps/web/src/store/preferences.ts b/apps/web/src/store/preferences.ts index d860d1a..f3ea3d5 100644 --- a/apps/web/src/store/preferences.ts +++ b/apps/web/src/store/preferences.ts @@ -6,7 +6,7 @@ interface Preferences { language: Language; setLanguage(language: Language): voi export const usePreferences = create()(persist((set) => ({ language: 'da', setLanguage: (language) => set({ language }) }), { name: 'tech-library-preferences' })); const messages = { - da: { library: 'Bibliotek', favorites: 'Favoritter', editorial: 'Redaktion', login: 'Log ind', logout: 'Log ud', register: 'Opret konto', username: 'Brugernavn', password: 'Adgangskode', sourceLibrary: 'Et levende teknisk opslagsværk', headline: 'Forstå teknologien.', headlineAccent: 'Se hele sammenhængen.', intro: 'Kurateret viden om moderne web-, app- og systemudvikling — fra første begreb til arkitekturbeslutning. Hvert udsagn føres tilbage til sin kilde.', search: 'Søg efter React, databaser, sikkerhed…', curated: 'kuraterede emner', official: 'Officielle primærkilder', verified: 'Løbende verificeret', filters: 'Filtrér', reset: 'Nulstil', domain: 'Fagområde', type: 'Type', allTopics: 'Alle emner', results: 'resultater', loading: 'Henter biblioteket…', noResults: 'Ingen emner matcher din søgning.', sources: 'Kilder', overview: 'Overblik', depth: 'Fordybelse', favorite: 'Føj til favoritter', unfavorite: 'Fjern fra favoritter', loginHint: 'Log ind for at gemme favoritter.', accountTitle: 'Din Tech Library-konto', noFavorites: 'Du har endnu ingen favoritter.' }, - en: { library: 'Library', favorites: 'Favorites', editorial: 'Editorial', login: 'Log in', logout: 'Log out', register: 'Create account', username: 'Username', password: 'Password', sourceLibrary: 'A living technical reference', headline: 'Understand the technology.', headlineAccent: 'See the whole picture.', intro: 'Curated knowledge about modern web, app, and systems development — from first concepts to architecture decisions. Every claim traces back to its source.', search: 'Search for React, databases, security…', curated: 'curated topics', official: 'Official primary sources', verified: 'Continuously verified', filters: 'Filter', reset: 'Reset', domain: 'Domain', type: 'Type', allTopics: 'All topics', results: 'results', loading: 'Loading the library…', noResults: 'No topics match your search.', sources: 'Sources', overview: 'Overview', depth: 'In depth', favorite: 'Add to favorites', unfavorite: 'Remove from favorites', loginHint: 'Log in to save favorites.', accountTitle: 'Your Tech Library account', noFavorites: 'You do not have any favorites yet.' } + da: { library: 'Bibliotek', favorites: 'Favoritter', editorial: 'Redaktion', login: 'Log ind', logout: 'Log ud', register: 'Opret konto', username: 'Brugernavn', password: 'Adgangskode', sourceLibrary: 'Et levende teknisk opslagsværk', headline: 'Forstå teknologien.', headlineAccent: 'Se hele sammenhængen.', intro: 'Kurateret viden om moderne web-, app- og systemudvikling — fra første begreb til arkitekturbeslutning. Hvert udsagn føres tilbage til sin kilde.', search: 'Søg efter React, databaser, sikkerhed…', curated: 'kuraterede emner', official: 'Officielle primærkilder', verified: 'Verificeret', filters: 'Filtrér', reset: 'Nulstil', domain: 'Fagområde', type: 'Type', version: 'Version', revision: 'Revision', allTopics: 'Alle emner', results: 'resultater', loading: 'Henter biblioteket…', noResults: 'Ingen emner matcher din søgning.', sources: 'Kilder', overview: 'Overblik', depth: 'Fordybelse', favorite: 'Føj til favoritter', unfavorite: 'Fjern fra favoritter', loginHint: 'Log ind for at gemme favoritter.', accountTitle: 'Din Tech Library-konto', noFavorites: 'Du har endnu ingen favoritter.', footer: 'Levende viden. Dokumenterede kilder.' }, + en: { library: 'Library', favorites: 'Favorites', editorial: 'Editorial', login: 'Log in', logout: 'Log out', register: 'Create account', username: 'Username', password: 'Password', sourceLibrary: 'A living technical reference', headline: 'Understand the technology.', headlineAccent: 'See the whole picture.', intro: 'Curated knowledge about modern web, app, and systems development — from first concepts to architecture decisions. Every claim traces back to its source.', search: 'Search for React, databases, security…', curated: 'curated topics', official: 'Official primary sources', verified: 'Verified', filters: 'Filter', reset: 'Reset', domain: 'Domain', type: 'Type', version: 'Version', revision: 'Revision', allTopics: 'All topics', results: 'results', loading: 'Loading the library…', noResults: 'No topics match your search.', sources: 'Sources', overview: 'Overview', depth: 'In depth', favorite: 'Add to favorites', unfavorite: 'Remove from favorites', loginHint: 'Log in to save favorites.', accountTitle: 'Your Tech Library account', noFavorites: 'You do not have any favorites yet.', footer: 'Living knowledge. Documented sources.' } } as const; export const useText = () => { const language = usePreferences((state) => state.language); return { language, t: messages[language] }; }; diff --git a/apps/web/src/ui/AppLayout.tsx b/apps/web/src/ui/AppLayout.tsx index b757379..d253510 100644 --- a/apps/web/src/ui/AppLayout.tsx +++ b/apps/web/src/ui/AppLayout.tsx @@ -10,7 +10,7 @@ export function AppLayout() { const { language, t } = useText(); const setLanguage = usePreferences((state) => state.setLanguage); const client = useQueryClient(); const session = useQuery({ queryKey: ['user-session'], queryFn: userApi.me, retry: false }); const logout = useMutation({ mutationFn: () => userApi.logout(session.data!.csrfToken), onSuccess: () => { client.setQueryData(['user-session'], null); client.invalidateQueries({ queryKey: ['topics'] }); } }); - return
TLTech Library
Living knowledge. Documented sources.Source
; + return
TLTech Library
; } function AccountDialog() {