mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-22 14:51:45 +00:00
perf: major trip planner performance overhaul (#218)
Store & re-render optimization: - TripPlannerPage uses selective Zustand selectors instead of full store - placesSlice only updates affected days on place update/delete - Route calculation only reacts to selected day's assignments - DayPlanSidebar uses stable action refs instead of full store Map marker performance: - Shared photoService for PlaceAvatar and MapView (single cache, no duplicate requests) - Client-side base64 thumbnail generation via canvas (CORS-safe for Wikimedia) - Map markers use base64 data URL <img> tags for smooth zoom (no external image decode) - Sidebar uses same base64 thumbnails with IntersectionObserver for visible-first loading - Icon cache prevents duplicate L.divIcon creation - MarkerClusterGroup with animate:false and optimized chunk settings - Photo fetch deduplication and batched state updates Server optimizations: - Wikimedia image size reduced to 400px (from 600px) - Photo cache: 5min TTL for errors (was 12h), prevents stale 404 caching - Removed unused image-proxy endpoint UX improvements: - Splash screen with plane animation during initial photo preload - Markdown rendering in DayPlanSidebar place descriptions - Missing i18n keys added, all 12 languages synced to 1376 keys
This commit is contained in:
@@ -248,6 +248,7 @@ const ar: Record<string, string | { name: string; category: string }[]> = {
|
||||
'settings.roleAdmin': 'مسؤول',
|
||||
'settings.oidcLinked': 'مرتبط مع',
|
||||
'settings.changePassword': 'تغيير كلمة المرور',
|
||||
'settings.mustChangePassword': 'يجب عليك تغيير كلمة المرور قبل المتابعة. يرجى تعيين كلمة مرور جديدة أدناه.',
|
||||
'settings.currentPassword': 'كلمة المرور الحالية',
|
||||
'settings.currentPasswordRequired': 'كلمة المرور الحالية مطلوبة',
|
||||
'settings.newPassword': 'كلمة المرور الجديدة',
|
||||
@@ -695,7 +696,6 @@ const ar: Record<string, string | { name: string; category: string }[]> = {
|
||||
'atlas.statsTab': 'الإحصائيات',
|
||||
'atlas.bucketTab': 'قائمة الأمنيات',
|
||||
'atlas.addBucket': 'إضافة إلى قائمة الأمنيات',
|
||||
'atlas.bucketNamePlaceholder': 'مكان أو وجهة...',
|
||||
'atlas.bucketNotesPlaceholder': 'ملاحظات (اختياري)',
|
||||
'atlas.bucketEmpty': 'قائمة أمنياتك فارغة',
|
||||
'atlas.bucketEmptyHint': 'أضف أماكن تحلم بزيارتها',
|
||||
@@ -708,7 +708,6 @@ const ar: Record<string, string | { name: string; category: string }[]> = {
|
||||
'atlas.nextTrip': 'الرحلة القادمة',
|
||||
'atlas.daysLeft': 'يوم متبقٍ',
|
||||
'atlas.streak': 'سلسلة',
|
||||
'atlas.year': 'سنة',
|
||||
'atlas.years': 'سنوات',
|
||||
'atlas.yearInRow': 'سنة متتالية',
|
||||
'atlas.yearsInRow': 'سنوات متتالية',
|
||||
@@ -738,6 +737,7 @@ const ar: Record<string, string | { name: string; category: string }[]> = {
|
||||
'trip.tabs.budget': 'الميزانية',
|
||||
'trip.tabs.files': 'الملفات',
|
||||
'trip.loading': 'جارٍ تحميل الرحلة...',
|
||||
'trip.loadingPhotos': 'جارٍ تحميل صور الأماكن...',
|
||||
'trip.mobilePlan': 'الخطة',
|
||||
'trip.mobilePlaces': 'الأماكن',
|
||||
'trip.toast.placeUpdated': 'تم تحديث المكان',
|
||||
|
||||
@@ -294,6 +294,7 @@ const br: Record<string, string | { name: string; category: string }[]> = {
|
||||
'settings.mcp.toast.createError': 'Falha ao criar token',
|
||||
'settings.mcp.toast.deleted': 'Token excluído',
|
||||
'settings.mcp.toast.deleteError': 'Falha ao excluir token',
|
||||
'settings.mustChangePassword': 'Você deve alterar sua senha antes de continuar. Defina uma nova senha abaixo.',
|
||||
|
||||
// Login
|
||||
'login.error': 'Falha no login. Verifique suas credenciais.',
|
||||
@@ -503,11 +504,13 @@ const br: Record<string, string | { name: string; category: string }[]> = {
|
||||
'admin.addons.disabled': 'Desativado',
|
||||
'admin.addons.type.trip': 'Viagem',
|
||||
'admin.addons.type.global': 'Global',
|
||||
'admin.addons.type.integration': 'Integração',
|
||||
'admin.addons.tripHint': 'Disponível como aba em cada viagem',
|
||||
'admin.addons.globalHint': 'Disponível como seção própria na navegação principal',
|
||||
'admin.addons.toast.updated': 'Complemento atualizado',
|
||||
'admin.addons.toast.error': 'Falha ao atualizar complemento',
|
||||
'admin.addons.noAddons': 'Nenhum complemento disponível',
|
||||
'admin.addons.integrationHint': 'Serviços de backend e integrações de API sem página dedicada',
|
||||
// Weather info
|
||||
'admin.weather.title': 'Dados meteorológicos',
|
||||
'admin.weather.badge': 'Desde 24 de março de 2026',
|
||||
@@ -675,7 +678,6 @@ const br: Record<string, string | { name: string; category: string }[]> = {
|
||||
'atlas.statsTab': 'Estatísticas',
|
||||
'atlas.bucketTab': 'Lista de desejos',
|
||||
'atlas.addBucket': 'Adicionar à lista de desejos',
|
||||
'atlas.bucketNamePlaceholder': 'Lugar ou destino...',
|
||||
'atlas.bucketNotesPlaceholder': 'Notas (opcional)',
|
||||
'atlas.bucketEmpty': 'Sua lista de desejos está vazia',
|
||||
'atlas.bucketEmptyHint': 'Adicione lugares que sonha em visitar',
|
||||
@@ -688,7 +690,6 @@ const br: Record<string, string | { name: string; category: string }[]> = {
|
||||
'atlas.nextTrip': 'Próxima viagem',
|
||||
'atlas.daysLeft': 'dias restantes',
|
||||
'atlas.streak': 'Sequência',
|
||||
'atlas.year': 'ano',
|
||||
'atlas.years': 'anos',
|
||||
'atlas.yearInRow': 'ano seguido',
|
||||
'atlas.yearsInRow': 'anos seguidos',
|
||||
@@ -730,6 +731,7 @@ const br: Record<string, string | { name: string; category: string }[]> = {
|
||||
'trip.toast.reservationAdded': 'Reserva adicionada',
|
||||
'trip.toast.deleted': 'Excluído',
|
||||
'trip.confirm.deletePlace': 'Tem certeza de que deseja excluir este lugar?',
|
||||
'trip.loadingPhotos': 'Carregando fotos dos lugares...',
|
||||
|
||||
// Day Plan Sidebar
|
||||
'dayplan.emptyDay': 'Nenhum lugar planejado para este dia',
|
||||
@@ -1414,6 +1416,20 @@ const br: Record<string, string | { name: string; category: string }[]> = {
|
||||
|
||||
// Permissions
|
||||
'admin.tabs.permissions': 'Permissões',
|
||||
'admin.tabs.mcpTokens': 'Tokens MCP',
|
||||
'admin.mcpTokens.title': 'Tokens MCP',
|
||||
'admin.mcpTokens.subtitle': 'Gerenciar tokens de API de todos os usuários',
|
||||
'admin.mcpTokens.owner': 'Proprietário',
|
||||
'admin.mcpTokens.tokenName': 'Nome do Token',
|
||||
'admin.mcpTokens.created': 'Criado',
|
||||
'admin.mcpTokens.lastUsed': 'Último uso',
|
||||
'admin.mcpTokens.never': 'Nunca',
|
||||
'admin.mcpTokens.empty': 'Nenhum token MCP foi criado ainda',
|
||||
'admin.mcpTokens.deleteTitle': 'Excluir Token',
|
||||
'admin.mcpTokens.deleteMessage': 'Isso revogará o token imediatamente. O usuário perderá o acesso MCP por este token.',
|
||||
'admin.mcpTokens.deleteSuccess': 'Token excluído',
|
||||
'admin.mcpTokens.deleteError': 'Falha ao excluir token',
|
||||
'admin.mcpTokens.loadError': 'Falha ao carregar tokens',
|
||||
'perm.title': 'Configurações de Permissões',
|
||||
'perm.subtitle': 'Controle quem pode realizar ações no aplicativo',
|
||||
'perm.saved': 'Configurações de permissões salvas',
|
||||
|
||||
@@ -695,7 +695,6 @@ const cs: Record<string, string | { name: string; category: string }[]> = {
|
||||
'atlas.statsTab': 'Statistiky',
|
||||
'atlas.bucketTab': 'Bucket List',
|
||||
'atlas.addBucket': 'Přidat na Bucket List',
|
||||
'atlas.bucketNamePlaceholder': 'Místo nebo destinace...',
|
||||
'atlas.bucketNotesPlaceholder': 'Poznámky (volitelné)',
|
||||
'atlas.bucketEmpty': 'Váš seznam přání je prázdný',
|
||||
'atlas.bucketEmptyHint': 'Přidejte místa, která sníte navštívit',
|
||||
@@ -738,6 +737,7 @@ const cs: Record<string, string | { name: string; category: string }[]> = {
|
||||
'trip.tabs.budget': 'Rozpočet',
|
||||
'trip.tabs.files': 'Soubory',
|
||||
'trip.loading': 'Načítání cesty...',
|
||||
'trip.loadingPhotos': 'Načítání fotek míst...',
|
||||
'trip.mobilePlan': 'Plán',
|
||||
'trip.mobilePlaces': 'Místa',
|
||||
'trip.toast.placeUpdated': 'Místo bylo aktualizováno',
|
||||
|
||||
@@ -243,6 +243,7 @@ const de: Record<string, string | { name: string; category: string }[]> = {
|
||||
'settings.roleAdmin': 'Administrator',
|
||||
'settings.oidcLinked': 'Verknüpft mit',
|
||||
'settings.changePassword': 'Passwort ändern',
|
||||
'settings.mustChangePassword': 'Sie müssen Ihr Passwort ändern, bevor Sie fortfahren können. Bitte legen Sie unten ein neues Passwort fest.',
|
||||
'settings.currentPassword': 'Aktuelles Passwort',
|
||||
'settings.currentPasswordRequired': 'Aktuelles Passwort wird benötigt',
|
||||
'settings.newPassword': 'Neues Passwort',
|
||||
@@ -693,7 +694,6 @@ const de: Record<string, string | { name: string; category: string }[]> = {
|
||||
'atlas.statsTab': 'Statistik',
|
||||
'atlas.bucketTab': 'Bucket List',
|
||||
'atlas.addBucket': 'Zur Bucket List hinzufügen',
|
||||
'atlas.bucketNamePlaceholder': 'Ort oder Reiseziel...',
|
||||
'atlas.bucketNotesPlaceholder': 'Notizen (optional)',
|
||||
'atlas.bucketEmpty': 'Deine Bucket List ist leer',
|
||||
'atlas.bucketEmptyHint': 'Füge Orte hinzu, die du besuchen möchtest',
|
||||
@@ -706,7 +706,6 @@ const de: Record<string, string | { name: string; category: string }[]> = {
|
||||
'atlas.nextTrip': 'Nächster Trip',
|
||||
'atlas.daysLeft': 'Tage',
|
||||
'atlas.streak': 'Streak',
|
||||
'atlas.year': 'Jahr',
|
||||
'atlas.years': 'Jahre',
|
||||
'atlas.yearInRow': 'Jahr in Folge',
|
||||
'atlas.yearsInRow': 'Jahre in Folge',
|
||||
@@ -736,6 +735,7 @@ const de: Record<string, string | { name: string; category: string }[]> = {
|
||||
'trip.tabs.budget': 'Budget',
|
||||
'trip.tabs.files': 'Dateien',
|
||||
'trip.loading': 'Reise wird geladen...',
|
||||
'trip.loadingPhotos': 'Fotos der Orte werden geladen...',
|
||||
'trip.mobilePlan': 'Planung',
|
||||
'trip.mobilePlaces': 'Orte',
|
||||
'trip.toast.placeUpdated': 'Ort aktualisiert',
|
||||
|
||||
@@ -732,6 +732,7 @@ const en: Record<string, string | { name: string; category: string }[]> = {
|
||||
'trip.tabs.budget': 'Budget',
|
||||
'trip.tabs.files': 'Files',
|
||||
'trip.loading': 'Loading trip...',
|
||||
'trip.loadingPhotos': 'Loading place photos...',
|
||||
'trip.mobilePlan': 'Plan',
|
||||
'trip.mobilePlaces': 'Places',
|
||||
'trip.toast.placeUpdated': 'Place updated',
|
||||
|
||||
@@ -244,6 +244,7 @@ const es: Record<string, string> = {
|
||||
'settings.roleAdmin': 'Administrador',
|
||||
'settings.oidcLinked': 'Vinculado con',
|
||||
'settings.changePassword': 'Cambiar contraseña',
|
||||
'settings.mustChangePassword': 'Debe cambiar su contraseña antes de continuar. Establezca una nueva contraseña a continuación.',
|
||||
'settings.currentPassword': 'Contraseña actual',
|
||||
'settings.newPassword': 'Nueva contraseña',
|
||||
'settings.confirmPassword': 'Confirmar nueva contraseña',
|
||||
@@ -697,9 +698,7 @@ const es: Record<string, string> = {
|
||||
'atlas.addToBucket': 'Añadir a lista de deseos',
|
||||
'atlas.addPoi': 'Añadir lugar',
|
||||
'atlas.searchCountry': 'Buscar un país...',
|
||||
'atlas.bucketNamePlaceholder': 'Nombre (país, ciudad, lugar…)',
|
||||
'atlas.month': 'Mes',
|
||||
'atlas.year': 'Año',
|
||||
'atlas.addToBucketHint': 'Guardar como lugar que quieres visitar',
|
||||
'atlas.bucketWhen': '¿Cuándo planeas visitarlo?',
|
||||
|
||||
@@ -712,6 +711,7 @@ const es: Record<string, string> = {
|
||||
'trip.tabs.budget': 'Presupuesto',
|
||||
'trip.tabs.files': 'Archivos',
|
||||
'trip.loading': 'Cargando viaje...',
|
||||
'trip.loadingPhotos': 'Cargando fotos de los lugares...',
|
||||
'trip.mobilePlan': 'Plan',
|
||||
'trip.mobilePlaces': 'Lugares',
|
||||
'trip.toast.placeUpdated': 'Lugar actualizado',
|
||||
|
||||
@@ -243,6 +243,7 @@ const fr: Record<string, string> = {
|
||||
'settings.roleAdmin': 'Administrateur',
|
||||
'settings.oidcLinked': 'Lié avec',
|
||||
'settings.changePassword': 'Changer le mot de passe',
|
||||
'settings.mustChangePassword': 'Vous devez changer votre mot de passe avant de continuer. Veuillez définir un nouveau mot de passe ci-dessous.',
|
||||
'settings.currentPassword': 'Mot de passe actuel',
|
||||
'settings.currentPasswordRequired': 'Le mot de passe actuel est requis',
|
||||
'settings.newPassword': 'Nouveau mot de passe',
|
||||
@@ -720,9 +721,7 @@ const fr: Record<string, string> = {
|
||||
'atlas.addToBucket': 'Ajouter à la bucket list',
|
||||
'atlas.addPoi': 'Ajouter un lieu',
|
||||
'atlas.searchCountry': 'Rechercher un pays…',
|
||||
'atlas.bucketNamePlaceholder': 'Nom (pays, ville, lieu…)',
|
||||
'atlas.month': 'Mois',
|
||||
'atlas.year': 'Année',
|
||||
'atlas.addToBucketHint': 'Sauvegarder comme lieu à visiter',
|
||||
'atlas.bucketWhen': 'Quand prévoyez-vous d\'y aller ?',
|
||||
|
||||
@@ -735,6 +734,7 @@ const fr: Record<string, string> = {
|
||||
'trip.tabs.budget': 'Budget',
|
||||
'trip.tabs.files': 'Fichiers',
|
||||
'trip.loading': 'Chargement du voyage…',
|
||||
'trip.loadingPhotos': 'Chargement des photos des lieux...',
|
||||
'trip.mobilePlan': 'Plan',
|
||||
'trip.mobilePlaces': 'Lieux',
|
||||
'trip.toast.placeUpdated': 'Lieu mis à jour',
|
||||
|
||||
@@ -246,6 +246,7 @@ const hu: Record<string, string | { name: string; category: string }[]> = {
|
||||
'settings.mfa.toastEnabled': 'Kétfaktoros hitelesítés engedélyezve',
|
||||
'settings.mfa.toastDisabled': 'Kétfaktoros hitelesítés kikapcsolva',
|
||||
'settings.mfa.demoBlocked': 'Demo módban nem érhető el',
|
||||
'settings.mustChangePassword': 'A folytatás előtt meg kell változtatnod a jelszavad. Kérjük, adj meg egy új jelszót alább.',
|
||||
'admin.notifications.title': 'Értesítések',
|
||||
'admin.notifications.hint': 'Válasszon értesítési csatornát. Egyszerre csak egy lehet aktív.',
|
||||
'admin.notifications.none': 'Kikapcsolva',
|
||||
@@ -746,6 +747,7 @@ const hu: Record<string, string | { name: string; category: string }[]> = {
|
||||
'trip.toast.reservationAdded': 'Foglalás hozzáadva',
|
||||
'trip.toast.deleted': 'Törölve',
|
||||
'trip.confirm.deletePlace': 'Biztosan törölni szeretnéd ezt a helyet?',
|
||||
'trip.loadingPhotos': 'Helyek fotóinak betöltése...',
|
||||
|
||||
// Napi terv oldalsáv
|
||||
'dayplan.emptyDay': 'Nincs tervezett hely erre a napra',
|
||||
|
||||
@@ -246,6 +246,7 @@ const it: Record<string, string | { name: string; category: string }[]> = {
|
||||
'settings.mfa.toastEnabled': 'Autenticazione a due fattori abilitata',
|
||||
'settings.mfa.toastDisabled': 'Autenticazione a due fattori disabilitata',
|
||||
'settings.mfa.demoBlocked': 'Non disponibile in modalità demo',
|
||||
'settings.mustChangePassword': 'Devi cambiare la password prima di continuare. Imposta una nuova password qui sotto.',
|
||||
'admin.notifications.title': 'Notifiche',
|
||||
'admin.notifications.hint': 'Scegli un canale di notifica. Solo uno può essere attivo alla volta.',
|
||||
'admin.notifications.none': 'Disattivato',
|
||||
@@ -691,7 +692,6 @@ const it: Record<string, string | { name: string; category: string }[]> = {
|
||||
'atlas.statsTab': 'Statistiche',
|
||||
'atlas.bucketTab': 'Lista desideri',
|
||||
'atlas.addBucket': 'Aggiungi alla lista desideri',
|
||||
'atlas.bucketNamePlaceholder': 'Luogo o destinazione...',
|
||||
'atlas.bucketNotesPlaceholder': 'Note (opzionale)',
|
||||
'atlas.bucketEmpty': 'La tua lista desideri è vuota',
|
||||
'atlas.bucketEmptyHint': 'Aggiungi luoghi che sogni di visitare',
|
||||
@@ -724,6 +724,7 @@ const it: Record<string, string | { name: string; category: string }[]> = {
|
||||
'atlas.tripPlural': 'Viaggi',
|
||||
'atlas.placeVisited': 'Luogo visitato',
|
||||
'atlas.placesVisited': 'Luoghi visitati',
|
||||
'atlas.searchCountry': 'Cerca un paese...',
|
||||
|
||||
// Trip Planner
|
||||
'trip.tabs.plan': 'Programma',
|
||||
@@ -746,6 +747,7 @@ const it: Record<string, string | { name: string; category: string }[]> = {
|
||||
'trip.toast.reservationAdded': 'Prenotazione aggiunta',
|
||||
'trip.toast.deleted': 'Eliminato',
|
||||
'trip.confirm.deletePlace': 'Sei sicuro di voler eliminare questo luogo?',
|
||||
'trip.loadingPhotos': 'Caricamento foto dei luoghi...',
|
||||
|
||||
// Day Plan Sidebar
|
||||
'dayplan.emptyDay': 'Nessun luogo programmato per questo giorno',
|
||||
|
||||
@@ -243,6 +243,7 @@ const nl: Record<string, string> = {
|
||||
'settings.roleAdmin': 'Beheerder',
|
||||
'settings.oidcLinked': 'Gekoppeld met',
|
||||
'settings.changePassword': 'Wachtwoord wijzigen',
|
||||
'settings.mustChangePassword': 'U moet uw wachtwoord wijzigen voordat u kunt doorgaan. Stel hieronder een nieuw wachtwoord in.',
|
||||
'settings.currentPassword': 'Huidig wachtwoord',
|
||||
'settings.currentPasswordRequired': 'Huidig wachtwoord is verplicht',
|
||||
'settings.newPassword': 'Nieuw wachtwoord',
|
||||
@@ -720,9 +721,7 @@ const nl: Record<string, string> = {
|
||||
'atlas.addToBucket': 'Aan bucket list toevoegen',
|
||||
'atlas.addPoi': 'Plaats toevoegen',
|
||||
'atlas.searchCountry': 'Zoek een land...',
|
||||
'atlas.bucketNamePlaceholder': 'Naam (land, stad, plek…)',
|
||||
'atlas.month': 'Maand',
|
||||
'atlas.year': 'Jaar',
|
||||
'atlas.addToBucketHint': 'Opslaan als plek die je wilt bezoeken',
|
||||
'atlas.bucketWhen': 'Wanneer ben je van plan te gaan?',
|
||||
|
||||
@@ -735,6 +734,7 @@ const nl: Record<string, string> = {
|
||||
'trip.tabs.budget': 'Budget',
|
||||
'trip.tabs.files': 'Bestanden',
|
||||
'trip.loading': 'Reis laden...',
|
||||
'trip.loadingPhotos': 'Plaatsfoto laden...',
|
||||
'trip.mobilePlan': 'Plan',
|
||||
'trip.mobilePlaces': 'Plaatsen',
|
||||
'trip.toast.placeUpdated': 'Plaats bijgewerkt',
|
||||
|
||||
@@ -243,6 +243,7 @@ const ru: Record<string, string> = {
|
||||
'settings.roleAdmin': 'Администратор',
|
||||
'settings.oidcLinked': 'Связан с',
|
||||
'settings.changePassword': 'Изменить пароль',
|
||||
'settings.mustChangePassword': 'Вы должны сменить пароль перед продолжением. Пожалуйста, установите новый пароль ниже.',
|
||||
'settings.currentPassword': 'Текущий пароль',
|
||||
'settings.currentPasswordRequired': 'Текущий пароль обязателен',
|
||||
'settings.newPassword': 'Новый пароль',
|
||||
@@ -720,9 +721,7 @@ const ru: Record<string, string> = {
|
||||
'atlas.addToBucket': 'В список желаний',
|
||||
'atlas.addPoi': 'Добавить место',
|
||||
'atlas.searchCountry': 'Поиск страны...',
|
||||
'atlas.bucketNamePlaceholder': 'Название (страна, город, место…)',
|
||||
'atlas.month': 'Месяц',
|
||||
'atlas.year': 'Год',
|
||||
'atlas.addToBucketHint': 'Сохранить как место для посещения',
|
||||
'atlas.bucketWhen': 'Когда вы планируете поехать?',
|
||||
|
||||
@@ -735,6 +734,7 @@ const ru: Record<string, string> = {
|
||||
'trip.tabs.budget': 'Бюджет',
|
||||
'trip.tabs.files': 'Файлы',
|
||||
'trip.loading': 'Загрузка поездки...',
|
||||
'trip.loadingPhotos': 'Загрузка фото мест...',
|
||||
'trip.mobilePlan': 'План',
|
||||
'trip.mobilePlaces': 'Места',
|
||||
'trip.toast.placeUpdated': 'Место обновлено',
|
||||
|
||||
@@ -243,6 +243,7 @@ const zh: Record<string, string> = {
|
||||
'settings.roleAdmin': '管理员',
|
||||
'settings.oidcLinked': '已关联',
|
||||
'settings.changePassword': '修改密码',
|
||||
'settings.mustChangePassword': '您必须更改密码才能继续。请在下方设置新密码。',
|
||||
'settings.currentPassword': '当前密码',
|
||||
'settings.currentPasswordRequired': '请输入当前密码',
|
||||
'settings.newPassword': '新密码',
|
||||
@@ -720,9 +721,7 @@ const zh: Record<string, string> = {
|
||||
'atlas.addToBucket': '添加到心愿单',
|
||||
'atlas.addPoi': '添加地点',
|
||||
'atlas.searchCountry': '搜索国家...',
|
||||
'atlas.bucketNamePlaceholder': '名称(国家、城市、地点…)',
|
||||
'atlas.month': '月份',
|
||||
'atlas.year': '年份',
|
||||
'atlas.addToBucketHint': '保存为想去的地方',
|
||||
'atlas.bucketWhen': '你计划什么时候去?',
|
||||
|
||||
@@ -735,6 +734,7 @@ const zh: Record<string, string> = {
|
||||
'trip.tabs.budget': '预算',
|
||||
'trip.tabs.files': '文件',
|
||||
'trip.loading': '加载旅行中...',
|
||||
'trip.loadingPhotos': '正在加载地点照片...',
|
||||
'trip.mobilePlan': '计划',
|
||||
'trip.mobilePlaces': '地点',
|
||||
'trip.toast.placeUpdated': '地点已更新',
|
||||
|
||||
Reference in New Issue
Block a user