Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
8.4 kB
2
Indexable
Never
import React from 'react';
import PropTypes from 'prop-types';
import * as Yup from 'yup';
import clsx from 'clsx';
import { Modal } from 'antd';
import Tooltip from '../../elements/Tooltip';
import { ButtonFilled } from '@telkomdesign/tedis-reactjs-component/lib';
import TextInput from '../../elements/TextInput';
import { REGEX, ICONS } from '../../../configs';
import { Formik } from 'formik';
import { postData, endpoints } from '../../../configs/Api';
import get from 'lodash.get';

class ModalPassword extends React.Component {
  constructor(props) {
    super(props);
    this.form = React.createRef();
    this.state = {
      focused: '', visible: false
    };
  }

  componentDidUpdate(prevProps) {
    const { toggleModal } = this.props;
    if (toggleModal !== prevProps.toggleModal) {
      this._handleToggleModal();
    }
  }

  _handleBlurPassword = () => {
    this._handleSetFocus('');
  }

  _schemaChangePassword = () => {
    return Yup.object().shape({
      oldPassword: Yup.string()
        .required('')
        .matches(REGEX.idealPassword, 'errorAll')
        .matches(REGEX.checkUpperLowerCase, 'errorAll')
        .min(8, 'errorOld'),
      newPassword: Yup.string()
        .required('')
        .matches(REGEX.idealPassword, 'errorAll')
        .matches(REGEX.checkUpperLowerCase, 'errorAll')
        .min(8, 'errorAll')
    });
  }

  _renderTooltipPassword = (helpers) => {
    const { classes } = this.props;
    const { values, touched, errors } = helpers;
    const { newPassword, oldPassword } = values;
    return (
      <div className={classes.tooltipPassword}>
        <p className={clsx('', {
          ['passed']: oldPassword && oldPassword.length > 7 || newPassword && newPassword.length > 7,
          ['failed']: touched.oldPassword && errors.oldPassword === 'errorAll' ||touched.newPassword && errors.newPassword === 'errorAll'
        })}>
          {oldPassword && oldPassword.length > 7 || newPassword && newPassword.length > 7 ?
            <img src={ICONS.checklistCircle} /> : <b>•</b>}
          Minimal terdiri dari 8 karakter
        </p>
        <p className={clsx('', {
          ['passed']: REGEX.checkUpperLowerCase.test(newPassword) || REGEX.checkUpperLowerCase.test(oldPassword),
          ['failed']: touched.oldPassword && errors.oldPassword === 'errorAll' || touched.newPassword && errors.newPassword === 'errorAll' ||
          touched.oldPassword && errors.oldPassword === 'error2' || touched.newPassword && errors.newPassword === 'error2'
        })}>
          {REGEX.checkUpperLowerCase.test(newPassword)
          || REGEX.checkUpperLowerCase.test(oldPassword) ?
            <img src={ICONS.checklistCircle} /> : <b>•</b>}
          Kombinasi huruf kapital dan huruf kecil
        </p>
        <p className={clsx('', {
          ['passed']: REGEX.idealPassword.test(newPassword) || REGEX.idealPassword.test(oldPassword),
          ['failed']: touched.oldPassword && errors.oldPassword === 'errorAll'|| touched.newPassword && errors.newPassword === 'errorAll' ||
          touched.oldPassword && errors.oldPassword || touched.newPassword && errors.newPassword === 'error3'
        })}>
          {REGEX.idealPassword.test(newPassword)
          || REGEX.idealPassword.test(oldPassword) ? <img src={ICONS.checklistCircle} /> : <b>•</b>}
          Minimal terdiri dari 1 angka atau simbol
        </p>
      </div>
    );
  }

  _handleChange = ({ target: { name, value } }) => {
    const { setFieldValue, touched,
      setFieldTouched } = this.form.current;
    setFieldValue(name, value);
    if (!touched[name]) setFieldTouched(name, true);
  }

