| import { useLocation } from "react-router-dom"; | import { useLocation } from "react-router-dom"; | ||||
| import { | import { | ||||
| HOME_PAGE, | |||||
| ADS_PAGE, | ADS_PAGE, | ||||
| AD_DETAILS_PAGE, | AD_DETAILS_PAGE, | ||||
| FORGOT_PASSWORD_PAGE, | FORGOT_PASSWORD_PAGE, | ||||
| CREATE_AD_PAGE, | CREATE_AD_PAGE, | ||||
| } from "./constants/pages"; | } from "./constants/pages"; | ||||
| // import LoginPage from './pages/LoginPage/LoginPage'; | |||||
| import LoginPage from "./pages/LoginPage/LoginPageMUI"; | import LoginPage from "./pages/LoginPage/LoginPageMUI"; | ||||
| // import HomePage from './pages/HomePage/HomePage'; | |||||
| import HomePage from "./pages/HomePage/HomePageMUI"; | |||||
| import AdsPage from "./pages/AdsPage/AdsPage"; | import AdsPage from "./pages/AdsPage/AdsPage"; | ||||
| import NotFoundPage from "./pages/ErrorPages/NotFoundPage"; | import NotFoundPage from "./pages/ErrorPages/NotFoundPage"; | ||||
| import ErrorPage from "./pages/ErrorPages/ErrorPage"; | import ErrorPage from "./pages/ErrorPages/ErrorPage"; | ||||
| // import ForgotPasswordPage from './pages/ForgotPasswordPage/ForgotPasswordPage'; | |||||
| import ForgotPasswordPage from "./pages/ForgotPasswordPage/ForgotPasswordPageMUI"; | import ForgotPasswordPage from "./pages/ForgotPasswordPage/ForgotPasswordPageMUI"; | ||||
| import PrivateRoute from "./components/Router/PrivateRoute"; | import PrivateRoute from "./components/Router/PrivateRoute"; | ||||
| import ForgotPasswordConfirmationPage from "./pages/ForgotPasswordPage/ForgotPasswordConfirmationPageMUI"; | import ForgotPasswordConfirmationPage from "./pages/ForgotPasswordPage/ForgotPasswordConfirmationPageMUI"; | ||||
| /> | /> | ||||
| <Route exact path={REGISTER_PAGE} component={RegisterPage} /> | <Route exact path={REGISTER_PAGE} component={RegisterPage} /> | ||||
| <Route path={RESET_PASSWORD_PAGE} component={ResetPasswordPage} /> | <Route path={RESET_PASSWORD_PAGE} component={ResetPasswordPage} /> | ||||
| <PrivateRoute exact path={HOME_PAGE} component={HomePage} /> | |||||
| <PrivateRoute exact path={ADS_PAGE} component={AdsPage} /> | <PrivateRoute exact path={ADS_PAGE} component={AdsPage} /> | ||||
| <PrivateRoute exact path={AD_DETAILS_PAGE} component={AdDetailsPage} /> | <PrivateRoute exact path={AD_DETAILS_PAGE} component={AdDetailsPage} /> | ||||
| <PrivateRoute exact path={USER_DETAILS_PAGE} component={UserDetails} /> | <PrivateRoute exact path={USER_DETAILS_PAGE} component={UserDetails} /> |
| import * as redux from "react-redux"; | |||||
| import store from "../../store"; | |||||
| import { Router } from "react-router-dom"; | |||||
| import { render } from "@testing-library/react"; | |||||
| import history from "../../store/utils/history"; | |||||
| import ErrorPage from "../../pages/ErrorPages/ErrorPage"; | |||||
| describe("ErrorPage render tests", () => { | |||||
| const cont = ( | |||||
| <redux.Provider store={store}> | |||||
| <Router history={history}> | |||||
| <ErrorPage /> | |||||
| </Router> | |||||
| </redux.Provider> | |||||
| ); | |||||
| // beforeEach(() => { | |||||
| // jest.mock("react-i18next", () => ({ | |||||
| // useTranslation: () => ({ | |||||
| // t: (key) => key, | |||||
| // i18n: { changeLanguage: jest.fn() }, | |||||
| // }), | |||||
| // })); | |||||
| // }); | |||||
| afterEach(() => { | |||||
| jest.restoreAllMocks(); | |||||
| }); | |||||
| it("Should render", () => { | |||||
| const { container } = render(cont); | |||||
| expect(container.getElementsByClassName("c-error-page")[0]).toBeDefined(); | |||||
| }); | |||||
| it("Should render status code 500", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container.getElementsByClassName("c-error-page__title")[0].textContent | |||||
| ).toBe("500"); | |||||
| }); | |||||
| it("Should render text", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container.getElementsByClassName("c-error-page__text")[0] | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| }); |
| import * as redux from "react-redux"; | |||||
| import store from "../../store"; | |||||
| import { Router } from "react-router-dom"; | |||||
| import { render, screen } from "@testing-library/react"; | |||||
| import history from "../../store/utils/history"; | |||||
| import ForgotPasswordConfirmationPage from "../../pages/ForgotPasswordPage/ForgotPasswordConfirmationPageMUI"; | |||||
| describe("ForgotPasswordConfirmationPage render tests", () => { | |||||
| const cont = ( | |||||
| <redux.Provider store={store}> | |||||
| <Router history={history}> | |||||
| <ForgotPasswordConfirmationPage /> | |||||
| </Router> | |||||
| </redux.Provider> | |||||
| ); | |||||
| afterEach(() => { | |||||
| jest.restoreAllMocks(); | |||||
| }); | |||||
| it("Should render", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container.getElementsByClassName("c-login-container")[0] | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| it("Should render login logo", () => { | |||||
| const { container } = render(cont); | |||||
| expect(container.getElementsByClassName("login-logo")[0]).toBeDefined(); | |||||
| }); | |||||
| it("Should render header", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container | |||||
| .getElementsByClassName("c-login-container")[0] | |||||
| .querySelector("h") | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| it("Should render paragraph", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container | |||||
| .getElementsByClassName("c-login-container")[0] | |||||
| .querySelector("p") | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| it("Should link for paragraph", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container | |||||
| .getElementsByClassName("c-login-container")[0] | |||||
| .querySelector("p") | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| it("Should render link for going to login page", () => { | |||||
| render(cont); | |||||
| expect(screen.getByTestId("back-link")).toBeDefined(); | |||||
| }); | |||||
| it("Should render dilig logo", () => { | |||||
| render(cont); | |||||
| expect(screen.getByTestId("dilig-logo")).toBeDefined(); | |||||
| }); | |||||
| }); |
| import * as redux from "react-redux"; | |||||
| import store from "../../store"; | |||||
| import { Router } from "react-router-dom"; | |||||
| import { fireEvent, render, screen, waitFor } from "@testing-library/react"; | |||||
| import history from "../../store/utils/history"; | |||||
| import ForgotPasswordPage from "../../pages/ForgotPasswordPage/ForgotPasswordPageMUI"; | |||||
| describe("ForgotPasswordPage render tests", () => { | |||||
| const cont = ( | |||||
| <redux.Provider store={store}> | |||||
| <Router history={history}> | |||||
| <ForgotPasswordPage /> | |||||
| </Router> | |||||
| </redux.Provider> | |||||
| ); | |||||
| let spyOnUseDispatch; | |||||
| let mockDispatch; | |||||
| beforeEach(() => { | |||||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||||
| mockDispatch = jest.fn(); | |||||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||||
| }); | |||||
| afterEach(() => { | |||||
| jest.restoreAllMocks(); | |||||
| }); | |||||
| it("Should render", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container.getElementsByClassName("c-login-container")[0] | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| it("Should render login logo", () => { | |||||
| const { container } = render(cont); | |||||
| expect(container.getElementsByClassName("login-logo")[0]).toBeDefined(); | |||||
| }); | |||||
| it("Should render header", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container | |||||
| .getElementsByClassName("c-login-container")[0] | |||||
| .querySelector("h") | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| it("Should render paragraph", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container | |||||
| .getElementsByClassName("c-login-container")[0] | |||||
| .querySelector("p") | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| it("Should render email input", () => { | |||||
| render(cont); | |||||
| expect(screen.getByTestId("email-input")).toBeDefined(); | |||||
| }); | |||||
| it("Should render submit button", () => { | |||||
| const { container } = render(cont); | |||||
| expect(container.getElementsByClassName("c-btn")[0]).toBeDefined(); | |||||
| }); | |||||
| it("Should render link for going to login page", () => { | |||||
| render(cont); | |||||
| expect(screen.getByTestId("back-link")).toBeDefined(); | |||||
| }); | |||||
| it("Should render dilig logo", () => { | |||||
| render(cont); | |||||
| expect(screen.getByTestId("dilig-logo")).toBeDefined(); | |||||
| }); | |||||
| it("Should not dispatch function because input for email is empty", async () => { | |||||
| const { container } = render(cont); | |||||
| fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(0)); | |||||
| }); | |||||
| it("Should dispatch function becxause input for email is not empty", async () => { | |||||
| const { container } = render(cont); | |||||
| fireEvent.change(screen.getByTestId("email-input"), { | |||||
| target: { value: "dzenis@dilig.net" }, | |||||
| }); | |||||
| fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(1)); | |||||
| }); | |||||
| }); |
| import * as redux from "react-redux"; | |||||
| import store from "../../store"; | |||||
| import { Router } from "react-router-dom"; | |||||
| import { render } from "@testing-library/react"; | |||||
| import history from "../../store/utils/history"; | |||||
| import NotFoundPage from "../../pages/ErrorPages/NotFoundPage"; | |||||
| describe("ErrorPage render tests", () => { | |||||
| const cont = ( | |||||
| <redux.Provider store={store}> | |||||
| <Router history={history}> | |||||
| <NotFoundPage /> | |||||
| </Router> | |||||
| </redux.Provider> | |||||
| ); | |||||
| afterEach(() => { | |||||
| jest.restoreAllMocks(); | |||||
| }); | |||||
| it("Should render", () => { | |||||
| const { container } = render(cont); | |||||
| expect(container.getElementsByClassName("not-found-page")[0]).toBeDefined(); | |||||
| }); | |||||
| it("Should render status code 404", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container.getElementsByClassName("c-error-page__title")[0].textContent | |||||
| ).toBe("404"); | |||||
| }); | |||||
| it("Should render text", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container.getElementsByClassName("c-error-page__text")[0] | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| it("Should render button for going back to previous page", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container.getElementsByClassName("c-error-page__button")[0] | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| }); |
| import * as redux from "react-redux"; | |||||
| import store from "../../store"; | |||||
| import { Router } from "react-router-dom"; | |||||
| import { fireEvent, render, screen, waitFor } from "@testing-library/react"; | |||||
| import history from "../../store/utils/history"; | |||||
| import ResetPasswordPage from "../../pages/ForgotPasswordPage/ResetPasswordPageMUI"; | |||||
| describe("ResetPassword render tests", () => { | |||||
| const cont = ( | |||||
| <redux.Provider store={store}> | |||||
| <Router history={history}> | |||||
| <ResetPasswordPage /> | |||||
| </Router> | |||||
| </redux.Provider> | |||||
| ); | |||||
| let spyOnUseDispatch; | |||||
| let mockDispatch; | |||||
| beforeEach(() => { | |||||
| spyOnUseDispatch = jest.spyOn(redux, "useDispatch"); | |||||
| mockDispatch = jest.fn(); | |||||
| spyOnUseDispatch.mockReturnValue(mockDispatch); | |||||
| }); | |||||
| afterEach(() => { | |||||
| jest.restoreAllMocks(); | |||||
| }); | |||||
| it("Should render", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container.getElementsByClassName("c-login-container")[0] | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| it("Should render login logo", () => { | |||||
| const { container } = render(cont); | |||||
| expect(container.getElementsByClassName("login-logo")[0]).toBeDefined(); | |||||
| }); | |||||
| it("Should render header", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container | |||||
| .getElementsByClassName("c-login-container")[0] | |||||
| .querySelector("h") | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| it("Should render paragraph", () => { | |||||
| const { container } = render(cont); | |||||
| expect( | |||||
| container | |||||
| .getElementsByClassName("c-login-container")[0] | |||||
| .querySelector("p") | |||||
| ).toBeDefined(); | |||||
| }); | |||||
| it("Should render password input", () => { | |||||
| render(cont); | |||||
| expect(screen.getByTestId("password-input")).toBeDefined(); | |||||
| }); | |||||
| it("Should render confirm password input", () => { | |||||
| render(cont); | |||||
| expect(screen.getByTestId("confirm-password-input")).toBeDefined(); | |||||
| }); | |||||
| it("Should render submit button", () => { | |||||
| const { container } = render(cont); | |||||
| expect(container.getElementsByClassName("c-btn")[0]).toBeDefined(); | |||||
| }); | |||||
| it("Should render link for going to login page", () => { | |||||
| render(cont); | |||||
| expect(screen.getByTestId("back-link")).toBeDefined(); | |||||
| }); | |||||
| it("Should render dilig logo", () => { | |||||
| render(cont); | |||||
| expect(screen.getByTestId("dilig-logo")).toBeDefined(); | |||||
| }); | |||||
| it("Should not dispatch function because input for password is empty", async () => { | |||||
| const { container } = render(cont); | |||||
| fireEvent.change(screen.getByTestId("confirm-password-input"), { | |||||
| target: { value: "nekaSifra" }, | |||||
| }); | |||||
| fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(0)); | |||||
| }); | |||||
| it("Should not dispatch function because input for confirm password is empty", async () => { | |||||
| const { container } = render(cont); | |||||
| fireEvent.change(screen.getByTestId("password-input"), { | |||||
| target: { value: "nekaSifra" }, | |||||
| }); | |||||
| fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(0)); | |||||
| }); | |||||
| it("Should not dispatch function because paswwords doesn't match", async () => { | |||||
| const { container } = render(cont); | |||||
| fireEvent.change(screen.getByTestId("password-input"), { | |||||
| target: { value: "nekaSifra" }, | |||||
| }); | |||||
| fireEvent.change(screen.getByTestId("confirm-password-input"), { | |||||
| target: { value: "nekaDrugaSifra" }, | |||||
| }); | |||||
| fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(0)); | |||||
| }); | |||||
| it("Should dispatch function because no input is empty and passwords match", async () => { | |||||
| const { container } = render(cont); | |||||
| fireEvent.change(screen.getByTestId("password-input"), { | |||||
| target: { value: "nekaSifra" }, | |||||
| }); | |||||
| fireEvent.change(screen.getByTestId("confirm-password-input"), { | |||||
| target: { value: "nekaSifra" }, | |||||
| }); | |||||
| fireEvent.click(container.getElementsByClassName("c-btn")[0]); | |||||
| await waitFor(() => expect(mockDispatch).toBeCalledTimes(1)); | |||||
| }); | |||||
| }); |
| return ( | return ( | ||||
| // <div className="c-error-page"> to be FIXED LATER!!!! | // <div className="c-error-page"> to be FIXED LATER!!!! | ||||
| <div className=""> | |||||
| <div className="not-found-page"> | |||||
| <Section className="c-error-page__content-container"> | <Section className="c-error-page__content-container"> | ||||
| <div className="c-error-page__content"> | <div className="c-error-page__content"> | ||||
| <h1 className="c-error-page__title">404</h1> | <h1 className="c-error-page__title">404</h1> |
| import React from 'react'; | |||||
| import { useTranslation } from 'react-i18next'; | |||||
| import React from "react"; | |||||
| import { useTranslation } from "react-i18next"; | |||||
| import HrLogo from "../../assets/images/hrcenter.png"; | import HrLogo from "../../assets/images/hrcenter.png"; | ||||
| import DiligLogo from "../../assets/images/logo_horizontal_black.png"; | import DiligLogo from "../../assets/images/logo_horizontal_black.png"; | ||||
| import { | |||||
| Box, | |||||
| Container, | |||||
| Typography, | |||||
| Link, | |||||
| Grid, | |||||
| } from '@mui/material'; | |||||
| import Backdrop from '../../components/MUI/BackdropComponent'; | |||||
| import { BASE_PAGE } from '../../constants/pages'; | |||||
| import { NavLink } from 'react-router-dom'; | |||||
| import { Box, Container, Typography, Link, Grid } from "@mui/material"; | |||||
| import Backdrop from "../../components/MUI/BackdropComponent"; | |||||
| import { BASE_PAGE } from "../../constants/pages"; | |||||
| import { NavLink } from "react-router-dom"; | |||||
| const ForgotPasswordConfirmationPage = () => { | const ForgotPasswordConfirmationPage = () => { | ||||
| const { t } = useTranslation(); | |||||
| const { t } = useTranslation(); | |||||
| return ( | |||||
| <Container | |||||
| component="main" | |||||
| maxWidth="xl" | |||||
| className="c-login-container" | |||||
| fullwidth="true"> | |||||
| <div className="l-t-rectangle"></div> | |||||
| <div className="r-b-rectangle"></div> | |||||
| <Box | |||||
| sx={{ | |||||
| marginTop: 2, | |||||
| width: 350, | |||||
| height: 684, | |||||
| display: "flex", | |||||
| flexDirection: "column", | |||||
| alignItems: "center", | |||||
| }} | |||||
| > | |||||
| <img src={HrLogo} className="login-logo" /> | |||||
| <Typography variant="h5" sx={{ m: 2, mt: 3 }}> | |||||
| {t("login.forgotYourPassword")} | |||||
| </Typography> | |||||
| <Typography variant="p"> | |||||
| {t("login.forgotYourPasswordConfimation")} | |||||
| </Typography> | |||||
| <Box | |||||
| component="form" | |||||
| sx={{ position: 'relative', mt: 1, p: 1 }} | |||||
| > | |||||
| <Backdrop position="absolute" isLoading={false} /> | |||||
| <Grid container justifyContent="center"> | |||||
| <Link | |||||
| to={BASE_PAGE} | |||||
| component={NavLink} | |||||
| variant="body2" | |||||
| underline="hover" | |||||
| > | |||||
| {t('login.forgotYourPasswordBackLink')} | |||||
| </Link> | |||||
| </Grid> | |||||
| <div className="flex-center"> | |||||
| <img src={DiligLogo} style={{ margin: "70px auto 0px auto" }} /> | |||||
| </div> | |||||
| </Box> | |||||
| </Box> | |||||
| </Container> | |||||
| ); | |||||
| return ( | |||||
| <Container | |||||
| component="main" | |||||
| maxWidth="xl" | |||||
| className="c-login-container" | |||||
| fullwidth="true" | |||||
| > | |||||
| <div className="l-t-rectangle"></div> | |||||
| <div className="r-b-rectangle"></div> | |||||
| <Box | |||||
| sx={{ | |||||
| marginTop: 2, | |||||
| width: 350, | |||||
| height: 684, | |||||
| display: "flex", | |||||
| flexDirection: "column", | |||||
| alignItems: "center", | |||||
| }} | |||||
| > | |||||
| <img src={HrLogo} className="login-logo" /> | |||||
| <Typography variant="h5" sx={{ m: 2, mt: 3 }}> | |||||
| {t("login.forgotYourPassword")} | |||||
| </Typography> | |||||
| <Typography variant="p"> | |||||
| {t("login.forgotYourPasswordConfimation")} | |||||
| </Typography> | |||||
| <Box component="form" sx={{ position: "relative", mt: 1, p: 1 }}> | |||||
| <Backdrop position="absolute" isLoading={false} /> | |||||
| <Grid container justifyContent="center"> | |||||
| <Link | |||||
| to={BASE_PAGE} | |||||
| component={NavLink} | |||||
| variant="body2" | |||||
| underline="hover" | |||||
| data-testid="back-link" | |||||
| > | |||||
| {t("login.forgotYourPasswordBackLink")} | |||||
| </Link> | |||||
| </Grid> | |||||
| <div className="flex-center" data-testid="dilig-logo"> | |||||
| <img src={DiligLogo} style={{ margin: "70px auto 0px auto" }} /> | |||||
| </div> | |||||
| </Box> | |||||
| </Box> | |||||
| </Container> | |||||
| ); | |||||
| }; | }; | ||||
| export default ForgotPasswordConfirmationPage; | export default ForgotPasswordConfirmationPage; |
| import React from 'react'; | |||||
| import { Formik, Form, Field } from 'formik'; | |||||
| import { useTranslation } from 'react-i18next'; | |||||
| import * as Yup from 'yup'; | |||||
| import i18next from 'i18next'; | |||||
| import Auth from '../../components/Auth/Auth'; | |||||
| import AuthCard from '../../components/AuthCards/AuthCard'; | |||||
| import TextField from '../../components/InputFields/TextField'; | |||||
| import Button from '../../components/Button/Button'; | |||||
| import Section from '../../components/Section/Section'; | |||||
| const forgotPasswordValidationSchema = Yup.object().shape({ | |||||
| email: Yup.string().required( | |||||
| i18next.t('login.securityQuestion.answerRequired'), | |||||
| ), | |||||
| }); | |||||
| const ForgotPasswordPage = () => { | |||||
| const { t } = useTranslation(); | |||||
| const handleSubmit = (values) => { | |||||
| console.log("Values",values) | |||||
| }; | |||||
| return ( | |||||
| <Auth> | |||||
| <AuthCard | |||||
| title={t('forgotPassword.title')} | |||||
| > | |||||
| <Section> | |||||
| <div className="c-reset-security"> | |||||
| <div className="c-reset-security__form"> | |||||
| <Formik | |||||
| onSubmit={handleSubmit} | |||||
| initialValues={{ email: '' }} | |||||
| validationSchema={forgotPasswordValidationSchema} | |||||
| > | |||||
| <Form> | |||||
| <Field | |||||
| label={t('login.forgotPasswordEmail')} | |||||
| name="email" | |||||
| component={TextField} | |||||
| /> | |||||
| <Button | |||||
| className="c-reset-security__button" | |||||
| authButton | |||||
| variant="primary" | |||||
| type="submit" | |||||
| > | |||||
| {t('forgotPassword.label')} | |||||
| </Button> | |||||
| </Form> | |||||
| </Formik> | |||||
| </div> | |||||
| </div> | |||||
| </Section> | |||||
| </AuthCard> | |||||
| </Auth> | |||||
| ); | |||||
| }; | |||||
| export default ForgotPasswordPage; |
| helperText={formik.touched.email && formik.errors.email} | helperText={formik.touched.email && formik.errors.email} | ||||
| autoFocus | autoFocus | ||||
| fullWidth | fullWidth | ||||
| inputProps={{"data-testid": "email-input"}} | |||||
| /> | /> | ||||
| <Button | <Button | ||||
| type="submit" | type="submit" | ||||
| component={NavLink} | component={NavLink} | ||||
| variant="body2" | variant="body2" | ||||
| underline="hover" | underline="hover" | ||||
| data-testid="back-link" | |||||
| > | > | ||||
| {t('login.forgotYourPasswordBackLink')} | {t('login.forgotYourPasswordBackLink')} | ||||
| </Link> | </Link> | ||||
| </Grid> | </Grid> | ||||
| <div className="flex-center"> | |||||
| <div className="flex-center" data-testid="dilig-logo"> | |||||
| <img src={DiligLogo} style={{ margin: "70px auto 0px auto" }} /> | <img src={DiligLogo} style={{ margin: "70px auto 0px auto" }} /> | ||||
| </div> | </div> | ||||
| </Box> | </Box> |
| import React, { useState } from 'react'; | |||||
| import React, { useState } from "react"; | |||||
| import PropTypes from "prop-types"; | import PropTypes from "prop-types"; | ||||
| import { useFormik } from 'formik'; | |||||
| import { useTranslation } from 'react-i18next'; | |||||
| import { useFormik } from "formik"; | |||||
| import { useTranslation } from "react-i18next"; | |||||
| import { useDispatch } from "react-redux"; | import { useDispatch } from "react-redux"; | ||||
| import DiligLogo from "../../assets/images/logo_horizontal_black.png"; | import DiligLogo from "../../assets/images/logo_horizontal_black.png"; | ||||
| import * as Yup from 'yup'; | |||||
| import * as Yup from "yup"; | |||||
| // import i18next from 'i18next'; | // import i18next from 'i18next'; | ||||
| import HrLogo from "../../assets/images/hrcenter.png"; | import HrLogo from "../../assets/images/hrcenter.png"; | ||||
| import { | import { | ||||
| Box, | |||||
| Container, | |||||
| Typography, | |||||
| Button, | |||||
| InputAdornment, | |||||
| IconButton, | |||||
| TextField, | |||||
| Link, | |||||
| Grid, | |||||
| } from '@mui/material'; | |||||
| Box, | |||||
| Container, | |||||
| Typography, | |||||
| Button, | |||||
| InputAdornment, | |||||
| IconButton, | |||||
| TextField, | |||||
| Link, | |||||
| Grid, | |||||
| } from "@mui/material"; | |||||
| import { Visibility, VisibilityOff } from "@mui/icons-material"; | import { Visibility, VisibilityOff } from "@mui/icons-material"; | ||||
| import Backdrop from '../../components/MUI/BackdropComponent'; | |||||
| import { BASE_PAGE } from '../../constants/pages'; | |||||
| import { NavLink } from 'react-router-dom'; | |||||
| import { resetPassword } from '../../store/actions/login/loginActions'; | |||||
| import Backdrop from "../../components/MUI/BackdropComponent"; | |||||
| import { BASE_PAGE } from "../../constants/pages"; | |||||
| import { NavLink } from "react-router-dom"; | |||||
| import { resetPassword } from "../../store/actions/login/loginActions"; | |||||
| function getQueryVariable(variable) { | function getQueryVariable(variable) { | ||||
| var query = window.location.search.substring(1); | |||||
| var vars = query.split("&"); | |||||
| for (var i = 0; i < vars.length; i++) { | |||||
| var pair = vars[i].split("="); | |||||
| if (pair[0] == variable) { return pair[1]; } | |||||
| } | |||||
| return (false); | |||||
| var query = window.location.search.substring(1); | |||||
| var vars = query.split("&"); | |||||
| for (var i = 0; i < vars.length; i++) { | |||||
| var pair = vars[i].split("="); | |||||
| if (pair[0] == variable) { | |||||
| return pair[1]; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | } | ||||
| const ResetPasswordPage = ({ history }) => { | const ResetPasswordPage = ({ history }) => { | ||||
| const dispatch = useDispatch(); | |||||
| const { t } = useTranslation(); | |||||
| const dispatch = useDispatch(); | |||||
| const { t } = useTranslation(); | |||||
| const [showPassword, setShowPassword] = useState(false); | |||||
| const [showConfirmPassword, setShowConfirmPassword] = useState(false); | |||||
| const handleClickShowPassword = () => setShowPassword(!showPassword); | |||||
| const handleMouseDownPassword = () => setShowPassword(!showPassword); | |||||
| const [showPassword, setShowPassword] = useState(false); | |||||
| const [showConfirmPassword, setShowConfirmPassword] = useState(false); | |||||
| const handleClickShowPassword = () => setShowPassword(!showPassword); | |||||
| const handleMouseDownPassword = () => setShowPassword(!showPassword); | |||||
| const handleClickShowConfirmPassword = () => setShowConfirmPassword(!showConfirmPassword); | |||||
| const handleMouseDownConfirmPassword = () => setShowConfirmPassword(!showConfirmPassword); | |||||
| const handleClickShowConfirmPassword = () => | |||||
| setShowConfirmPassword(!showConfirmPassword); | |||||
| const handleMouseDownConfirmPassword = () => | |||||
| setShowConfirmPassword(!showConfirmPassword); | |||||
| const resetPasswordValidationSchema = Yup.object().shape({ | |||||
| password: Yup.string().required(t("login.passwordRequired")), | |||||
| confirmPassword: Yup.string().required(t("login.passwordRequired")) | |||||
| .oneOf([Yup.ref('password'), null], t('login.passwordDontMatch')) | |||||
| }); | |||||
| const resetPasswordValidationSchema = Yup.object().shape({ | |||||
| password: Yup.string().required(t("login.passwordRequired")), | |||||
| confirmPassword: Yup.string() | |||||
| .required(t("login.passwordRequired")) | |||||
| .oneOf([Yup.ref("password"), null], t("login.passwordDontMatch")), | |||||
| }); | |||||
| const handleSubmit = (values) => { | |||||
| const password = values.password; | |||||
| // const confirmPassword = values.confirmPassword; | |||||
| // if (password === confirmPassword) | |||||
| { | |||||
| const code = getQueryVariable('token'), | |||||
| email = getQueryVariable('email'); | |||||
| dispatch( | |||||
| resetPassword({ | |||||
| code, | |||||
| email, | |||||
| password, | |||||
| handleApiResponseSuccess, | |||||
| }) | |||||
| ); | |||||
| } | |||||
| }; | |||||
| const handleSubmit = (values) => { | |||||
| const password = values.password; | |||||
| // const confirmPassword = values.confirmPassword; | |||||
| // if (password === confirmPassword) | |||||
| { | |||||
| const code = getQueryVariable("token"), | |||||
| email = getQueryVariable("email"); | |||||
| dispatch( | |||||
| resetPassword({ | |||||
| code, | |||||
| email, | |||||
| password, | |||||
| handleApiResponseSuccess, | |||||
| }) | |||||
| ); | |||||
| } | |||||
| }; | |||||
| const handleApiResponseSuccess = () => { | |||||
| history.push({ | |||||
| pathname: BASE_PAGE, | |||||
| state: { | |||||
| from: history.location.pathname, | |||||
| }, | |||||
| }); | |||||
| }; | |||||
| const handleApiResponseSuccess = () => { | |||||
| history.push({ | |||||
| pathname: BASE_PAGE, | |||||
| state: { | |||||
| from: history.location.pathname, | |||||
| }, | |||||
| }); | |||||
| }; | |||||
| const formik = useFormik({ | |||||
| initialValues: { | |||||
| password: '', | |||||
| confirmPassword: '', | |||||
| }, | |||||
| validationSchema: resetPasswordValidationSchema, | |||||
| onSubmit: handleSubmit, | |||||
| validateOnBlur: true, | |||||
| enableReinitialize: true, | |||||
| }); | |||||
| const formik = useFormik({ | |||||
| initialValues: { | |||||
| password: "", | |||||
| confirmPassword: "", | |||||
| }, | |||||
| validationSchema: resetPasswordValidationSchema, | |||||
| onSubmit: handleSubmit, | |||||
| validateOnBlur: true, | |||||
| enableReinitialize: true, | |||||
| }); | |||||
| return ( | |||||
| <Container | |||||
| component="main" | |||||
| maxWidth="xl" | |||||
| className="c-login-container" | |||||
| fullwidth="true"> | |||||
| <div className="l-t-rectangle"></div> | |||||
| <div className="r-b-rectangle"></div> | |||||
| <Box | |||||
| sx={{ | |||||
| marginTop: 2, | |||||
| width: 350, | |||||
| height: 684, | |||||
| display: "flex", | |||||
| flexDirection: "column", | |||||
| alignItems: "center", | |||||
| }} | |||||
| > | |||||
| <img src={HrLogo} className="login-logo" /> | |||||
| <Typography variant="h5" sx={{ m: 2, mt: 3 }}> | |||||
| {t("login.resetYourPassword")} | |||||
| </Typography> | |||||
| <Typography variant="p"> | |||||
| {t("login.resetYourPasswordHelpText")} | |||||
| </Typography> | |||||
| <Box | |||||
| component="form" | |||||
| onSubmit={formik.handleSubmit} | |||||
| sx={{ position: 'relative', mt: 1, p: 1 }} | |||||
| > | |||||
| <Backdrop position="absolute" isLoading={false} /> | |||||
| <TextField | |||||
| className="rounded-input" | |||||
| name="password" | |||||
| label={t("common.labelPassword")} | |||||
| margin="normal" | |||||
| type={showPassword ? "text" : "password"} | |||||
| value={formik.values.password} | |||||
| onChange={formik.handleChange} | |||||
| error={formik.touched.password && Boolean(formik.errors.password)} | |||||
| helperText={formik.touched.password && formik.errors.password} | |||||
| fullWidth | |||||
| InputProps={{ | |||||
| endAdornment: ( | |||||
| <InputAdornment position="end"> | |||||
| <IconButton | |||||
| onClick={handleClickShowPassword} | |||||
| onMouseDown={handleMouseDownPassword} | |||||
| > | |||||
| {showPassword ? <Visibility /> : <VisibilityOff />} | |||||
| </IconButton> | |||||
| </InputAdornment> | |||||
| ), | |||||
| }} | |||||
| /> | |||||
| <TextField | |||||
| className="rounded-input" | |||||
| name="confirmPassword" | |||||
| label={t("common.labelConfirmPassword")} | |||||
| margin="normal" | |||||
| type={showConfirmPassword ? "text" : "password"} | |||||
| value={formik.values.confirmPassword} | |||||
| onChange={formik.handleChange} | |||||
| error={formik.touched.confirmPassword && Boolean(formik.errors.confirmPassword)} | |||||
| helperText={formik.touched.confirmPassword && formik.errors.confirmPassword} | |||||
| fullWidth | |||||
| InputProps={{ | |||||
| endAdornment: ( | |||||
| <InputAdornment position="end"> | |||||
| <IconButton | |||||
| onClick={handleClickShowConfirmPassword} | |||||
| onMouseDown={handleMouseDownConfirmPassword} | |||||
| > | |||||
| {showConfirmPassword ? <Visibility /> : <VisibilityOff />} | |||||
| </IconButton> | |||||
| </InputAdornment> | |||||
| ), | |||||
| }} | |||||
| /> | |||||
| <Button | |||||
| type="submit" | |||||
| variant="contained" | |||||
| sx={{ mt: 3, mb: 2 }} | |||||
| fullWidth | |||||
| className="c-btn c-btn--primary" | |||||
| > | |||||
| {t('login.forgotYourPasswordButton')} | |||||
| </Button> | |||||
| <Grid container justifyContent="center"> | |||||
| <Link | |||||
| to={BASE_PAGE} | |||||
| component={NavLink} | |||||
| variant="body2" | |||||
| underline="hover" | |||||
| > | |||||
| {t('login.forgotYourPasswordBackLink')} | |||||
| </Link> | |||||
| </Grid> | |||||
| <div className="flex-center"> | |||||
| <img src={DiligLogo} style={{ margin: "70px auto 0px auto" }} /> | |||||
| </div> | |||||
| </Box> | |||||
| </Box> | |||||
| </Container> | |||||
| ); | |||||
| return ( | |||||
| <Container | |||||
| component="main" | |||||
| maxWidth="xl" | |||||
| className="c-login-container" | |||||
| fullwidth="true" | |||||
| > | |||||
| <div className="l-t-rectangle"></div> | |||||
| <div className="r-b-rectangle"></div> | |||||
| <Box | |||||
| sx={{ | |||||
| marginTop: 2, | |||||
| width: 350, | |||||
| height: 684, | |||||
| display: "flex", | |||||
| flexDirection: "column", | |||||
| alignItems: "center", | |||||
| }} | |||||
| > | |||||
| <img src={HrLogo} className="login-logo" /> | |||||
| <Typography variant="h5" sx={{ m: 2, mt: 3 }}> | |||||
| {t("login.resetYourPassword")} | |||||
| </Typography> | |||||
| <Typography variant="p"> | |||||
| {t("login.resetYourPasswordHelpText")} | |||||
| </Typography> | |||||
| <Box | |||||
| component="form" | |||||
| onSubmit={formik.handleSubmit} | |||||
| sx={{ position: "relative", mt: 1, p: 1 }} | |||||
| > | |||||
| <Backdrop position="absolute" isLoading={false} /> | |||||
| <TextField | |||||
| className="rounded-input" | |||||
| name="password" | |||||
| label={t("common.labelPassword")} | |||||
| margin="normal" | |||||
| type={showPassword ? "text" : "password"} | |||||
| value={formik.values.password} | |||||
| onChange={formik.handleChange} | |||||
| error={formik.touched.password && Boolean(formik.errors.password)} | |||||
| helperText={formik.touched.password && formik.errors.password} | |||||
| fullWidth | |||||
| inputProps={{ "data-testid": "password-input" }} | |||||
| InputProps={{ | |||||
| endAdornment: ( | |||||
| <InputAdornment position="end"> | |||||
| <IconButton | |||||
| onClick={handleClickShowPassword} | |||||
| onMouseDown={handleMouseDownPassword} | |||||
| > | |||||
| {showPassword ? <Visibility /> : <VisibilityOff />} | |||||
| </IconButton> | |||||
| </InputAdornment> | |||||
| ), | |||||
| }} | |||||
| /> | |||||
| <TextField | |||||
| className="rounded-input" | |||||
| name="confirmPassword" | |||||
| label={t("common.labelConfirmPassword")} | |||||
| margin="normal" | |||||
| type={showConfirmPassword ? "text" : "password"} | |||||
| value={formik.values.confirmPassword} | |||||
| onChange={formik.handleChange} | |||||
| error={ | |||||
| formik.touched.confirmPassword && | |||||
| Boolean(formik.errors.confirmPassword) | |||||
| } | |||||
| helperText={ | |||||
| formik.touched.confirmPassword && formik.errors.confirmPassword | |||||
| } | |||||
| fullWidth | |||||
| inputProps={{ "data-testid": "confirm-password-input" }} | |||||
| InputProps={{ | |||||
| endAdornment: ( | |||||
| <InputAdornment position="end"> | |||||
| <IconButton | |||||
| onClick={handleClickShowConfirmPassword} | |||||
| onMouseDown={handleMouseDownConfirmPassword} | |||||
| > | |||||
| {showConfirmPassword ? <Visibility /> : <VisibilityOff />} | |||||
| </IconButton> | |||||
| </InputAdornment> | |||||
| ), | |||||
| }} | |||||
| /> | |||||
| <Button | |||||
| type="submit" | |||||
| variant="contained" | |||||
| sx={{ mt: 3, mb: 2 }} | |||||
| fullWidth | |||||
| className="c-btn c-btn--primary" | |||||
| > | |||||
| {t("login.forgotYourPasswordButton")} | |||||
| </Button> | |||||
| <Grid container justifyContent="center"> | |||||
| <Link | |||||
| to={BASE_PAGE} | |||||
| component={NavLink} | |||||
| variant="body2" | |||||
| underline="hover" | |||||
| data-testid="back-link" | |||||
| > | |||||
| {t("login.forgotYourPasswordBackLink")} | |||||
| </Link> | |||||
| </Grid> | |||||
| <div className="flex-center" data-testid="dilig-logo"> | |||||
| <img src={DiligLogo} style={{ margin: "70px auto 0px auto" }} /> | |||||
| </div> | |||||
| </Box> | |||||
| </Box> | |||||
| </Container> | |||||
| ); | |||||
| }; | }; | ||||
| ResetPasswordPage.propTypes = { | ResetPasswordPage.propTypes = { | ||||
| history: PropTypes.shape({ | |||||
| replace: PropTypes.func, | |||||
| push: PropTypes.func, | |||||
| location: PropTypes.shape({ | |||||
| pathname: PropTypes.string, | |||||
| }), | |||||
| }), | |||||
| } | |||||
| history: PropTypes.shape({ | |||||
| replace: PropTypes.func, | |||||
| push: PropTypes.func, | |||||
| location: PropTypes.shape({ | |||||
| pathname: PropTypes.string, | |||||
| }), | |||||
| }), | |||||
| }; | |||||
| export default ResetPasswordPage; | export default ResetPasswordPage; |
| import React from 'react'; | |||||
| const HomePage = () => { | |||||
| return ( | |||||
| <div className="c-error-page"> | |||||
| <div className="c-error-page__content"> | |||||
| <h1 className="c-error-page__title">Home page</h1> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| HomePage.propTypes = {}; | |||||
| export default HomePage; |
| import React from "react"; | |||||
| // import { Box, Grid } from '@mui/material'; | |||||
| // import Navbar from "../../components/MUI/NavbarComponent"; | |||||
| // import Modals from '../../components/MUI/Examples/ModalsExample'; | |||||
| // import DataGrid from '../../components/MUI/Examples/DataGridExample'; | |||||
| // import PagingSortingFiltering from '../../components/MUI/Examples/PagingSortingFilteringExample'; | |||||
| // import PagingSortingFilteringServerSide from '../../components/MUI/Examples/PagingSortingFilteringExampleServerSide'; | |||||
| // import RandomDataProvider from '../../context/RandomDataContext'; | |||||
| const HomePage = () => { | |||||
| return ( | |||||
| <div> | |||||
| {/* <Navbar /> */} | |||||
| <div className="l-t-rectangle"></div> | |||||
| <div className="r-b-rectangle"></div> | |||||
| {/* <Box sx={{ mt: 4, mx: 4 }}> | |||||
| <Grid container spacing={2} justifyContent="center"> | |||||
| <Grid item xs={12} md={3}> | |||||
| <Modals /> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={6}> | |||||
| <DataGrid /> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={9}> | |||||
| <PagingSortingFiltering /> | |||||
| </Grid> | |||||
| <Grid item xs={12} md={9}> */} | |||||
| {/* Move to higher components? */} | |||||
| {/* <RandomDataProvider> | |||||
| <PagingSortingFilteringServerSide /> | |||||
| </RandomDataProvider> | |||||
| </Grid> | |||||
| </Grid> | |||||
| </Box> */} | |||||
| </div> | |||||
| ); | |||||
| }; | |||||
| export default HomePage; |
| import React from 'react'; | |||||
| import PropTypes from 'prop-types'; | |||||
| import { Field, Form, Formik } from 'formik'; | |||||
| import { useDispatch, useSelector } from 'react-redux'; | |||||
| import { NavLink } from 'react-router-dom'; | |||||
| import * as Yup from 'yup'; | |||||
| import { useTranslation } from 'react-i18next'; | |||||
| import i18next from 'i18next'; | |||||
| import PasswordField from '../../components/InputFields/PasswordField'; | |||||
| import Button from '../../components/Button/Button'; | |||||
| import TextField from '../../components/InputFields/TextField'; | |||||
| import Auth from '../../components/Auth/Auth'; | |||||
| import AuthCard from '../../components/AuthCards/AuthCard'; | |||||
| import { | |||||
| clearLoginErrors, | |||||
| fetchUser, | |||||
| } from '../../store/actions/login/loginActions'; | |||||
| import { | |||||
| selectLoginError, | |||||
| } from '../../store/selectors/loginSelectors'; | |||||
| import { | |||||
| FORGOT_PASSWORD_PAGE, HOME_PAGE, | |||||
| } from '../../constants/pages'; | |||||
| import { selectIsLoadingByActionType } from '../../store/selectors/loadingSelectors'; | |||||
| import { LOGIN_USER_LOADING } from '../../store/actions/login/loginActionConstants'; | |||||
| const LoginValidationSchema = Yup.object().shape({ | |||||
| username: Yup.string().required(i18next.t('login.usernameRequired')), | |||||
| password: Yup.string().required(i18next.t('login.passwordRequired')), | |||||
| }); | |||||
| const LoginPage = ({ history }) => { | |||||
| const dispatch = useDispatch(); | |||||
| const { t } = useTranslation(); | |||||
| const error = useSelector(selectLoginError); | |||||
| // When user refreshes page | |||||
| // useEffect(() => { | |||||
| // function redirectClient() { | |||||
| // if (!tokens.RefreshToken && !tokens.JwtToken) { | |||||
| // return | |||||
| // } | |||||
| // } | |||||
| // redirectClient(); | |||||
| // }, [history, tokens]); | |||||
| const isLoading = useSelector( | |||||
| selectIsLoadingByActionType(LOGIN_USER_LOADING), | |||||
| ); | |||||
| const handleApiResponseSuccess =()=>{ | |||||
| history.push({ | |||||
| pathname: HOME_PAGE, | |||||
| state: { | |||||
| from: history.location.pathname, | |||||
| }, | |||||
| }); | |||||
| } | |||||
| const handleSubmit = (values) => { | |||||
| // destructure value as username. | |||||
| const { username: Username } = values; | |||||
| const { password: Password } = values; | |||||
| dispatch(clearLoginErrors()); | |||||
| dispatch( | |||||
| fetchUser({ | |||||
| Username, | |||||
| Password, | |||||
| handleApiResponseSuccess | |||||
| }, | |||||
| ), | |||||
| ); | |||||
| }; | |||||
| return ( | |||||
| <Auth> | |||||
| <AuthCard | |||||
| title="Log In" | |||||
| isLoading={isLoading} | |||||
| > | |||||
| <div className="c-login c-login--user"> | |||||
| <div className="c-login__form"> | |||||
| <Formik | |||||
| initialValues={{ | |||||
| username: '', | |||||
| password: '', | |||||
| }} | |||||
| onSubmit={handleSubmit} | |||||
| validationSchema={LoginValidationSchema} | |||||
| validateOnBlur | |||||
| enableReinitialize | |||||
| > | |||||
| {({ values }) => ( | |||||
| <Form> | |||||
| <Field | |||||
| label={t('common.labelUsername')} | |||||
| value={values.username.value} | |||||
| component={TextField} | |||||
| name="username" | |||||
| /> | |||||
| <Field | |||||
| label={ | |||||
| <div className="c-login--password__label"> | |||||
| {t('common.labelPassword')} | |||||
| </div> | |||||
| } | |||||
| link={ | |||||
| <NavLink | |||||
| to={FORGOT_PASSWORD_PAGE} | |||||
| > | |||||
| {t('login.forgotYourPassword')} | |||||
| </NavLink> | |||||
| } | |||||
| name="password" | |||||
| component={PasswordField} | |||||
| errorMessage={error} | |||||
| autoFocus | |||||
| /> | |||||
| <Button | |||||
| className="c-login__button" | |||||
| authButton | |||||
| variant="primary" | |||||
| type="submit" | |||||
| > | |||||
| {t('common.continue')} | |||||
| </Button> | |||||
| </Form> | |||||
| )} | |||||
| </Formik> | |||||
| </div> | |||||
| </div> | |||||
| </AuthCard> | |||||
| </Auth> | |||||
| ); | |||||
| }; | |||||
| LoginPage.propTypes = { | |||||
| history: PropTypes.shape({ | |||||
| replace: PropTypes.func, | |||||
| push: PropTypes.func, | |||||
| location: PropTypes.shape({ | |||||
| pathname: PropTypes.string, | |||||
| }), | |||||
| }), | |||||
| }; | |||||
| export default LoginPage; |