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:
162
src/i18n/en.ts
Normal file
162
src/i18n/en.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
import { TranslationKeys } from './types';
|
||||
|
||||
export const en: TranslationKeys = {
|
||||
common: {
|
||||
save: 'Save',
|
||||
cancel: 'Cancel',
|
||||
edit: 'Edit',
|
||||
delete: 'Delete',
|
||||
loading: 'Loading...',
|
||||
error: 'Error',
|
||||
success: 'Success',
|
||||
search: 'Search',
|
||||
back: 'Back',
|
||||
confirm: 'Confirm',
|
||||
check: 'Check',
|
||||
link: 'Link',
|
||||
none: 'None',
|
||||
},
|
||||
home: {
|
||||
title: 'Whisky Vault',
|
||||
logout: 'Logout',
|
||||
stats: {
|
||||
title: 'Your Bar Statistics',
|
||||
totalValue: 'Total Value',
|
||||
activeBottles: 'In the Bar',
|
||||
avgRating: 'Avg Rating',
|
||||
topDistillery: 'Top Distillery',
|
||||
},
|
||||
dramOfDay: {
|
||||
button: 'Dram of the Day',
|
||||
rollAgain: 'Not today, roll again',
|
||||
suggestion: 'How about a...',
|
||||
noOpenBottles: 'No open bottles found! Maybe time for a new tasting? 🥃',
|
||||
title: 'Your Dram for today',
|
||||
viewBottle: 'View Bottle',
|
||||
},
|
||||
searchPlaceholder: 'Search bottles or notes...',
|
||||
noBottles: 'No bottles found. Time to go shopping! 🥃',
|
||||
collection: 'Your Collection',
|
||||
reTry: 'Retry',
|
||||
all: 'All',
|
||||
},
|
||||
grid: {
|
||||
searchPlaceholder: 'Search by name or distillery...',
|
||||
noResults: 'No bottles found matching your filters. 🔎',
|
||||
sortBy: {
|
||||
createdAt: 'Newest first',
|
||||
lastTasted: 'Last tasted',
|
||||
name: 'Alphabetical',
|
||||
},
|
||||
filter: {
|
||||
category: 'Category',
|
||||
distillery: 'Distillery',
|
||||
status: 'Status',
|
||||
},
|
||||
addSession: 'ADD TO SESSION',
|
||||
addedOn: 'Added on',
|
||||
reviewRequired: 'REVIEW',
|
||||
unknownBottle: 'Unknown Bottle',
|
||||
},
|
||||
bottle: {
|
||||
details: 'Details',
|
||||
distillery: 'Distillery',
|
||||
category: 'Category',
|
||||
abv: 'ABV',
|
||||
age: 'Age',
|
||||
years: 'years',
|
||||
lastTasted: 'Last Tasted',
|
||||
neverTasted: 'Never',
|
||||
purchasePrice: 'Purchase Price',
|
||||
distilled: 'Distilled',
|
||||
bottled: 'Bottled',
|
||||
batch: 'Batch / Code',
|
||||
status: {
|
||||
sealed: 'Sealed',
|
||||
open: 'Open',
|
||||
sampled: 'Sample',
|
||||
empty: 'Empty',
|
||||
},
|
||||
whiskybaseId: 'Whiskybase ID',
|
||||
tastingNotes: 'Tasting Notes',
|
||||
tastingNotesDesc: 'Your previous impressions and notes.',
|
||||
noNotes: 'No notes yet.',
|
||||
editDetails: 'Edit Details',
|
||||
editTitle: 'Fix Details',
|
||||
autoSearch: 'Auto Search',
|
||||
applyId: 'Apply ID',
|
||||
saveChanges: 'Save Changes',
|
||||
noMatchFound: 'No match found.',
|
||||
priceLabel: 'Purchase Price',
|
||||
nameLabel: 'Name',
|
||||
distilleryLabel: 'Distillery',
|
||||
categoryLabel: 'Category',
|
||||
abvLabel: 'ABV%',
|
||||
ageLabel: 'Age',
|
||||
distilledLabel: 'Distilled',
|
||||
bottledLabel: 'Bottled',
|
||||
batchLabel: 'Batch / Code',
|
||||
bottleStatus: 'Bottle Status',
|
||||
},
|
||||
camera: {
|
||||
scanBottle: 'Scan Bottle',
|
||||
uploadImage: 'Upload Image',
|
||||
analyzing: 'Analyzing bottle...',
|
||||
analysisError: 'Analysis failed',
|
||||
matchFound: 'Bottle identified!',
|
||||
notAWhisky: "Doesn't look like whisky.",
|
||||
lowConfidence: 'Unsure about details. Please check.',
|
||||
saveToVault: 'Save to Vault',
|
||||
tastingNow: 'Tasting Now',
|
||||
backToList: 'Back to List',
|
||||
whiskybaseSearch: 'Search Whiskybase',
|
||||
searchingWb: 'Searching Whiskybase...',
|
||||
wbMatchFound: 'Match found',
|
||||
magicShot: 'Magic Shot',
|
||||
saveSuccess: 'Successfully saved!',
|
||||
later: 'Later (Back to List)',
|
||||
openingCamera: 'Open Camera',
|
||||
saving: 'Saving...',
|
||||
nextBottle: 'Next Bottle',
|
||||
newPhoto: 'Take New Photo',
|
||||
inVault: 'Save in Vault',
|
||||
offlineNotice: "Offline! Photo captured – it'll be analyzed automatically once you're back online. 📡",
|
||||
alreadyInVault: 'Already in Vault!',
|
||||
alreadyInVaultDesc: 'You already have this whisky in your collection. Want to go directly to the bottle?',
|
||||
saveAnyway: 'Save as new bottle anyway',
|
||||
analysisSuccess: 'Image analyzed successfully',
|
||||
results: 'Results',
|
||||
toVault: 'Go to bottle in Vault',
|
||||
authRequired: 'Please sign in to save bottles.',
|
||||
processingError: 'Processing failed. Please try again.',
|
||||
},
|
||||
tasting: {
|
||||
addNote: 'Add Tasting Note',
|
||||
isSample: "I'm drinking a sample",
|
||||
isBottle: "I'm drinking from the bottle",
|
||||
rating: 'Rating',
|
||||
nose: 'Nose',
|
||||
palate: 'Palate',
|
||||
finish: 'Finish',
|
||||
notesPlaceholder: 'What do you smell and taste?',
|
||||
overall: 'Overall Impression',
|
||||
saveTasting: 'Save Tasting',
|
||||
participants: 'Participants',
|
||||
addParticipant: 'Add Buddy',
|
||||
},
|
||||
buddy: {
|
||||
title: 'Your Buddies',
|
||||
addBuddy: 'Add Buddy',
|
||||
placeholder: 'Buddy name...',
|
||||
noBuddies: 'No buddies added yet.',
|
||||
},
|
||||
session: {
|
||||
title: 'Tasting Sessions',
|
||||
activeSession: 'Active Session',
|
||||
allSessions: 'All Sessions',
|
||||
newSession: 'Start New Session',
|
||||
sessionName: 'Session Name',
|
||||
noSessions: 'No sessions yet.',
|
||||
expiryWarning: 'This session will expire soon.',
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user