feat: implement comprehensive i18n system with German and English support
- Created type-safe i18n system with TranslationKeys interface - Added German (de) and English (en) translations with 160+ keys - Implemented I18nContext provider and useI18n hook - Added LanguageSwitcher component for language selection - Refactored all major components to use translations: * Home page, StatsDashboard, DramOfTheDay * BottleGrid, EditBottleForm, CameraCapture * BuddyList, SessionList, TastingNoteForm * StatusSwitcher and bottle management features - Implemented locale-aware currency formatting (EUR) - Implemented locale-aware date formatting - Added localStorage persistence for language preference - Added automatic browser language detection - Organized translations into 8 main categories - System is extensible for additional languages
This commit is contained in:
160
src/i18n/types.ts
Normal file
160
src/i18n/types.ts
Normal file
@@ -0,0 +1,160 @@
|
||||
export type TranslationKeys = {
|
||||
common: {
|
||||
save: string;
|
||||
cancel: string;
|
||||
edit: string;
|
||||
delete: string;
|
||||
loading: string;
|
||||
error: string;
|
||||
success: string;
|
||||
search: string;
|
||||
back: string;
|
||||
confirm: string;
|
||||
check: string;
|
||||
link: string;
|
||||
none: string;
|
||||
};
|
||||
home: {
|
||||
title: string;
|
||||
logout: string;
|
||||
stats: {
|
||||
title: string;
|
||||
totalValue: string;
|
||||
activeBottles: string;
|
||||
avgRating: string;
|
||||
topDistillery: string;
|
||||
};
|
||||
dramOfDay: {
|
||||
button: string;
|
||||
rollAgain: string;
|
||||
suggestion: string;
|
||||
noOpenBottles: string;
|
||||
title: string;
|
||||
viewBottle: string;
|
||||
};
|
||||
searchPlaceholder: string;
|
||||
noBottles: string;
|
||||
collection: string;
|
||||
reTry: string;
|
||||
all: string;
|
||||
};
|
||||
grid: {
|
||||
searchPlaceholder: string;
|
||||
noResults: string;
|
||||
sortBy: {
|
||||
createdAt: string;
|
||||
lastTasted: string;
|
||||
name: string;
|
||||
};
|
||||
filter: {
|
||||
category: string;
|
||||
distillery: string;
|
||||
status: string;
|
||||
};
|
||||
addSession: string;
|
||||
addedOn: string;
|
||||
reviewRequired: string;
|
||||
unknownBottle: string;
|
||||
};
|
||||
bottle: {
|
||||
details: string;
|
||||
distillery: string;
|
||||
category: string;
|
||||
abv: string;
|
||||
age: string;
|
||||
years: string;
|
||||
lastTasted: string;
|
||||
neverTasted: string;
|
||||
purchasePrice: string;
|
||||
distilled: string;
|
||||
bottled: string;
|
||||
batch: string;
|
||||
status: {
|
||||
sealed: string;
|
||||
open: string;
|
||||
sampled: string;
|
||||
empty: string;
|
||||
};
|
||||
whiskybaseId: string;
|
||||
tastingNotes: string;
|
||||
tastingNotesDesc: string;
|
||||
noNotes: string;
|
||||
editDetails: string;
|
||||
editTitle: string;
|
||||
autoSearch: string;
|
||||
applyId: string;
|
||||
saveChanges: string;
|
||||
noMatchFound: string;
|
||||
priceLabel: string;
|
||||
nameLabel: string;
|
||||
distilleryLabel: string;
|
||||
categoryLabel: string;
|
||||
abvLabel: string;
|
||||
ageLabel: string;
|
||||
distilledLabel: string;
|
||||
bottledLabel: string;
|
||||
batchLabel: string;
|
||||
bottleStatus: string;
|
||||
};
|
||||
camera: {
|
||||
scanBottle: string;
|
||||
uploadImage: string;
|
||||
analyzing: string;
|
||||
analysisError: string;
|
||||
matchFound: string;
|
||||
notAWhisky: string;
|
||||
lowConfidence: string;
|
||||
saveToVault: string;
|
||||
tastingNow: string;
|
||||
backToList: string;
|
||||
whiskybaseSearch: string;
|
||||
searchingWb: string;
|
||||
wbMatchFound: string;
|
||||
magicShot: string;
|
||||
saveSuccess: string;
|
||||
later: string;
|
||||
openingCamera: string;
|
||||
saving: string;
|
||||
nextBottle: string;
|
||||
newPhoto: string;
|
||||
inVault: string;
|
||||
offlineNotice: string;
|
||||
alreadyInVault: string;
|
||||
alreadyInVaultDesc: string;
|
||||
saveAnyway: string;
|
||||
analysisSuccess: string;
|
||||
results: string;
|
||||
toVault: string;
|
||||
authRequired: string;
|
||||
processingError: string;
|
||||
};
|
||||
tasting: {
|
||||
addNote: string;
|
||||
isSample: string;
|
||||
isBottle: string;
|
||||
rating: string;
|
||||
nose: string;
|
||||
palate: string;
|
||||
finish: string;
|
||||
notesPlaceholder: string;
|
||||
overall: string;
|
||||
saveTasting: string;
|
||||
participants: string;
|
||||
addParticipant: string;
|
||||
};
|
||||
buddy: {
|
||||
title: string;
|
||||
addBuddy: string;
|
||||
placeholder: string;
|
||||
noBuddies: string;
|
||||
};
|
||||
session: {
|
||||
title: string;
|
||||
activeSession: string;
|
||||
allSessions: string;
|
||||
newSession: string;
|
||||
sessionName: string;
|
||||
noSessions: string;
|
||||
expiryWarning: string;
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user