Refactor locale system: align types with usage, add CMS formatting docs (#59)

* Initial plan

* Initial analysis: understanding locale system issues

Co-authored-by: denshooter <44590296+denshooter@users.noreply.github.com>

* Fix translation types to match actual component usage

Co-authored-by: denshooter <44590296+denshooter@users.noreply.github.com>

* Add comprehensive locale system documentation and fix API route types

Co-authored-by: denshooter <44590296+denshooter@users.noreply.github.com>

* Address code review feedback: improve readability and translate comments to English

Co-authored-by: denshooter <44590296+denshooter@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: denshooter <44590296+denshooter@users.noreply.github.com>
This commit is contained in:
Copilot
2026-01-22 21:25:41 +01:00
committed by GitHub
parent 37a1bc4e18
commit 7604e00e0f
9 changed files with 1452 additions and 342 deletions

View File

@@ -26,170 +26,181 @@ export async function getNavTranslations(locale: string): Promise<NavTranslation
}
export async function getFooterTranslations(locale: string): Promise<FooterTranslations> {
const [role, description, privacy, imprint, copyright, madeWith, resetConsent] = await Promise.all([
const [
role,
madeIn,
legalNotice,
privacyPolicy,
privacySettings,
privacySettingsTitle,
builtWith
] = await Promise.all([
getLocalizedMessage('footer.role', locale),
getLocalizedMessage('footer.description', locale),
getLocalizedMessage('footer.links.privacy', locale),
getLocalizedMessage('footer.links.imprint', locale),
getLocalizedMessage('footer.copyright', locale),
getLocalizedMessage('footer.madeWith', locale),
getLocalizedMessage('footer.resetConsent', locale),
getLocalizedMessage('footer.madeIn', locale),
getLocalizedMessage('footer.legalNotice', locale),
getLocalizedMessage('footer.privacyPolicy', locale),
getLocalizedMessage('footer.privacySettings', locale),
getLocalizedMessage('footer.privacySettingsTitle', locale),
getLocalizedMessage('footer.builtWith', locale),
]);
return {
role,
description,
links: { privacy, imprint },
copyright,
madeWith,
resetConsent,
madeIn,
legalNotice,
privacyPolicy,
privacySettings,
privacySettingsTitle,
builtWith,
};
}
export async function getHeroTranslations(locale: string): Promise<HeroTranslations> {
const keys = [
'home.hero.greeting',
'home.hero.name',
'home.hero.role',
'home.hero.description',
'home.hero.ctaWork',
'home.hero.ctaContact',
'home.hero.features.f1',
'home.hero.features.f2',
'home.hero.features.f3',
'home.hero.scrollDown',
];
const values = await Promise.all(keys.map(key => getLocalizedMessage(key, locale)));
return {
greeting: values[0],
name: values[1],
role: values[2],
description: values[3],
cta: {
projects: values[4],
contact: values[5],
},
description: values[0],
ctaWork: values[1],
ctaContact: values[2],
features: {
f1: values[6],
f2: values[7],
f3: values[8],
f1: values[3],
f2: values[4],
f3: values[5],
},
scrollDown: values[9],
};
}
export async function getAboutTranslations(locale: string): Promise<AboutTranslations> {
// Diese Keys sind NICHT korrekt - wir nutzen nur für Type Compatibility
// Die About Component nutzt actually: title, p1, p2, p3, hobbiesTitle, hobbies.*, techStackTitle, techStack.*
// Lade alle benötigten Keys
const keys = [
'home.about.title',
'home.about.description',
'home.about.techStack.title',
'home.about.techStack.categories.frontendMobile',
'home.about.techStack.categories.backendDevops',
'home.about.techStack.categories.toolsAutomation',
'home.about.techStack.categories.securityAdmin',
'home.about.techStack.items.selfHostedServices',
'home.about.hobbiesTitle', // Nicht "interests.title"!
'home.about.hobbies.selfHosting',
'home.about.hobbies.gaming',
'home.about.hobbies.gameServers',
'home.about.hobbies.jogging',
'home.about.p1',
'home.about.p2',
'home.about.p3',
'home.about.funFactTitle',
'home.about.funFactBody',
'home.about.techStackTitle',
'home.about.techStack.categories.frontendMobile',
'home.about.techStack.categories.backendDevops',
'home.about.techStack.categories.toolsAutomation',
'home.about.techStack.categories.securityAdmin',
'home.about.techStack.items.selfHostedServices',
'home.about.hobbiesTitle',
'home.about.hobbies.selfHosting',
'home.about.hobbies.gaming',
'home.about.hobbies.gameServers',
'home.about.hobbies.jogging',
];
const values = await Promise.all(keys.map(key => getLocalizedMessage(key, locale)));
return {
title: values[0],
description: values[1],
p1: values[1],
p2: values[2],
p3: values[3],
funFactTitle: values[4],
funFactBody: values[5],
techStackTitle: values[6],
techStack: {
title: values[2],
categories: {
frontendMobile: values[3],
backendDevops: values[4],
toolsAutomation: values[5],
securityAdmin: values[6],
frontendMobile: values[7],
backendDevops: values[8],
toolsAutomation: values[9],
securityAdmin: values[10],
},
items: {
selfHostedServices: values[7],
selfHostedServices: values[11],
},
},
interests: {
title: values[8], // hobbiesTitle
cybersecurity: {
title: values[9], // hobbies.selfHosting
description: values[10], // hobbies.gaming
},
selfHosting: {
title: values[11], // hobbies.gameServers
description: values[12], // hobbies.jogging
},
gaming: {
title: values[13], // p1
description: values[14], // p2
},
automation: {
title: values[15], // p3
description: values[16], // funFactTitle
},
hobbiesTitle: values[12],
hobbies: {
selfHosting: values[13],
gaming: values[14],
gameServers: values[15],
jogging: values[16],
},
};
}
export async function getProjectsTranslations(locale: string): Promise<ProjectsTranslations> {
const [title, viewAll] = await Promise.all([
const [title, subtitle, viewAll] = await Promise.all([
getLocalizedMessage('home.projects.title', locale),
getLocalizedMessage('home.projects.subtitle', locale),
getLocalizedMessage('home.projects.viewAll', locale),
]);
return { title, viewAll };
return { title, subtitle, viewAll };
}
export async function getContactTranslations(locale: string): Promise<ContactTranslations> {
const keys = [
'home.contact.title',
'home.contact.description',
'home.contact.form.name',
'home.contact.form.email',
'home.contact.form.message',
'home.contact.form.send',
'home.contact.subtitle',
'home.contact.getInTouch',
'home.contact.getInTouchBody',
'home.contact.form.title',
'home.contact.form.sending',
'home.contact.form.success',
'home.contact.form.error',
'home.contact.info.title',
'home.contact.form.send',
'home.contact.form.placeholders.name',
'home.contact.form.placeholders.email',
'home.contact.form.placeholders.subject',
'home.contact.form.placeholders.message',
'home.contact.form.errors.nameRequired',
'home.contact.form.errors.nameMin',
'home.contact.form.errors.emailRequired',
'home.contact.form.errors.emailInvalid',
'home.contact.form.errors.subjectRequired',
'home.contact.form.errors.subjectMin',
'home.contact.form.errors.messageRequired',
'home.contact.form.errors.messageMin',
'home.contact.form.characters',
'home.contact.info.email',
'home.contact.info.response',
'home.contact.info.emailLabel',
'home.contact.info.location',
'home.contact.info.locationValue',
];
const values = await Promise.all(keys.map(key => getLocalizedMessage(key, locale)));
return {
title: values[0],
description: values[1],
subtitle: values[1],
getInTouch: values[2],
getInTouchBody: values[3],
form: {
name: values[2],
email: values[3],
message: values[4],
send: values[5],
sending: values[6],
success: values[7],
error: values[8],
title: values[4],
sending: values[5],
send: values[6],
placeholders: {
name: values[7],
email: values[8],
subject: values[9],
message: values[10],
},
errors: {
nameRequired: values[11],
nameMin: values[12],
emailRequired: values[13],
emailInvalid: values[14],
subjectRequired: values[15],
subjectMin: values[16],
messageRequired: values[17],
messageMin: values[18],
},
characters: values[19],
},
info: {
title: values[9],
email: values[10],
response: values[11],
emailLabel: values[12],
email: values[20],
location: values[21],
locationValue: values[22],
},
};
}