fix(i18n): comprehensive translation audit and fixes across all 14 languages

- Fix critical bug: Photos and Files pages had German text hardcoded in JSX,
  now use t() keys visible correctly in all languages
- Add 16 new translation keys (photos/files UI, login validation, common errors,
  rate limit message) across all 14 language files
- Add missing keys in packing, memories, and budget sections for br, de, it, es,
  fr, nl, pl, cs, hu, ru, zh, zh-TW, ar
- Add 152+ missing keys for zh-TW (entire sections were absent)
- Change Vacay addon name to 'Férias' in pt-BR only
- Add client-side HTTP 429 interceptor that shows translated rate limit message
- Replace hardcoded English fallbacks in TripPlannerPage, DayPlanSidebar,
  DisplaySettingsTab, MapSettingsTab, AccountTab, and TodoListPanel with t()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Isaias Tavares
2026-04-12 09:35:22 -03:00
parent 7abfb4deba
commit 9c42a01391
27 changed files with 357 additions and 56 deletions
+4 -4
View File
@@ -105,7 +105,7 @@ export default function TodoListPanel({ tripId, items }: { tripId: number; items
if (!name || categories.includes(name)) { setAddingCategory(false); setNewCategoryName(''); return }
addTodoItem(tripId, { name: t('todo.newItem'), category: name } as any)
.then(() => { setAddingCategory(false); setNewCategoryName(''); setFilter(name) })
.catch(err => toast.error(err instanceof Error ? err.message : 'Error'))
.catch(err => toast.error(err instanceof Error ? err.message : t('common.error')))
}
// Get category count (non-done items)
@@ -479,7 +479,7 @@ function DetailPane({ item, tripId, categories, members, onClose }: {
due_date: dueDate || null, category: category || null,
assigned_user_id: assignedUserId, priority,
} as any)
} catch (err: unknown) { toast.error(err instanceof Error ? err.message : 'Error') }
} catch (err: unknown) { toast.error(err instanceof Error ? err.message : t('common.error')) }
setSaving(false)
}
@@ -487,7 +487,7 @@ function DetailPane({ item, tripId, categories, members, onClose }: {
try {
await deleteTodoItem(tripId, item.id)
onClose()
} catch (err: unknown) { toast.error(err instanceof Error ? err.message : 'Error') }
} catch (err: unknown) { toast.error(err instanceof Error ? err.message : t('common.error')) }
}
const labelStyle: React.CSSProperties = { fontSize: 12, fontWeight: 500, color: 'var(--text-secondary)', marginBottom: 4, display: 'block' }
@@ -663,7 +663,7 @@ function NewTaskPane({ tripId, categories, members, defaultCategory, onCreated,
assigned_user_id: assignedUserId,
} as any)
if (item?.id) onCreated(item.id)
} catch (err: unknown) { toast.error(err instanceof Error ? err.message : 'Error') }
} catch (err: unknown) { toast.error(err instanceof Error ? err.message : t('common.error')) }
setSaving(false)
}