{
{
marginBottom: '20px'
}}
>
- 📍 Use My Current Location
+ {t('station.settings.useLocation')}
{/* Theme */}
- {['dark', 'light', 'legacy', 'retro'].map((t) => (
+ {['dark', 'light', 'legacy', 'retro'].map((theme) => (
))}
@@ -323,7 +330,7 @@ export const SettingsPanel = ({ isOpen, onClose, config, onSave }) => {
{/* Layout */}
{['modern', 'classic'].map((l) => (
@@ -341,7 +348,7 @@ export const SettingsPanel = ({ isOpen, onClose, config, onSave }) => {
fontWeight: layout === l ? '600' : '400'
}}
>
- {l === 'modern' ? '🖥️' : '📺'} {l.charAt(0).toUpperCase() + l.slice(1)}
+ {l === 'modern' ? '🖥️' : '📺'} {t('station.settings.layout.' + l)}
))}
@@ -353,7 +360,7 @@ export const SettingsPanel = ({ isOpen, onClose, config, onSave }) => {
{/* DX Cluster Source */}
- → Real-time DX Spider feed via our dedicated proxy service
+ {t('station.settings.dx.describe')}
@@ -394,7 +401,7 @@ export const SettingsPanel = ({ isOpen, onClose, config, onSave }) => {
cursor: 'pointer'
}}
>
- Cancel
+ {t('cancel')}
- Settings are saved in your browser
+ {t('station.settings.button.save.confirm')}
diff --git a/src/lang/en.json b/src/lang/en.json
new file mode 100644
index 0000000..41da978
--- /dev/null
+++ b/src/lang/en.json
@@ -0,0 +1,40 @@
+{
+ "cancel": "Cancel",
+ "station.settings.altitude": "Altitude (m)",
+ "station.settings.antenna": "Antenna",
+ "station.settings.button.save": "Save Settings",
+ "station.settings.button.save.confirm": "Settings are saved in your browser",
+ "station.settings.callsign": "Your Callsign",
+ "station.settings.describe": "Please enter your callsign and grid square to get started. Your settings will be saved in your browser.",
+ "station.settings.dx.describe": "→ Real-time DX Spider feed via our dedicated proxy service",
+ "station.settings.dx.option1": "⭐ DX Spider Proxy (Recommended)",
+ "station.settings.dx.option2": "HamQTH Cluster",
+ "station.settings.dx.option3": "DXWatch",
+ "station.settings.dx.option4": "Auto (try all sources)",
+ "station.settings.dx.title": "DX Cluster Source",
+ "station.settings.layout": "Layout",
+ "station.settings.layout.classic": "Classic",
+ "station.settings.layout.classic.describe": "→ Original HamClock-style layout",
+ "station.settings.layout.modern": "Modern",
+ "station.settings.layout.modern.describe": "→ Modern responsive grid layout",
+ "station.settings.latitude": "Latitude",
+ "station.settings.locator": "Grid Square (or enter Lat/Lon below)",
+ "station.settings.longitude": "Longitude",
+ "station.settings.power": "Power (W)",
+ "station.settings.theme": "THEME",
+ "station.settings.theme.dark": "Dark",
+ "station.settings.theme.dark.describe": "→ Modern dark theme (default)",
+ "station.settings.theme.legacy": "Legacy",
+ "station.settings.theme.legacy.describe": "→ Green CRT terminal style",
+ "station.settings.theme.light": "Light",
+ "station.settings.theme.light.describe": "→ Light theme for daytime use",
+ "station.settings.theme.retro": "Retro",
+ "station.settings.theme.retro.describe": "→ 90s Windows retro style",
+ "station.settings.timezone": "Timezone",
+ "station.settings.title": "Station Settings",
+ "station.settings.tip.env": "💡 Tip: For permanent config, copy
.env.example to
.env and set CALLSIGN and LOCATOR",
+ "station.settings.useLocation": "📍 Use My Current Location",
+ "station.settings.useLocation.error1": "Unable to get location. Please enter manually.",
+ "station.settings.useLocation.error2": "Geolocation is not supported by your browser.",
+ "station.settings.welcome": "👋 Welcome to OpenHamClock!"
+}
diff --git a/src/lang/fr.json b/src/lang/fr.json
new file mode 100644
index 0000000..b1c0e93
--- /dev/null
+++ b/src/lang/fr.json
@@ -0,0 +1,40 @@
+{
+ "Cancel": "Annuler",
+ "station.settings.altitude": "Altitude (m)",
+ "station.settings.antenna": "Antenne",
+ "station.settings.button.save": "Enregistrer les paramètres",
+ "station.settings.button.save.confirm": "Les paramètres sont enregistrés dans votre navigateur",
+ "station.settings.callsign": "Indicatif d'appel",
+ "station.settings.describe": "Veuillez entrer votre indicatif d'appel et votre carré de grille pour commencer. Vos paramètres seront enregistrés dans votre navigateur.",
+ "station.settings.dx.describe": "→ Flux en temps réel de DX Spider via notre service proxy dédié",
+ "station.settings.dx.option1": "⭐ Proxy DX Spider (Recommandé)",
+ "station.settings.dx.option2": "Cluster HamQTH",
+ "station.settings.dx.option3": "DXWatch",
+ "station.settings.dx.option4": "Auto (essayer toutes les sources)",
+ "station.settings.dx.title": "Source du cluster DX",
+ "station.settings.layout": "Disposition",
+ "station.settings.layout.classic": "Classique",
+ "station.settings.layout.classic.describe": "→ Disposition de style HamClock original",
+ "station.settings.layout.modern": "Moderne",
+ "station.settings.layout.modern.describe": "→ Disposition en grille réactive moderne",
+ "station.settings.latitude": "Latitude",
+ "station.settings.locator": "Carré de grille (ou entrez Lat/Lon ci-dessous)",
+ "station.settings.longitude": "Longitude",
+ "station.settings.power": "Puissance (W)",
+ "station.settings.theme": "THÈME",
+ "station.settings.theme.dark": "Sombre",
+ "station.settings.theme.dark.describe": "→ Thème sombre moderne (par défaut)",
+ "station.settings.theme.legacy": "Classique",
+ "station.settings.theme.legacy.describe": "→ Style CRT terminal vert",
+ "station.settings.theme.light": "Clair",
+ "station.settings.theme.light.describe": "→ Thème clair pour une utilisation diurne",
+ "station.settings.theme.retro": "Rétro",
+ "station.settings.theme.retro.describe": "→ Style rétro Windows des années 90",
+ "station.settings.timezone": "Fuseau horaire",
+ "station.settings.title": "⚙ Paramètres de la station",
+ "station.settings.tip.env": "💡 Astuce : Pour une configuration permanente, copiez
.env.example vers
.env et définissez Indicatif d'appel et Carré de grille",
+ "station.settings.useLocation": "📍 Utiliser ma position actuelle",
+ "station.settings.useLocation.error1": "Impossible d'obtenir la position. Veuillez entrer manuellement.",
+ "station.settings.useLocation.error2": "La géolocalisation n'est pas prise en charge par votre navigateur.",
+ "station.settings.welcome": "👋 Bienvenue sur OpenHamClock !"
+}
diff --git a/src/lang/i18n.js b/src/lang/i18n.js
new file mode 100644
index 0000000..0596300
--- /dev/null
+++ b/src/lang/i18n.js
@@ -0,0 +1,31 @@
+import i18n from 'i18next';
+import LanguageDetector from 'i18next-browser-languagedetector';
+import { initReactI18next } from 'react-i18next';
+
+import translationFR from './fr.json';
+import translationEN from './en.json';
+
+export const resources = {
+ fr: { translation: translationFR },
+ en: { translation: translationEN }
+} ;
+
+i18n
+ .use(LanguageDetector) // Automatically detects the user's language
+ .use(initReactI18next)
+ .init({
+ fallbackLng: 'en',
+ resources: {
+ fr: {
+ translation: translationFR
+ },
+ en: {
+ translation: translationEN
+ }
+ },
+ interpolation: {
+ escapeValue: false
+ }
+ });
+
+export default i18n;
\ No newline at end of file
diff --git a/src/main.jsx b/src/main.jsx
index 4302c8f..e582a26 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -2,6 +2,7 @@ import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './styles/main.css';
+import './lang/i18n';
ReactDOM.createRoot(document.getElementById('root')).render(