mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 08:13:56 +10:00
feat: store signature on signup
This commit is contained in:
@ -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">
|
||||||
|
|||||||
@ -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,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -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);
|
||||||
|
|
||||||
|
|||||||
@ -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>;
|
||||||
|
|||||||
Reference in New Issue
Block a user