<commit_before><commit_msg>refactor: add ChangePasswordDialog component<commit_after>import React, { useEffect, useRef } from 'react'
import PropTypes from 'prop-types'
import { Flex } from 'rebass/styled-components'
import { FormattedMessage, useIntl } from 'react-intl'
import { Dialog, Heading, Message, Button, DialogOverlay } from 'components/UI'
import { PasswordInput, Form } from 'components/Form'
import messages from './messages'

const DialogWrapper = ({ loginError, clearLoginError, isOpen, onChange, onCancel }) => {
  const intl = useIntl()
  const formApiRef = useRef(null)
  useEffect(() => {
    const { current: formApi } = formApiRef
    if (loginError) {
      formApi.setFormError(loginError)
      clearLoginError()
    }
  }, [loginError, formApiRef, clearLoginError])

  if (!isOpen) {
    return null
  }

  const buttons = (
    <>
      <Button type="submit" variant="primary">
        <FormattedMessage {...messages.password_change_button_text} />
      </Button>
      <Button onClick={onCancel} type="button" variant="secondary">
        <FormattedMessage {...messages.password_dialog_cancel_button_text} />
      </Button>
    </>
  )

  const header = (
    <Flex alignItems="center" flexDirection="column" mb={4}>
      <Heading.h1>
        <FormattedMessage {...messages.password_change_dialog_header} />
      </Heading.h1>
    </Flex>
  )

  const handleSubmit = values => onChange(values)

  return (
    <DialogOverlay alignItems="center" justifyContent="center" position="fixed">
      <Form getApi={api => (formApiRef.current = api)} onSubmit={handleSubmit}>
        {({ formState: { submits, error } }) => {
          const willValidateInline = submits > 0
          return (
            <Dialog buttons={buttons} header={header} onClose={onCancel} width={640}>
              <Flex alignItems="center" alignSelf="stretch" flexDirection="column" width={350}>
                {error && (
                  <Message mb={3} variant="error">
                    {error}
                  </Message>
                )}
                <PasswordInput
                  description={intl.formatMessage(messages.password_old_password)}
                  field="oldPassword"
                  hasMessageSpacer
                  isRequired
                  mb={2}
                  validateOnBlur={willValidateInline}
                  validateOnChange={willValidateInline}
                  width={1}
                  willAutoFocus
                />
                <PasswordInput
                  description={intl.formatMessage(messages.password_new_password)}
                  field="newPassword"
                  hasMessageSpacer
                  isRequired
                  minLength={6}
                  width={1}
                />
              </Flex>
            </Dialog>
          )
        }}
      </Form>
    </DialogOverlay>
  )
}

DialogWrapper.propTypes = {
  clearLoginError: PropTypes.func.isRequired,
  isOpen: PropTypes.bool.isRequired,
  isRestoreMode: PropTypes.bool,
  loginError: PropTypes.string,
  onCancel: PropTypes.func.isRequired,
  onChange: PropTypes.func.isRequired,
}

export default DialogWrapper
{'fraction_non_alphanumeric': 0.1134572959344469, 'fraction_numerical': 0.004727387330601954, 'mean_word_length': 2.248720573183214, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 34, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7149208', 'n_tokens_mistral': 873, 'n_tokens_neox': 849, 'n_words': 169}