| @@ -21,3 +21,5 @@ | |||
| npm-debug.log* | |||
| yarn-debug.log* | |||
| yarn-error.log* | |||
| /.idea | |||
| @@ -0,0 +1,17 @@ | |||
| FROM node:16 | |||
| WORKDIR ./src | |||
| COPY package*.json ./ | |||
| COPY src ./ | |||
| COPY public ./ | |||
| RUN npm install | |||
| ENV NODE_ENV='docker' | |||
| # Bundle app source | |||
| COPY . . | |||
| EXPOSE 3000 | |||
| CMD [ "npm", "start" ] | |||
| @@ -4,6 +4,7 @@ import { Redirect, Route, Switch } from "react-router-dom"; | |||
| import { | |||
| LOGIN_PAGE, | |||
| ADMIN_LOGIN_PAGE, | |||
| HOME_PAGE, | |||
| NOT_FOUND_PAGE, | |||
| ERROR_PAGE, | |||
| @@ -24,6 +25,7 @@ import { | |||
| // POLICY_PRIVACY_PAGE, | |||
| } from "./constants/pages"; | |||
| import LoginPage from "./pages/LoginPage/LoginPage"; | |||
| import AdminLoginPage from "./pages/AdminLoginPage/AdminLoginPage"; | |||
| import HomePage from "./pages/HomePage/HomePageMUI"; | |||
| import NotFoundPage from "./pages/ErrorPages/NotFoundPage"; | |||
| import ErrorPage from "./pages/ErrorPages/ErrorPage"; | |||
| @@ -49,6 +51,7 @@ const AppRoutes = () => { | |||
| <Switch> | |||
| <Route exact path={BASE_PAGE} component={HomePage} /> | |||
| <AuthRoute exact path={LOGIN_PAGE} component={LoginPage} /> | |||
| <AuthRoute exact path={ADMIN_LOGIN_PAGE} component={AdminLoginPage} /> | |||
| <Route path={NOT_FOUND_PAGE} component={NotFoundPage} /> | |||
| <Route path={ERROR_PAGE} component={ErrorPage} /> | |||
| <AuthRoute path={REGISTER_SUCCESSFUL_PAGE} component={RegisterSuccessful} /> | |||
| @@ -3,17 +3,18 @@ import PropTypes from "prop-types"; | |||
| import { LoginDescription as Description } from "./LoginDescription.styled"; | |||
| import { useTranslation } from "react-i18next"; | |||
| const LoginDescription = () => { | |||
| const LoginDescription = (props) => { | |||
| const { t } = useTranslation(); | |||
| return ( | |||
| <Description component="h1" variant="h6"> | |||
| {t("login.welcomeText")} | |||
| {props.isAdmin?t("admin.login.welcomeText"):t("login.welcomeText")} | |||
| </Description> | |||
| ); | |||
| }; | |||
| LoginDescription.propTypes = { | |||
| children: PropTypes.node, | |||
| isAdmin: PropTypes.bool | |||
| }; | |||
| export default LoginDescription; | |||
| @@ -10,6 +10,7 @@ import { | |||
| import { selectLoginError } from "../../store/selectors/loginSelectors"; | |||
| import { HOME_PAGE } from "../../constants/pages"; | |||
| import { ReactComponent as Logo } from "../../assets/images/svg/logo-vertical.svg"; | |||
| import { ReactComponent as LogoAdmin } from "../../assets/images/svg/logo-vertical-admin.svg"; | |||
| import { LoginPageContainer, LoginFormContainer } from "./Login.styled"; | |||
| import loginValidation from "../../validations/loginValidation"; | |||
| import loginInitialValues from "../../initialValues/loginInitialValues"; | |||
| @@ -22,7 +23,7 @@ import ForgotPasswordLink from "./ForgotPasswordLink/ForgotPasswordLink"; | |||
| import LoginButton from "./LoginButton/LoginButton"; | |||
| import RegisterLink from "./RegisterLink/RegisterLink"; | |||
| const Login = () => { | |||
| const Login = (props) => { | |||
| const dispatch = useDispatch(); | |||
| const error = useSelector(selectLoginError); | |||
| const history = useHistory(); | |||
| @@ -103,16 +104,18 @@ const Login = () => { | |||
| return ( | |||
| <LoginPageContainer> | |||
| <Logo /> | |||
| <LoginTitle /> | |||
| <LoginDescription /> | |||
| { | |||
| props.isAdmin ? <LogoAdmin/> : <Logo/> | |||
| } | |||
| <LoginTitle isAdmin={props.isAdmin} /> | |||
| <LoginDescription isAdmin={props.isAdmin}/> | |||
| <LoginFormContainer component="form" onSubmit={handleSubmitForm}> | |||
| <EmailField formik={formik} /> | |||
| <PasswordField formik={formik} ref={passwordRef} /> | |||
| <ErrorMessage formik={formik} /> | |||
| <ForgotPasswordLink /> | |||
| {!props.isAdmin ? <ForgotPasswordLink/>:<></>} | |||
| <LoginButton formik={formik} /> | |||
| <RegisterLink /> | |||
| {!props.isAdmin ? <RegisterLink/>:<></>} | |||
| </LoginFormContainer> | |||
| </LoginPageContainer> | |||
| ); | |||
| @@ -126,5 +129,6 @@ Login.propTypes = { | |||
| pathname: PropTypes.string, | |||
| }), | |||
| }), | |||
| isAdmin: PropTypes.bool | |||
| }; | |||
| export default Login; | |||
| @@ -3,17 +3,20 @@ import PropTypes from "prop-types"; | |||
| import { useTranslation } from "react-i18next"; | |||
| import { LoginTitle as Title } from "./LoginTitle.styled"; | |||
| const LoginTitle = () => { | |||
| const LoginTitle = (props) => { | |||
| const { t } = useTranslation(); | |||
| return ( | |||
| <Title component="h1" variant="h5"> | |||
| {t("login.logInTitle")} | |||
| { | |||
| props.isAdmin ? t("admin.login.logInTitle") : t("login.logInTitle") | |||
| } | |||
| </Title> | |||
| ); | |||
| }; | |||
| LoginTitle.propTypes = { | |||
| children: PropTypes.node, | |||
| isAdmin: PropTypes.bool | |||
| }; | |||
| export default LoginTitle; | |||
| @@ -1,6 +1,7 @@ | |||
| export const BASE_PAGE = '/'; | |||
| export const LOGIN_PAGE = '/login'; | |||
| export const FORGOT_PASSWORD_PAGE = '/forgot-password'; | |||
| export const ADMIN_LOGIN_PAGE = '/admin/login'; | |||
| export const HOME_PAGE = '/home'; | |||
| export const ERROR_PAGE = '/error-page'; | |||
| export const NOT_FOUND_PAGE = '/not-found'; | |||
| @@ -390,4 +390,22 @@ export default { | |||
| description: "Opis", | |||
| email: "Mejl kompanije", | |||
| }, | |||
| admin: { | |||
| login:{ | |||
| welcome: "React template", | |||
| welcomeText: "Trampa sa kolegama na dohvat ruke", | |||
| emailFormat: "Nevalidan format email adrese!", | |||
| emailRequired: "Email adresa je obavezna!", | |||
| noUsers: "Ne postoji korisnik sa zadatom email adresom.", | |||
| passwordStrength: "Your password is {{strength}}.", | |||
| passwordLength: "Lozinka mora imati najmanje 8 karaktera!", | |||
| email: "Unesite email adresu kako biste se prijavili", | |||
| logInTitle: "Uloguj se", | |||
| logIn: "Uloguj se", | |||
| usernameRequired: "Username je obavezan!", | |||
| passwordRequired: "Lozinka je obavezna!", | |||
| wrongCredentials: "Pogrešan mail ili lozinka!", | |||
| headerTitle: "Ulogujte se", | |||
| } | |||
| } | |||
| }; | |||
| @@ -0,0 +1,15 @@ | |||
| import React from 'react' | |||
| import PropTypes from 'prop-types' | |||
| import Login from '../../components/Login/Login' | |||
| const LoginPage = () => { | |||
| return ( | |||
| <Login isAdmin/> | |||
| ) | |||
| } | |||
| LoginPage.propTypes = { | |||
| children: PropTypes.node, | |||
| } | |||
| export default LoginPage | |||
| @@ -4,7 +4,7 @@ import Login from '../../components/Login/Login' | |||
| const LoginPage = () => { | |||
| return ( | |||
| <Login /> | |||
| <Login isAdmin={false}/> | |||
| ) | |||
| } | |||