import { zodResolver } from '@hookform/resolvers/zod'; import { Trans, msg } from '@lingui/macro'; import { useLingui } from '@lingui/react'; import type { User } from '@prisma/client'; import { useForm } from 'react-hook-form'; import { match } from 'ts-pattern'; import { z } from 'zod'; import { authClient } from '@documenso/auth/client'; import { AppError } from '@documenso/lib/errors/app-error'; import { ZCurrentPasswordSchema, ZPasswordSchema } from '@documenso/trpc/server/auth-router/schema'; import { cn } from '@documenso/ui/lib/utils'; import { Button } from '@documenso/ui/primitives/button'; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from '@documenso/ui/primitives/form/form'; import { PasswordInput } from '@documenso/ui/primitives/password-input'; import { useToast } from '@documenso/ui/primitives/use-toast'; export const ZPasswordFormSchema = z .object({ currentPassword: ZCurrentPasswordSchema, password: ZPasswordSchema, repeatedPassword: ZPasswordSchema, }) .refine((data) => data.password === data.repeatedPassword, { message: 'Passwords do not match', path: ['repeatedPassword'], }); export type TPasswordFormSchema = z.infer; export type PasswordFormProps = { className?: string; user: User; }; export const PasswordForm = ({ className }: PasswordFormProps) => { const { _ } = useLingui(); const { toast } = useToast(); const form = useForm({ values: { currentPassword: '', password: '', repeatedPassword: '', }, resolver: zodResolver(ZPasswordFormSchema), }); const isSubmitting = form.formState.isSubmitting; const onFormSubmit = async ({ currentPassword, password }: TPasswordFormSchema) => { try { await authClient.updatePassword({ currentPassword, password, }); form.reset(); toast({ title: _(msg`Password updated`), description: _(msg`Your password has been updated successfully.`), duration: 5000, }); } catch (err) { const error = AppError.parseError(err); const errorMessage = match(error.code) .with('NO_PASSWORD', () => msg`User has no password.`) .with('INCORRECT_PASSWORD', () => msg`Current password is incorrect.`) .with( 'SAME_PASSWORD', () => msg`Your new password cannot be the same as your old password.`, ) .otherwise( () => msg`We encountered an unknown error while attempting to update your password. Please try again later.`, ); toast({ title: _(msg`An error occurred`), description: _(errorMessage), variant: 'destructive', }); } }; return (
( Current Password )} /> ( Password )} /> ( Repeat Password )} />
); };