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 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | 7x 7x 7x 7x 18x 16x 16x 16x 16x 2x 14x 4x 4x 4x 4x 14x 280x | 'use client'
import { Form, Formik } from 'formik'
import Link from 'next/link'
import { notFound, useSearchParams } from 'next/navigation'
import { useState } from 'react'
import { ObjectSchema, object, ref, string } from 'yup'
import { PASSWORD_MATCH_ERROR, PASSWORD_MIN_LENGTH_ERROR } from '../../../../../../content/validation'
import { Alert, AlertProps } from '../../../../../components/Alert/Alert'
import { Button } from '../../../../../components/ButtonsAndLinks/Button/Button'
import { PasswordInput } from '../../../../../components/Form/PasswordInput/PasswordInput'
import { Headline } from '../../../../../components/Headline/Headline'
import { ChangePasswordResponse, changePassword } from '../../../../../services/api/auth/resetPassword'
import { routes } from '../../../../../services/routes/routes'
type ChangePasswordFormValues = {
newPassword: string
newPasswordConfirm: string
}
// Formik
const initialFormValues: ChangePasswordFormValues = {
newPassword: '',
newPasswordConfirm: '',
}
const validationSchema: ObjectSchema<ChangePasswordFormValues> = object({
newPassword: string().required('Bitte geben Sie ein neues Passwort ein.').min(8, PASSWORD_MIN_LENGTH_ERROR),
newPasswordConfirm: string()
.required('Bitte geben Sie ihr neues Passwort erneut ein.')
.oneOf([ref('newPassword')], PASSWORD_MATCH_ERROR),
})
const alertContent: { [key: string]: AlertProps } = {
OK: {
icon: 'check_circle',
color: 'green',
headline: 'Erfolgreich!',
description: (
<>
<p>
Passwort wurde erfolgreich geändert. Klicken Sie{' '}
<Link className="inline font-semibold text-green-600 hover:text-green-700" href={routes.account.login()}>
hier{' '}
</Link>
um sich einzuloggen.
</p>
</>
),
},
TOKEN_INVALID: {
icon: 'warning',
color: 'red',
headline: 'Ungültiger Link',
description: 'Der Link ist ungültig. Bitte fordern Sie einen neuen Link an.',
},
ERROR: {
icon: 'warning',
color: 'red',
headline: 'Fehler!',
description: 'Beim Ändern des Passworts ist etwas schief gelaufen. Bitte versuchen Sie es später erneut.',
},
}
/**
* Change Password Page.
*/
const ChangePassword = () => {
const searchParams = useSearchParams()
const token = searchParams.get('token')
// Local State
const [isLoading, setIsLoading] = useState(false)
const [status, setStatus] = useState<ChangePasswordResponse | null>(null)
// Render 404 if no token is provided
if (!token) {
return notFound()
}
const onSubmit = async (values: ChangePasswordFormValues) => {
setIsLoading(true)
const response = await changePassword(values.newPassword, token)
setStatus(response)
setIsLoading(false)
}
return (
<div className="container my-auto flex flex-col">
<header>
<Headline>Passwort ändern</Headline>
<p className="mb-2 font-semibold md:mb-4">Ändern und bestätigen Sie Ihr neues Passwort.</p>
</header>
<main className="rounded-xl border border-gray-200 p-4 md:p-6 lg:w-2/3 xl:w-1/2">
<Formik initialValues={initialFormValues} validationSchema={validationSchema} onSubmit={onSubmit}>
{({ dirty, isValid }) => (
<Form className="mb-4">
<PasswordInput
name="newPassword"
labelText="Neues Passwort"
placeholder="Geben Sie ein neues Passwort ein."
/>
<PasswordInput
name="newPasswordConfirm"
labelText="Neues Passwort bestätigen"
placeholder="Wiederholen Sie das neue Passwort."
/>
<Button
datacy="submit-button"
type="submit"
icon="lock_reset"
loading={isLoading}
disabled={!(dirty && isValid)}
className="ml-auto"
>
Passwort ändern
</Button>
</Form>
)}
</Formik>
{status && <Alert {...alertContent[status]} />}
</main>
</div>
)
}
export default ChangePassword
|