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:
@@ -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],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user