From 8ddfa8fde084d796fc84abb3cc0870a51f8db06e Mon Sep 17 00:00:00 2001 From: Maurice Date: Mon, 30 Mar 2026 18:24:22 +0200 Subject: [PATCH] i18n: translate all shared trip page strings to 9 languages --- client/src/i18n/translations/ar.ts | 16 +++++++++++++++ client/src/i18n/translations/br.ts | 16 +++++++++++++++ client/src/i18n/translations/de.ts | 16 +++++++++++++++ client/src/i18n/translations/en.ts | 16 +++++++++++++++ client/src/i18n/translations/es.ts | 16 +++++++++++++++ client/src/i18n/translations/fr.ts | 16 +++++++++++++++ client/src/i18n/translations/nl.ts | 16 +++++++++++++++ client/src/i18n/translations/ru.ts | 16 +++++++++++++++ client/src/i18n/translations/zh.ts | 16 +++++++++++++++ client/src/pages/SharedTripPage.tsx | 32 ++++++++++++++--------------- 10 files changed, 160 insertions(+), 16 deletions(-) diff --git a/client/src/i18n/translations/ar.ts b/client/src/i18n/translations/ar.ts index 92d18ee..9dd8573 100644 --- a/client/src/i18n/translations/ar.ts +++ b/client/src/i18n/translations/ar.ts @@ -170,6 +170,22 @@ const ar: Record = { 'share.permMap': 'الخريطة والخطة', 'share.permBookings': 'الحجوزات', 'share.permPacking': 'الأمتعة', + 'shared.expired': 'الرابط منتهي أو غير صالح', + 'shared.expiredHint': 'رابط الرحلة المشترك لم يعد نشطًا.', + 'shared.readOnly': 'عرض للقراءة فقط', + 'shared.tabPlan': 'الخطة', + 'shared.tabBookings': 'الحجوزات', + 'shared.tabPacking': 'قائمة التعبئة', + 'shared.tabBudget': 'الميزانية', + 'shared.tabChat': 'الدردشة', + 'shared.days': 'أيام', + 'shared.places': 'أماكن', + 'shared.other': 'أخرى', + 'shared.totalBudget': 'إجمالي الميزانية', + 'shared.messages': 'رسائل', + 'shared.sharedVia': 'تمت المشاركة عبر', + 'shared.confirmed': 'مؤكد', + 'shared.pending': 'قيد الانتظار', 'share.permBudget': 'الميزانية', 'share.permCollab': 'الدردشة', 'settings.on': 'تشغيل', diff --git a/client/src/i18n/translations/br.ts b/client/src/i18n/translations/br.ts index d742375..48d4394 100644 --- a/client/src/i18n/translations/br.ts +++ b/client/src/i18n/translations/br.ts @@ -165,6 +165,22 @@ const br: Record = { 'share.permMap': 'Mapa e plano', 'share.permBookings': 'Reservas', 'share.permPacking': 'Mala', + 'shared.expired': 'Link expirado ou inválido', + 'shared.expiredHint': 'Este link de viagem compartilhado não está mais ativo.', + 'shared.readOnly': 'Visualização somente leitura', + 'shared.tabPlan': 'Plano', + 'shared.tabBookings': 'Reservas', + 'shared.tabPacking': 'Bagagem', + 'shared.tabBudget': 'Orçamento', + 'shared.tabChat': 'Chat', + 'shared.days': 'dias', + 'shared.places': 'lugares', + 'shared.other': 'Outros', + 'shared.totalBudget': 'Orçamento total', + 'shared.messages': 'mensagens', + 'shared.sharedVia': 'Compartilhado via', + 'shared.confirmed': 'Confirmado', + 'shared.pending': 'Pendente', 'share.permBudget': 'Orçamento', 'share.permCollab': 'Chat', 'settings.on': 'Ligado', diff --git a/client/src/i18n/translations/de.ts b/client/src/i18n/translations/de.ts index 2d84bad..274e376 100644 --- a/client/src/i18n/translations/de.ts +++ b/client/src/i18n/translations/de.ts @@ -165,6 +165,22 @@ const de: Record = { 'share.permMap': 'Karte & Plan', 'share.permBookings': 'Buchungen', 'share.permPacking': 'Packliste', + 'shared.expired': 'Link abgelaufen oder ungültig', + 'shared.expiredHint': 'Dieser geteilte Reise-Link ist nicht mehr aktiv.', + 'shared.readOnly': 'Nur-Lesen Ansicht', + 'shared.tabPlan': 'Plan', + 'shared.tabBookings': 'Buchungen', + 'shared.tabPacking': 'Packliste', + 'shared.tabBudget': 'Budget', + 'shared.tabChat': 'Chat', + 'shared.days': 'Tage', + 'shared.places': 'Orte', + 'shared.other': 'Sonstige', + 'shared.totalBudget': 'Gesamtbudget', + 'shared.messages': 'Nachrichten', + 'shared.sharedVia': 'Geteilt über', + 'shared.confirmed': 'Bestätigt', + 'shared.pending': 'Ausstehend', 'share.permBudget': 'Budget', 'share.permCollab': 'Chat', 'settings.on': 'An', diff --git a/client/src/i18n/translations/en.ts b/client/src/i18n/translations/en.ts index 98082a6..fac08a9 100644 --- a/client/src/i18n/translations/en.ts +++ b/client/src/i18n/translations/en.ts @@ -165,6 +165,22 @@ const en: Record = { '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', diff --git a/client/src/i18n/translations/es.ts b/client/src/i18n/translations/es.ts index f4758b9..d76b83a 100644 --- a/client/src/i18n/translations/es.ts +++ b/client/src/i18n/translations/es.ts @@ -166,6 +166,22 @@ const es: Record = { 'share.permMap': 'Mapa y plan', 'share.permBookings': 'Reservas', 'share.permPacking': 'Equipaje', + 'shared.expired': 'Enlace expirado o inválido', + 'shared.expiredHint': 'Este enlace de viaje compartido ya no está activo.', + 'shared.readOnly': 'Vista de solo lectura', + 'shared.tabPlan': 'Plan', + 'shared.tabBookings': 'Reservas', + 'shared.tabPacking': 'Equipaje', + 'shared.tabBudget': 'Presupuesto', + 'shared.tabChat': 'Chat', + 'shared.days': 'días', + 'shared.places': 'lugares', + 'shared.other': 'Otro', + 'shared.totalBudget': 'Presupuesto total', + 'shared.messages': 'mensajes', + 'shared.sharedVia': 'Compartido vía', + 'shared.confirmed': 'Confirmado', + 'shared.pending': 'Pendiente', 'share.permBudget': 'Presupuesto', 'share.permCollab': 'Chat', 'settings.on': 'Activado', diff --git a/client/src/i18n/translations/fr.ts b/client/src/i18n/translations/fr.ts index 0af501b..24b87b9 100644 --- a/client/src/i18n/translations/fr.ts +++ b/client/src/i18n/translations/fr.ts @@ -165,6 +165,22 @@ const fr: Record = { 'share.permMap': 'Carte et plan', 'share.permBookings': 'Réservations', 'share.permPacking': 'Bagages', + 'shared.expired': 'Lien expiré ou invalide', + 'shared.expiredHint': 'Ce lien de partage n\'est plus actif.', + 'shared.readOnly': 'Vue en lecture seule', + 'shared.tabPlan': 'Plan', + 'shared.tabBookings': 'Réservations', + 'shared.tabPacking': 'Bagages', + 'shared.tabBudget': 'Budget', + 'shared.tabChat': 'Chat', + 'shared.days': 'jours', + 'shared.places': 'lieux', + 'shared.other': 'Autre', + 'shared.totalBudget': 'Budget total', + 'shared.messages': 'messages', + 'shared.sharedVia': 'Partagé via', + 'shared.confirmed': 'Confirmé', + 'shared.pending': 'En attente', 'share.permBudget': 'Budget', 'share.permCollab': 'Chat', 'settings.on': 'Activé', diff --git a/client/src/i18n/translations/nl.ts b/client/src/i18n/translations/nl.ts index e4d7efe..cf63d18 100644 --- a/client/src/i18n/translations/nl.ts +++ b/client/src/i18n/translations/nl.ts @@ -165,6 +165,22 @@ const nl: Record = { 'share.permMap': 'Kaart en plan', 'share.permBookings': 'Boekingen', 'share.permPacking': 'Paklijst', + 'shared.expired': 'Link verlopen of ongeldig', + 'shared.expiredHint': 'Deze gedeelde reislink is niet meer actief.', + 'shared.readOnly': 'Alleen-lezen weergave', + 'shared.tabPlan': 'Plan', + 'shared.tabBookings': 'Boekingen', + 'shared.tabPacking': 'Paklijst', + 'shared.tabBudget': 'Budget', + 'shared.tabChat': 'Chat', + 'shared.days': 'dagen', + 'shared.places': 'plaatsen', + 'shared.other': 'Overig', + 'shared.totalBudget': 'Totaal budget', + 'shared.messages': 'berichten', + 'shared.sharedVia': 'Gedeeld via', + 'shared.confirmed': 'Bevestigd', + 'shared.pending': 'In afwachting', 'share.permBudget': 'Budget', 'share.permCollab': 'Chat', 'settings.on': 'Aan', diff --git a/client/src/i18n/translations/ru.ts b/client/src/i18n/translations/ru.ts index ace3bda..e0f4f35 100644 --- a/client/src/i18n/translations/ru.ts +++ b/client/src/i18n/translations/ru.ts @@ -165,6 +165,22 @@ const ru: Record = { 'share.permMap': 'Карта и план', 'share.permBookings': 'Бронирования', 'share.permPacking': 'Вещи', + 'shared.expired': 'Ссылка устарела или недействительна', + 'shared.expiredHint': 'Эта ссылка на поездку больше не активна.', + 'shared.readOnly': 'Режим только для чтения', + 'shared.tabPlan': 'План', + 'shared.tabBookings': 'Бронирования', + 'shared.tabPacking': 'Багаж', + 'shared.tabBudget': 'Бюджет', + 'shared.tabChat': 'Чат', + 'shared.days': 'дней', + 'shared.places': 'мест', + 'shared.other': 'Прочее', + 'shared.totalBudget': 'Общий бюджет', + 'shared.messages': 'сообщений', + 'shared.sharedVia': 'Поделено через', + 'shared.confirmed': 'Подтверждено', + 'shared.pending': 'Ожидает', 'share.permBudget': 'Бюджет', 'share.permCollab': 'Чат', 'settings.on': 'Вкл.', diff --git a/client/src/i18n/translations/zh.ts b/client/src/i18n/translations/zh.ts index f822e53..66610d3 100644 --- a/client/src/i18n/translations/zh.ts +++ b/client/src/i18n/translations/zh.ts @@ -165,6 +165,22 @@ const zh: Record = { 'share.permMap': '地图与计划', 'share.permBookings': '预订', 'share.permPacking': '行李', + 'shared.expired': '链接已过期或无效', + 'shared.expiredHint': '此共享旅行链接已失效。', + 'shared.readOnly': '只读共享视图', + 'shared.tabPlan': '计划', + 'shared.tabBookings': '预订', + 'shared.tabPacking': '行李', + 'shared.tabBudget': '预算', + 'shared.tabChat': '聊天', + 'shared.days': '天', + 'shared.places': '个地点', + 'shared.other': '其他', + 'shared.totalBudget': '总预算', + 'shared.messages': '条消息', + 'shared.sharedVia': '通过以下分享', + 'shared.confirmed': '已确认', + 'shared.pending': '待确认', 'share.permBudget': '预算', 'share.permCollab': '聊天', 'settings.on': '开', diff --git a/client/src/pages/SharedTripPage.tsx b/client/src/pages/SharedTripPage.tsx index b325ea6..d17a3a4 100644 --- a/client/src/pages/SharedTripPage.tsx +++ b/client/src/pages/SharedTripPage.tsx @@ -55,8 +55,8 @@ export default function SharedTripPage() {
🔒
-

Link expired or invalid

-

This shared trip link is no longer active.

+

{t('shared.expired')}

+

{t('shared.expiredHint')}

) @@ -109,11 +109,11 @@ export default function SharedTripPage() { {[trip.start_date, trip.end_date].filter(Boolean).map((d: string) => new Date(d + 'T00:00:00').toLocaleDateString(locale, { day: 'numeric', month: 'short', year: 'numeric' })).join(' — ')} {days?.length > 0 && ·} - {days?.length > 0 && {days.length} days} + {days?.length > 0 && {days.length} {t('shared.days')}} )} -
Read-only shared view
+
{t('shared.readOnly')}
{/* Language picker - top right */}
@@ -142,11 +142,11 @@ export default function SharedTripPage() { {/* Tabs */}
{[ - { id: 'plan', label: 'Plan', Icon: Map }, - ...(permissions?.share_bookings ? [{ id: 'bookings', label: 'Bookings', Icon: Ticket }] : []), - ...(permissions?.share_packing ? [{ id: 'packing', label: 'Packing', Icon: Luggage }] : []), - ...(permissions?.share_budget ? [{ id: 'budget', label: 'Budget', Icon: Wallet }] : []), - ...(permissions?.share_collab ? [{ id: 'collab', label: 'Chat', Icon: MessageCircle }] : []), + { id: 'plan', label: t('shared.tabPlan'), Icon: Map }, + ...(permissions?.share_bookings ? [{ id: 'bookings', label: t('shared.tabBookings'), Icon: Ticket }] : []), + ...(permissions?.share_packing ? [{ id: 'packing', label: t('shared.tabPacking'), Icon: Luggage }] : []), + ...(permissions?.share_budget ? [{ id: 'budget', label: t('shared.tabBudget'), Icon: Wallet }] : []), + ...(permissions?.share_collab ? [{ id: 'collab', label: t('shared.tabChat'), Icon: MessageCircle }] : []), ].map(tab => (
{selectedDay === day.id && merged.length > 0 && ( @@ -287,7 +287,7 @@ export default function SharedTripPage() {
- {r.status} + {r.status === 'confirmed' ? t('shared.confirmed') : t('shared.pending')} ) @@ -298,7 +298,7 @@ export default function SharedTripPage() { {/* Packing */} {activeTab === 'packing' && (packing || []).length > 0 && (
- {Object.entries((packing || []).reduce((g: any, i: any) => { const c = i.category || 'Other'; (g[c] = g[c] || []).push(i); return g }, {})).map(([cat, items]: [string, any]) => ( + {Object.entries((packing || []).reduce((g: any, i: any) => { const c = i.category || t('shared.other'); (g[c] = g[c] || []).push(i); return g }, {})).map(([cat, items]: [string, any]) => (
{cat}
{items.map((item: any) => ( @@ -313,13 +313,13 @@ export default function SharedTripPage() { {/* Budget */} {activeTab === 'budget' && (budget || []).length > 0 && (() => { - const grouped = (budget || []).reduce((g: any, i: any) => { const c = i.category || 'Other'; (g[c] = g[c] || []).push(i); return g }, {}) + const grouped = (budget || []).reduce((g: any, i: any) => { const c = i.category || t('shared.other'); (g[c] = g[c] || []).push(i); return g }, {}) const total = (budget || []).reduce((s: number, i: any) => s + (parseFloat(i.total_price) || 0), 0) return (
{/* Total card */}
-
Total Budget
+
{t('shared.totalBudget')}
{total.toLocaleString(locale, { minimumFractionDigits: 2 })} {trip.currency || 'EUR'}
{/* By category */} @@ -346,7 +346,7 @@ export default function SharedTripPage() {
- Chat · {(collab || []).length} messages + {t('shared.tabChat')} · {(collab || []).length} {t('shared.messages')}
{(collab || []).map((msg: any, i: number) => { @@ -382,7 +382,7 @@ export default function SharedTripPage() {
TREK - Shared via TREK + {t('shared.sharedVia')} TREK
Made with by Maurice · GitHub