diff --git a/nest_frontend/Localization.js b/nest_frontend/Localization.js
new file mode 100644
index 0000000..e4bf72d
--- /dev/null
+++ b/nest_frontend/Localization.js
@@ -0,0 +1,29 @@
+import LocalizedStrings from "react-localization"
+
+
+/**
+ * All strings contained in the app should be present in this dict.
+ *
+ * If a key is missing in a language, the italian one is displayed instead.
+ *
+ * Define format strings as in C#:
+ * ```js
+ * "Raggio di {number} km"
+ * "{number} km radius"
+ * ```
+ */
+export default new LocalizedStrings({
+ // 🇮🇹
+ it: {
+ appName: "N.E.S.T.",
+ appFullName: "Noi Estraiamo Statistiche Tweet",
+ },
+ // 🇬🇧
+ en: {
+ appName: "N.E.S.T.",
+ },
+ // 🇫🇮
+ fi: {
+ appName: "N.E.S.T.",
+ }
+})
diff --git a/nest_frontend/components/interactive/Logo.js b/nest_frontend/components/interactive/Logo.js
index cff1d65..5fd5d3b 100644
--- a/nest_frontend/components/interactive/Logo.js
+++ b/nest_frontend/components/interactive/Logo.js
@@ -4,6 +4,7 @@ import LogoDark from "../../media/LogoDark.png"
import LogoLight from "../../media/LogoLight.png"
import ContextTheme from "../../contexts/ContextTheme"
import classNames from "classnames"
+import Localization from "../../Localization"
/**
@@ -33,6 +34,12 @@ export default function Logo({ className, ...props }) {
}
return (
-
+
)
}
diff --git a/nest_frontend/components/interactive/SelectLanguage.js b/nest_frontend/components/interactive/SelectLanguage.js
new file mode 100644
index 0000000..a788f22
--- /dev/null
+++ b/nest_frontend/components/interactive/SelectLanguage.js
@@ -0,0 +1,31 @@
+import React, { useState } from "react"
+import Select from "../base/Select"
+import Localization from "../../Localization"
+
+
+/**
+ * A {@link Select} which allows the user to choose between the various available themes, switching between them as soon
+ * as the user selects a different one.
+ *
+ * @param props - Additional props to pass to the {@link Select}.
+ * @returns {JSX.Element}
+ * @constructor
+ */
+export default function SelectLanguage({ ...props }) {
+ const [_language, _setLanguage] = useState(Localization.getLanguage())
+
+ const setLanguage = event => {
+ const language = event.target.value
+ console.info("Changing language to: ", language)
+ Localization.setLanguage(language)
+ _setLanguage(language)
+ }
+
+ return (
+
+ )
+}
diff --git a/nest_frontend/routes/PageSettings.js b/nest_frontend/routes/PageSettings.js
index 684719c..70e98d5 100644
--- a/nest_frontend/routes/PageSettings.js
+++ b/nest_frontend/routes/PageSettings.js
@@ -5,6 +5,7 @@ import BoxHeader from "../components/base/BoxHeader"
import BoxFull from "../components/base/BoxFull"
import SelectTheme from "../components/interactive/SelectTheme"
import BoxLoggedIn from "../components/interactive/BoxLoggedIn"
+import SelectLanguage from "../components/interactive/SelectLanguage"
export default function PageSettings({ children, className, ...props }) {
@@ -15,6 +16,9 @@ export default function PageSettings({ children, className, ...props }) {
Cambia tema:
+
+ Cambia lingua:
+
🚧 Non implementato.
diff --git a/package-lock.json b/package-lock.json
index a3d1726..8ac80f8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -19,9 +19,11 @@
"classnames": "^2.3.1",
"is-string": "^1.0.5",
"leaflet": "^1.7.1",
+ "localized-strings": "github:Steffo99/localized-strings",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-leaflet": "^3.1.0",
+ "react-localization": "^1.0.17",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
@@ -12694,6 +12696,11 @@
"node": ">=8.9.0"
}
},
+ "node_modules/localized-strings": {
+ "version": "0.2.4",
+ "resolved": "git+ssh://git@github.com/Steffo99/localized-strings.git#bf6d078ba2b2264cac05fc6f61900e5752740da6",
+ "license": "MIT"
+ },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -16445,6 +16452,17 @@
"react-dom": "^17.0.1"
}
},
+ "node_modules/react-localization": {
+ "version": "1.0.17",
+ "resolved": "https://registry.npmjs.org/react-localization/-/react-localization-1.0.17.tgz",
+ "integrity": "sha512-UowuLAvnEPXJgzxjDX/9hKdKYvtUgC6hQ5PV0CnT5f/77tItIUru5tTwgrDY2UL5oUK3JRMgz42tqnAU2W5eoA==",
+ "dependencies": {
+ "localized-strings": "^0.2.0"
+ },
+ "peerDependencies": {
+ "react": "^17.0.0 || ^16.0.0 || ^15.6.0"
+ }
+ },
"node_modules/react-refresh": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
@@ -32561,6 +32579,10 @@
"json5": "^2.1.2"
}
},
+ "localized-strings": {
+ "version": "git+ssh://git@github.com/Steffo99/localized-strings.git#bf6d078ba2b2264cac05fc6f61900e5752740da6",
+ "from": "localized-strings@github:Steffo99/localized-strings"
+ },
"locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -35546,6 +35568,14 @@
"@react-leaflet/core": "^1.0.2"
}
},
+ "react-localization": {
+ "version": "1.0.17",
+ "resolved": "https://registry.npmjs.org/react-localization/-/react-localization-1.0.17.tgz",
+ "integrity": "sha512-UowuLAvnEPXJgzxjDX/9hKdKYvtUgC6hQ5PV0CnT5f/77tItIUru5tTwgrDY2UL5oUK3JRMgz42tqnAU2W5eoA==",
+ "requires": {
+ "localized-strings": "^0.2.0"
+ }
+ },
"react-refresh": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.8.3.tgz",
diff --git a/package.json b/package.json
index d82944f..685f4c1 100644
--- a/package.json
+++ b/package.json
@@ -14,9 +14,11 @@
"classnames": "^2.3.1",
"is-string": "^1.0.5",
"leaflet": "^1.7.1",
+ "localized-strings": "github:Steffo99/localized-strings",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-leaflet": "^3.1.0",
+ "react-localization": "^1.0.17",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",