Viewing File: /home/ubuntu/voice-assistant-frontend/src/components/Profile/ChangePasswordModal.jsx

import React, { useEffect, useState } from "react";
import { Form, Button, Modal, InputGroup } from "react-bootstrap";
import * as Yup from "yup";
import { Formik, Form as FORM, Field, ErrorMessage } from "formik";
import { Link, useNavigate } from "react-router-dom";
import { useTranslation } from "react-multi-lang";
import { useDispatch, useSelector } from "react-redux";
import { changePasswordStart } from "../../store/slices/AdminSlice";
import { ButtonLoader } from "../Helper/Loader";
import useLogout from "../../hooks/useLogout";

const ChangePasswordModal = (props) => {
  const t = useTranslation("change_password");
  const { logout } = useLogout();
  const dispatch = useDispatch();
  const changePassword = useSelector((state) => state.admin.changePassword);
  const [skipRender, setSkipRender] = useState(true);
  const [showPassword, setShowPassword] = useState(
    {  old_password:false,
      password: false,
      confirmPassword: false
    });

  const handleSubmit = (values) => {
    dispatch(changePasswordStart(values));
  };

  const togglePasswordVisibility = (value) => {
    if (value == 1)
      setShowPassword(prevState => ({
        ...prevState,
        password: !prevState.password
      }));
    else if(value == 0){
      setShowPassword(prevState => ({
        ...prevState,
        confirmPassword: !prevState.confirmPassword
      }));
    }
    else{
      setShowPassword(prevState => ({
        ...prevState,
        old_password: !prevState.old_password
      }));
    }
  };

  useEffect(() => {
    if (
      !skipRender &&
      !changePassword.loading &&
      Object.keys(changePassword.data).length > 0
    ) {
      logout();
      props.closeChangePasswordModal();
    }
    setSkipRender(false);
  }, [changePassword]);

  const changepasswordSchema = Yup.object().shape({
    old_password: Yup.string()
    .required(t("old_password.required"))
    .matches(/^\S+$/, t("old_password.space_invalid"))
    .matches(/[A-Z]/, t("old_password.invalid"))
    .matches(/[0-9]/, t("old_password.number_invalid"))
    .matches(/[\W_]/, t("old_password.special_character_invalid"))
    .min(6, t("old_password.min_length_invalid")),
      password: Yup.string()
      .required(t("password.required"))
      .matches(/^\S+$/, t("password.space_invalid"))
      .matches(/[A-Z]/, t("password.invalid"))
      .matches(/[0-9]/, t("password.number_invalid"))
      .matches(/[\W_]/, t("password.special_character_invalid"))
      .min(6, t("password.min_length_invalid")),
    password_confirmation: Yup.string()
      .required(t("password_confirmation.required"))
      .when("password", {
        is: (val) => (val && val.length > 0 ? true : false),
        then: Yup.string().oneOf(
          [Yup.ref("password")],
          t("password_confirmation.invalid")
        ),
      }),
  });
  
  return (
    <>
      <Modal
        className="modal-dialog-center change-password-modal"
        size="md"
        centered
        show={props.changePassword}
        onHide={props.closeChangePasswordModal}
      >
        <Modal.Body>
          <h4>Change Password</h4>
          <Button
            className="modal-close"
            onClick={() => props.closeChangePasswordModal()}
          >
            <svg
              xmlns="http://www.w3.org/2000/svg"
              width="15"
              height="15"
              fill="none"
              viewBox="0 0 11 11"
            >
              <path
                fill="#979BA2"
                d="M10.756.252a.83.83 0 00-1.176 0L5.5 4.324 1.42.244A.83.83 0 10.244 1.42l4.08 4.08-4.08 4.08a.83.83 0 101.176 1.176l4.08-4.08 4.08 4.08a.831.831 0 101.176-1.176L6.676 5.5l4.08-4.08a.836.836 0 000-1.168z"
              ></path>
            </svg>
          </Button>
          <div className="change-password-form-sec">
            <Formik
              initialValues={{
                old_password: "",
                password: "",
                password_confirmation: "",
              }}
              validationSchema={changepasswordSchema}
              onSubmit={handleSubmit}
            >
              {({ setFieldValue, values }) => (
                <FORM className="profile-form-sec">
                  <Form.Label>{t("old_password.label")}</Form.Label>
                  <InputGroup className="mb-3 auth-input-group">
                    <InputGroup.Text>
                      <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-lock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="#878E96" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-6z" /><path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0" /><path d="M8 11v-4a4 4 0 1 1 8 0v4" /></svg>
                    </InputGroup.Text>
                    <Field
                      className="form-control"
                      placeholder={t("old_password.placeholder")}
                      type={showPassword.old_password ? "text" : "password"}
                      name="old_password"
                      aria-label="Username"
                      aria-describedby="basic-addon1"
                    />
                    <InputGroup.Text className="border-right-input" onClick={() => togglePasswordVisibility(2)}>
                      {!showPassword.old_password ? (<svg
                        xmlns="http://www.w3.org/2000/svg"
                        class="icon icon-tabler icon-tabler-eye"
                        width="24"
                        height="24"
                        viewBox="0 0 24 24"
                        stroke-width="2"
                        stroke="#878E96"
                        fill="none"
                        stroke-linecap="round"
                        stroke-linejoin="round"
                      >
                        <path stroke="none" d="M0 0h24v24H0z" fill="none" />
                        <path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
                        <path d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6" />
                      </svg>) : (<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-eye-off" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="#878E96" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M10.585 10.587a2 2 0 0 0 2.829 2.828" /><path d="M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87" /><path d="M3 3l18 18" /></svg>)

                      }
                    </InputGroup.Text>
                  </InputGroup>
                  <ErrorMessage
                    component={"div"}
                    name="old_password"
                    className="errorMsg"
                  />
                  <Form.Label>{t("password.label")}</Form.Label>
                  <InputGroup className="mb-3 auth-input-group">
                    <InputGroup.Text>
                      <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-lock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="#878E96" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-6z" /><path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0" /><path d="M8 11v-4a4 4 0 1 1 8 0v4" /></svg>
                    </InputGroup.Text>
                    <Field
                      className="form-control"
                      placeholder={t("password.placeholder")}
                      name="password"
                      aria-label="Username"
                      aria-describedby="basic-addon1"
                      type={showPassword.password ? "text" : "password"}
                    />
                    <InputGroup.Text className="border-right-input" onClick={() => togglePasswordVisibility(1)}>
                      {!showPassword.password ? (<svg
                        xmlns="http://www.w3.org/2000/svg"
                        class="icon icon-tabler icon-tabler-eye"
                        width="24"
                        height="24"
                        viewBox="0 0 24 24"
                        stroke-width="2"
                        stroke="#878E96"
                        fill="none"
                        stroke-linecap="round"
                        stroke-linejoin="round"
                      >
                        <path stroke="none" d="M0 0h24v24H0z" fill="none" />
                        <path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
                        <path d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6" />
                      </svg>) : (<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-eye-off" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="#878E96" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M10.585 10.587a2 2 0 0 0 2.829 2.828" /><path d="M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87" /><path d="M3 3l18 18" /></svg>)

                      }
                    </InputGroup.Text>
                  </InputGroup>
                  <ErrorMessage
                    component={"div"}
                    name="password"
                    className="errorMsg"
                  />
                  <Form.Label>{t("password_confirmation.label")}</Form.Label>
                  <InputGroup className="mb-3 auth-input-group">
                    <InputGroup.Text>
                      <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-lock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="#878E96" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-6z" /><path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0" /><path d="M8 11v-4a4 4 0 1 1 8 0v4" /></svg>
                    </InputGroup.Text>
                    <Field
                      className="form-control"
                      placeholder={t("password_confirmation.placeholder")}
                      type={showPassword.confirmPassword ? "text" : "password"}
                      name="password_confirmation"
                      aria-label="Username"
                      aria-describedby="basic-addon1"
                    />
                    <InputGroup.Text className="border-right-input" onClick={() => togglePasswordVisibility(0)}>
                    {!showPassword.confirmPassword ? (<svg
                        xmlns="http://www.w3.org/2000/svg"
                        class="icon icon-tabler icon-tabler-eye"
                        width="24"
                        height="24"
                        viewBox="0 0 24 24"
                        stroke-width="2"
                        stroke="#878E96"
                        fill="none"
                        stroke-linecap="round"
                        stroke-linejoin="round"
                      >
                        <path stroke="none" d="M0 0h24v24H0z" fill="none" />
                        <path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
                        <path d="M21 12c-2.4 4 -5.4 6 -9 6c-3.6 0 -6.6 -2 -9 -6c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6" />
                      </svg>) : (<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-eye-off" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="#878E96" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none" /><path d="M10.585 10.587a2 2 0 0 0 2.829 2.828" /><path d="M16.681 16.673a8.717 8.717 0 0 1 -4.681 1.327c-3.6 0 -6.6 -2 -9 -6c1.272 -2.12 2.712 -3.678 4.32 -4.674m2.86 -1.146a9.055 9.055 0 0 1 1.82 -.18c3.6 0 6.6 2 9 6c-.666 1.11 -1.379 2.067 -2.138 2.87" /><path d="M3 3l18 18" /></svg>)

                      }
                    </InputGroup.Text>
                  </InputGroup>
                  <ErrorMessage
                    component={"div"}
                    name="password_confirmation"
                    className="errorMsg"
                  />
                  <div className="change-password-btn-sec">
                    <Button className="default-grey-btn" onClick={() => props.closeChangePasswordModal()}>
                     {t("cancel")}
                    </Button>
                    <Button
                      type="submit"
                      className="default-btn"
                      disabled={
                        changePassword.buttonDisable
                      }
                    >
                      {changePassword.buttonDisable ? (
                        <ButtonLoader />
                      ) : (
                        t("submit")
                      )}
                    </Button>
                  </div>
                </FORM>
              )}
            </Formik>
          </div>
        </Modal.Body>
      </Modal>
    </>
  );
};

export default ChangePasswordModal;
Back to Directory File Manager