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
  |