Untitled

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

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

  componentDidUpdate(prevProps) {
    const {
      auth: { error, fetching }, toggleModal, profilPT: { fetching: fetchingPT, error: errorPT }
    } = this.props;
    const { auth: { fetching: prevFetching }, profilPT: { error: prevErrorPT } } = prevProps;
    const { formEmail, errorNewEmail, submitting } = this.state;
    if (!fetching && fetching !== prevFetching) {
      if (error) {
        if (error.message.type === 'password' && (error.code === 401 || error.code === 417)) {
          this.form.current?.setFieldError('password', 'Sandi yang Anda input salah');
          this.setState({ formEmail: false });
        }
      }
      else if (!error && !formEmail) this.setState({ formEmail: true });
    }
    if (prevErrorPT !== errorPT) {
      if (get(errorPT, 'message.0.type') === 'email' && errorPT?.code === 409) {
        if (errorNewEmail !== null) this.form.current?.setFieldError('newEmail', this.state.errorNewEmail);
        else {
          this.form.current?.setFieldError('newEmail', 'Email yang Anda input sudah teregistrasi');
        }
      }
      else if (get(errorPT, 'message') === 'Access token expired!' && errorPT?.code === 401) {
        this.setState({ visible: false });
      }
      else if (errorPT === 'Access token expired!') {
        this.setState({ visible: false });
      }
    }
    if (formEmail && errorNewEmail === null
      && errorPT === null && submitting && !fetchingPT) {
      this.props.onSubmit(this.form.current.values);
      this.setState({ visible: false });
    }
    if (toggleModal !== prevProps.toggleModal) {
      this._handleToggleModal();
    }
  }

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

  _renderFormEmail = (helpers) => {
    const { handleSubmit: _handleSubmit, handleChange: _handleChange,
      handleBlur: _handleBlur, handleBlur, touched, errors, values, setFieldValue } = helpers;
    const { formEmail, errorNewEmail } = this.state;
    const { classes } = this.props;
    const tooltipVisible = Object.keys(errors).length > 0 && errors.password === 'errorAll' || this.state.focused === 'password' ;
    return (
      <form className={clsx('wrapperForm', { 'error-pass': tooltipVisible })} onSubmit={_handleSubmit}>
        {!formEmail && <Tooltip
          title={this._renderTooltipPassword(helpers)}
          placement="bottomLeft"
          type="password"
          className={classes.tooltipBox}
          zIndex={1300}
          visible={tooltipVisible}>
          <TextInput
            name={'password'}
            label="Sandi"
            type={'password'}
            value={values.password}
            closeIcon={<img src={ICONS.closeIcon} />}
            centered
            footer={false}
            zIndex={1300}
            focused={this.state.focused}
            onFocus={this._handleSetFocus.bind(this, 'password')}
            hinterror={!tooltipVisible && touched.password && errors.password}
            className={classes.wrapperModal}
            onBlur={(e) => {
              handleBlur(e);
              this._handleSetFocus('');
            }}
            onChange={_handleChange}
          />
        </Tooltip>}
        {formEmail && <TextInput
          name={'newEmail'}
          label="Email Baru"
          type={'newEmail'}
          value={values.newEmail}
          closeIcon={<img src={ICONS.closeIcon} />}
          centered
          footer={false}
          zIndex={1300}
          hinterror={touched.newEmail && (errors.newEmail || errorNewEmail)}
          className={classes.wrapperModal}
          onBlur={_handleBlur}
          onChange={this._handleEmailChange.bind(this, setFieldValue)}
        />}
        <ButtonFilled
          className={classes.saveBtn}
          size="48"
          type="submit"
          disabled={!formEmail && errors?.password || errors?.newEmail && !values.newEmail &&
            touched.newEmail || !values.password || formEmail && !values.newEmail ||
            formEmail && values.newEmail && errorNewEmail}
        >
          {!formEmail ? 'Lanjutkan' : 'Simpan Perubahan'}
        </ButtonFilled>
      </form>
    );
  }

  _handleEmailChange = (setFieldValue, value) => {
    this.setState({ errorNewEmail: null });
    setFieldValue('newEmail', value.target.value);
  }

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

  _handleEmail = (values) => {
    const { actions: { authRequestPt, checkEmailPt, requestProfilePt },
      auth: { pt }, profilPT: { profile } } = this.props;
    const { password, newEmail } = values;
    const { formEmail } = this.state;
    const email = get(profile, 'email');
    const token = get(pt, 'token');
    if (!formEmail) {
      requestProfilePt({ token: get(pt, 'token') });
      authRequestPt({ email, password });
    }
    if (formEmail) {
      if (email === newEmail) this.setState({ errorNewEmail: 'Email yang Anda input sama dengan Email Sebelumnya', submitting: false });
      else {
        checkEmailPt(newEmail, token);
        this.setState({ errorNewEmail: null, submitting: true });
      }
    }
  }

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

  _handleReset = () => {
    this.setState({ formEmail: false, errorNewEmail: null, submitting: false });
    this.form.current?.setValues({ newEmail: '', password: '' });
  }

  _schemaChangeEmail = () => {
    return Yup.object().shape({
      newEmail: Yup.string()
        .matches(REGEX.emailv2, 'Format tidak sesuai, gunakan format @')
        .required(''),
      password: Yup.string()
        .required('')
        .matches(REGEX.idealPassword, 'errorAll')
        .matches(REGEX.checkUpperLowerCase, 'errorAll')
        .min(8, 'errorAll')
    });
  }


  render() {
    const { classes, onClose } = this.props;
    const { newEmail, password, visible, formEmail } = this.state;
    const initialValues = { newEmail, password };
    return (
      <div>
        <Modal
          visible={visible}
          onCancel={onClose}
          onClose={onClose}
          closeIcon={<img src={ICONS.closeIcon} />}
          centered
          footer={false}
          zIndex={1300}
          className={classes.wrapperModal}
        >
          <p className="modal-title">Ubah Email</p>
          <p className="modal-description">{formEmail? 'Silakan isi kolom berikut dengan alamat Email Baru.': 'Silakan isi kolom berikut untuk mengubah email.'} </p>
          <Formik
            innerRef={this.form}
            initialValues={initialValues}
            validationSchema={this._schemaChangeEmail}
            component={this._renderFormEmail}
            onSubmit={this._handleEmail}
          />
        </Modal>
      </div>
    );
  }
}

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

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

export default ModalChangeEmail;