added i18next translation
parent
4b07aae6bc
commit
df9c92d909
|
@ -7300,6 +7300,14 @@
|
||||||
"terser": "^4.6.3"
|
"terser": "^4.6.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"html-parse-stringify2": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/html-parse-stringify2/-/html-parse-stringify2-2.0.1.tgz",
|
||||||
|
"integrity": "sha1-3FZwtyksoVi3vJFsmmc1rIhyg0o=",
|
||||||
|
"requires": {
|
||||||
|
"void-elements": "^2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"html-webpack-plugin": {
|
"html-webpack-plugin": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.0.tgz",
|
||||||
|
@ -7532,6 +7540,30 @@
|
||||||
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
|
||||||
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
|
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
|
||||||
},
|
},
|
||||||
|
"i18next": {
|
||||||
|
"version": "19.8.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next/-/i18next-19.8.4.tgz",
|
||||||
|
"integrity": "sha512-FfVPNWv+felJObeZ6DSXZkj9QM1Ivvh7NcFCgA8XPtJWHz0iXVa9BUy+QY8EPrCLE+vWgDfV/sc96BgXVo6HAA==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"i18next-browser-languagedetector": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-KIToAzf8zwWvacgnRwJp63ase26o24AuNUlfNVJ5YZAFmdGhsJpmFClxXPuk9rv1FMI4lnc8zLSqgZPEZMrW4g==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.5.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"i18next-http-backend": {
|
||||||
|
"version": "1.0.21",
|
||||||
|
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-1.0.21.tgz",
|
||||||
|
"integrity": "sha512-UDeHoV2B+31Gr++0KFAVjM5l+SEwePpF6sfDyaDq5ennM9QNJ78PBEMPStwkreEm4h5C8sT7M1JdNQrLcU1Wdg==",
|
||||||
|
"requires": {
|
||||||
|
"node-fetch": "2.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"iconv-lite": {
|
"iconv-lite": {
|
||||||
"version": "0.4.24",
|
"version": "0.4.24",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||||
|
@ -10326,6 +10358,11 @@
|
||||||
"minimist": "^1.2.5"
|
"minimist": "^1.2.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"moment": {
|
||||||
|
"version": "2.29.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||||
|
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
||||||
|
},
|
||||||
"move-concurrently": {
|
"move-concurrently": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||||
|
@ -10440,6 +10477,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node-fetch": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
||||||
|
},
|
||||||
"node-forge": {
|
"node-forge": {
|
||||||
"version": "0.10.0",
|
"version": "0.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
||||||
|
@ -12591,6 +12633,15 @@
|
||||||
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.8.tgz",
|
||||||
"integrity": "sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw=="
|
"integrity": "sha512-HvPuUQnLp5H7TouGq3kzBeioJmXms1wHy9EGjz2OURWBp4qZO6AfGEcnxts1D/CbwPLRAgTMPCEgYhA3sEM4vw=="
|
||||||
},
|
},
|
||||||
|
"react-i18next": {
|
||||||
|
"version": "11.8.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.8.4.tgz",
|
||||||
|
"integrity": "sha512-QlPJfX+Roi+jEQ6frBSsLHHH+VWbUoCl6wZDT8XHMd6PsSgepjgD2sZf/h7F46JnHeuy0U+SxY3TtrJF+aDIyg==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.3.1",
|
||||||
|
"html-parse-stringify2": "2.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-is": {
|
"react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
|
@ -15301,6 +15352,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz",
|
||||||
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="
|
"integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ=="
|
||||||
},
|
},
|
||||||
|
"void-elements": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
|
||||||
|
"integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
|
||||||
|
},
|
||||||
"w3c-hr-time": {
|
"w3c-hr-time": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
|
||||||
|
@ -15576,11 +15632,6 @@
|
||||||
"minimalistic-assert": "^1.0.0"
|
"minimalistic-assert": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"web-vitals": {
|
|
||||||
"version": "0.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-0.2.4.tgz",
|
|
||||||
"integrity": "sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg=="
|
|
||||||
},
|
|
||||||
"webidl-conversions": {
|
"webidl-conversions": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
|
||||||
|
|
|
@ -12,7 +12,11 @@
|
||||||
"react-dom": "^17.0.1",
|
"react-dom": "^17.0.1",
|
||||||
"react-router-dom": "^5.2.0",
|
"react-router-dom": "^5.2.0",
|
||||||
"react-scripts": "4.0.1",
|
"react-scripts": "4.0.1",
|
||||||
"web-vitals": "^0.2.4"
|
"i18next": "^19.4.4",
|
||||||
|
"i18next-browser-languagedetector": "^4.1.1",
|
||||||
|
"i18next-http-backend": "^1.0.10",
|
||||||
|
"react-i18next": "^11.4.0",
|
||||||
|
"moment": "^2.25.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"DATE": "{{date,intlDate}}",
|
||||||
|
"LONG_DATE": "{{date,intlLongDate}}",
|
||||||
|
"DATE_FORMAT": "{{date, format}}",
|
||||||
|
"TIME_FROM_X": "{{date,intlTimeFromX}}",
|
||||||
|
"H_FROM_X": "{{date,intlHoursFromX}}",
|
||||||
|
"H_FROM_M": "{{number,intlHoursFromMinutes}}",
|
||||||
|
"NUMBER": "{{number,intlNumber}}",
|
||||||
|
"DECIMAL": "{{number,intlDecimal}}",
|
||||||
|
"DECIMAL2": "{{number,intlDecimal2}}",
|
||||||
|
"Language": {
|
||||||
|
"English": "English",
|
||||||
|
"Romanian": "Romanian"
|
||||||
|
},
|
||||||
|
"Login": {
|
||||||
|
"Username": "Username",
|
||||||
|
"Password": "Password"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"Language": {
|
||||||
|
"English": "Engleză",
|
||||||
|
"Romanian": "Română"
|
||||||
|
},
|
||||||
|
"Login": {
|
||||||
|
"Username": "Utilizator",
|
||||||
|
"Password": "Parolă"
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import {
|
||||||
ApplicationStateContext,
|
ApplicationStateContext,
|
||||||
ApplicationDispatchContext
|
ApplicationDispatchContext
|
||||||
} from "../../../state/ApplicationContexts";
|
} from "../../../state/ApplicationContexts";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
const useStyles = makeStyles(theme => ({
|
const useStyles = makeStyles(theme => ({
|
||||||
field: {
|
field: {
|
||||||
|
@ -17,6 +18,7 @@ const useStyles = makeStyles(theme => ({
|
||||||
|
|
||||||
const LoginComponent = () => {
|
const LoginComponent = () => {
|
||||||
const classes = useStyles();
|
const classes = useStyles();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const state = useContext(ApplicationStateContext);
|
const state = useContext(ApplicationStateContext);
|
||||||
const dispatchActions = useContext(ApplicationDispatchContext);
|
const dispatchActions = useContext(ApplicationDispatchContext);
|
||||||
|
@ -30,7 +32,7 @@ const LoginComponent = () => {
|
||||||
<TextField
|
<TextField
|
||||||
className={classes.field}
|
className={classes.field}
|
||||||
id="username"
|
id="username"
|
||||||
label="Username"
|
label={t("Login.Username")}
|
||||||
onChange={handleChange("userName")}
|
onChange={handleChange("userName")}
|
||||||
value={state.credentials.userName}
|
value={state.credentials.userName}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
|
@ -44,7 +46,7 @@ const LoginComponent = () => {
|
||||||
<br />
|
<br />
|
||||||
<PasswordField
|
<PasswordField
|
||||||
id="password"
|
id="password"
|
||||||
label="Password"
|
label={t("Login.Password")}
|
||||||
className={classes.field}
|
className={classes.field}
|
||||||
onChange={handleChange("password")}
|
onChange={handleChange("password")}
|
||||||
value={state.credentials.password}
|
value={state.credentials.password}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React, { Suspense } from "react";
|
import React, { Suspense } from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
import "./utils/i18n";
|
||||||
import App from "./components/App";
|
import App from "./components/App";
|
||||||
import { BrowserRouter as Router } from "react-router-dom";
|
import { BrowserRouter as Router } from "react-router-dom";
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
import i18n from "i18next";
|
||||||
|
import { initReactI18next } from "react-i18next";
|
||||||
|
import Backend from "i18next-http-backend";
|
||||||
|
import LanguageDetector from "i18next-browser-languagedetector";
|
||||||
|
import moment from "moment";
|
||||||
|
import "moment/locale/ro.js";
|
||||||
|
import "moment/locale/de.js";
|
||||||
|
|
||||||
|
i18n
|
||||||
|
.use(Backend)
|
||||||
|
.use(LanguageDetector)
|
||||||
|
.use(initReactI18next) // passes i18n down to react-i18next
|
||||||
|
.init(
|
||||||
|
{
|
||||||
|
fallbackLng: "en",
|
||||||
|
debug: true,
|
||||||
|
ns: ["translations"],
|
||||||
|
defaultNS: "translations",
|
||||||
|
//whitelist: ["en", "ro"],
|
||||||
|
interpolation: {
|
||||||
|
escapeValue: false, // not needed for react as it escapes by default
|
||||||
|
format: function (value, format, lng) {
|
||||||
|
if (format === "uppercase") return value.toUpperCase();
|
||||||
|
if (format === "intlDate") {
|
||||||
|
if (value && moment(value).isValid()) {
|
||||||
|
return moment(value).format("L");
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format === "intlLongDate") {
|
||||||
|
if (value && moment(value).isValid()) {
|
||||||
|
return moment(value).format("LLLL");
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format === "intlTimeFromX") {
|
||||||
|
if (value && moment(value.start).isValid()) {
|
||||||
|
let startDate = moment(value.start);
|
||||||
|
let endDate = moment(value.end);
|
||||||
|
return moment(endDate).from(startDate, true);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format === "intlHoursFromX") {
|
||||||
|
if (value && moment(value.start).isValid()) {
|
||||||
|
let startDate = moment(value.start);
|
||||||
|
let endDate = moment(value.end);
|
||||||
|
let span = moment.duration(endDate - startDate);
|
||||||
|
return `${parseInt(span.asHours(), 10)}h ${parseInt(
|
||||||
|
span.asMinutes() % 60,
|
||||||
|
10
|
||||||
|
)}m`;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (format === "intlNumber")
|
||||||
|
return new Intl.NumberFormat(lng).format(value);
|
||||||
|
if (format === "intlDecimal")
|
||||||
|
return new Intl.NumberFormat(lng, {
|
||||||
|
minimumFractionDigits: 2
|
||||||
|
}).format(value);
|
||||||
|
if (format === "intlDecimal2")
|
||||||
|
return new Intl.NumberFormat(lng, {
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2
|
||||||
|
}).format(value);
|
||||||
|
|
||||||
|
//dateformat
|
||||||
|
if (value && value.format) {
|
||||||
|
if (value.value && moment(value).isValid()) {
|
||||||
|
return moment(value.value).format(value.format);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
backend: {
|
||||||
|
loadPath: `${
|
||||||
|
process.env.PUBLIC_URL || ""
|
||||||
|
}/public/locales/{{lng}}/{{ns}}.json`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
const currentLang = i18n.language;
|
||||||
|
if (!currentLang || !currentLang.startsWith("ro")) {
|
||||||
|
i18n.changeLanguage("en");
|
||||||
|
} else {
|
||||||
|
i18n.changeLanguage("ro");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
i18n.on("languageChanged", function (lng) {
|
||||||
|
moment.locale(lng);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default i18n;
|
Loading…
Reference in New Issue