feat: store signature on signup

This commit is contained in:
Mythie
2023-09-01 19:46:44 +10:00
parent 7218b950fe
commit 7bcf5fbd86
4 changed files with 25 additions and 7 deletions

View File

@ -3,13 +3,14 @@
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from '@hookform/resolvers/zod';
import { Loader } from 'lucide-react'; import { Loader } from 'lucide-react';
import { signIn } from 'next-auth/react'; import { signIn } from 'next-auth/react';
import { useForm } from 'react-hook-form'; import { Controller, useForm } from 'react-hook-form';
import { z } from 'zod'; import { z } from 'zod';
import { TRPCClientError } from '@documenso/trpc/client'; import { TRPCClientError } from '@documenso/trpc/client';
import { trpc } from '@documenso/trpc/react'; import { trpc } from '@documenso/trpc/react';
import { cn } from '@documenso/ui/lib/utils'; import { cn } from '@documenso/ui/lib/utils';
import { Button } from '@documenso/ui/primitives/button'; import { Button } from '@documenso/ui/primitives/button';
import { FormErrorMessage } from '@documenso/ui/primitives/form/form-error-message';
import { Input } from '@documenso/ui/primitives/input'; import { Input } from '@documenso/ui/primitives/input';
import { Label } from '@documenso/ui/primitives/label'; import { Label } from '@documenso/ui/primitives/label';
import { SignaturePad } from '@documenso/ui/primitives/signature-pad'; import { SignaturePad } from '@documenso/ui/primitives/signature-pad';
@ -19,6 +20,7 @@ export const ZSignUpFormSchema = z.object({
name: z.string().min(1), name: z.string().min(1),
email: z.string().email().min(1), email: z.string().email().min(1),
password: z.string().min(6).max(72), password: z.string().min(6).max(72),
signature: z.string().min(1, { message: 'We need your signature to sign documents' }),
}); });
export type TSignUpFormSchema = z.infer<typeof ZSignUpFormSchema>; export type TSignUpFormSchema = z.infer<typeof ZSignUpFormSchema>;
@ -31,6 +33,7 @@ export const SignUpForm = ({ className }: SignUpFormProps) => {
const { toast } = useToast(); const { toast } = useToast();
const { const {
control,
register, register,
handleSubmit, handleSubmit,
formState: { errors, isSubmitting }, formState: { errors, isSubmitting },
@ -39,15 +42,16 @@ export const SignUpForm = ({ className }: SignUpFormProps) => {
name: '', name: '',
email: '', email: '',
password: '', password: '',
signature: '',
}, },
resolver: zodResolver(ZSignUpFormSchema), resolver: zodResolver(ZSignUpFormSchema),
}); });
const { mutateAsync: signup } = trpc.auth.signup.useMutation(); const { mutateAsync: signup } = trpc.auth.signup.useMutation();
const onFormSubmit = async ({ name, email, password }: TSignUpFormSchema) => { const onFormSubmit = async ({ name, email, password, signature }: TSignUpFormSchema) => {
try { try {
await signup({ name, email, password }); await signup({ name, email, password, signature });
await signIn('credentials', { await signIn('credentials', {
email, email,
@ -119,8 +123,19 @@ export const SignUpForm = ({ className }: SignUpFormProps) => {
</Label> </Label>
<div> <div>
<SignaturePad className="mt-2 h-36 w-full rounded-lg border bg-white dark:border-[#e2d7c5] dark:bg-[#fcf8ee]" /> <Controller
control={control}
name="signature"
render={({ field: { onChange } }) => (
<SignaturePad
className="mt-2 h-36 w-full rounded-lg border bg-white dark:border-[#e2d7c5] dark:bg-[#fcf8ee]"
onChange={(v) => onChange(v ?? '')}
/>
)}
/>
</div> </div>
<FormErrorMessage className="mt-1.5" error={errors.signature} />
</div> </div>
<Button size="lg" disabled={isSubmitting} className="dark:bg-documenso dark:hover:opacity-90"> <Button size="lg" disabled={isSubmitting} className="dark:bg-documenso dark:hover:opacity-90">

View File

@ -9,9 +9,10 @@ export interface CreateUserOptions {
name: string; name: string;
email: string; email: string;
password: string; password: string;
signature?: string | null;
} }
export const createUser = async ({ name, email, password }: CreateUserOptions) => { export const createUser = async ({ name, email, password, signature }: CreateUserOptions) => {
const hashedPassword = await hash(password, SALT_ROUNDS); const hashedPassword = await hash(password, SALT_ROUNDS);
const userExists = await prisma.user.findFirst({ const userExists = await prisma.user.findFirst({
@ -29,6 +30,7 @@ export const createUser = async ({ name, email, password }: CreateUserOptions) =
name, name,
email: email.toLowerCase(), email: email.toLowerCase(),
password: hashedPassword, password: hashedPassword,
signature,
identityProvider: IdentityProvider.DOCUMENSO, identityProvider: IdentityProvider.DOCUMENSO,
}, },
}); });

View File

@ -8,9 +8,9 @@ import { ZSignUpMutationSchema } from './schema';
export const authRouter = router({ export const authRouter = router({
signup: procedure.input(ZSignUpMutationSchema).mutation(async ({ input }) => { signup: procedure.input(ZSignUpMutationSchema).mutation(async ({ input }) => {
try { try {
const { name, email, password } = input; const { name, email, password, signature } = input;
return await createUser({ name, email, password }); return await createUser({ name, email, password, signature });
} catch (err) { } catch (err) {
console.error(err); console.error(err);

View File

@ -4,6 +4,7 @@ export const ZSignUpMutationSchema = z.object({
name: z.string().min(1), name: z.string().min(1),
email: z.string().email(), email: z.string().email(),
password: z.string().min(6), password: z.string().min(6),
signature: z.string().min(1, { message: 'A signature is required.' }),
}); });
export type TSignUpMutationSchema = z.infer<typeof ZSignUpMutationSchema>; export type TSignUpMutationSchema = z.infer<typeof ZSignUpMutationSchema>;