Merge branch 'feat/refresh' into feat-api-error

This commit is contained in:
Nafees Nazik
2023-09-02 11:53:18 +05:30
committed by GitHub
10 changed files with 38 additions and 18 deletions
@@ -3,6 +3,7 @@ import { notFound } from 'next/navigation';
import { match } from 'ts-pattern'; import { match } from 'ts-pattern';
import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer'; import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer';
import { getServerComponentSession } from '@documenso/lib/next-auth/get-server-session';
import { getDocumentAndSenderByToken } from '@documenso/lib/server-only/document/get-document-by-token'; import { getDocumentAndSenderByToken } from '@documenso/lib/server-only/document/get-document-by-token';
import { viewedDocument } from '@documenso/lib/server-only/document/viewed-document'; import { viewedDocument } from '@documenso/lib/server-only/document/viewed-document';
import { getFieldsForToken } from '@documenso/lib/server-only/field/get-fields-for-token'; import { getFieldsForToken } from '@documenso/lib/server-only/field/get-fields-for-token';
@@ -42,10 +43,12 @@ export default async function SigningPage({ params: { token } }: SigningPageProp
return notFound(); return notFound();
} }
const user = await getServerComponentSession();
const documentUrl = `data:application/pdf;base64,${document.document}`; const documentUrl = `data:application/pdf;base64,${document.document}`;
return ( return (
<SigningProvider email={recipient.email} fullName={recipient.name}> <SigningProvider email={recipient.email} fullName={recipient.name} signature={user?.signature}>
<div className="mx-auto w-full max-w-screen-xl px-4 md:px-8"> <div className="mx-auto w-full max-w-screen-xl px-4 md:px-8">
<h1 className="mt-4 truncate text-2xl font-semibold md:text-3xl" title={document.title}> <h1 className="mt-4 truncate text-2xl font-semibold md:text-3xl" title={document.title}>
{document.title} {document.title}
@@ -28,9 +28,9 @@ export const useRequiredSigningContext = () => {
}; };
export interface SigningProviderProps { export interface SigningProviderProps {
fullName?: string; fullName?: string | null;
email?: string; email?: string | null;
signature?: string; signature?: string | null;
children: React.ReactNode; children: React.ReactNode;
} }
@@ -118,6 +118,7 @@ export const ProfileForm = ({ className, user }: ProfileFormProps) => {
render={({ field: { onChange } }) => ( render={({ field: { onChange } }) => (
<SignaturePad <SignaturePad
className="h-44 w-full rounded-lg border bg-white backdrop-blur-sm dark:border-[#e2d7c5] dark:bg-[#fcf8ee]" className="h-44 w-full rounded-lg border bg-white backdrop-blur-sm dark:border-[#e2d7c5] dark:bg-[#fcf8ee]"
defaultValue={user.signature ?? undefined}
onChange={(v) => onChange(v ?? '')} onChange={(v) => onChange(v ?? '')}
/> />
)} )}
+19 -4
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">
+3 -1
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,
}, },
}); });
@@ -6,12 +6,7 @@ export type UpdateProfileOptions = {
signature: string; signature: string;
}; };
export const updateProfile = async ({ export const updateProfile = async ({ userId, name, signature }: UpdateProfileOptions) => {
userId,
name,
// TODO: Actually use signature
signature: _signature,
}: UpdateProfileOptions) => {
// Existence check // Existence check
await prisma.user.findFirstOrThrow({ await prisma.user.findFirstOrThrow({
where: { where: {
@@ -25,7 +20,7 @@ export const updateProfile = async ({
}, },
data: { data: {
name, name,
// signature, signature,
}, },
}); });
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "signature" TEXT;
+1
View File
@@ -20,6 +20,7 @@ model User {
emailVerified DateTime? emailVerified DateTime?
password String? password String?
source String? source String?
signature String?
identityProvider IdentityProvider @default(DOCUMENSO) identityProvider IdentityProvider @default(DOCUMENSO)
accounts Account[] accounts Account[]
sessions Session[] sessions Session[]
+2 -2
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);
@@ -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>;