  _renderForm = (helpers) => {
    const { handleSubmit: _handleSubmit,
      touched, errors, values } = helpers;
    const { oldPassword, newPassword } = values;
    const { classes } = this.props;
    const tooltipVisible = Object.keys(errors).length > 0 && errors.newPassword === 'errorAll' || this.state.focused === 'newPassword' && !values.newPassword;
    const tooltipVisible1 = Object.keys(errors).length > 0 && errors.oldPassword === 'errorAll' || this.state.focused === 'oldPassword' && !values.oldPassword;

    return (
      <form className={clsx('wrapperChangePass', { 'error-new': tooltipVisible } )} onSubmit={_handleSubmit}>
        <p className="modal-title">Ubah Sandi</p>
        <p className="modal-description">Silakan isi kolom berikut untuk mengubah sandi. </p>

        <Tooltip
          title={this._renderTooltipPassword(helpers)}
          placement="bottomLeft"
          type="password"
          className={classes.tooltipBox}
          zIndex={1300}
          visible={tooltipVisible1}>
          <TextInput
            onBlur={this._handleBlurPassword}
            name={'oldPassword'}
            label="Sandi Lama"
            type={'password'}
            value={oldPassword}
            hinterror={!tooltipVisible1 && touched.oldPassword}
            onChange={this._handleChange}
            onFocus={this._handleSetFocus.bind(this, 'oldPassword')}
          />
        </Tooltip>
        <Tooltip
          title={this._renderTooltipPassword(helpers)}
          placement="bottomLeft"
          type="password"
          className={classes.tooltipBox}
          zIndex={1300}
          visible={tooltipVisible}>
          <TextInput
            onBlur={this._handleBlurPassword}
            name={'newPassword'}
            label="Sandi Baru"
            type={'password'}
            value={newPassword}
            hinterror={!tooltipVisible && touched.newPassword && errors.newPassword}
            onChange={this._handleChange}
            onFocus={this._handleSetFocus.bind(this, 'newPassword')}
          />
        </Tooltip>
        <ButtonFilled
          className={classes.saveBtn}
          size="48"
          type="submit"
          disabled={!values.oldPassword || !values.newPassword || errors?.newPassword ||
            errors?.oldPassword}
        >
          Simpan Perubahan
        </ButtonFilled>
      </form>
    );
  }

  _handleSetFocus = (focus) => {
    this.setState({
      focused: focus,
    });
  };

  _handleToggleModal = () => this.setState({ visible: !this.state.visible });

  _handleCheckValidPassword = async () => {
    const { auth: { pt }, onSubmit,
        actions: { requestProfilePt } } = this.props, { values, setFieldError } = this.form.current;
    requestProfilePt({ token: get(pt, 'token') });
    try {
      await postData({
        endpoint: endpoints.postLoginPerguruanTinggi,
        payload: { email: pt.profile.email, password: values.oldPassword },
      });
      if(values.oldPassword !== values.newPassword) {
        this.setState({ focused: '' }, () => {
          onSubmit(values);
        });
      } else setFieldError('newPassword', 'Sandi Baru sama dengan Sandi Lama');
    } catch (error) {
      if (error?.response?.data?.message?.type === 'password') {
        setFieldError('oldPassword', 'Sandi Lama tidak sesuai');
      }
    }
  }

  render() {
    const { classes, onClose } = this.props;
    const { visible } = this.state;
    const initialValues = { newPassword: '',
      oldPassword: '' };
    return (
      <>
        <Modal
          visible={visible}
          closable
          destroyOnClose
          closeIcon={<img src={ICONS.closeIcon} />}
          onCancel={onClose}
          centered
          footer={false}
          zIndex={1300}
          className={classes.wrapperModal}
        >
          <Formik
            innerRef={this.form}
            initialValues={initialValues}
            validationSchema={this._schemaChangePassword}
            component={this._renderForm}
            onSubmit={this._handleCheckValidPassword}
          />
        </ Modal>
      </>
    );
  }
}

ModalPassword.defaultProps = {
  classes: {},
  onClose: () => null,
  toggleModal: false,
  onSubmit: () => null,
};

ModalPassword.propTypes = {
  auth: PropTypes.object.isRequired,
  profilPT: PropTypes.object.isRequired,
  classes: PropTypes.object,
  visible: PropTypes.bool.isRequired,
  onClose: PropTypes.func,
  onSubmit: PropTypes.func,
  toggleModal: PropTypes.bool,
  actions: PropTypes.object.isRequired,
};

export default ModalPassword;