Files
portfolio/lib/translations-loader.ts
T
denshooter 229715235f feat: plakat redesign phase 1 (tokens, fonts, poster hero, header)
- New design tokens: signal red, ink and paper as RGB channels; ink and paper
  swap roles in dark mode so every component inverts cleanly
- Fonts via next/font: Bricolage Grotesque (with wdth/opsz axes), Geist,
  Geist Mono; drop Inter and Playfair
- Poster hero: kicker, giant DK0 wordmark that reacts to pointer distance
  (weight and width through a damped spring, desktop only, off for reduced
  motion), claim as h1, intro with thesis countdown, marquee strip
- Header in poster style: transparent over the red hero, paper strip with
  ink rule when scrolled or on subpages; drawer menu restyled
- Remove wavy SVG separators, CSS shader gradient, background blobs and
  unused providers that caused the pink/purple bands between sections
- Drop the global p/span/div color override so colors inherit properly
- New hero texts in de/en, tests and i18n key check updated

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 23:48:24 +02:00

193 lines
5.5 KiB
TypeScript

import { getLocalizedMessage } from '@/lib/i18n-loader';
import type {
NavTranslations,
FooterTranslations,
AboutTranslations,
ProjectsTranslations,
ContactTranslations,
ConsentTranslations,
} from '@/types/translations';
/**
* Lädt alle Translations für eine Section aus Directus
* Nutzt optimierte Batch-Abfragen wo möglich
*/
export async function getNavTranslations(locale: string): Promise<NavTranslations> {
const [home, about, projects, contact] = await Promise.all([
getLocalizedMessage('nav.home', locale),
getLocalizedMessage('nav.about', locale),
getLocalizedMessage('nav.projects', locale),
getLocalizedMessage('nav.contact', locale),
]);
return { home, about, projects, contact };
}
export async function getFooterTranslations(locale: string): Promise<FooterTranslations> {
const [
role,
madeIn,
legalNotice,
privacyPolicy,
privacySettings,
privacySettingsTitle,
builtWith
] = await Promise.all([
getLocalizedMessage('footer.role', 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,
madeIn,
legalNotice,
privacyPolicy,
privacySettings,
privacySettingsTitle,
builtWith,
};
}
export async function getAboutTranslations(locale: string): Promise<AboutTranslations> {
const keys = [
'home.about.title',
'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],
p1: values[1],
p2: values[2],
p3: values[3],
funFactTitle: values[4],
funFactBody: values[5],
techStackTitle: values[6],
techStack: {
categories: {
frontendMobile: values[7],
backendDevops: values[8],
toolsAutomation: values[9],
securityAdmin: values[10],
},
items: {
selfHostedServices: values[11],
},
},
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, subtitle, viewAll] = await Promise.all([
getLocalizedMessage('home.projects.title', locale),
getLocalizedMessage('home.projects.subtitle', locale),
getLocalizedMessage('home.projects.viewAll', locale),
]);
return { title, subtitle, viewAll };
}
export async function getContactTranslations(locale: string): Promise<ContactTranslations> {
const keys = [
'home.contact.title',
'home.contact.subtitle',
'home.contact.getInTouch',
'home.contact.getInTouchBody',
'home.contact.form.title',
'home.contact.form.sending',
'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.location',
'home.contact.info.locationValue',
];
const values = await Promise.all(keys.map(key => getLocalizedMessage(key, locale)));
return {
title: values[0],
subtitle: values[1],
getInTouch: values[2],
getInTouchBody: values[3],
form: {
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: {
email: values[20],
location: values[21],
locationValue: values[22],
},
};
}
export async function getConsentTranslations(locale: string): Promise<ConsentTranslations> {
const [title, description, accept, decline] = await Promise.all([
getLocalizedMessage('consent.title', locale),
getLocalizedMessage('consent.description', locale),
getLocalizedMessage('consent.accept', locale),
getLocalizedMessage('consent.decline', locale),
]);
return { title, description, accept, decline };
}