All files / components/Form/AccountForm AccountForm.tsx

100% Statements 20/20
100% Branches 18/18
100% Functions 5/5
100% Lines 17/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97                                                  16x         16x 10x 10x     10x 14x 14x   10x         10x   4x 2x   2x     4x 1x 1x     10x     214x                                                                        
'use client'
import { Form, Formik } from 'formik'
import { useRouter, useSearchParams } from 'next/navigation'
import { ObjectSchema, object, string } from 'yup'
import { validateMail } from '../../../../utils/validateMail'
import { routes } from '../../../services/routes/routes'
import { loginApi, registerApi } from '../../../store/auth/auth'
import { useAppDispatch, useAppSelector } from '../../../store/hooks'
import { Alert } from '../../Alert/Alert'
import { Button } from '../../ButtonsAndLinks/Button/Button'
import { Route } from '../../ButtonsAndLinks/Route/Route'
import { PasswordInput } from '../PasswordInput/PasswordInput'
import { TextInput } from '../TextInput/TextInput'
import { EMAIL_REQUIRED_ERROR, PASSWORD_MIN_LENGTH_ERROR, PASSWORD_REQUIRED_ERROR } from '../../../../content/validation'
 
type AccountFormProps = {
	type?: 'login' | 'register'
}
 
type AccountDto = {
	email: string
	password: string
}
 
// Formik
const initialFormValues: AccountDto = {
	email: '',
	password: '',
}
 
export const AccountForm: React.FC<AccountFormProps> = ({ type }) => {
	const router = useRouter()
	const searchparams = useSearchParams()
 
	// Redux
	const dispatch = useAppDispatch()
	const registerError = useAppSelector((state) => state.auth.registerError)
	const loginError = useAppSelector((state) => state.auth.loginError)
 
	const accountValidationSchema: ObjectSchema<AccountDto> = object({
		email: string().matches(validateMail.regex, validateMail.message).required(EMAIL_REQUIRED_ERROR),
		password: string().min(8, PASSWORD_MIN_LENGTH_ERROR).required(PASSWORD_REQUIRED_ERROR),
	})
 
	const onSubmitAccountForm = async (values: AccountDto) => {
		let response
		if (type === 'login') {
			response = await dispatch(loginApi({ email: values.email, password: values.password }))
		} else {
			response = await dispatch(registerApi({ email: values.email, password: values.password }))
		}
 
		if (response.meta.requestStatus === 'rejected') return
		const callbackUrl = searchparams.get('callbackUrl') ?? routes.profile.myLastWills
		router.replace(callbackUrl)
	}
 
	return (
		<Formik initialValues={initialFormValues} validationSchema={accountValidationSchema} onSubmit={onSubmitAccountForm}>
			{({ dirty, isValid }) => (
				<Form className="mb-3">
					<TextInput autoComplete="email" type="email" name="email" labelText="E-Mail" placeholder="E-Mail" />
					<PasswordInput />
					{type === 'login' && (
						<Route href={routes.account.resetPassword} kind="tertiary" className="ml-auto">
							Passwort vergessen?
						</Route>
					)}
 
					{loginError && type === 'login' && (
						<div className="mt-5">
							<Alert datacy="alert-error" headline="Fehler" description={loginError} />
						</div>
					)}
 
					{registerError && type === 'register' && (
						<div className="mt-5">
							<Alert datacy="alert-error" headline="Fehler" description={registerError} />
						</div>
					)}
 
					<Button
						className="mt-8 md:justify-center"
						width="w-full"
						datacy="submit-button"
						icon="login"
						disabled={!(dirty && isValid)}
						type="submit"
					>
						{type === 'login' ? 'Einloggen' : 'Registrieren'}
					</Button>
				</Form>
			)}
		</Formik>
	)
}