| > | > | ||||
| <TextFieldStyled | <TextFieldStyled | ||||
| inputRef={ref} | inputRef={ref} | ||||
| inputProps={props.inputProps} | |||||
| placeholder={props.placeholder} | placeholder={props.placeholder} | ||||
| width={props.width} | width={props.width} | ||||
| height={props.height} | height={props.height} | ||||
| onFocus: PropTypes.func, | onFocus: PropTypes.func, | ||||
| onBlur: PropTypes.func, | onBlur: PropTypes.func, | ||||
| focused: PropTypes.bool, | focused: PropTypes.bool, | ||||
| inputProps: PropTypes.any, | |||||
| InputProps: PropTypes.shape({ | InputProps: PropTypes.shape({ | ||||
| startAdornment: PropTypes.node, | startAdornment: PropTypes.node, | ||||
| endAdornment: PropTypes.node, | endAdornment: PropTypes.node, |
| signUp: "Registrujte se.", | signUp: "Registrujte se.", | ||||
| usernameRequired: "Username je obavezan!", | usernameRequired: "Username je obavezan!", | ||||
| passwordRequired: "Lozinka je obavezna!", | passwordRequired: "Lozinka je obavezna!", | ||||
| passwordConfirmRequired: "Potvrdite lozinku!", | |||||
| passwordConfirmIncorrect: "Lozinke se ne podudaraju!", | |||||
| forgotYourPassword: "Zaboravili ste lozinku?", | forgotYourPassword: "Zaboravili ste lozinku?", | ||||
| forgotPasswordEmail: "Email", | forgotPasswordEmail: "Email", | ||||
| useDifferentEmail: "Iskoristite drugačiju lozinku.", | useDifferentEmail: "Iskoristite drugačiju lozinku.", | ||||
| passwordLabel: "Nova Lozinka", | passwordLabel: "Nova Lozinka", | ||||
| passwordConfirmLabel: "Potvrdite Lozinku", | passwordConfirmLabel: "Potvrdite Lozinku", | ||||
| buttonText: "Postavi lozinku", | buttonText: "Postavi lozinku", | ||||
| resetSuccess: "Uspešno ste promenili lozinku!" | |||||
| }, | }, | ||||
| filters: { | filters: { | ||||
| title: "Filteri", | title: "Filteri", |
| const formik = useFormik({ | const formik = useFormik({ | ||||
| initialValues: { | initialValues: { | ||||
| mail: props.informations?.mail ?? "", | mail: props.informations?.mail ?? "", | ||||
| password: props.informations?.password ?? "", | |||||
| registerPassword: props.informations?.registerPassword ?? "", | |||||
| }, | }, | ||||
| validationSchema: firstPartValidation, | validationSchema: firstPartValidation, | ||||
| onSubmit: props.handleSubmit, | onSubmit: props.handleSubmit, | ||||
| formik.setFieldValue("mail", ""); | formik.setFieldValue("mail", ""); | ||||
| formik.setFieldTouched("mail", true); | formik.setFieldTouched("mail", true); | ||||
| } | } | ||||
| if (formik.errors.password) { | |||||
| formik.setFieldValue("password", ""); | |||||
| formik.setFieldTouched("password", true); | |||||
| if (formik.errors.registerPassword) { | |||||
| formik.setFieldValue("registerPassword", ""); | |||||
| formik.setFieldTouched("registerPassword", true); | |||||
| } | } | ||||
| } else { | } else { | ||||
| formik.handleSubmit(event); | formik.handleSubmit(event); | ||||
| /> | /> | ||||
| <TextField | <TextField | ||||
| name="password" | |||||
| name="registerPassword" | |||||
| inputProps={{ autocomplete: "new-password" }} | |||||
| placeholder={t("common.labelPassword")} | placeholder={t("common.labelPassword")} | ||||
| margin="normal" | margin="normal" | ||||
| type={showPassword ? "text" : "password"} | type={showPassword ? "text" : "password"} | ||||
| value={formik.values.password} | |||||
| value={formik.values.registerPassword} | |||||
| onChange={(value) => | onChange={(value) => | ||||
| formik.setFieldValue("password", value.target.value) | |||||
| formik.setFieldValue("registerPassword", value.target.value) | |||||
| } | |||||
| error={ | |||||
| formik.touched.registerPassword && | |||||
| Boolean(formik.errors.registerPassword) | |||||
| } | |||||
| helperText={ | |||||
| formik.touched.registerPassword && formik.errors.registerPassword | |||||
| } | } | ||||
| error={formik.touched.password && Boolean(formik.errors.password)} | |||||
| helperText={formik.touched.password && formik.errors.password} | |||||
| fullWidth | fullWidth | ||||
| InputProps={{ | InputProps={{ | ||||
| endAdornment: ( | endAdornment: ( | ||||
| }} | }} | ||||
| /> | /> | ||||
| {console.log(formik)} | |||||
| {formik.errors.mail && formik.touched.mail ? ( | {formik.errors.mail && formik.touched.mail ? ( | ||||
| <ErrorMessage>{formik.errors.mail}</ErrorMessage> | <ErrorMessage>{formik.errors.mail}</ErrorMessage> | ||||
| ) : formik.errors.password && formik.touched.password ? ( | |||||
| <ErrorMessage>{formik.errors.password}</ErrorMessage> | |||||
| ) : formik.errors.registerPassword && formik.touched.registerPassword ? ( | |||||
| <ErrorMessage>{formik.errors.registerPassword}</ErrorMessage> | |||||
| ) : ( | ) : ( | ||||
| props.error && <ErrorMessage>{props.errorMessage}</ErrorMessage> | props.error && <ErrorMessage>{props.errorMessage}</ErrorMessage> | ||||
| )} | )} | ||||
| textcolor="white" | textcolor="white" | ||||
| disabled={ | disabled={ | ||||
| formik.values.mail.length === 0 || | formik.values.mail.length === 0 || | ||||
| formik.values.password.length === 0 || | |||||
| formik.values.registerPassword.length === 0 || | |||||
| formik.values.mail === props.error | formik.values.mail === props.error | ||||
| } | } | ||||
| > | > |
| import React from "react"; | |||||
| import PropTypes from "prop-types"; | |||||
| import { ErrorText } from "./ErrorMessage.styled"; | |||||
| const ErrorMessage = (props) => { | |||||
| const formik = props.formik; | |||||
| return ( | |||||
| <> | |||||
| {formik.errors.password?.length > 0 && formik.touched.password ? ( | |||||
| <ErrorText>{formik.errors.password}</ErrorText> | |||||
| ) : ( | |||||
| formik.errors.passwordConfirm?.length > 0 && | |||||
| formik.touched.passwordConfirm && ( | |||||
| <ErrorText>{formik.errors.passwordConfirm}</ErrorText> | |||||
| ) | |||||
| )} | |||||
| </> | |||||
| ); | |||||
| }; | |||||
| ErrorMessage.propTypes = { | |||||
| formik: PropTypes.any, | |||||
| }; | |||||
| export default ErrorMessage; |
| import { Typography } from "@mui/material"; | |||||
| import styled from "styled-components"; | |||||
| import selectedTheme from "../../../themes"; | |||||
| export const ErrorText = styled(Typography)` | |||||
| color: red; | |||||
| font-family: ${selectedTheme.fonts.textFont}; | |||||
| position: relative; | |||||
| top: -7px; | |||||
| font-size: 14px; | |||||
| ` |
| import React, { useEffect, useState } from "react"; | import React, { useEffect, useState } from "react"; | ||||
| import { useFormik } from "formik"; | import { useFormik } from "formik"; | ||||
| import { useTranslation } from "react-i18next"; | import { useTranslation } from "react-i18next"; | ||||
| import * as Yup from "yup"; | |||||
| import { ReactComponent as Logo } from "../../assets/images/svg/logo-vertical.svg"; | import { ReactComponent as Logo } from "../../assets/images/svg/logo-vertical.svg"; | ||||
| import { | import { | ||||
| ResetPasswordPageContainer, | ResetPasswordPageContainer, | ||||
| import { ReactComponent as VisibilityOff } from "../../assets/images/svg/eye.svg"; | import { ReactComponent as VisibilityOff } from "../../assets/images/svg/eye.svg"; | ||||
| import { IconButton } from "../../components/Buttons/IconButton/IconButton"; | import { IconButton } from "../../components/Buttons/IconButton/IconButton"; | ||||
| import jwt from "jsonwebtoken"; | import jwt from "jsonwebtoken"; | ||||
| import resetPasswordValidation from "../../validations/resetPasswordValidation"; | |||||
| import ErrorMessage from "./ErrorMessage/ErrorMessage"; | |||||
| const ResetPasswordPage = () => { | const ResetPasswordPage = () => { | ||||
| const history = useHistory(); | const history = useHistory(); | ||||
| const routeMatch = useRouteMatch(); | const routeMatch = useRouteMatch(); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| const tokenFromParams = routeMatch.params.token | |||||
| const tokenFromParams = routeMatch.params.token; | |||||
| setToken(tokenFromParams); | setToken(tokenFromParams); | ||||
| const data = jwt.decode(tokenFromParams); | const data = jwt.decode(tokenFromParams); | ||||
| if (!data || new Date() > new Date(data?.exp * 1000)) { | if (!data || new Date() > new Date(data?.exp * 1000)) { | ||||
| password: "", | password: "", | ||||
| passwordConfirm: "", | passwordConfirm: "", | ||||
| }, | }, | ||||
| validationSchema: Yup.object().shape({ | |||||
| password: Yup.string().required().min(8), | |||||
| passwordConfirm: Yup.string().oneOf([Yup.ref("password"), null]), | |||||
| }), | |||||
| validationSchema: resetPasswordValidation, | |||||
| onSubmit: handleSubmit, | onSubmit: handleSubmit, | ||||
| validateOnBlur: true, | validateOnBlur: true, | ||||
| enableReinitialize: true, | enableReinitialize: true, | ||||
| }} | }} | ||||
| /> | /> | ||||
| <ErrorMessage formik={formik} /> | |||||
| <PrimaryButton | <PrimaryButton | ||||
| type="submit" | type="submit" | ||||
| variant="contained" | variant="contained" |
| import { all, takeLatest, call, put } from "@redux-saga/core/effects"; | import { all, takeLatest, call, put } from "@redux-saga/core/effects"; | ||||
| import i18n from "../../i18n"; | |||||
| import { forgotPasswordRequest, resetPasswordRequest } from "../../request/forgotPasswordRequest"; | import { forgotPasswordRequest, resetPasswordRequest } from "../../request/forgotPasswordRequest"; | ||||
| import { FORGOT_PASSWORD, RESET_PASSWORD } from "../actions/user/userActionConstants"; | import { FORGOT_PASSWORD, RESET_PASSWORD } from "../actions/user/userActionConstants"; | ||||
| import { forgotPasswordError, forgotPasswordSuccess } from "../actions/user/userActions"; | import { forgotPasswordError, forgotPasswordSuccess } from "../actions/user/userActions"; | ||||
| import { makeToastMessage } from "../utils/makeToastMessage"; | |||||
| function* forgotPassword({payload}) { | function* forgotPassword({payload}) { | ||||
| try { | try { | ||||
| if (payload.handleResponseSuccess) { | if (payload.handleResponseSuccess) { | ||||
| yield call(payload.handleResponseSuccess); | yield call(payload.handleResponseSuccess); | ||||
| } | } | ||||
| makeToastMessage(i18n.t("resetPassword.resetSuccess")) | |||||
| } | } | ||||
| } | } | ||||
| catch(e) { | catch(e) { |
| import i18n from "../i18n"; | import i18n from "../i18n"; | ||||
| export default Yup.object().shape({ | export default Yup.object().shape({ | ||||
| email: Yup.string().email(i18n.t("login.emailFormat")).required(i18n.t("login.emailRequired")), | |||||
| email: Yup.string() | |||||
| .email(i18n.t("login.emailFormat")) | |||||
| .required(i18n.t("login.emailRequired")), | |||||
| password: Yup.string() | password: Yup.string() | ||||
| .required(i18n.t("login.passwordRequired")) | .required(i18n.t("login.passwordRequired")) | ||||
| .min(8, i18n.t("login.passwordLength")), | .min(8, i18n.t("login.passwordLength")), |
| mail: Yup.string() | mail: Yup.string() | ||||
| .email(i18n.t("forgotPassword.emailFormat")) | .email(i18n.t("forgotPassword.emailFormat")) | ||||
| .required(i18n.t("login.usernameRequired")), | .required(i18n.t("login.usernameRequired")), | ||||
| password: Yup.string() | |||||
| registerPassword: Yup.string() | |||||
| .required(i18n.t("login.passwordRequired")) | .required(i18n.t("login.passwordRequired")) | ||||
| .min(8, i18n.t("login.passwordLength")) | .min(8, i18n.t("login.passwordLength")) | ||||
| .minLowercase(1, i18n.t("password.strongPassword")) | .minLowercase(1, i18n.t("password.strongPassword")) |
| import * as Yup from "yup"; | import * as Yup from "yup"; | ||||
| import YupPassword from "yup-password"; | |||||
| import i18n from "../i18n"; | |||||
| YupPassword(Yup); | |||||
| export default Yup.object().shape({ | export default Yup.object().shape({ | ||||
| password: Yup.string().required().min(8), | |||||
| passwordConfirm: Yup.string().oneOf([Yup.ref("password"), null]), | |||||
| password: Yup.string() | |||||
| .required(i18n.t("login.passwordRequired")) | |||||
| .min(8, i18n.t("login.passwordLength")) | |||||
| .minLowercase(1, i18n.t("password.strongPassword")) | |||||
| .minUppercase(1, i18n.t("password.strongPassword")) | |||||
| .minSymbols(1, i18n.t("password.strongPassword")) | |||||
| .minNumbers(1, i18n.t("password.strongPassword")), | |||||
| passwordConfirm: Yup.string() | |||||
| .oneOf( | |||||
| [Yup.ref("password"), null], | |||||
| i18n.t("login.passwordConfirmIncorrect") | |||||
| ) | |||||
| .required(i18n.t("login.passwordConfirmRequired")), | |||||
| }); | }); |