1472 lines
68 KiB
TypeScript
1472 lines
68 KiB
TypeScript
const en: Record<string, string | { name: string; category: string }[]> = {
|
||
// Common
|
||
'common.save': 'Save',
|
||
'common.cancel': 'Cancel',
|
||
'common.delete': 'Delete',
|
||
'common.edit': 'Edit',
|
||
'common.add': 'Add',
|
||
'common.loading': 'Loading...',
|
||
'common.error': 'Error',
|
||
'common.back': 'Back',
|
||
'common.all': 'All',
|
||
'common.close': 'Close',
|
||
'common.open': 'Open',
|
||
'common.upload': 'Upload',
|
||
'common.search': 'Search',
|
||
'common.confirm': 'Confirm',
|
||
'common.ok': 'OK',
|
||
'common.yes': 'Yes',
|
||
'common.no': 'No',
|
||
'common.or': 'or',
|
||
'common.none': 'None',
|
||
'common.date': 'Date',
|
||
'common.rename': 'Rename',
|
||
'common.name': 'Name',
|
||
'common.email': 'Email',
|
||
'common.password': 'Password',
|
||
'common.saving': 'Saving...',
|
||
'common.saved': 'Saved',
|
||
'trips.reminder': 'Reminder',
|
||
'trips.reminderNone': 'None',
|
||
'trips.reminderDay': 'day',
|
||
'trips.reminderDays': 'days',
|
||
'trips.reminderCustom': 'Custom',
|
||
'trips.reminderDaysBefore': 'days before departure',
|
||
'trips.reminderDisabledHint': 'Trip reminders are disabled. Enable them in Admin > Settings > Notifications.',
|
||
'common.update': 'Update',
|
||
'common.change': 'Change',
|
||
'common.uploading': 'Uploading…',
|
||
'common.backToPlanning': 'Back to Planning',
|
||
'common.reset': 'Reset',
|
||
|
||
// Navbar
|
||
'nav.trip': 'Trip',
|
||
'nav.share': 'Share',
|
||
'nav.settings': 'Settings',
|
||
'nav.admin': 'Admin',
|
||
'nav.logout': 'Log out',
|
||
'nav.lightMode': 'Light Mode',
|
||
'nav.darkMode': 'Dark Mode',
|
||
'nav.autoMode': 'Auto Mode',
|
||
'nav.administrator': 'Administrator',
|
||
|
||
// Dashboard
|
||
'dashboard.title': 'My Trips',
|
||
'dashboard.subtitle.loading': 'Loading trips...',
|
||
'dashboard.subtitle.trips': '{count} trips ({archived} archived)',
|
||
'dashboard.subtitle.empty': 'Start your first trip',
|
||
'dashboard.subtitle.activeOne': '{count} active trip',
|
||
'dashboard.subtitle.activeMany': '{count} active trips',
|
||
'dashboard.subtitle.archivedSuffix': ' · {count} archived',
|
||
'dashboard.newTrip': 'New Trip',
|
||
'dashboard.gridView': 'Grid view',
|
||
'dashboard.listView': 'List view',
|
||
'dashboard.currency': 'Currency',
|
||
'dashboard.timezone': 'Timezones',
|
||
'dashboard.localTime': 'Local',
|
||
'dashboard.timezoneCustomTitle': 'Custom Timezone',
|
||
'dashboard.timezoneCustomLabelPlaceholder': 'Label (optional)',
|
||
'dashboard.timezoneCustomTzPlaceholder': 'e.g. America/New_York',
|
||
'dashboard.timezoneCustomAdd': 'Add',
|
||
'dashboard.timezoneCustomErrorEmpty': 'Enter a timezone identifier',
|
||
'dashboard.timezoneCustomErrorInvalid': 'Invalid timezone. Use format like Europe/Berlin',
|
||
'dashboard.timezoneCustomErrorDuplicate': 'Already added',
|
||
'dashboard.emptyTitle': 'No trips yet',
|
||
'dashboard.emptyText': 'Create your first trip and start planning!',
|
||
'dashboard.emptyButton': 'Create First Trip',
|
||
'dashboard.nextTrip': 'Next Trip',
|
||
'dashboard.shared': 'Shared',
|
||
'dashboard.sharedBy': 'Shared by {name}',
|
||
'dashboard.days': 'Days',
|
||
'dashboard.places': 'Places',
|
||
'dashboard.archive': 'Archive',
|
||
'dashboard.restore': 'Restore',
|
||
'dashboard.archived': 'Archived',
|
||
'dashboard.status.ongoing': 'Ongoing',
|
||
'dashboard.status.today': 'Today',
|
||
'dashboard.status.tomorrow': 'Tomorrow',
|
||
'dashboard.status.past': 'Past',
|
||
'dashboard.status.daysLeft': '{count} days left',
|
||
'dashboard.toast.loadError': 'Failed to load trips',
|
||
'dashboard.toast.created': 'Trip created successfully!',
|
||
'dashboard.toast.createError': 'Failed to create trip',
|
||
'dashboard.toast.updated': 'Trip updated!',
|
||
'dashboard.toast.updateError': 'Failed to update trip',
|
||
'dashboard.toast.deleted': 'Trip deleted',
|
||
'dashboard.toast.deleteError': 'Failed to delete trip',
|
||
'dashboard.toast.archived': 'Trip archived',
|
||
'dashboard.toast.archiveError': 'Failed to archive trip',
|
||
'dashboard.toast.restored': 'Trip restored',
|
||
'dashboard.toast.restoreError': 'Failed to restore trip',
|
||
'dashboard.confirm.delete': 'Delete trip "{title}"? All places and plans will be permanently deleted.',
|
||
'dashboard.editTrip': 'Edit Trip',
|
||
'dashboard.createTrip': 'Create New Trip',
|
||
'dashboard.tripTitle': 'Title',
|
||
'dashboard.tripTitlePlaceholder': 'e.g. Summer in Japan',
|
||
'dashboard.tripDescription': 'Description',
|
||
'dashboard.tripDescriptionPlaceholder': 'What is this trip about?',
|
||
'dashboard.startDate': 'Start Date',
|
||
'dashboard.endDate': 'End Date',
|
||
'dashboard.noDateHint': 'No date set — 7 default days will be created. You can change this anytime.',
|
||
'dashboard.coverImage': 'Cover Image',
|
||
'dashboard.addCoverImage': 'Add cover image (or drag & drop)',
|
||
'dashboard.addMembers': 'Travel buddies',
|
||
'dashboard.addMember': 'Add member',
|
||
'dashboard.coverSaved': 'Cover image saved',
|
||
'dashboard.coverUploadError': 'Failed to upload',
|
||
'dashboard.coverRemoveError': 'Failed to remove',
|
||
'dashboard.titleRequired': 'Title is required',
|
||
'dashboard.endDateError': 'End date must be after start date',
|
||
|
||
// Settings
|
||
'settings.title': 'Settings',
|
||
'settings.subtitle': 'Configure your personal settings',
|
||
'settings.map': 'Map',
|
||
'settings.mapTemplate': 'Map Template',
|
||
'settings.mapTemplatePlaceholder.select': 'Select template...',
|
||
'settings.mapDefaultHint': 'Leave empty for OpenStreetMap (default)',
|
||
'settings.mapTemplatePlaceholder': 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||
'settings.mapHint': 'URL template for map tiles',
|
||
'settings.latitude': 'Latitude',
|
||
'settings.longitude': 'Longitude',
|
||
'settings.saveMap': 'Save Map',
|
||
'settings.apiKeys': 'API Keys',
|
||
'settings.mapsKey': 'Google Maps API Key',
|
||
'settings.mapsKeyHint': 'For place search. Requires Places API (New). Get at console.cloud.google.com',
|
||
'settings.weatherKey': 'OpenWeatherMap API Key',
|
||
'settings.weatherKeyHint': 'For weather data. Free at openweathermap.org/api',
|
||
'settings.keyPlaceholder': 'Enter key...',
|
||
'settings.configured': 'Configured',
|
||
'settings.saveKeys': 'Save Keys',
|
||
'settings.display': 'Display',
|
||
'settings.colorMode': 'Color Mode',
|
||
'settings.light': 'Light',
|
||
'settings.dark': 'Dark',
|
||
'settings.auto': 'Auto',
|
||
'settings.language': 'Language',
|
||
'settings.temperature': 'Temperature Unit',
|
||
'settings.timeFormat': 'Time Format',
|
||
'settings.routeCalculation': 'Route Calculation',
|
||
'settings.blurBookingCodes': 'Blur Booking Codes',
|
||
'settings.notifications': 'Notifications',
|
||
'settings.notifyTripInvite': 'Trip invitations',
|
||
'settings.notifyBookingChange': 'Booking changes',
|
||
'settings.notifyTripReminder': 'Trip reminders',
|
||
'settings.notifyVacayInvite': 'Vacay fusion invitations',
|
||
'settings.notifyPhotosShared': 'Shared photos (Immich)',
|
||
'settings.notifyCollabMessage': 'Chat messages (Collab)',
|
||
'settings.notifyPackingTagged': 'Packing list: assignments',
|
||
'settings.notifyWebhook': 'Webhook notifications',
|
||
'admin.notifications.title': 'Notifications',
|
||
'admin.notifications.hint': 'Choose one notification channel. Only one can be active at a time.',
|
||
'admin.notifications.none': 'Disabled',
|
||
'admin.notifications.email': 'Email (SMTP)',
|
||
'admin.notifications.webhook': 'Webhook',
|
||
'admin.notifications.events': 'Notification Events',
|
||
'admin.notifications.eventsHint': 'Choose which events trigger notifications for all users.',
|
||
'admin.notifications.configureFirst': 'Configure the SMTP or webhook settings below first, then enable events.',
|
||
'admin.notifications.save': 'Save notification settings',
|
||
'admin.notifications.saved': 'Notification settings saved',
|
||
'admin.notifications.testWebhook': 'Send test webhook',
|
||
'admin.notifications.testWebhookSuccess': 'Test webhook sent successfully',
|
||
'admin.notifications.testWebhookFailed': 'Test webhook failed',
|
||
'admin.smtp.title': 'Email & Notifications',
|
||
'admin.smtp.hint': 'SMTP configuration for sending email notifications.',
|
||
'admin.smtp.testButton': 'Send test email',
|
||
'admin.webhook.hint': 'Send notifications to an external webhook (Discord, Slack, etc.).',
|
||
'admin.smtp.testSuccess': 'Test email sent successfully',
|
||
'admin.smtp.testFailed': 'Test email failed',
|
||
'settings.notificationsDisabled': 'Notifications are not configured. Ask an admin to enable email or webhook notifications.',
|
||
'settings.notificationsActive': 'Active channel',
|
||
'settings.notificationsManagedByAdmin': 'Notification events are configured by your administrator.',
|
||
'dayplan.icsTooltip': 'Export calendar (ICS)',
|
||
'share.linkTitle': 'Public Link',
|
||
'share.linkHint': 'Create a link anyone can use to view this trip without logging in. Read-only — no editing possible.',
|
||
'share.createLink': 'Create link',
|
||
'share.deleteLink': 'Delete link',
|
||
'share.createError': 'Could not create link',
|
||
'common.copy': 'Copy',
|
||
'common.copied': 'Copied',
|
||
'share.permMap': 'Map & Plan',
|
||
'share.permBookings': 'Bookings',
|
||
'share.permPacking': 'Packing',
|
||
'shared.expired': 'Link expired or invalid',
|
||
'shared.expiredHint': 'This shared trip link is no longer active.',
|
||
'shared.readOnly': 'Read-only shared view',
|
||
'shared.tabPlan': 'Plan',
|
||
'shared.tabBookings': 'Bookings',
|
||
'shared.tabPacking': 'Packing',
|
||
'shared.tabBudget': 'Budget',
|
||
'shared.tabChat': 'Chat',
|
||
'shared.days': 'days',
|
||
'shared.places': 'places',
|
||
'shared.other': 'Other',
|
||
'shared.totalBudget': 'Total Budget',
|
||
'shared.messages': 'messages',
|
||
'shared.sharedVia': 'Shared via',
|
||
'shared.confirmed': 'Confirmed',
|
||
'shared.pending': 'Pending',
|
||
'share.permBudget': 'Budget',
|
||
'share.permCollab': 'Chat',
|
||
'settings.on': 'On',
|
||
'settings.off': 'Off',
|
||
'settings.mcp.title': 'MCP Configuration',
|
||
'settings.mcp.endpoint': 'MCP Endpoint',
|
||
'settings.mcp.clientConfig': 'Client Configuration',
|
||
'settings.mcp.clientConfigHint': 'Replace <your_token> with an API token from the list below. The path to npx may need to be adjusted for your system (e.g. C:\\PROGRA~1\\nodejs\\npx.cmd on Windows).',
|
||
'settings.mcp.copy': 'Copy',
|
||
'settings.mcp.copied': 'Copied!',
|
||
'settings.mcp.apiTokens': 'API Tokens',
|
||
'settings.mcp.createToken': 'Create New Token',
|
||
'settings.mcp.noTokens': 'No tokens yet. Create one to connect MCP clients.',
|
||
'settings.mcp.tokenCreatedAt': 'Created',
|
||
'settings.mcp.tokenUsedAt': 'Used',
|
||
'settings.mcp.deleteTokenTitle': 'Delete Token',
|
||
'settings.mcp.deleteTokenMessage': 'This token will stop working immediately. Any MCP client using it will lose access.',
|
||
'settings.mcp.modal.createTitle': 'Create API Token',
|
||
'settings.mcp.modal.tokenName': 'Token Name',
|
||
'settings.mcp.modal.tokenNamePlaceholder': 'e.g. Claude Desktop, Work laptop',
|
||
'settings.mcp.modal.creating': 'Creating…',
|
||
'settings.mcp.modal.create': 'Create Token',
|
||
'settings.mcp.modal.createdTitle': 'Token Created',
|
||
'settings.mcp.modal.createdWarning': 'This token will only be shown once. Copy and store it now — it cannot be recovered.',
|
||
'settings.mcp.modal.done': 'Done',
|
||
'settings.mcp.toast.created': 'Token created',
|
||
'settings.mcp.toast.createError': 'Failed to create token',
|
||
'settings.mcp.toast.deleted': 'Token deleted',
|
||
'settings.mcp.toast.deleteError': 'Failed to delete token',
|
||
'settings.account': 'Account',
|
||
'settings.username': 'Username',
|
||
'settings.email': 'Email',
|
||
'settings.role': 'Role',
|
||
'settings.roleAdmin': 'Administrator',
|
||
'settings.oidcLinked': 'Linked with',
|
||
'settings.changePassword': 'Change Password',
|
||
'settings.currentPassword': 'Current password',
|
||
'settings.currentPasswordRequired': 'Current password is required',
|
||
'settings.newPassword': 'New password',
|
||
'settings.confirmPassword': 'Confirm new password',
|
||
'settings.updatePassword': 'Update password',
|
||
'settings.passwordRequired': 'Please enter current and new password',
|
||
'settings.passwordTooShort': 'Password must be at least 8 characters',
|
||
'settings.passwordMismatch': 'Passwords do not match',
|
||
'settings.passwordWeak': 'Password must contain uppercase, lowercase, and a number',
|
||
'settings.passwordChanged': 'Password changed successfully',
|
||
'settings.mustChangePassword': 'You must change your password before you can continue. Please set a new password below.',
|
||
'settings.deleteAccount': 'Delete account',
|
||
'settings.deleteAccountTitle': 'Delete your account?',
|
||
'settings.deleteAccountWarning': 'Your account and all your trips, places, and files will be permanently deleted. This action cannot be undone.',
|
||
'settings.deleteAccountConfirm': 'Delete permanently',
|
||
'settings.deleteBlockedTitle': 'Deletion not possible',
|
||
'settings.deleteBlockedMessage': 'You are the only administrator. Promote another user to admin before deleting your account.',
|
||
'settings.roleUser': 'User',
|
||
'settings.saveProfile': 'Save Profile',
|
||
'settings.toast.mapSaved': 'Map settings saved',
|
||
'settings.toast.keysSaved': 'API keys saved',
|
||
'settings.toast.displaySaved': 'Display settings saved',
|
||
'settings.toast.profileSaved': 'Profile saved',
|
||
'settings.uploadAvatar': 'Upload Profile Picture',
|
||
'settings.removeAvatar': 'Remove Profile Picture',
|
||
'settings.avatarUploaded': 'Profile picture updated',
|
||
'settings.avatarRemoved': 'Profile picture removed',
|
||
'settings.avatarError': 'Upload failed',
|
||
'settings.mfa.title': 'Two-factor authentication (2FA)',
|
||
'settings.mfa.description': 'Adds a second step when you sign in with email and password. Use an authenticator app (Google Authenticator, Authy, etc.).',
|
||
'settings.mfa.requiredByPolicy': 'Your administrator requires two-factor authentication. Set up an authenticator app below before continuing.',
|
||
'settings.mfa.backupTitle': 'Backup codes',
|
||
'settings.mfa.backupDescription': 'Use these one-time backup codes if you lose access to your authenticator app.',
|
||
'settings.mfa.backupWarning': 'Save these codes now. Each code can only be used once.',
|
||
'settings.mfa.backupCopy': 'Copy codes',
|
||
'settings.mfa.backupDownload': 'Download TXT',
|
||
'settings.mfa.backupPrint': 'Print / PDF',
|
||
'settings.mfa.backupCopied': 'Backup codes copied',
|
||
'settings.mfa.enabled': '2FA is enabled on your account.',
|
||
'settings.mfa.disabled': '2FA is not enabled.',
|
||
'settings.mfa.setup': 'Set up authenticator',
|
||
'settings.mfa.scanQr': 'Scan this QR code with your app, or enter the secret manually.',
|
||
'settings.mfa.secretLabel': 'Secret key (manual entry)',
|
||
'settings.mfa.codePlaceholder': '6-digit code',
|
||
'settings.mfa.enable': 'Enable 2FA',
|
||
'settings.mfa.cancelSetup': 'Cancel',
|
||
'settings.mfa.disableTitle': 'Disable 2FA',
|
||
'settings.mfa.disableHint': 'Enter your account password and a current code from your authenticator.',
|
||
'settings.mfa.disable': 'Disable 2FA',
|
||
'settings.mfa.toastEnabled': 'Two-factor authentication enabled',
|
||
'settings.mfa.toastDisabled': 'Two-factor authentication disabled',
|
||
'settings.mfa.demoBlocked': 'Not available in demo mode',
|
||
|
||
// Login
|
||
'login.error': 'Login failed. Please check your credentials.',
|
||
'login.tagline': 'Your Trips.\nYour Plan.',
|
||
'login.description': 'Plan trips collaboratively with interactive maps, budgets, and real-time sync.',
|
||
'login.features.maps': 'Interactive Maps',
|
||
'login.features.mapsDesc': 'Google Places, routes & clustering',
|
||
'login.features.realtime': 'Real-Time Sync',
|
||
'login.features.realtimeDesc': 'Plan together via WebSocket',
|
||
'login.features.budget': 'Budget Tracking',
|
||
'login.features.budgetDesc': 'Categories, charts & per-person costs',
|
||
'login.features.collab': 'Collaboration',
|
||
'login.features.collabDesc': 'Multi-user with shared trips',
|
||
'login.features.packing': 'Packing Lists',
|
||
'login.features.packingDesc': 'Categories, progress & suggestions',
|
||
'login.features.bookings': 'Reservations',
|
||
'login.features.bookingsDesc': 'Flights, hotels, restaurants & more',
|
||
'login.features.files': 'Documents',
|
||
'login.features.filesDesc': 'Upload & manage documents',
|
||
'login.features.routes': 'Smart Routes',
|
||
'login.features.routesDesc': 'Auto-optimize & Google Maps export',
|
||
'login.selfHosted': 'Self-hosted \u00B7 Open Source \u00B7 Your data stays yours',
|
||
'login.title': 'Sign In',
|
||
'login.subtitle': 'Welcome back',
|
||
'login.signingIn': 'Signing in…',
|
||
'login.signIn': 'Sign In',
|
||
'login.createAdmin': 'Create Admin Account',
|
||
'login.createAdminHint': 'Set up the first admin account for TREK.',
|
||
'login.setNewPassword': 'Set New Password',
|
||
'login.setNewPasswordHint': 'You must change your password before continuing.',
|
||
'login.createAccount': 'Create Account',
|
||
'login.createAccountHint': 'Register a new account.',
|
||
'login.creating': 'Creating…',
|
||
'login.noAccount': "Don't have an account?",
|
||
'login.hasAccount': 'Already have an account?',
|
||
'login.register': 'Register',
|
||
'login.emailPlaceholder': 'your@email.com',
|
||
'login.username': 'Username',
|
||
'login.oidc.registrationDisabled': 'Registration is disabled. Contact your administrator.',
|
||
'login.oidc.noEmail': 'No email received from provider.',
|
||
'login.oidc.tokenFailed': 'Authentication failed.',
|
||
'login.oidc.invalidState': 'Invalid session. Please try again.',
|
||
'login.demoFailed': 'Demo login failed',
|
||
'login.oidcSignIn': 'Sign in with {name}',
|
||
'login.oidcOnly': 'Password authentication is disabled. Please sign in using your SSO provider.',
|
||
'login.demoHint': 'Try the demo — no registration needed',
|
||
'login.mfaTitle': 'Two-factor authentication',
|
||
'login.mfaSubtitle': 'Enter the 6-digit code from your authenticator app.',
|
||
'login.mfaCodeLabel': 'Verification code',
|
||
'login.mfaCodeRequired': 'Enter the code from your authenticator app.',
|
||
'login.mfaHint': 'Open Google Authenticator, Authy, or another TOTP app.',
|
||
'login.mfaBack': '← Back to sign in',
|
||
'login.mfaVerify': 'Verify',
|
||
|
||
// Register
|
||
'register.passwordMismatch': 'Passwords do not match',
|
||
'register.passwordTooShort': 'Password must be at least 6 characters',
|
||
'register.failed': 'Registration failed',
|
||
'register.getStarted': 'Get Started',
|
||
'register.subtitle': 'Create an account and start planning your dream trips.',
|
||
'register.feature1': 'Unlimited trip plans',
|
||
'register.feature2': 'Interactive map view',
|
||
'register.feature3': 'Manage places and categories',
|
||
'register.feature4': 'Track reservations',
|
||
'register.feature5': 'Create packing lists',
|
||
'register.feature6': 'Store photos and files',
|
||
'register.createAccount': 'Create Account',
|
||
'register.startPlanning': 'Start your trip planning',
|
||
'register.minChars': 'Min. 6 characters',
|
||
'register.confirmPassword': 'Confirm Password',
|
||
'register.repeatPassword': 'Repeat password',
|
||
'register.registering': 'Registering...',
|
||
'register.register': 'Register',
|
||
'register.hasAccount': 'Already have an account?',
|
||
'register.signIn': 'Sign In',
|
||
|
||
// Admin
|
||
'admin.title': 'Administration',
|
||
'admin.subtitle': 'User management and system settings',
|
||
'admin.tabs.users': 'Users',
|
||
'admin.tabs.categories': 'Categories',
|
||
'admin.tabs.backup': 'Backup',
|
||
'admin.tabs.audit': 'Audit log',
|
||
'admin.stats.users': 'Users',
|
||
'admin.stats.trips': 'Trips',
|
||
'admin.stats.places': 'Places',
|
||
'admin.stats.photos': 'Photos',
|
||
'admin.stats.files': 'Files',
|
||
'admin.table.user': 'User',
|
||
'admin.table.email': 'Email',
|
||
'admin.table.role': 'Role',
|
||
'admin.table.created': 'Created',
|
||
'admin.table.lastLogin': 'Last Login',
|
||
'admin.table.actions': 'Actions',
|
||
'admin.you': '(You)',
|
||
'admin.editUser': 'Edit User',
|
||
'admin.newPassword': 'New Password',
|
||
'admin.newPasswordHint': 'Leave empty to keep current password',
|
||
'admin.deleteUser': 'Delete user "{name}"? All trips will be permanently deleted.',
|
||
'admin.deleteUserTitle': 'Delete user',
|
||
'admin.newPasswordPlaceholder': 'Enter new password…',
|
||
'admin.toast.loadError': 'Failed to load admin data',
|
||
'admin.toast.userUpdated': 'User updated',
|
||
'admin.toast.updateError': 'Failed to update',
|
||
'admin.toast.userDeleted': 'User deleted',
|
||
'admin.toast.deleteError': 'Failed to delete',
|
||
'admin.toast.cannotDeleteSelf': 'Cannot delete your own account',
|
||
'admin.toast.userCreated': 'User created',
|
||
'admin.toast.createError': 'Failed to create user',
|
||
'admin.toast.fieldsRequired': 'Username, email and password are required',
|
||
'admin.createUser': 'Create User',
|
||
'admin.invite.title': 'Invite Links',
|
||
'admin.invite.subtitle': 'Create one-time registration links',
|
||
'admin.invite.create': 'Create Link',
|
||
'admin.invite.createAndCopy': 'Create & Copy',
|
||
'admin.invite.empty': 'No invite links created yet',
|
||
'admin.invite.maxUses': 'Max. Uses',
|
||
'admin.invite.expiry': 'Expires after',
|
||
'admin.invite.uses': 'used',
|
||
'admin.invite.expiresAt': 'expires',
|
||
'admin.invite.createdBy': 'by',
|
||
'admin.invite.active': 'Active',
|
||
'admin.invite.expired': 'Expired',
|
||
'admin.invite.usedUp': 'Used up',
|
||
'admin.invite.copied': 'Invite link copied to clipboard',
|
||
'admin.invite.copyLink': 'Copy link',
|
||
'admin.invite.deleted': 'Invite link deleted',
|
||
'admin.invite.createError': 'Failed to create invite link',
|
||
'admin.invite.deleteError': 'Failed to delete invite link',
|
||
'admin.tabs.settings': 'Settings',
|
||
'admin.allowRegistration': 'Allow Registration',
|
||
'admin.allowRegistrationHint': 'New users can register themselves',
|
||
'admin.requireMfa': 'Require two-factor authentication (2FA)',
|
||
'admin.requireMfaHint': 'Users without 2FA must complete setup in Settings before using the app.',
|
||
'admin.apiKeys': 'API Keys',
|
||
'admin.apiKeysHint': 'Optional. Enables extended place data like photos and weather.',
|
||
'admin.mapsKey': 'Google Maps API Key',
|
||
'admin.mapsKeyHint': 'Required for place search. Get at console.cloud.google.com',
|
||
'admin.mapsKeyHintLong': 'Without an API key, OpenStreetMap is used for place search. With a Google API key, photos, ratings, and opening hours can be loaded as well. Get one at console.cloud.google.com.',
|
||
'admin.recommended': 'Recommended',
|
||
'admin.weatherKey': 'OpenWeatherMap API Key',
|
||
'admin.weatherKeyHint': 'For weather data. Free at openweathermap.org',
|
||
'admin.validateKey': 'Test',
|
||
'admin.keyValid': 'Connected',
|
||
'admin.keyInvalid': 'Invalid',
|
||
'admin.keySaved': 'API keys saved',
|
||
'admin.oidcTitle': 'Single Sign-On (OIDC)',
|
||
'admin.oidcSubtitle': 'Allow login via external providers like Google, Apple, Authentik or Keycloak.',
|
||
'admin.oidcDisplayName': 'Display Name',
|
||
'admin.oidcIssuer': 'Issuer URL',
|
||
'admin.oidcIssuerHint': 'The OpenID Connect Issuer URL of the provider. e.g. https://accounts.google.com',
|
||
'admin.oidcSaved': 'OIDC configuration saved',
|
||
'admin.oidcOnlyMode': 'Disable password authentication',
|
||
'admin.oidcOnlyModeHint': 'When enabled, only SSO login is permitted. Password-based login and registration are blocked.',
|
||
|
||
// File Types
|
||
'admin.fileTypes': 'Allowed File Types',
|
||
'admin.fileTypesHint': 'Configure which file types users can upload.',
|
||
'admin.fileTypesFormat': 'Comma-separated extensions (e.g. jpg,png,pdf,doc). Use * to allow all types.',
|
||
'admin.fileTypesSaved': 'File type settings saved',
|
||
|
||
// Packing Templates & Bag Tracking
|
||
'admin.bagTracking.title': 'Bag Tracking',
|
||
'admin.bagTracking.subtitle': 'Enable weight and bag assignment for packing items',
|
||
'admin.tabs.config': 'Configuration',
|
||
'admin.tabs.templates': 'Packing Templates',
|
||
'admin.packingTemplates.title': 'Packing Templates',
|
||
'admin.packingTemplates.subtitle': 'Create reusable packing lists for your trips',
|
||
'admin.packingTemplates.create': 'New Template',
|
||
'admin.packingTemplates.namePlaceholder': 'Template name (e.g. Beach Holiday)',
|
||
'admin.packingTemplates.empty': 'No templates created yet',
|
||
'admin.packingTemplates.items': 'items',
|
||
'admin.packingTemplates.categories': 'categories',
|
||
'admin.packingTemplates.itemName': 'Item name',
|
||
'admin.packingTemplates.itemCategory': 'Category',
|
||
'admin.packingTemplates.categoryName': 'Category name (e.g. Clothing)',
|
||
'admin.packingTemplates.addCategory': 'Add category',
|
||
'admin.packingTemplates.created': 'Template created',
|
||
'admin.packingTemplates.deleted': 'Template deleted',
|
||
'admin.packingTemplates.loadError': 'Failed to load templates',
|
||
'admin.packingTemplates.createError': 'Failed to create template',
|
||
'admin.packingTemplates.deleteError': 'Failed to delete template',
|
||
'admin.packingTemplates.saveError': 'Failed to save',
|
||
|
||
// Addons
|
||
'admin.tabs.addons': 'Addons',
|
||
'admin.addons.title': 'Addons',
|
||
'admin.addons.subtitle': 'Enable or disable features to customize your TREK experience.',
|
||
'admin.addons.catalog.packing.name': 'Packing',
|
||
'admin.addons.catalog.packing.description': 'Checklists to prepare your luggage for each trip',
|
||
'admin.addons.catalog.budget.name': 'Budget',
|
||
'admin.addons.catalog.budget.description': 'Track expenses and plan your trip budget',
|
||
'admin.addons.catalog.documents.name': 'Documents',
|
||
'admin.addons.catalog.documents.description': 'Store and manage travel documents',
|
||
'admin.addons.catalog.vacay.name': 'Vacay',
|
||
'admin.addons.catalog.vacay.description': 'Personal vacation planner with calendar view',
|
||
'admin.addons.catalog.atlas.name': 'Atlas',
|
||
'admin.addons.catalog.atlas.description': 'World map with visited countries and travel stats',
|
||
'admin.addons.catalog.collab.name': 'Collab',
|
||
'admin.addons.catalog.collab.description': 'Real-time notes, polls, and chat for trip planning',
|
||
'admin.addons.catalog.memories.name': 'Photos (Immich)',
|
||
'admin.addons.catalog.memories.description': 'Share trip photos via your Immich instance',
|
||
'admin.addons.catalog.mcp.name': 'MCP',
|
||
'admin.addons.catalog.mcp.description': 'Model Context Protocol for AI assistant integration',
|
||
'admin.addons.subtitleBefore': 'Enable or disable features to customize your ',
|
||
'admin.addons.subtitleAfter': ' experience.',
|
||
'admin.addons.enabled': 'Enabled',
|
||
'admin.addons.disabled': 'Disabled',
|
||
'admin.addons.type.trip': 'Trip',
|
||
'admin.addons.type.global': 'Global',
|
||
'admin.addons.type.integration': 'Integration',
|
||
'admin.addons.tripHint': 'Available as a tab within each trip',
|
||
'admin.addons.globalHint': 'Available as a standalone section in the main navigation',
|
||
'admin.addons.integrationHint': 'Backend services and API integrations with no dedicated page',
|
||
'admin.addons.toast.updated': 'Addon updated',
|
||
'admin.addons.toast.error': 'Failed to update addon',
|
||
'admin.addons.noAddons': 'No addons available',
|
||
// Weather info
|
||
'admin.weather.title': 'Weather Data',
|
||
'admin.weather.badge': 'Since March 24, 2026',
|
||
'admin.weather.description': 'TREK uses Open-Meteo as its weather data source. Open-Meteo is a free, open-source weather service — no API key required.',
|
||
'admin.weather.forecast': '16-day forecast',
|
||
'admin.weather.forecastDesc': 'Previously 5 days (OpenWeatherMap)',
|
||
'admin.weather.climate': 'Historical climate data',
|
||
'admin.weather.climateDesc': 'Averages from the last 85 years for days beyond the 16-day forecast',
|
||
'admin.weather.requests': '10,000 requests / day',
|
||
'admin.weather.requestsDesc': 'Free, no API key required',
|
||
'admin.weather.locationHint': 'Weather is based on the first place with coordinates in each day. If no place is assigned to a day, any place from the place list is used as a reference.',
|
||
|
||
// GitHub
|
||
'admin.tabs.mcpTokens': 'MCP Tokens',
|
||
'admin.mcpTokens.title': 'MCP Tokens',
|
||
'admin.mcpTokens.subtitle': 'Manage API tokens across all users',
|
||
'admin.mcpTokens.owner': 'Owner',
|
||
'admin.mcpTokens.tokenName': 'Token Name',
|
||
'admin.mcpTokens.created': 'Created',
|
||
'admin.mcpTokens.lastUsed': 'Last Used',
|
||
'admin.mcpTokens.never': 'Never',
|
||
'admin.mcpTokens.empty': 'No MCP tokens have been created yet',
|
||
'admin.mcpTokens.deleteTitle': 'Delete Token',
|
||
'admin.mcpTokens.deleteMessage': 'This will revoke the token immediately. The user will lose MCP access through this token.',
|
||
'admin.mcpTokens.deleteSuccess': 'Token deleted',
|
||
'admin.mcpTokens.deleteError': 'Failed to delete token',
|
||
'admin.mcpTokens.loadError': 'Failed to load tokens',
|
||
'admin.tabs.github': 'GitHub',
|
||
|
||
'admin.audit.subtitle': 'Security-sensitive and administration events (backups, users, MFA, settings).',
|
||
'admin.audit.empty': 'No audit entries yet.',
|
||
'admin.audit.refresh': 'Refresh',
|
||
'admin.audit.loadMore': 'Load more',
|
||
'admin.audit.showing': '{count} loaded · {total} total',
|
||
'admin.audit.col.time': 'Time',
|
||
'admin.audit.col.user': 'User',
|
||
'admin.audit.col.action': 'Action',
|
||
'admin.audit.col.resource': 'Resource',
|
||
'admin.audit.col.ip': 'IP',
|
||
'admin.audit.col.details': 'Details',
|
||
'admin.github.title': 'Release History',
|
||
'admin.github.subtitle': 'Latest updates from {repo}',
|
||
'admin.github.latest': 'Latest',
|
||
'admin.github.prerelease': 'Pre-release',
|
||
'admin.github.showDetails': 'Show details',
|
||
'admin.github.hideDetails': 'Hide details',
|
||
'admin.github.loadMore': 'Load more',
|
||
'admin.github.loading': 'Loading...',
|
||
'admin.github.error': 'Failed to load releases',
|
||
'admin.github.by': 'by',
|
||
'admin.github.support': 'Helps me keep building TREK',
|
||
|
||
'admin.update.available': 'Update available',
|
||
'admin.update.text': 'TREK {version} is available. You are running {current}.',
|
||
'admin.update.button': 'View on GitHub',
|
||
'admin.update.install': 'Install Update',
|
||
'admin.update.confirmTitle': 'Install Update?',
|
||
'admin.update.confirmText': 'TREK will be updated from {current} to {version}. The server will restart automatically afterwards.',
|
||
'admin.update.dataInfo': 'All your data (trips, users, API keys, uploads, Vacay, Atlas, budgets) will be preserved.',
|
||
'admin.update.warning': 'The app will be briefly unavailable during the restart.',
|
||
'admin.update.confirm': 'Update Now',
|
||
'admin.update.installing': 'Updating…',
|
||
'admin.update.success': 'Update installed! Server is restarting…',
|
||
'admin.update.failed': 'Update failed',
|
||
'admin.update.backupHint': 'We recommend creating a backup before updating.',
|
||
'admin.update.backupLink': 'Go to Backup',
|
||
'admin.update.howTo': 'How to Update',
|
||
'admin.update.dockerText': 'Your TREK instance runs in Docker. To update to {version}, run the following commands on your server:',
|
||
'admin.update.reloadHint': 'Please reload the page in a few seconds.',
|
||
|
||
// Vacay addon
|
||
'vacay.subtitle': 'Plan and manage vacation days',
|
||
'vacay.settings': 'Settings',
|
||
'vacay.year': 'Year',
|
||
'vacay.addYear': 'Add year',
|
||
'vacay.removeYear': 'Remove year',
|
||
'vacay.removeYearConfirm': 'Remove {year}?',
|
||
'vacay.removeYearHint': 'All vacation entries and company holidays for this year will be permanently deleted.',
|
||
'vacay.remove': 'Remove',
|
||
'vacay.persons': 'Persons',
|
||
'vacay.noPersons': 'No persons added',
|
||
'vacay.addPerson': 'Add Person',
|
||
'vacay.editPerson': 'Edit Person',
|
||
'vacay.removePerson': 'Remove Person',
|
||
'vacay.removePersonConfirm': 'Remove {name}?',
|
||
'vacay.removePersonHint': 'All vacation entries for this person will be permanently deleted.',
|
||
'vacay.personName': 'Name',
|
||
'vacay.personNamePlaceholder': 'Enter name',
|
||
'vacay.color': 'Color',
|
||
'vacay.add': 'Add',
|
||
'vacay.legend': 'Legend',
|
||
'vacay.publicHoliday': 'Public Holiday',
|
||
'vacay.companyHoliday': 'Company Holiday',
|
||
'vacay.weekend': 'Weekend',
|
||
'vacay.modeVacation': 'Vacation',
|
||
'vacay.modeCompany': 'Company Holiday',
|
||
'vacay.entitlement': 'Entitlement',
|
||
'vacay.entitlementDays': 'Days',
|
||
'vacay.used': 'Used',
|
||
'vacay.remaining': 'Left',
|
||
'vacay.carriedOver': 'from {year}',
|
||
'vacay.blockWeekends': 'Block Weekends',
|
||
'vacay.blockWeekendsHint': 'Prevent vacation entries on weekend days',
|
||
'vacay.weekendDays': 'Weekend days',
|
||
'vacay.mon': 'Mon',
|
||
'vacay.tue': 'Tue',
|
||
'vacay.wed': 'Wed',
|
||
'vacay.thu': 'Thu',
|
||
'vacay.fri': 'Fri',
|
||
'vacay.sat': 'Sat',
|
||
'vacay.sun': 'Sun',
|
||
'vacay.publicHolidays': 'Public Holidays',
|
||
'vacay.publicHolidaysHint': 'Mark public holidays in the calendar',
|
||
'vacay.selectCountry': 'Select country',
|
||
'vacay.selectRegion': 'Select region (optional)',
|
||
'vacay.addCalendar': 'Add calendar',
|
||
'vacay.calendarLabel': 'Label (optional)',
|
||
'vacay.calendarColor': 'Color',
|
||
'vacay.noCalendars': 'No holiday calendars added yet',
|
||
'vacay.companyHolidays': 'Company Holidays',
|
||
'vacay.companyHolidaysHint': 'Allow marking company-wide holiday days',
|
||
'vacay.companyHolidaysNoDeduct': 'Company holidays do not count towards vacation days.',
|
||
'vacay.carryOver': 'Carry Over',
|
||
'vacay.carryOverHint': 'Automatically carry remaining vacation days into the next year',
|
||
'vacay.sharing': 'Sharing',
|
||
'vacay.sharingHint': 'Share your vacation plan with other TREK users',
|
||
'vacay.owner': 'Owner',
|
||
'vacay.shareEmailPlaceholder': 'Email of TREK user',
|
||
'vacay.shareSuccess': 'Plan shared successfully',
|
||
'vacay.shareError': 'Could not share plan',
|
||
'vacay.dissolve': 'Dissolve Fusion',
|
||
'vacay.dissolveHint': 'Separate calendars again. Your entries will be kept.',
|
||
'vacay.dissolveAction': 'Dissolve',
|
||
'vacay.dissolved': 'Calendar separated',
|
||
'vacay.fusedWith': 'Fused with',
|
||
'vacay.you': 'you',
|
||
'vacay.noData': 'No data',
|
||
'vacay.changeColor': 'Change color',
|
||
'vacay.inviteUser': 'Invite User',
|
||
'vacay.inviteHint': 'Invite another TREK user to share a combined vacation calendar.',
|
||
'vacay.selectUser': 'Select user',
|
||
'vacay.sendInvite': 'Send Invite',
|
||
'vacay.inviteSent': 'Invite sent',
|
||
'vacay.inviteError': 'Could not send invite',
|
||
'vacay.pending': 'pending',
|
||
'vacay.noUsersAvailable': 'No users available',
|
||
'vacay.accept': 'Accept',
|
||
'vacay.decline': 'Decline',
|
||
'vacay.acceptFusion': 'Accept & Fuse',
|
||
'vacay.inviteTitle': 'Fusion Request',
|
||
'vacay.inviteWantsToFuse': 'wants to share a vacation calendar with you.',
|
||
'vacay.fuseInfo1': 'Both of you will see all vacation entries in one shared calendar.',
|
||
'vacay.fuseInfo2': 'Both parties can create and edit entries for each other.',
|
||
'vacay.fuseInfo3': 'Both parties can delete entries and change vacation entitlements.',
|
||
'vacay.fuseInfo4': 'Settings like public holidays and company holidays are shared.',
|
||
'vacay.fuseInfo5': 'The fusion can be dissolved at any time by either party. Your entries will be preserved.',
|
||
'nav.myTrips': 'My Trips',
|
||
|
||
// Atlas addon
|
||
'atlas.subtitle': 'Your travel footprint around the world',
|
||
'atlas.countries': 'Countries',
|
||
'atlas.trips': 'Trips',
|
||
'atlas.places': 'Places',
|
||
'atlas.unmark': 'Remove',
|
||
'atlas.confirmMark': 'Mark this country as visited?',
|
||
'atlas.confirmUnmark': 'Remove this country from your visited list?',
|
||
'atlas.markVisited': 'Mark as visited',
|
||
'atlas.markVisitedHint': 'Add this country to your visited list',
|
||
'atlas.addToBucket': 'Add to bucket list',
|
||
'atlas.addPoi': 'Add place',
|
||
'atlas.searchCountry': 'Search a country...',
|
||
'atlas.bucketNamePlaceholder': 'Name (country, city, place...)',
|
||
'atlas.month': 'Month',
|
||
'atlas.year': 'Year',
|
||
'atlas.addToBucketHint': 'Save as a place you want to visit',
|
||
'atlas.bucketWhen': 'When do you plan to visit?',
|
||
'atlas.statsTab': 'Stats',
|
||
'atlas.bucketTab': 'Bucket List',
|
||
'atlas.addBucket': 'Add to bucket list',
|
||
'atlas.bucketNotesPlaceholder': 'Notes (optional)',
|
||
'atlas.bucketEmpty': 'Your bucket list is empty',
|
||
'atlas.bucketEmptyHint': 'Add places you dream of visiting',
|
||
'atlas.days': 'Days',
|
||
'atlas.visitedCountries': 'Visited Countries',
|
||
'atlas.cities': 'Cities',
|
||
'atlas.noData': 'No travel data yet',
|
||
'atlas.noDataHint': 'Create a trip and add places to see your world map',
|
||
'atlas.lastTrip': 'Last trip',
|
||
'atlas.nextTrip': 'Next trip',
|
||
'atlas.daysLeft': 'days left',
|
||
'atlas.streak': 'Streak',
|
||
'atlas.years': 'years',
|
||
'atlas.yearInRow': 'year in a row',
|
||
'atlas.yearsInRow': 'years in a row',
|
||
'atlas.tripIn': 'trip in',
|
||
'atlas.tripsIn': 'trips in',
|
||
'atlas.since': 'since',
|
||
'atlas.europe': 'Europe',
|
||
'atlas.asia': 'Asia',
|
||
'atlas.northAmerica': 'N. America',
|
||
'atlas.southAmerica': 'S. America',
|
||
'atlas.africa': 'Africa',
|
||
'atlas.oceania': 'Oceania',
|
||
'atlas.other': 'Other',
|
||
'atlas.firstVisit': 'First trip',
|
||
'atlas.lastVisitLabel': 'Last trip',
|
||
'atlas.tripSingular': 'Trip',
|
||
'atlas.tripPlural': 'Trips',
|
||
'atlas.placeVisited': 'Place visited',
|
||
'atlas.placesVisited': 'Places visited',
|
||
|
||
// Trip Planner
|
||
'trip.tabs.plan': 'Plan',
|
||
'trip.tabs.reservations': 'Bookings',
|
||
'trip.tabs.reservationsShort': 'Book',
|
||
'trip.tabs.packing': 'Packing List',
|
||
'trip.tabs.packingShort': 'Packing',
|
||
'trip.tabs.budget': 'Budget',
|
||
'trip.tabs.files': 'Files',
|
||
'trip.loading': 'Loading trip...',
|
||
'trip.mobilePlan': 'Plan',
|
||
'trip.mobilePlaces': 'Places',
|
||
'trip.toast.placeUpdated': 'Place updated',
|
||
'trip.toast.placeAdded': 'Place added',
|
||
'trip.toast.placeDeleted': 'Place deleted',
|
||
'trip.toast.selectDay': 'Please select a day first',
|
||
'trip.toast.assignedToDay': 'Place assigned to day',
|
||
'trip.toast.reorderError': 'Failed to reorder',
|
||
'trip.toast.reservationUpdated': 'Reservation updated',
|
||
'trip.toast.reservationAdded': 'Reservation added',
|
||
'trip.toast.deleted': 'Deleted',
|
||
'trip.confirm.deletePlace': 'Are you sure you want to delete this place?',
|
||
|
||
// Day Plan Sidebar
|
||
'dayplan.emptyDay': 'No places planned for this day',
|
||
'dayplan.cannotReorderTransport': 'Bookings with a fixed time cannot be reordered',
|
||
'dayplan.confirmRemoveTimeTitle': 'Remove time?',
|
||
'dayplan.confirmRemoveTimeBody': 'This place has a fixed time ({time}). Moving it will remove the time and allow free sorting.',
|
||
'dayplan.confirmRemoveTimeAction': 'Remove time & move',
|
||
'dayplan.cannotDropOnTimed': 'Items cannot be placed between time-bound entries',
|
||
'dayplan.cannotBreakChronology': 'This would break the chronological order of timed items and bookings',
|
||
'dayplan.addNote': 'Add Note',
|
||
'dayplan.editNote': 'Edit Note',
|
||
'dayplan.noteAdd': 'Add Note',
|
||
'dayplan.noteEdit': 'Edit Note',
|
||
'dayplan.noteTitle': 'Note',
|
||
'dayplan.noteSubtitle': 'Daily Note',
|
||
'dayplan.totalCost': 'Total Cost',
|
||
'dayplan.days': 'Days',
|
||
'dayplan.dayN': 'Day {n}',
|
||
'dayplan.calculating': 'Calculating...',
|
||
'dayplan.route': 'Route',
|
||
'dayplan.optimize': 'Optimize',
|
||
'dayplan.optimized': 'Route optimized',
|
||
'dayplan.routeError': 'Failed to calculate route',
|
||
'dayplan.toast.needTwoPlaces': 'At least two places needed for route optimization',
|
||
'dayplan.toast.routeOptimized': 'Route optimized',
|
||
'dayplan.toast.noGeoPlaces': 'No places with coordinates found for route calculation',
|
||
'dayplan.confirmed': 'Confirmed',
|
||
'dayplan.pendingRes': 'Pending',
|
||
'dayplan.pdf': 'PDF',
|
||
'dayplan.pdfTooltip': 'Export day plan as PDF',
|
||
'dayplan.pdfError': 'Failed to export PDF',
|
||
|
||
// Places Sidebar
|
||
'places.addPlace': 'Add Place/Activity',
|
||
'places.importGpx': 'Import GPX',
|
||
'places.gpxImported': '{count} places imported from GPX',
|
||
'places.urlResolved': 'Place imported from URL',
|
||
'places.gpxError': 'GPX import failed',
|
||
'places.assignToDay': 'Add to which day?',
|
||
'places.all': 'All',
|
||
'places.unplanned': 'Unplanned',
|
||
'places.search': 'Search places...',
|
||
'places.allCategories': 'All Categories',
|
||
'places.categoriesSelected': 'categories',
|
||
'places.clearFilter': 'Clear filter',
|
||
'places.count': '{count} places',
|
||
'places.countSingular': '1 place',
|
||
'places.allPlanned': 'All places are planned',
|
||
'places.noneFound': 'No places found',
|
||
'places.editPlace': 'Edit Place',
|
||
'places.formName': 'Name',
|
||
'places.formNamePlaceholder': 'e.g. Eiffel Tower',
|
||
'places.formDescription': 'Description',
|
||
'places.formDescriptionPlaceholder': 'Short description...',
|
||
'places.formAddress': 'Address',
|
||
'places.formAddressPlaceholder': 'Street, City, Country',
|
||
'places.formLat': 'Latitude (e.g. 48.8566)',
|
||
'places.formLng': 'Longitude (e.g. 2.3522)',
|
||
'places.formCategory': 'Category',
|
||
'places.noCategory': 'No Category',
|
||
'places.categoryNamePlaceholder': 'Category name',
|
||
'places.formTime': 'Time',
|
||
'places.startTime': 'Start',
|
||
'places.endTime': 'End',
|
||
'places.endTimeBeforeStart': 'End time is before start time',
|
||
'places.timeCollision': 'Time overlap with:',
|
||
'places.formWebsite': 'Website',
|
||
'places.formNotesPlaceholder': 'Personal notes...',
|
||
'places.formReservation': 'Reservation',
|
||
'places.reservationNotesPlaceholder': 'Reservation notes, confirmation number...',
|
||
'places.mapsSearchPlaceholder': 'Search places...',
|
||
'places.mapsSearchError': 'Place search failed.',
|
||
'places.osmHint': 'Using OpenStreetMap search (no photos, opening hours, or ratings). Add a Google API key in settings for full details.',
|
||
'places.osmActive': 'Search via OpenStreetMap (no photos, ratings or opening hours). Add a Google API key in Settings for enhanced data.',
|
||
'places.categoryCreateError': 'Failed to create category',
|
||
'places.nameRequired': 'Please enter a name',
|
||
'places.saveError': 'Failed to save',
|
||
// Place Inspector
|
||
'inspector.opened': 'Open',
|
||
'inspector.closed': 'Closed',
|
||
'inspector.openingHours': 'Opening Hours',
|
||
'inspector.showHours': 'Show opening hours',
|
||
'inspector.files': 'Files',
|
||
'inspector.filesCount': '{count} files',
|
||
'inspector.removeFromDay': 'Remove from Day',
|
||
'inspector.addToDay': 'Add to Day',
|
||
'inspector.confirmedRes': 'Confirmed Reservation',
|
||
'inspector.pendingRes': 'Pending Reservation',
|
||
'inspector.google': 'Open in Google Maps',
|
||
'inspector.website': 'Open Website',
|
||
'inspector.addRes': 'Reservation',
|
||
'inspector.editRes': 'Edit Reservation',
|
||
'inspector.participants': 'Participants',
|
||
'inspector.trackStats': 'Track Stats',
|
||
|
||
// Reservations
|
||
'reservations.title': 'Bookings',
|
||
'reservations.empty': 'No reservations yet',
|
||
'reservations.emptyHint': 'Add reservations for flights, hotels and more',
|
||
'reservations.add': 'Add Reservation',
|
||
'reservations.addManual': 'Manual Booking',
|
||
'reservations.placeHint': 'Tip: Reservations are best created directly from a place to link them with your day plan.',
|
||
'reservations.confirmed': 'Confirmed',
|
||
'reservations.pending': 'Pending',
|
||
'reservations.summary': '{confirmed} confirmed, {pending} pending',
|
||
'reservations.fromPlan': 'From Plan',
|
||
'reservations.showFiles': 'Show Files',
|
||
'reservations.editTitle': 'Edit Reservation',
|
||
'reservations.status': 'Status',
|
||
'reservations.datetime': 'Date & Time',
|
||
'reservations.startTime': 'Start time',
|
||
'reservations.endTime': 'End time',
|
||
'reservations.date': 'Date',
|
||
'reservations.time': 'Time',
|
||
'reservations.timeAlt': 'Time (alternative, e.g. 19:30)',
|
||
'reservations.notes': 'Notes',
|
||
'reservations.notesPlaceholder': 'Additional notes...',
|
||
'reservations.meta.airline': 'Airline',
|
||
'reservations.meta.flightNumber': 'Flight No.',
|
||
'reservations.meta.from': 'From',
|
||
'reservations.meta.to': 'To',
|
||
'reservations.meta.trainNumber': 'Train No.',
|
||
'reservations.meta.platform': 'Platform',
|
||
'reservations.meta.seat': 'Seat',
|
||
'reservations.meta.checkIn': 'Check-in',
|
||
'reservations.meta.checkOut': 'Check-out',
|
||
'reservations.meta.linkAccommodation': 'Accommodation',
|
||
'reservations.meta.pickAccommodation': 'Link to accommodation',
|
||
'reservations.meta.noAccommodation': 'None',
|
||
'reservations.meta.hotelPlace': 'Accommodation',
|
||
'reservations.meta.pickHotel': 'Select accommodation',
|
||
'reservations.meta.fromDay': 'From',
|
||
'reservations.meta.toDay': 'To',
|
||
'reservations.meta.selectDay': 'Select day',
|
||
'reservations.type.flight': 'Flight',
|
||
'reservations.type.hotel': 'Accommodation',
|
||
'reservations.type.restaurant': 'Restaurant',
|
||
'reservations.type.train': 'Train',
|
||
'reservations.type.car': 'Rental Car',
|
||
'reservations.type.cruise': 'Cruise',
|
||
'reservations.type.event': 'Event',
|
||
'reservations.type.tour': 'Tour',
|
||
'reservations.type.other': 'Other',
|
||
'reservations.confirm.delete': 'Are you sure you want to delete the reservation "{name}"?',
|
||
'reservations.confirm.deleteTitle': 'Delete booking?',
|
||
'reservations.confirm.deleteBody': '"{name}" will be permanently deleted.',
|
||
'reservations.toast.updated': 'Reservation updated',
|
||
'reservations.toast.removed': 'Reservation deleted',
|
||
'reservations.toast.fileUploaded': 'File uploaded',
|
||
'reservations.toast.uploadError': 'Failed to upload',
|
||
'reservations.newTitle': 'New Reservation',
|
||
'reservations.bookingType': 'Booking Type',
|
||
'reservations.titleLabel': 'Title',
|
||
'reservations.titlePlaceholder': 'e.g. Lufthansa LH123, Hotel Adlon, ...',
|
||
'reservations.locationAddress': 'Location / Address',
|
||
'reservations.locationPlaceholder': 'Address, Airport, Hotel...',
|
||
'reservations.confirmationCode': 'Booking Code',
|
||
'reservations.confirmationPlaceholder': 'e.g. ABC12345',
|
||
'reservations.day': 'Day',
|
||
'reservations.noDay': 'No Day',
|
||
'reservations.place': 'Place',
|
||
'reservations.noPlace': 'No Place',
|
||
'reservations.pendingSave': 'will be saved…',
|
||
'reservations.uploading': 'Uploading...',
|
||
'reservations.attachFile': 'Attach file',
|
||
'reservations.linkExisting': 'Link existing file',
|
||
'reservations.toast.saveError': 'Failed to save',
|
||
'reservations.toast.updateError': 'Failed to update',
|
||
'reservations.toast.deleteError': 'Failed to delete',
|
||
'reservations.confirm.remove': 'Remove reservation for "{name}"?',
|
||
'reservations.linkAssignment': 'Link to day assignment',
|
||
'reservations.pickAssignment': 'Select an assignment from your plan...',
|
||
'reservations.noAssignment': 'No link (standalone)',
|
||
|
||
// Budget
|
||
'budget.title': 'Budget',
|
||
'budget.emptyTitle': 'No budget created yet',
|
||
'budget.emptyText': 'Create categories and entries to plan your travel budget',
|
||
'budget.emptyPlaceholder': 'Enter category name...',
|
||
'budget.createCategory': 'Create Category',
|
||
'budget.category': 'Category',
|
||
'budget.categoryName': 'Category Name',
|
||
'budget.table.name': 'Name',
|
||
'budget.table.total': 'Total',
|
||
'budget.table.persons': 'Persons',
|
||
'budget.table.days': 'Days',
|
||
'budget.table.perPerson': 'Per Person',
|
||
'budget.table.perDay': 'Per Day',
|
||
'budget.table.perPersonDay': 'P. p / Day',
|
||
'budget.table.note': 'Note',
|
||
'budget.newEntry': 'New Entry',
|
||
'budget.defaultEntry': 'New Entry',
|
||
'budget.defaultCategory': 'New Category',
|
||
'budget.total': 'Total',
|
||
'budget.totalBudget': 'Total Budget',
|
||
'budget.byCategory': 'By Category',
|
||
'budget.editTooltip': 'Click to edit',
|
||
'budget.confirm.deleteCategory': 'Are you sure you want to delete the category "{name}" with {count} entries?',
|
||
'budget.deleteCategory': 'Delete Category',
|
||
'budget.perPerson': 'Per Person',
|
||
'budget.paid': 'Paid',
|
||
'budget.open': 'Open',
|
||
'budget.noMembers': 'No members assigned',
|
||
'budget.settlement': 'Settlement',
|
||
'budget.settlementInfo': 'Click a member avatar on a budget item to mark them green — this means they paid. The settlement then shows who owes whom and how much.',
|
||
'budget.netBalances': 'Net Balances',
|
||
|
||
// Files
|
||
'files.title': 'Files',
|
||
'files.count': '{count} files',
|
||
'files.countSingular': '1 file',
|
||
'files.uploaded': '{count} uploaded',
|
||
'files.uploadError': 'Upload failed',
|
||
'files.dropzone': 'Drop files here',
|
||
'files.dropzoneHint': 'or click to browse',
|
||
'files.allowedTypes': 'Images, PDF, DOC, DOCX, XLS, XLSX, TXT, CSV · Max 50 MB',
|
||
'files.uploading': 'Uploading...',
|
||
'files.filterAll': 'All',
|
||
'files.filterPdf': 'PDFs',
|
||
'files.filterImages': 'Images',
|
||
'files.filterDocs': 'Documents',
|
||
'files.filterCollab': 'Collab Notes',
|
||
'files.sourceCollab': 'From Collab Notes',
|
||
'files.empty': 'No files yet',
|
||
'files.emptyHint': 'Upload files to attach them to your trip',
|
||
'files.openTab': 'Open in new tab',
|
||
'files.confirm.delete': 'Are you sure you want to delete this file?',
|
||
'files.toast.deleted': 'File deleted',
|
||
'files.toast.deleteError': 'Failed to delete file',
|
||
'files.sourcePlan': 'Day Plan',
|
||
'files.sourceBooking': 'Booking',
|
||
'files.attach': 'Attach',
|
||
'files.pasteHint': 'You can also paste images from clipboard (Ctrl+V)',
|
||
'files.trash': 'Trash',
|
||
'files.trashEmpty': 'Trash is empty',
|
||
'files.emptyTrash': 'Empty Trash',
|
||
'files.restore': 'Restore',
|
||
'files.star': 'Star',
|
||
'files.unstar': 'Unstar',
|
||
'files.assign': 'Assign',
|
||
'files.assignTitle': 'Assign File',
|
||
'files.assignPlace': 'Place',
|
||
'files.assignBooking': 'Booking',
|
||
'files.unassigned': 'Unassigned',
|
||
'files.unlink': 'Remove link',
|
||
'files.toast.trashed': 'Moved to trash',
|
||
'files.toast.restored': 'File restored',
|
||
'files.toast.trashEmptied': 'Trash emptied',
|
||
'files.toast.assigned': 'File assigned',
|
||
'files.toast.assignError': 'Assignment failed',
|
||
'files.toast.restoreError': 'Restore failed',
|
||
'files.confirm.permanentDelete': 'Permanently delete this file? This cannot be undone.',
|
||
'files.confirm.emptyTrash': 'Permanently delete all trashed files? This cannot be undone.',
|
||
'files.noteLabel': 'Note',
|
||
'files.notePlaceholder': 'Add a note...',
|
||
|
||
// Packing
|
||
'packing.title': 'Packing List',
|
||
'packing.empty': 'Packing list is empty',
|
||
'packing.import': 'Import',
|
||
'packing.importTitle': 'Import Packing List',
|
||
'packing.importHint': 'One item per line. Format: Category, Name, Weight in g (optional), Bag (optional), checked/unchecked (optional)',
|
||
'packing.importPlaceholder': 'Hygiene, Toothbrush\nClothing, T-Shirts, 200\nDocuments, Passport, , Carry-on\nElectronics, Charger, 50, Suitcase, checked',
|
||
'packing.importCsv': 'Load CSV/TXT',
|
||
'packing.importAction': 'Import {count}',
|
||
'packing.importSuccess': '{count} items imported',
|
||
'packing.importError': 'Import failed',
|
||
'packing.importEmpty': 'No items to import',
|
||
'packing.progress': '{packed} of {total} packed ({percent}%)',
|
||
'packing.clearChecked': 'Remove {count} checked',
|
||
'packing.clearCheckedShort': 'Remove {count}',
|
||
'packing.suggestions': 'Suggestions',
|
||
'packing.suggestionsTitle': 'Add Suggestions',
|
||
'packing.allSuggested': 'All suggestions added',
|
||
'packing.allPacked': 'All packed!',
|
||
'packing.addPlaceholder': 'Add new item...',
|
||
'packing.categoryPlaceholder': 'Category...',
|
||
'packing.filterAll': 'All',
|
||
'packing.filterOpen': 'Open',
|
||
'packing.filterDone': 'Done',
|
||
'packing.emptyTitle': 'Packing list is empty',
|
||
'packing.emptyHint': 'Add items or use the suggestions',
|
||
'packing.emptyFiltered': 'No items match this filter',
|
||
'packing.menuRename': 'Rename',
|
||
'packing.menuCheckAll': 'Check All',
|
||
'packing.menuUncheckAll': 'Uncheck All',
|
||
'packing.menuDeleteCat': 'Delete Category',
|
||
'packing.assignUser': 'Assign user',
|
||
'packing.noMembers': 'No trip members',
|
||
'packing.addItem': 'Add item',
|
||
'packing.addItemPlaceholder': 'Item name...',
|
||
'packing.addCategory': 'Add category',
|
||
'packing.newCategoryPlaceholder': 'Category name (e.g. Clothing)',
|
||
'packing.applyTemplate': 'Apply template',
|
||
'packing.template': 'Template',
|
||
'packing.templateApplied': '{count} items added from template',
|
||
'packing.templateError': 'Failed to apply template',
|
||
'packing.bags': 'Bags',
|
||
'packing.noBag': 'Unassigned',
|
||
'packing.totalWeight': 'Total weight',
|
||
'packing.bagName': 'Bag name...',
|
||
'packing.addBag': 'Add bag',
|
||
'packing.changeCategory': 'Change Category',
|
||
'packing.confirm.clearChecked': 'Are you sure you want to remove {count} checked items?',
|
||
'packing.confirm.deleteCat': 'Are you sure you want to delete the category "{name}" with {count} items?',
|
||
'packing.defaultCategory': 'Other',
|
||
'packing.toast.saveError': 'Failed to save',
|
||
'packing.toast.deleteError': 'Failed to delete',
|
||
'packing.toast.renameError': 'Failed to rename',
|
||
'packing.toast.addError': 'Failed to add',
|
||
|
||
// Packing suggestions
|
||
'packing.suggestions.items': [
|
||
{ name: 'Passport', category: 'Documents' },
|
||
{ name: 'ID Card', category: 'Documents' },
|
||
{ name: 'Travel Insurance', category: 'Documents' },
|
||
{ name: 'Flight Tickets', category: 'Documents' },
|
||
{ name: 'Credit Card', category: 'Finances' },
|
||
{ name: 'Cash', category: 'Finances' },
|
||
{ name: 'Visa', category: 'Documents' },
|
||
{ name: 'T-Shirts', category: 'Clothing' },
|
||
{ name: 'Pants', category: 'Clothing' },
|
||
{ name: 'Underwear', category: 'Clothing' },
|
||
{ name: 'Socks', category: 'Clothing' },
|
||
{ name: 'Jacket', category: 'Clothing' },
|
||
{ name: 'Sleepwear', category: 'Clothing' },
|
||
{ name: 'Swimwear', category: 'Clothing' },
|
||
{ name: 'Rain Jacket', category: 'Clothing' },
|
||
{ name: 'Comfortable Shoes', category: 'Clothing' },
|
||
{ name: 'Toothbrush', category: 'Toiletries' },
|
||
{ name: 'Toothpaste', category: 'Toiletries' },
|
||
{ name: 'Shampoo', category: 'Toiletries' },
|
||
{ name: 'Deodorant', category: 'Toiletries' },
|
||
{ name: 'Sunscreen', category: 'Toiletries' },
|
||
{ name: 'Razor', category: 'Toiletries' },
|
||
{ name: 'Charger', category: 'Electronics' },
|
||
{ name: 'Power Bank', category: 'Electronics' },
|
||
{ name: 'Headphones', category: 'Electronics' },
|
||
{ name: 'Travel Adapter', category: 'Electronics' },
|
||
{ name: 'Camera', category: 'Electronics' },
|
||
{ name: 'Pain Medication', category: 'Health' },
|
||
{ name: 'Band-Aids', category: 'Health' },
|
||
{ name: 'Disinfectant', category: 'Health' },
|
||
],
|
||
|
||
// Members / Sharing
|
||
'members.shareTrip': 'Share Trip',
|
||
'members.inviteUser': 'Invite User',
|
||
'members.selectUser': 'Select user…',
|
||
'members.invite': 'Invite',
|
||
'members.allHaveAccess': 'All users already have access.',
|
||
'members.access': 'Access',
|
||
'members.person': 'person',
|
||
'members.persons': 'persons',
|
||
'members.you': 'you',
|
||
'members.owner': 'Owner',
|
||
'members.leaveTrip': 'Leave trip',
|
||
'members.removeAccess': 'Remove access',
|
||
'members.confirmLeave': 'Leave trip? You will lose access.',
|
||
'members.confirmRemove': 'Remove access for this user?',
|
||
'members.loadError': 'Failed to load members',
|
||
'members.added': 'added',
|
||
'members.addError': 'Failed to add',
|
||
'members.removed': 'Member removed',
|
||
'members.removeError': 'Failed to remove',
|
||
|
||
// Categories (Admin)
|
||
'categories.title': 'Categories',
|
||
'categories.subtitle': 'Manage categories for places',
|
||
'categories.new': 'New Category',
|
||
'categories.empty': 'No categories yet',
|
||
'categories.namePlaceholder': 'Category name',
|
||
'categories.icon': 'Icon',
|
||
'categories.color': 'Color',
|
||
'categories.customColor': 'Choose custom color',
|
||
'categories.preview': 'Preview',
|
||
'categories.defaultName': 'Category',
|
||
'categories.update': 'Update',
|
||
'categories.create': 'Create',
|
||
'categories.confirm.delete': 'Delete category? Places in this category will not be deleted.',
|
||
'categories.toast.loadError': 'Failed to load categories',
|
||
'categories.toast.nameRequired': 'Please enter a name',
|
||
'categories.toast.updated': 'Category updated',
|
||
'categories.toast.created': 'Category created',
|
||
'categories.toast.saveError': 'Failed to save',
|
||
'categories.toast.deleted': 'Category deleted',
|
||
'categories.toast.deleteError': 'Failed to delete',
|
||
|
||
// Backup (Admin)
|
||
'backup.title': 'Data Backup',
|
||
'backup.subtitle': 'Database and all uploaded files',
|
||
'backup.refresh': 'Refresh',
|
||
'backup.upload': 'Upload Backup',
|
||
'backup.uploading': 'Uploading…',
|
||
'backup.create': 'Create Backup',
|
||
'backup.creating': 'Creating…',
|
||
'backup.empty': 'No backups yet',
|
||
'backup.createFirst': 'Create first backup',
|
||
'backup.download': 'Download',
|
||
'backup.restore': 'Restore',
|
||
'backup.confirm.restore': 'Restore backup "{name}"?\n\nAll current data will be replaced with the backup.',
|
||
'backup.confirm.uploadRestore': 'Upload and restore backup file "{name}"?\n\nAll current data will be overwritten.',
|
||
'backup.confirm.delete': 'Delete backup "{name}"?',
|
||
'backup.toast.loadError': 'Failed to load backups',
|
||
'backup.toast.created': 'Backup created successfully',
|
||
'backup.toast.createError': 'Failed to create backup',
|
||
'backup.toast.restored': 'Backup restored. Page will reload…',
|
||
'backup.toast.restoreError': 'Failed to restore',
|
||
'backup.toast.uploadError': 'Failed to upload',
|
||
'backup.toast.deleted': 'Backup deleted',
|
||
'backup.toast.deleteError': 'Failed to delete',
|
||
'backup.toast.downloadError': 'Download failed',
|
||
'backup.toast.settingsSaved': 'Auto-backup settings saved',
|
||
'backup.toast.settingsError': 'Failed to save settings',
|
||
'backup.auto.title': 'Auto-Backup',
|
||
'backup.auto.subtitle': 'Automatic backup on a schedule',
|
||
'backup.auto.enable': 'Enable auto-backup',
|
||
'backup.auto.enableHint': 'Backups will be created automatically on the chosen schedule',
|
||
'backup.auto.interval': 'Interval',
|
||
'backup.auto.hour': 'Run at hour',
|
||
'backup.auto.hourHint': 'Server local time ({format} format)',
|
||
'backup.auto.dayOfWeek': 'Day of week',
|
||
'backup.auto.dayOfMonth': 'Day of month',
|
||
'backup.auto.dayOfMonthHint': 'Limited to 1–28 for compatibility with all months',
|
||
'backup.auto.scheduleSummary': 'Schedule',
|
||
'backup.auto.summaryDaily': 'Every day at {hour}:00',
|
||
'backup.auto.summaryWeekly': 'Every {day} at {hour}:00',
|
||
'backup.auto.summaryMonthly': 'Day {day} of every month at {hour}:00',
|
||
'backup.auto.envLocked': 'Docker',
|
||
'backup.auto.envLockedHint': 'Auto-backup is configured via Docker environment variables. To change these settings, update your docker-compose.yml and restart the container.',
|
||
'backup.auto.copyEnv': 'Copy Docker env vars',
|
||
'backup.auto.envCopied': 'Docker env vars copied to clipboard',
|
||
'backup.auto.keepLabel': 'Delete old backups after',
|
||
'backup.dow.sunday': 'Sun',
|
||
'backup.dow.monday': 'Mon',
|
||
'backup.dow.tuesday': 'Tue',
|
||
'backup.dow.wednesday': 'Wed',
|
||
'backup.dow.thursday': 'Thu',
|
||
'backup.dow.friday': 'Fri',
|
||
'backup.dow.saturday': 'Sat',
|
||
'backup.interval.hourly': 'Hourly',
|
||
'backup.interval.daily': 'Daily',
|
||
'backup.interval.weekly': 'Weekly',
|
||
'backup.interval.monthly': 'Monthly',
|
||
'backup.keep.1day': '1 day',
|
||
'backup.keep.3days': '3 days',
|
||
'backup.keep.7days': '7 days',
|
||
'backup.keep.14days': '14 days',
|
||
'backup.keep.30days': '30 days',
|
||
'backup.keep.forever': 'Keep forever',
|
||
|
||
// Photos
|
||
'photos.allDays': 'All Days',
|
||
'photos.noPhotos': 'No photos yet',
|
||
'photos.uploadHint': 'Upload your travel photos',
|
||
'photos.clickToSelect': 'or click to select',
|
||
'photos.linkPlace': 'Link Place',
|
||
'photos.noPlace': 'No Place',
|
||
'photos.uploadN': '{n} photo(s) upload',
|
||
|
||
// Backup restore modal
|
||
'backup.restoreConfirmTitle': 'Restore Backup?',
|
||
'backup.restoreWarning': 'All current data (trips, places, users, uploads) will be permanently replaced by the backup. This action cannot be undone.',
|
||
'backup.restoreTip': 'Tip: Create a backup of the current state before restoring.',
|
||
'backup.restoreConfirm': 'Yes, restore',
|
||
|
||
// PDF
|
||
'pdf.travelPlan': 'Travel Plan',
|
||
'pdf.planned': 'Planned',
|
||
'pdf.costLabel': 'Cost EUR',
|
||
'pdf.preview': 'PDF Preview',
|
||
'pdf.saveAsPdf': 'Save as PDF',
|
||
|
||
// Planner
|
||
'planner.places': 'Places',
|
||
'planner.bookings': 'Bookings',
|
||
'planner.packingList': 'Packing List',
|
||
'planner.documents': 'Documents',
|
||
'planner.dayPlan': 'Day Plan',
|
||
'planner.reservations': 'Reservations',
|
||
'planner.minTwoPlaces': 'At least 2 places with coordinates needed',
|
||
'planner.noGeoPlaces': 'No places with coordinates available',
|
||
'planner.routeCalculated': 'Route calculated',
|
||
'planner.routeCalcFailed': 'Route could not be calculated',
|
||
'planner.routeError': 'Error calculating route',
|
||
'planner.routeOptimized': 'Route optimized',
|
||
'planner.reservationUpdated': 'Reservation updated',
|
||
'planner.reservationAdded': 'Reservation added',
|
||
'planner.confirmDeleteReservation': 'Delete reservation?',
|
||
'planner.reservationDeleted': 'Reservation deleted',
|
||
'planner.days': 'Days',
|
||
'planner.allPlaces': 'All Places',
|
||
'planner.totalPlaces': '{n} places total',
|
||
'planner.noDaysPlanned': 'No days planned yet',
|
||
'planner.editTrip': 'Edit trip \u2192',
|
||
'planner.placeOne': '1 place',
|
||
'planner.placeN': '{n} places',
|
||
'planner.addNote': 'Add note',
|
||
'planner.noEntries': 'No entries for this day',
|
||
'planner.addPlace': 'Add place/activity',
|
||
'planner.addPlaceShort': '+ Add place/activity',
|
||
'planner.resPending': 'Reservation pending · ',
|
||
'planner.resConfirmed': 'Reservation confirmed · ',
|
||
'planner.notePlaceholder': 'Note\u2026',
|
||
'planner.noteTimePlaceholder': 'Time (optional)',
|
||
'planner.noteExamplePlaceholder': 'e.g. S3 at 14:30 from central station, ferry from pier 7, lunch break\u2026',
|
||
'planner.totalCost': 'Total cost',
|
||
'planner.searchPlaces': 'Search places\u2026',
|
||
'planner.allCategories': 'All Categories',
|
||
'planner.noPlacesFound': 'No places found',
|
||
'planner.addFirstPlace': 'Add first place',
|
||
'planner.noReservations': 'No reservations',
|
||
'planner.addFirstReservation': 'Add first reservation',
|
||
'planner.new': 'New',
|
||
'planner.addToDay': '+ Day',
|
||
'planner.calculating': 'Calculating\u2026',
|
||
'planner.route': 'Route',
|
||
'planner.optimize': 'Optimize',
|
||
'planner.openGoogleMaps': 'Open in Google Maps',
|
||
'planner.selectDayHint': 'Select a day from the left list to see the day plan',
|
||
'planner.noPlacesForDay': 'No places for this day yet',
|
||
'planner.addPlacesLink': 'Add places \u2192',
|
||
'planner.minTotal': 'min. total',
|
||
'planner.noReservation': 'No reservation',
|
||
'planner.removeFromDay': 'Remove from day',
|
||
'planner.addToThisDay': 'Add to day',
|
||
'planner.overview': 'Overview',
|
||
'planner.noDays': 'No days yet',
|
||
'planner.editTripToAddDays': 'Edit trip to add days',
|
||
'planner.dayCount': '{n} Days',
|
||
'planner.clickToUnlock': 'Click to unlock',
|
||
'planner.keepPosition': 'Keep position during route optimization',
|
||
'planner.dayDetails': 'Day details',
|
||
'planner.dayN': 'Day {n}',
|
||
|
||
// Dashboard Stats
|
||
'stats.countries': 'Countries',
|
||
'stats.cities': 'Cities',
|
||
'stats.trips': 'Trips',
|
||
'stats.places': 'Places',
|
||
'stats.worldProgress': 'World Progress',
|
||
'stats.visited': 'visited',
|
||
'stats.remaining': 'remaining',
|
||
'stats.visitedCountries': 'Visited Countries',
|
||
|
||
// Day Detail Panel
|
||
'day.precipProb': 'Rain probability',
|
||
'day.precipitation': 'Precipitation',
|
||
'day.wind': 'Wind',
|
||
'day.sunrise': 'Sunrise',
|
||
'day.sunset': 'Sunset',
|
||
'day.hourlyForecast': 'Hourly Forecast',
|
||
'day.climateHint': 'Historical averages — real forecast available within 16 days of this date.',
|
||
'day.noWeather': 'No weather data available. Add a place with coordinates.',
|
||
'day.overview': 'Daily Overview',
|
||
'day.accommodation': 'Accommodation',
|
||
'day.addAccommodation': 'Add accommodation',
|
||
'day.hotelDayRange': 'Apply to days',
|
||
'day.noPlacesForHotel': 'Add places to your trip first',
|
||
'day.allDays': 'All',
|
||
'day.checkIn': 'Check-in',
|
||
'day.checkOut': 'Check-out',
|
||
'day.confirmation': 'Confirmation',
|
||
'day.editAccommodation': 'Edit accommodation',
|
||
'day.reservations': 'Reservations',
|
||
|
||
// Photos / Immich
|
||
'memories.title': 'Photos',
|
||
'memories.notConnected': 'Immich not connected',
|
||
'memories.notConnectedHint': 'Connect your Immich instance in Settings to see your trip photos here.',
|
||
'memories.noDates': 'Add dates to your trip to load photos.',
|
||
'memories.noPhotos': 'No photos found',
|
||
'memories.noPhotosHint': 'No photos found in Immich for this trip\'s date range.',
|
||
'memories.photosFound': 'photos',
|
||
'memories.fromOthers': 'from others',
|
||
'memories.sharePhotos': 'Share photos',
|
||
'memories.sharing': 'Sharing',
|
||
'memories.reviewTitle': 'Review your photos',
|
||
'memories.reviewHint': 'Click photos to exclude them from sharing.',
|
||
'memories.shareCount': 'Share {count} photos',
|
||
'memories.immichUrl': 'Immich Server URL',
|
||
'memories.immichApiKey': 'API Key',
|
||
'memories.testConnection': 'Test connection',
|
||
'memories.connected': 'Connected',
|
||
'memories.disconnected': 'Not connected',
|
||
'memories.connectionSuccess': 'Connected to Immich',
|
||
'memories.connectionError': 'Could not connect to Immich',
|
||
'memories.saved': 'Immich settings saved',
|
||
'memories.addPhotos': 'Add photos',
|
||
'memories.selectPhotos': 'Select photos from Immich',
|
||
'memories.selectHint': 'Tap photos to select them.',
|
||
'memories.selected': 'selected',
|
||
'memories.addSelected': 'Add {count} photos',
|
||
'memories.alreadyAdded': 'Added',
|
||
'memories.private': 'Private',
|
||
'memories.stopSharing': 'Stop sharing',
|
||
'memories.oldest': 'Oldest first',
|
||
'memories.newest': 'Newest first',
|
||
'memories.allLocations': 'All locations',
|
||
'memories.tripDates': 'Trip dates',
|
||
'memories.allPhotos': 'All photos',
|
||
'memories.confirmShareTitle': 'Share with trip members?',
|
||
'memories.confirmShareHint': '{count} photos will be visible to all members of this trip. You can make individual photos private later.',
|
||
'memories.confirmShareButton': 'Share photos',
|
||
|
||
// Collab Addon
|
||
'collab.tabs.chat': 'Chat',
|
||
'collab.tabs.notes': 'Notes',
|
||
'collab.tabs.polls': 'Polls',
|
||
'collab.whatsNext.title': "What's Next",
|
||
'collab.whatsNext.today': 'Today',
|
||
'collab.whatsNext.tomorrow': 'Tomorrow',
|
||
'collab.whatsNext.empty': 'No upcoming activities',
|
||
'collab.whatsNext.until': 'to',
|
||
'collab.whatsNext.emptyHint': 'Activities with times will appear here',
|
||
'collab.chat.send': 'Send',
|
||
'collab.chat.placeholder': 'Type a message...',
|
||
'collab.chat.empty': 'Start the conversation',
|
||
'collab.chat.emptyHint': 'Messages are shared with all trip members',
|
||
'collab.chat.emptyDesc': 'Share ideas, plans, and updates with your travel group',
|
||
'collab.chat.today': 'Today',
|
||
'collab.chat.yesterday': 'Yesterday',
|
||
'collab.chat.deletedMessage': 'deleted a message',
|
||
'collab.chat.reply': 'Reply',
|
||
'collab.chat.loadMore': 'Load older messages',
|
||
'collab.chat.justNow': 'just now',
|
||
'collab.chat.minutesAgo': '{n}m ago',
|
||
'collab.chat.hoursAgo': '{n}h ago',
|
||
'collab.notes.title': 'Notes',
|
||
'collab.notes.new': 'New Note',
|
||
'collab.notes.empty': 'No notes yet',
|
||
'collab.notes.emptyHint': 'Start capturing ideas and plans',
|
||
'collab.notes.all': 'All',
|
||
'collab.notes.titlePlaceholder': 'Note title',
|
||
'collab.notes.contentPlaceholder': 'Write something...',
|
||
'collab.notes.categoryPlaceholder': 'Category',
|
||
'collab.notes.newCategory': 'New category...',
|
||
'collab.notes.category': 'Category',
|
||
'collab.notes.noCategory': 'No category',
|
||
'collab.notes.color': 'Color',
|
||
'collab.notes.save': 'Save',
|
||
'collab.notes.cancel': 'Cancel',
|
||
'collab.notes.edit': 'Edit',
|
||
'collab.notes.delete': 'Delete',
|
||
'collab.notes.pin': 'Pin',
|
||
'collab.notes.unpin': 'Unpin',
|
||
'collab.notes.daysAgo': '{n}d ago',
|
||
'collab.notes.categorySettings': 'Manage Categories',
|
||
'collab.notes.create': 'Create',
|
||
'collab.notes.website': 'Website',
|
||
'collab.notes.websitePlaceholder': 'https://...',
|
||
'collab.notes.attachFiles': 'Attach files',
|
||
'collab.notes.noCategoriesYet': 'No categories yet',
|
||
'collab.notes.emptyDesc': 'Create a note to get started',
|
||
'collab.polls.title': 'Polls',
|
||
'collab.polls.new': 'New Poll',
|
||
'collab.polls.empty': 'No polls yet',
|
||
'collab.polls.emptyHint': 'Ask the group and vote together',
|
||
'collab.polls.question': 'Question',
|
||
'collab.polls.questionPlaceholder': 'What should we do?',
|
||
'collab.polls.addOption': '+ Add option',
|
||
'collab.polls.optionPlaceholder': 'Option {n}',
|
||
'collab.polls.create': 'Create Poll',
|
||
'collab.polls.close': 'Close',
|
||
'collab.polls.closed': 'Closed',
|
||
'collab.polls.votes': '{n} votes',
|
||
'collab.polls.vote': '{n} vote',
|
||
'collab.polls.multipleChoice': 'Multiple choice',
|
||
'collab.polls.multiChoice': 'Multiple choice',
|
||
'collab.polls.deadline': 'Deadline',
|
||
'collab.polls.option': 'Option',
|
||
'collab.polls.options': 'Options',
|
||
'collab.polls.delete': 'Delete',
|
||
'collab.polls.closedSection': 'Closed',
|
||
|
||
// Permissions
|
||
'admin.tabs.permissions': 'Permissions',
|
||
'perm.title': 'Permission Settings',
|
||
'perm.subtitle': 'Control who can perform actions across the application',
|
||
'perm.saved': 'Permission settings saved',
|
||
'perm.resetDefaults': 'Reset to defaults',
|
||
'perm.customized': 'customized',
|
||
'perm.level.admin': 'Admin only',
|
||
'perm.level.tripOwner': 'Trip owner',
|
||
'perm.level.tripMember': 'Trip members',
|
||
'perm.level.everybody': 'Everyone',
|
||
'perm.cat.trip': 'Trip Management',
|
||
'perm.cat.members': 'Member Management',
|
||
'perm.cat.files': 'Files',
|
||
'perm.cat.content': 'Content & Schedule',
|
||
'perm.cat.extras': 'Budget, Packing & Collaboration',
|
||
'perm.action.trip_create': 'Create trips',
|
||
'perm.action.trip_edit': 'Edit trip details',
|
||
'perm.action.trip_delete': 'Delete trips',
|
||
'perm.action.trip_archive': 'Archive / unarchive trips',
|
||
'perm.action.trip_cover_upload': 'Upload cover image',
|
||
'perm.action.member_manage': 'Add / remove members',
|
||
'perm.action.file_upload': 'Upload files',
|
||
'perm.action.file_edit': 'Edit file metadata',
|
||
'perm.action.file_delete': 'Delete files',
|
||
'perm.action.place_edit': 'Add / edit / delete places',
|
||
'perm.action.day_edit': 'Edit days, notes & assignments',
|
||
'perm.action.reservation_edit': 'Manage reservations',
|
||
'perm.action.budget_edit': 'Manage budget',
|
||
'perm.action.packing_edit': 'Manage packing lists',
|
||
'perm.action.collab_edit': 'Collaboration (notes, polls, chat)',
|
||
'perm.action.share_manage': 'Manage share links',
|
||
'perm.actionHint.trip_create': 'Who can create new trips',
|
||
'perm.actionHint.trip_edit': 'Who can change trip name, dates, description and currency',
|
||
'perm.actionHint.trip_delete': 'Who can permanently delete a trip',
|
||
'perm.actionHint.trip_archive': 'Who can archive or unarchive a trip',
|
||
'perm.actionHint.trip_cover_upload': 'Who can upload or change the cover image',
|
||
'perm.actionHint.member_manage': 'Who can invite or remove trip members',
|
||
'perm.actionHint.file_upload': 'Who can upload files to a trip',
|
||
'perm.actionHint.file_edit': 'Who can edit file descriptions and links',
|
||
'perm.actionHint.file_delete': 'Who can move files to trash or permanently delete them',
|
||
'perm.actionHint.place_edit': 'Who can add, edit or delete places',
|
||
'perm.actionHint.day_edit': 'Who can edit days, day notes and place assignments',
|
||
'perm.actionHint.reservation_edit': 'Who can create, edit or delete reservations',
|
||
'perm.actionHint.budget_edit': 'Who can create, edit or delete budget items',
|
||
'perm.actionHint.packing_edit': 'Who can manage packing items and bags',
|
||
'perm.actionHint.collab_edit': 'Who can create notes, polls and send messages',
|
||
'perm.actionHint.share_manage': 'Who can create or delete public share links',
|
||
}
|
||
|
||
export default en
|