Keep/keep-notes/lib/i18n/load-translations.ts
sepehr ddb67ba9e5 fix: unify theme system - fix theme switching persistence
- Unified localStorage key to 'theme-preference' across all components
- Fixed header.tsx using wrong localStorage key ('theme' instead of 'theme-preference')
- Added localStorage hybrid persistence for instant theme changes
- Removed router.refresh() which was causing stale data revert
- Replaced Blue theme with Sepia
- Consolidated auth() calls to prevent race conditions
- Updated UserSettingsData types to include all themes
2026-01-18 22:33:41 +01:00

329 lines
7.1 KiB
TypeScript

/**
* Load translations from JSON files
*/
export type SupportedLanguage = 'en' | 'fr' | 'es' | 'de' | 'fa' | 'it' | 'pt' | 'ru' | 'zh' | 'ja' | 'ko' | 'ar' | 'hi' | 'nl' | 'pl'
export interface Translations {
auth: {
signIn: string
signUp: string
email: string
password: string
name: string
emailPlaceholder: string
passwordPlaceholder: string
namePlaceholder: string
passwordMinChars: string
resetPassword: string
resetPasswordInstructions: string
forgotPassword: string
noAccount: string
hasAccount: string
signInToAccount: string
createAccount: string
rememberMe: string
orContinueWith: string
}
sidebar: {
notes: string
reminders: string
labels: string
editLabels: string
archive: string
trash: string
}
notes: {
title: string
newNote: string
untitled: string
placeholder: string
markdownPlaceholder: string
titlePlaceholder: string
listItem: string
addListItem: string
newChecklist: string
add: string
adding: string
close: string
confirmDelete: string
confirmLeaveShare: string
sharedBy: string
leaveShare: string
delete: string
archive: string
unarchive: string
pin: string
unpin: string
color: string
changeColor: string
setReminder: string
setReminderButton: string
date: string
time: string
reminderDateTimeRequired: string
invalidDateTime: string
reminderMustBeFuture: string
reminderSet: string
addImage: string
addLink: string
linkAdded: string
linkMetadataFailed: string
linkAddFailed: string
invalidFileType: string
fileTooLarge: string
uploadFailed: string
contentOrMediaRequired: string
itemOrMediaRequired: string
noteCreated: string
noteCreateFailed: string
aiAssistant: string
changeSize: string
backgroundOptions: string
moreOptions: string
remindMe: string
markdownMode: string
addCollaborators: string
duplicate: string
share: string
showCollaborators: string
pinned: string
others: string
noNotes: string
noNotesFound: string
createFirstNote: string
}
labels: {
title: string
filter: string
manage: string
manageTooltip: string
changeColor: string
changeColorTooltip: string
delete: string
deleteTooltip: string
confirmDelete: string
newLabelPlaceholder: string
namePlaceholder: string
addLabel: string
createLabel: string
labelName: string
labelColor: string
manageLabels: string
clearAll: string
filterByLabel: string
tagAdded: string
}
search: {
placeholder: string
searchPlaceholder: string
semanticInProgress: string
semanticTooltip: string
searching: string
noResults: string
resultsFound: string
exactMatch: string
related: string
}
collaboration: {
emailPlaceholder: string
addCollaborator: string
removeCollaborator: string
owner: string
canEdit: string
canView: string
shareNote: string
}
ai: {
analyzing: string
clickToAddTag: string
ignoreSuggestion: string
generatingTitles: string
generateTitlesTooltip: string
poweredByAI: string
languageDetected: string
processing: string
}
titleSuggestions: {
available: string
title: string
generating: string
selectTitle: string
dismiss: string
}
semanticSearch: {
exactMatch: string
related: string
searching: string
}
paragraphRefactor: {
title: string
shorten: string
expand: string
improve: string
formal: string
casual: string
}
memoryEcho: {
title: string
description: string
dailyInsight: string
insightReady: string
}
nav: {
home: string
notes: string
notebooks: string
generalNotes: string
archive: string
settings: string
profile: string
aiSettings: string
logout: string
login: string
}
settings: {
title: string
description: string
account: string
appearance: string
theme: string
themeLight: string
themeDark: string
themeSystem: string
notifications: string
language: string
selectLanguage: string
privacy: string
security: string
about: string
version: string
settingsSaved: string
settingsError: string
}
profile: {
title: string
description: string
displayName: string
email: string
changePassword: string
changePasswordDescription: string
currentPassword: string
newPassword: string
confirmPassword: string
updatePassword: string
passwordChangeSuccess: string
passwordChangeFailed: string
passwordUpdated: string
passwordError: string
languagePreferences: string
languagePreferencesDescription: string
preferredLanguage: string
selectLanguage: string
languageDescription: string
autoDetect: string
updateSuccess: string
updateFailed: string
languageUpdateSuccess: string
languageUpdateFailed: string
profileUpdated: string
profileError: string
accountSettings: string
manageAISettings: string
}
aiSettings: {
title: string
description: string
features: string
provider: string
providerAuto: string
providerOllama: string
providerOpenAI: string
frequency: string
frequencyDaily: string
frequencyWeekly: string
saving: string
saved: string
error: string
}
general: {
loading: string
save: string
cancel: string
add: string
edit: string
confirm: string
close: string
back: string
next: string
previous: string
submit: string
reset: string
apply: string
clear: string
select: string
tryAgain: string
error: string
operationSuccess: string
operationFailed: string
}
colors: {
default: string
red: string
blue: string
green: string
yellow: string
purple: string
pink: string
orange: string
gray: string
}
reminder: {
title: string
setReminder: string
removeReminder: string
reminderDate: string
reminderTime: string
save: string
cancel: string
}
notebookSuggestion: {
title: string
description: string
move: string
dismiss: string
dismissIn: string
moveToNotebook: string
generalNotes: string
}
}
/**
* Load translations from JSON files
*/
export async function loadTranslations(language: SupportedLanguage): Promise<Translations> {
try {
const translations = await import(`@/locales/${language}.json`)
return translations.default as Translations
} catch (error) {
console.error(`Failed to load translations for ${language}:`, error)
// Fallback to English
const enTranslations = await import(`@/locales/en.json`)
return enTranslations.default as Translations
}
}
/**
* Get nested translation value from object using dot notation
*/
export function getTranslationValue(translations: Translations, key: string): string {
const keys = key.split('.')
let value: any = translations
for (const k of keys) {
value = value?.[k]
}
return typeof value === 'string' ? value : key
}