aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/app
diff options
context:
space:
mode:
authorAriel Costas Guerrero <ariel@costas.dev>2025-06-24 16:58:30 +0200
committerAriel Costas Guerrero <ariel@costas.dev>2025-06-24 16:58:30 +0200
commit3dac17a9fb54c977c97280ed4c482e9d4266b7de (patch)
treecf70257c1604e07a9d6c27ee28069d877ec3bfc1 /src/frontend/app
parentecb73e1684b42265af3f8d93541600e4d0f9c414 (diff)
Add missing translations
Diffstat (limited to 'src/frontend/app')
-rw-r--r--src/frontend/app/components/NavBar.tsx8
-rw-r--r--src/frontend/app/components/RegularTable.tsx20
-rw-r--r--src/frontend/app/i18n/locales/en-GB.json22
-rw-r--r--src/frontend/app/i18n/locales/es-ES.json22
-rw-r--r--src/frontend/app/i18n/locales/gl-ES.json22
-rw-r--r--src/frontend/app/routes/estimates-$id.tsx2
-rw-r--r--src/frontend/app/routes/stoplist.tsx14
7 files changed, 81 insertions, 29 deletions
diff --git a/src/frontend/app/components/NavBar.tsx b/src/frontend/app/components/NavBar.tsx
index 091cc21..eba7196 100644
--- a/src/frontend/app/components/NavBar.tsx
+++ b/src/frontend/app/components/NavBar.tsx
@@ -2,6 +2,7 @@ import { Link } from "react-router";
import { Map, MapPin, Settings } from "lucide-react";
import { useApp } from "../AppContext";
import type { LngLatLike } from "maplibre-gl";
+import { useTranslation } from "react-i18next";
// Helper: check if coordinates are within Vigo bounds
function isWithinVigo(lngLat: LngLatLike): boolean {
@@ -19,16 +20,17 @@ function isWithinVigo(lngLat: LngLatLike): boolean {
}
export default function NavBar() {
+ const { t } = useTranslation();
const { mapState, updateMapState, mapPositionMode } = useApp();
const navItems = [
{
- name: 'Paradas',
+ name: t('navbar.stops', 'Paradas'),
icon: MapPin,
path: '/stops'
},
{
- name: 'Mapa',
+ name: t('navbar.map', 'Mapa'),
icon: Map,
path: '/map',
callback: () => {
@@ -53,7 +55,7 @@ export default function NavBar() {
}
},
{
- name: 'Ajustes',
+ name: t('navbar.settings', 'Ajustes'),
icon: Settings,
path: '/settings'
}
diff --git a/src/frontend/app/components/RegularTable.tsx b/src/frontend/app/components/RegularTable.tsx
index 75b598b..e5b3782 100644
--- a/src/frontend/app/components/RegularTable.tsx
+++ b/src/frontend/app/components/RegularTable.tsx
@@ -1,3 +1,4 @@
+import { useTranslation } from "react-i18next";
import { type StopDetails } from "../routes/estimates-$id";
import LineIcon from "./LineIcon";
@@ -7,6 +8,7 @@ interface RegularTableProps {
}
export const RegularTable: React.FC<RegularTableProps> = ({ data, dataDate }) => {
+ const { t } = useTranslation();
const absoluteArrivalTime = (minutes: number) => {
const now = new Date()
@@ -21,19 +23,19 @@ export const RegularTable: React.FC<RegularTableProps> = ({ data, dataDate }) =>
if (meters > 1024) {
return `${(meters / 1000).toFixed(1)} km`;
} else {
- return `${meters} m`;
+ return `${meters} ${t('estimates.meters', 'm')}`;
}
}
return <table className="table">
- <caption>Estimaciones de llegadas a las {dataDate?.toLocaleTimeString()}</caption>
+ <caption>{t('estimates.caption', 'Estimaciones de llegadas a las {{time}}', { time: dataDate?.toLocaleTimeString() })}</caption>
<thead>
<tr>
- <th>Línea</th>
- <th>Ruta</th>
- <th>Llegada</th>
- <th>Distancia</th>
+ <th>{t('estimates.line', 'Línea')}</th>
+ <th>{t('estimates.route', 'Ruta')}</th>
+ <th>{t('estimates.arrival', 'Llegada')}</th>
+ <th>{t('estimates.distance', 'Distancia')}</th>
</tr>
</thead>
@@ -47,12 +49,12 @@ export const RegularTable: React.FC<RegularTableProps> = ({ data, dataDate }) =>
<td>
{estimate.minutes > 15
? absoluteArrivalTime(estimate.minutes)
- : `${estimate.minutes} min`}
+ : `${estimate.minutes} ${t('estimates.minutes', 'min')}`}
</td>
<td>
{estimate.meters > -1
? formatDistance(estimate.meters)
- : "No disponible"
+ : t('estimates.not_available', 'No disponible')
}
</td>
</tr>
@@ -62,7 +64,7 @@ export const RegularTable: React.FC<RegularTableProps> = ({ data, dataDate }) =>
{data?.estimates.length === 0 && (
<tfoot>
<tr>
- <td colSpan={4}>No hay estimaciones disponibles</td>
+ <td colSpan={4}>{t('estimates.none', 'No hay estimaciones disponibles')}</td>
</tr>
</tfoot>
)}
diff --git a/src/frontend/app/i18n/locales/en-GB.json b/src/frontend/app/i18n/locales/en-GB.json
index f53a802..cd0780c 100644
--- a/src/frontend/app/i18n/locales/en-GB.json
+++ b/src/frontend/app/i18n/locales/en-GB.json
@@ -24,15 +24,26 @@
},
"stoplist": {
"search_placeholder": "Search stop...",
- "favourites": "Favourites",
- "recents": "Recent"
+ "search_label": "Search stops",
+ "search_results": "Search results",
+ "favourites": "Favourite stops",
+ "no_favourites": "Go to a stop and mark it as favourite to see it here.",
+ "recents": "Recent",
+ "all_stops": "Stops"
},
"estimates": {
"minutes": "min",
"meters": "m",
"edit": "Edit name",
"favourite": "Favourite",
- "not_found": "Stop not found"
+ "not_found": "Stop not found",
+ "caption": "Arrival estimates at {{time}}",
+ "line": "Line",
+ "route": "Route",
+ "arrival": "Arrival",
+ "distance": "Distance",
+ "not_available": "Not available",
+ "none": "No estimates available"
},
"map": {
"popup_title": "Stop",
@@ -42,5 +53,10 @@
"loading": "Loading...",
"error": "An unexpected error occurred.",
"404": "The requested page could not be found."
+ },
+ "navbar": {
+ "stops": "Stops",
+ "map": "Map",
+ "settings": "Settings"
}
}
diff --git a/src/frontend/app/i18n/locales/es-ES.json b/src/frontend/app/i18n/locales/es-ES.json
index 814019e..2f2bb86 100644
--- a/src/frontend/app/i18n/locales/es-ES.json
+++ b/src/frontend/app/i18n/locales/es-ES.json
@@ -24,15 +24,26 @@
},
"stoplist": {
"search_placeholder": "Buscar parada...",
- "favourites": "Favoritas",
- "recents": "Recientes"
+ "search_label": "Buscar paradas",
+ "search_results": "Resultados de la búsqueda",
+ "favourites": "Paradas favoritas",
+ "no_favourites": "Accede a una parada y márcala como favorita para verla aquí.",
+ "recents": "Recientes",
+ "all_stops": "Paradas"
},
"estimates": {
"minutes": "min",
"meters": "m",
"edit": "Editar nombre",
"favourite": "Favorito",
- "not_found": "No se encontró la parada"
+ "not_found": "No se encontró la parada",
+ "caption": "Estimaciones de llegadas a las {{time}}",
+ "line": "Línea",
+ "route": "Ruta",
+ "arrival": "Llegada",
+ "distance": "Distancia",
+ "not_available": "No disponible",
+ "none": "No hay estimaciones disponibles"
},
"map": {
"popup_title": "Parada",
@@ -42,5 +53,10 @@
"loading": "Cargando...",
"error": "Ha ocurrido un error inesperado.",
"404": "La página solicitada no se pudo encontrar."
+ },
+ "navbar": {
+ "stops": "Paradas",
+ "map": "Mapa",
+ "settings": "Ajustes"
}
}
diff --git a/src/frontend/app/i18n/locales/gl-ES.json b/src/frontend/app/i18n/locales/gl-ES.json
index 3c0c2fc..d2558e5 100644
--- a/src/frontend/app/i18n/locales/gl-ES.json
+++ b/src/frontend/app/i18n/locales/gl-ES.json
@@ -24,15 +24,26 @@
},
"stoplist": {
"search_placeholder": "Buscar parada...",
- "favourites": "Favoritas",
- "recents": "Recentes"
+ "search_label": "Buscar paradas",
+ "search_results": "Resultados da busca",
+ "favourites": "Paradas favoritas",
+ "no_favourites": "Accede a unha parada e márcaa como favorita para vela aquí.",
+ "recents": "Recentes",
+ "all_stops": "Paradas"
},
"estimates": {
"minutes": "min",
"meters": "m",
"edit": "Editar nome",
"favourite": "Favorita",
- "not_found": "Non se atopou a parada"
+ "not_found": "Non se atopou a parada",
+ "caption": "Estimacións de chegadas ás {{time}}",
+ "line": "Liña",
+ "route": "Ruta",
+ "arrival": "Chegada",
+ "distance": "Distancia",
+ "not_available": "Non dispoñible",
+ "none": "Non hai estimacións dispoñibles"
},
"map": {
"popup_title": "Parada",
@@ -42,5 +53,10 @@
"loading": "Cargando...",
"error": "Produciuse un erro inesperado.",
"404": "Non se puido atopar a páxina solicitada."
+ },
+ "navbar": {
+ "stops": "Paradas",
+ "map": "Mapa",
+ "settings": "Axustes"
}
}
diff --git a/src/frontend/app/routes/estimates-$id.tsx b/src/frontend/app/routes/estimates-$id.tsx
index 5dbbc7d..e0e4fff 100644
--- a/src/frontend/app/routes/estimates-$id.tsx
+++ b/src/frontend/app/routes/estimates-$id.tsx
@@ -83,7 +83,7 @@ export default function Estimates() {
}
};
- if (data === null) return <h1 className="page-title">Cargando datos en tiempo real...</h1>
+ if (data === null) return <h1 className="page-title">{t('common.loading')}</h1>
return (
<div className="page-container">
diff --git a/src/frontend/app/routes/stoplist.tsx b/src/frontend/app/routes/stoplist.tsx
index 0ab6d15..9404b39 100644
--- a/src/frontend/app/routes/stoplist.tsx
+++ b/src/frontend/app/routes/stoplist.tsx
@@ -58,7 +58,7 @@ export default function StopList() {
return stopsList.reverse();
}, [data]);
- if (data === null) return <h1 className="page-title">Loading...</h1>
+ if (data === null) return <h1 className="page-title">{t('common.loading')}</h1>
return (
<div className="page-container">
@@ -67,7 +67,7 @@ export default function StopList() {
<form className="search-form">
<div className="form-group">
<label className="form-label" htmlFor="stopName">
- Buscar paradas
+ {t('stoplist.search_label', 'Buscar paradas')}
</label>
<input className="form-input" type="text" placeholder={randomPlaceholder} id="stopName" onChange={handleStopSearch} />
</div>
@@ -75,7 +75,7 @@ export default function StopList() {
{searchResults && searchResults.length > 0 && (
<div className="list-container">
- <h2 className="page-subtitle">Resultados de la búsqueda</h2>
+ <h2 className="page-subtitle">{t('stoplist.search_results', 'Resultados de la búsqueda')}</h2>
<ul className="list">
{searchResults.map((stop: Stop) => (
<StopItem key={stop.stopId} stop={stop} />
@@ -85,11 +85,11 @@ export default function StopList() {
)}
<div className="list-container">
- <h2 className="page-subtitle">Paradas favoritas</h2>
+ <h2 className="page-subtitle">{t('stoplist.favourites')}</h2>
{favouritedStops?.length === 0 && (
<p className="message">
- Accede a una parada y márcala como favorita para verla aquí.
+ {t('stoplist.no_favourites', 'Accede a una parada y márcala como favorita para verla aquí.')}
</p>
)}
@@ -102,7 +102,7 @@ export default function StopList() {
{recentStops && recentStops.length > 0 && (
<div className="list-container">
- <h2 className="page-subtitle">Recientes</h2>
+ <h2 className="page-subtitle">{t('stoplist.recents')}</h2>
<ul className="list">
{recentStops.map((stop: Stop) => (
@@ -113,7 +113,7 @@ export default function StopList() {
)}
<div className="list-container">
- <h2 className="page-subtitle">Paradas</h2>
+ <h2 className="page-subtitle">{t('stoplist.all_stops', 'Paradas')}</h2>
<ul className="list">
{data?.sort((a, b) => a.stopId - b.stopId).map((stop: Stop) => (