import React from 'react'; import { useMutation } from 'react-apollo'; import { useFormik, FormikErrors } from 'formik'; import { ApolloError } from 'apollo-client'; import { useTranslation } from 'react-i18next'; import { LockFilled, LoginOutlined, UserOutlined } from '@ant-design/icons'; import { Input, Button } from 'antd'; import LogoImage from '../../images/mayoor_logo.svg'; import { LoginMutation, LoginMutationVariables } from '../../__generated__/types'; import { CenteredWrapper } from '../CenteredWrapper/CenteredWrapper'; import { useAppDispatch } from '../../appContext/context'; import { LanguageSwitch } from '../LanguageSwitch/LanguageSwitch'; import { LOGIN_MUTATION } from './queries'; import * as S from './LoginForm.styles'; type FormValues = { username: string; password: string; }; export const LoginForm: React.FC = () => { const dispatch = useAppDispatch(); const { t } = useTranslation(); const [login, { loading }] = useMutation<LoginMutation, LoginMutationVariables>(LOGIN_MUTATION); const { errors, handleSubmit, values, handleChange, isValid, setErrors, touched } = useFormik< FormValues >({ initialValues: { username: '', password: '', }, validate: (values) => { const errors: FormikErrors<FormValues> = {}; if (!values.password) { errors.password = t('password_required'); } if (!values.username) { errors.username = t('username_required'); } return errors; }, onSubmit: async ({ username, password }) => { try { const result = await login({ variables: { email: username, password } }); if (result.data?.login) { dispatch({ type: 'SET_CURRENT_USER', user: result.data.login.user, }); localStorage.setItem('auth-token', result.data.login.token); } } catch (err) { if (err instanceof ApolloError) { if (err.graphQLErrors[0].extensions?.code === 'USER_NOT_FOUND') { setErrors({ username: t('user_not_found'), }); } if (err.graphQLErrors[0].extensions?.code === 'INVALID_PASSWORD') { setErrors({ password: t('invalid_password'), }); } } } }, }); return ( <CenteredWrapper> <S.LoginWrapper onSubmit={handleSubmit}> <S.Logo src={LogoImage} /> <S.FormItemStyled validateStatus={touched.username && errors.username ? 'error' : ''} help={touched.username && errors.username} > <Input prefix={<UserOutlined />} placeholder={t('Username')} name="username" onChange={handleChange} value={values.username} data-test-id="login-username" /> </S.FormItemStyled> <S.FormItemStyled validateStatus={touched.password && errors.password ? 'error' : ''} help={touched.password && errors.password} > <Input prefix={<LockFilled />} placeholder={t('Password')} name="password" onChange={handleChange} value={values.password} type="password" data-test-id="login-password" /> </S.FormItemStyled> <Button icon={<LoginOutlined />} loading={loading} disabled={!isValid} htmlType="submit" data-test-id="login-submit-button" > {t('Log In')} </Button> <S.LanguageSwitchWrapper> <LanguageSwitch /> </S.LanguageSwitchWrapper> </S.LoginWrapper> </CenteredWrapper> ); };