| import React from "react"; | |||||
| import React, { useEffect } from "react"; | |||||
| import { Router } from "react-router-dom"; | import { Router } from "react-router-dom"; | ||||
| import { Helmet } from "react-helmet-async"; | import { Helmet } from "react-helmet-async"; | ||||
| import i18next from "i18next"; | import i18next from "i18next"; | ||||
| import history from "./store/utils/history"; | import history from "./store/utils/history"; | ||||
| import AppRoutes from "./AppRoutes"; | import AppRoutes from "./AppRoutes"; | ||||
| import { useTranslation } from "react-i18next"; | |||||
| import { ToastContainer } from "react-toastify"; | import { ToastContainer } from "react-toastify"; | ||||
| import "react-toastify/dist/ReactToastify.css"; | import "react-toastify/dist/ReactToastify.css"; | ||||
| import { StyledEngineProvider } from "@mui/material"; | import { StyledEngineProvider } from "@mui/material"; | ||||
| import { authScopeStringGetHelper } from "util/helpers/authScopeHelpers"; | |||||
| import { JWT_REFRESH_TOKEN, JWT_TOKEN, LANGUAGE } from "constants/localStorage"; | |||||
| import { HOME_PAGE } from "constants/pages"; | |||||
| const App = () => { | const App = () => { | ||||
| const { i18n } = useTranslation(); | |||||
| useEffect(() => { | |||||
| const lang = authScopeStringGetHelper(LANGUAGE); | |||||
| if (lang) { | |||||
| i18n.changeLanguage(lang); | |||||
| } | |||||
| }, []); | |||||
| useEffect(() => { | |||||
| const token = authScopeStringGetHelper(JWT_TOKEN); | |||||
| const refreshToken = authScopeStringGetHelper(JWT_REFRESH_TOKEN); | |||||
| if (token && refreshToken) { | |||||
| history.push({ | |||||
| pathname: HOME_PAGE, | |||||
| state: { | |||||
| from: history.location.pathname, | |||||
| }, | |||||
| }); | |||||
| } | |||||
| }, []); | |||||
| return ( | return ( | ||||
| <> | <> | ||||
| <Router history={history}> | <Router history={history}> |
| import React from 'react'; | import React from 'react'; | ||||
| import { Paper, Typography } from '@mui/material'; | import { Paper, Typography } from '@mui/material'; | ||||
| import { DataGrid } from '@mui/x-data-grid'; | import { DataGrid } from '@mui/x-data-grid'; | ||||
| import { useTranslation } from 'react-i18next'; | |||||
| // Use these values from REDUX? | // Use these values from REDUX? | ||||
| const rows = [ | const rows = [ | ||||
| ]; | ]; | ||||
| const DataGridExample = () => { | const DataGridExample = () => { | ||||
| const {t} = useTranslation() | |||||
| return ( | return ( | ||||
| <Paper sx={{ p: 2 }} elevation={5}> | <Paper sx={{ p: 2 }} elevation={5}> | ||||
| <Typography variant="h4" gutterBottom align="center"> | <Typography variant="h4" gutterBottom align="center"> | ||||
| DataGrid Example | |||||
| {t('common.dataGridExample')} | |||||
| </Typography> | </Typography> | ||||
| <DataGrid autoHeight rows={rows} columns={columns} /> | <DataGrid autoHeight rows={rows} columns={columns} /> | ||||
| </Paper> | </Paper> |
| import React, { useState } from 'react'; | |||||
| import { Button, Menu, MenuItem } from '@mui/material'; | |||||
| import React, { useState } from "react"; | |||||
| import { Button, Menu, MenuItem } from "@mui/material"; | |||||
| import { useTranslation } from "react-i18next"; | |||||
| import { authScopeSetHelper } from "util/helpers/authScopeHelpers"; | |||||
| import { LANGUAGE } from "constants/localStorage"; | |||||
| const MenuListComponent = () => { | const MenuListComponent = () => { | ||||
| const [anchorEl, setAnchorEl] = useState(null); | |||||
| const open = Boolean(anchorEl); | |||||
| const handleClick = (event) => { | |||||
| setAnchorEl(event.currentTarget); | |||||
| }; | |||||
| const handleClose = () => { | |||||
| setAnchorEl(null); | |||||
| }; | |||||
| const { t, i18n } = useTranslation(); | |||||
| const [anchorEl, setAnchorEl] = useState(null); | |||||
| const open = Boolean(anchorEl); | |||||
| const handleClick = (event) => { | |||||
| setAnchorEl(event.currentTarget); | |||||
| }; | |||||
| const handleClose = () => { | |||||
| setAnchorEl(null); | |||||
| }; | |||||
| return ( | |||||
| <div> | |||||
| <Button onClick={handleClick}>Menu List</Button> | |||||
| <Menu id="menu-list" anchorEl={anchorEl} open={open} onClose={handleClose}> | |||||
| <MenuItem onClick={handleClose}>Menu Item 1</MenuItem> | |||||
| <MenuItem onClick={handleClose}>Menu Item 2</MenuItem> | |||||
| <MenuItem onClick={handleClose}>Menu Item 3</MenuItem> | |||||
| </Menu> | |||||
| </div> | |||||
| ); | |||||
| const handleLanguageChange = (language) => { | |||||
| i18n.changeLanguage(language); | |||||
| authScopeSetHelper(LANGUAGE, language) | |||||
| setAnchorEl(null); | |||||
| }; | |||||
| return ( | |||||
| <div> | |||||
| <Button onClick={handleClick}>{t("common.language")}</Button> | |||||
| <Menu | |||||
| id="menu-list" | |||||
| anchorEl={anchorEl} | |||||
| open={open} | |||||
| onClose={handleClose} | |||||
| > | |||||
| <MenuItem onClick={() => handleLanguageChange("en")}> | |||||
| {t("common.english")} | |||||
| </MenuItem> | |||||
| <MenuItem onClick={() => handleLanguageChange("sr")}> | |||||
| {t("common.serbian")} | |||||
| </MenuItem> | |||||
| </Menu> | |||||
| </div> | |||||
| ); | |||||
| }; | }; | ||||
| export default MenuListComponent; | export default MenuListComponent; |
| import React, { useEffect } from "react"; | import React, { useEffect } from "react"; | ||||
| import { Redirect, Route } from "react-router"; | import { Redirect, Route } from "react-router"; | ||||
| import { useDispatch } from "react-redux"; | |||||
| import { useDispatch, useSelector } from "react-redux"; | |||||
| import { authenticateUser } from "store/actions/login/loginActions"; | import { authenticateUser } from "store/actions/login/loginActions"; | ||||
| import { LOGIN_PAGE } from "constants/pages"; | import { LOGIN_PAGE } from "constants/pages"; | ||||
| import { selectIsUserAuthenticated } from "store/selectors/userSelectors"; | |||||
| const PrivateRoute = ({ ...props }) => { | const PrivateRoute = ({ ...props }) => { | ||||
| const dispatch = useDispatch(); | const dispatch = useDispatch(); | ||||
| // const isUserAuthenticated = useSelector(selectIsUserAuthenticated); | |||||
| const isUserAuthenticated = true; | |||||
| const isUserAuthenticated = useSelector(selectIsUserAuthenticated); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (!isUserAuthenticated) { | if (!isUserAuthenticated) { |
| export const JWT_TOKEN = 'JwtToken'; | export const JWT_TOKEN = 'JwtToken'; | ||||
| export const JWT_REFRESH_TOKEN = 'JwtRefreshToken'; | export const JWT_REFRESH_TOKEN = 'JwtRefreshToken'; | ||||
| export const REFRESH_TOKEN_CONST = 'RefreshToken'; | export const REFRESH_TOKEN_CONST = 'RefreshToken'; | ||||
| export const LANGUAGE = "Language" |
| import { format as formatDate } from 'date-fns'; | |||||
| import i18n from 'i18next'; | |||||
| import { initReactI18next } from 'react-i18next'; | |||||
| import { format as formatDate } from "date-fns"; | |||||
| import i18n from "i18next"; | |||||
| import { initReactI18next } from "react-i18next"; | |||||
| import enTranslations from './resources/en'; | |||||
| import enTranslations from "./resources/en"; | |||||
| import srTranslations from "./resources/sr"; | |||||
| i18n.use(initReactI18next).init({ | i18n.use(initReactI18next).init({ | ||||
| lng: 'en', | |||||
| fallbackLng: 'en', | |||||
| lng: "en", | |||||
| fallbackLng: "en", | |||||
| debug: false, | debug: false, | ||||
| supportedLngs: ['en'], | |||||
| supportedLngs: ["en", "sr"], | |||||
| resources: { | resources: { | ||||
| en: { | en: { | ||||
| translation: enTranslations, | translation: enTranslations, | ||||
| }, | }, | ||||
| sr: { | |||||
| translation: srTranslations, | |||||
| }, | |||||
| }, | }, | ||||
| interpolation: { | interpolation: { | ||||
| format: (value, format) => { | format: (value, format) => { |
| "You were registered as not active, please confirm that you are active in the next minute, if you don't you will be logged out.", | "You were registered as not active, please confirm that you are active in the next minute, if you don't you will be logged out.", | ||||
| }, | }, | ||||
| common: { | common: { | ||||
| language: "Language", | |||||
| english: 'English', | |||||
| serbian: "Serbian", | |||||
| close: 'Close', | close: 'Close', | ||||
| dataGridExample: 'Data Grid Example', | |||||
| trademark: 'TM', | trademark: 'TM', | ||||
| search: 'Search', | search: 'Search', | ||||
| error: 'Error', | error: 'Error', |
| export default { | |||||
| app: { | |||||
| title: 'React template' | |||||
| }, | |||||
| refresh: { | |||||
| title: 'Are you active?', | |||||
| cta: | |||||
| "You were registered as not active, please confirm that you are active in the next minute, if you don't you will be logged out.", | |||||
| }, | |||||
| common: { | |||||
| language: "Jezik", | |||||
| english: 'Engleski', | |||||
| serbian: "Srpski", | |||||
| dataGridExample: 'Primer Data Grid-a', | |||||
| close: 'Close', | |||||
| trademark: 'TM', | |||||
| search: 'Pretraga', | |||||
| error: 'Greška', | |||||
| continue: 'Nastavite', | |||||
| labelUsername: 'Korisničko ime', | |||||
| labelEmail: 'E-mail', | |||||
| labelPassword: 'Šifra', | |||||
| next: 'Napred', | |||||
| nextPage: 'Sledeća stranica', | |||||
| previousPage: 'Predhodna stranica', | |||||
| back: 'Nazad', | |||||
| goBack: 'Idite nazad', | |||||
| ok: 'U redu', | |||||
| done: 'Gotovo', | |||||
| confirm: 'Potvrdite', | |||||
| printDownload: 'Print/Download', | |||||
| cancel: 'Cancel', | |||||
| remove: 'Remove', | |||||
| invite: 'Invite', | |||||
| save: 'Save', | |||||
| complete: 'Complete', | |||||
| download: 'Download', | |||||
| yes: 'Yes', | |||||
| no: 'No', | |||||
| to: 'to', | |||||
| select: 'Select...', | |||||
| none: 'None', | |||||
| date: { | |||||
| range: '{{start}} to {{end}}', | |||||
| }, | |||||
| }, | |||||
| register: { | |||||
| registerTitle: "Register", | |||||
| usernameRequired: 'Username is required.', | |||||
| emailFormat: 'Invalid email address format.', | |||||
| emailRequired: 'An email or username is required.', | |||||
| passwordLength: 'Your password contain between 8 and 50 characters.', | |||||
| passwordRequired: 'A Password is required.', | |||||
| }, | |||||
| login: { | |||||
| welcome: 'React template', | |||||
| dontHaveAccount: "Nemate nalog? ", | |||||
| emailFormat: 'Loš format email-a', | |||||
| emailRequired: 'Email/korisničko ime je obavezno', | |||||
| noUsers: 'Ne postoji korisnik', | |||||
| passwordStrength: 'Your password is {{strength}}.', | |||||
| passwordLength: 'Your password contain between 8 and 50 characters.', | |||||
| signUpRecommendation: 'Registrujte se', | |||||
| email: 'Please enter your email address or username to log in:', | |||||
| logInTitle: 'Prijava', | |||||
| logIn: 'Ulogujte se', | |||||
| signUp: 'Sign Up', | |||||
| usernameRequired: 'Username is required.', | |||||
| passwordRequired: 'A Password is required.', | |||||
| forgotYourPassword: 'Zaboravili ste šifru?', | |||||
| forgotPasswordEmail:'Email', | |||||
| useDifferentEmail: 'Use different email address or username', | |||||
| }, | |||||
| password: { | |||||
| weak: 'weak', | |||||
| average: 'average', | |||||
| good: 'good', | |||||
| strong: 'strong', | |||||
| }, | |||||
| forgotPassword: { | |||||
| title: 'Forgot Password', | |||||
| label: 'Send email', | |||||
| emailRequired: 'An email is required.', | |||||
| emailFormat: 'Invalid email address format.', | |||||
| forgotPassword: { | |||||
| title: 'Forgot Password', | |||||
| subtitle: | |||||
| 'Please answer the security question to gain access to your account:', | |||||
| label: 'Reset Password', | |||||
| }, | |||||
| }, | |||||
| notFound: { | |||||
| text: "We're sorry but we couldn't find the page you were looking for.", | |||||
| goBack: 'Go back to homepage', | |||||
| }, | |||||
| errorPage: { | |||||
| text: | |||||
| "We're sorry, an internal server error came up. Please be patient or try again later.", | |||||
| goBack: 'Go back to homepage', | |||||
| logout: 'Logout', | |||||
| }, | |||||
| apiErrors:{ | |||||
| ClientIpAddressIsNullOrEmpty:"Client Ip address is null or empty", | |||||
| UsernameDoesNotExist: "Username does not exist", | |||||
| WrongCredentials: "Wrong credentials", | |||||
| SomethingWentWrong: "Something went wrong", | |||||
| WrongPasswordAccountIsLocked: "Wrong credentials, account is locked", | |||||
| AccountIsLocked: "Account is locked" | |||||
| } | |||||
| }; | |||||