diff --git a/client/src/pages/DashboardPage.tsx b/client/src/pages/DashboardPage.tsx index d403243d..9965d704 100644 --- a/client/src/pages/DashboardPage.tsx +++ b/client/src/pages/DashboardPage.tsx @@ -300,9 +300,9 @@ export default function DashboardPage(): React.ReactElement {

{t('dashboard.title')}

- - - + + +
@@ -529,6 +530,7 @@ function BoardingPassHero({ trip, bundle, locale, onOpen, onEdit, onCopy, onArch // ── Atlas / stats row ──────────────────────────────────────────────────────── function AtlasStats({ stats }: { stats: TravelStats | null }): React.ReactElement { + const { t } = useTranslation() const countries = stats?.countries || [] const distanceKm = stats?.totalDistanceKm || 0 const distanceText = distanceKm >= 1000 ? `${(distanceKm / 1000).toFixed(1)}k` : String(distanceKm) @@ -537,8 +539,8 @@ function AtlasStats({ stats }: { stats: TravelStats | null }): React.ReactElemen return (
-
Atlas · Countries visited
-
{countries.length} of 195
+
{t('dashboard.atlas.countriesVisited')}
+
{countries.length} {t('dashboard.atlas.ofTotal', { total: 195 })}
{countries.slice(0, 5).map((c, i) => ( @@ -551,27 +553,27 @@ function AtlasStats({ stats }: { stats: TravelStats | null }): React.ReactElemen
-
Trips total
+
{t('dashboard.atlas.tripsTotal')}
{stats?.totalTrips ?? 0}
-
{stats?.totalPlaces ?? 0} places mapped
+
{t('dashboard.atlas.placesMapped', { count: stats?.totalPlaces ?? 0 })}
-
Days traveled
-
{stats?.totalDays ?? 0} days
-
across all trips
+
{t('dashboard.atlas.daysTraveled')}
+
{stats?.totalDays ?? 0} {t('dashboard.atlas.daysUnit')}
+
{t('dashboard.atlas.acrossAllTrips')}
-
Distance flown
-
{distanceText} km
-
≈ {equatorTimes}× around the equator
+
{t('dashboard.atlas.distanceFlown')}
+
{distanceText} {t('dashboard.atlas.kmUnit')}
+
{t('dashboard.atlas.aroundEquator', { count: equatorTimes })}
@@ -586,18 +588,19 @@ function TripCard({ trip, locale, onOpen, onEdit, onCopy, onArchive, onDelete }: trip: DashboardTrip; locale: string; onOpen: () => void onEdit: () => void; onCopy: () => void; onArchive: () => void; onDelete: () => void }): React.ReactElement { + const { t } = useTranslation() const status = getTripStatus(trip) const start = splitDate(trip.start_date, locale) const end = splitDate(trip.end_date, locale) const until = daysUntil(trip.start_date) const statusClass = status === 'ongoing' ? '' : status === 'past' ? 'completed' : status === 'future' || status === 'today' || status === 'tomorrow' ? 'upcoming' : 'idea' - const statusLabel = status === 'ongoing' ? 'Live now' - : status === 'today' ? 'Today' - : status === 'tomorrow' ? 'Tomorrow' - : status === 'future' && until !== null ? (until > 60 ? `In ${Math.round(until / 30)} months` : `In ${until} days`) - : status === 'past' ? 'Completed' - : 'Idea' + const statusLabel = status === 'ongoing' ? t('dashboard.mobile.liveNow') + : status === 'today' ? t('dashboard.status.today') + : status === 'tomorrow' ? t('dashboard.status.tomorrow') + : status === 'future' && until !== null ? (until > 60 ? t('dashboard.mobile.inMonths', { count: Math.round(until / 30) }) : t('dashboard.mobile.inDays', { count: until })) + : status === 'past' ? t('dashboard.mobile.completed') + : t('dashboard.card.idea') const stop = (e: React.MouseEvent, fn: () => void) => { e.stopPropagation(); fn() } @@ -626,12 +629,12 @@ function TripCard({ trip, locale, onOpen, onEdit, onCopy, onArchive, onDelete }: {end.m} {end.d} - ) : No dates set} + ) : {t('dashboard.hero.noDates')}}
-
{trip.day_count ?? 0}Days
-
{trip.place_count ?? 0}Places
-
{trip.shared_count ?? 0}{trip.shared_count === 1 ? 'Buddy' : 'Buddies'}
+
{trip.day_count ?? 0}{t('dashboard.days')}
+
{trip.place_count ?? 0}{t('dashboard.places')}
+
{trip.shared_count ?? 0}{trip.shared_count === 1 ? t('dashboard.card.buddyOne') : t('dashboard.members')}
@@ -642,6 +645,7 @@ function TripCard({ trip, locale, onOpen, onEdit, onCopy, onArchive, onDelete }: const FX_FALLBACK = ['EUR', 'USD', 'GBP', 'CHF', 'JPY', 'CAD', 'AUD', 'CNY', 'SEK', 'NOK', 'DKK', 'PLN', 'CZK', 'HUF', 'TRY', 'THB', 'INR', 'BRL', 'MXN', 'ZAR'] function CurrencyTool(): React.ReactElement { + const { t } = useTranslation() const [from, setFrom] = useState(() => localStorage.getItem('trek_fx_from') || 'EUR') const [to, setTo] = useState(() => localStorage.getItem('trek_fx_to') || 'USD') const [amount, setAmount] = useState('100') @@ -667,24 +671,24 @@ function CurrencyTool(): React.ReactElement { return (
-
Currency
+
{t('dashboard.currency')}
-
From
+
{t('dashboard.fx.from')}
setAmount(e.target.value)} inputMode="decimal" />
-
To
+
{t('dashboard.fx.to')}
- {rate != null ? `1 ${from} = ${rate.toFixed(4)} ${to}` : 'Rate unavailable'} + {rate != null ? `1 ${from} = ${rate.toFixed(4)} ${to}` : t('dashboard.fx.unavailable')}
) @@ -707,6 +711,7 @@ function shortZone(tz: string): string { } function TimezoneTool({ locale }: { locale: string }): React.ReactElement { + const { t } = useTranslation() const home = Intl.DateTimeFormat().resolvedOptions().timeZone const [now, setNow] = useState(() => new Date()) const [zones, setZones] = useState(() => { @@ -747,14 +752,14 @@ function TimezoneTool({ locale }: { locale: string }): React.ReactElement { return (
-
Timezones
+
{t('dashboard.timezone')}
{adding && (
- +
)}
@@ -770,7 +775,7 @@ function TimezoneTool({ locale }: { locale: string }): React.ReactElement {
))} {zones.length === 0 && ( -
Noch keine weiteren Zeitzonen — über + hinzufügen
+
{t('dashboard.tz.empty')}
)}
@@ -781,13 +786,14 @@ function TimezoneTool({ locale }: { locale: string }): React.ReactElement { function UpcomingTool({ items, locale, onOpen }: { items: UpcomingReservation[]; locale: string; onOpen: (tripId: number) => void }): React.ReactElement { + const { t } = useTranslation() return (
-
Upcoming reservations
+
{t('dashboard.upcoming.title')}
{items.length === 0 ? ( -
Nothing booked yet.
+
{t('dashboard.upcoming.empty')}
) : (
{items.map(r => {