mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 00:03:33 +10:00
chore: cleanup and feedback implementation
This commit is contained in:
@ -57,7 +57,7 @@ export const DesktopNav = ({ className, ...props }: DesktopNavProps) => {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Braces className="mr-2 h-5 w-5" />
|
<Braces className="mr-2 h-5 w-5" />
|
||||||
API Token
|
API Tokens
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|||||||
@ -60,7 +60,7 @@ export const MobileNav = ({ className, ...props }: MobileNavProps) => {
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<Braces className="mr-2 h-5 w-5" />
|
<Braces className="mr-2 h-5 w-5" />
|
||||||
API Token
|
API Tokens
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
import type { NextApiRequest, NextApiResponse } from 'next';
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
||||||
|
|
||||||
import { createDocumentData } from '@documenso/lib/server-only/document-data/create-document-data';
|
import { upsertDocumentMeta } from '@documenso/lib/server-only/document-meta/upsert-document-meta';
|
||||||
import { createDocument } from '@documenso/lib/server-only/document/create-document';
|
|
||||||
import { deleteDocument } from '@documenso/lib/server-only/document/delete-document';
|
import { deleteDocument } from '@documenso/lib/server-only/document/delete-document';
|
||||||
|
import { findDocuments } from '@documenso/lib/server-only/document/find-documents';
|
||||||
import { getDocumentById } from '@documenso/lib/server-only/document/get-document-by-id';
|
import { getDocumentById } from '@documenso/lib/server-only/document/get-document-by-id';
|
||||||
import { getDocuments } from '@documenso/lib/server-only/public-api/get-documents';
|
import { sendDocument } from '@documenso/lib/server-only/document/send-document';
|
||||||
|
import { setFieldsForDocument } from '@documenso/lib/server-only/field/set-fields-for-document';
|
||||||
import { checkUserFromToken } from '@documenso/lib/server-only/public-api/get-user-by-token';
|
import { checkUserFromToken } from '@documenso/lib/server-only/public-api/get-user-by-token';
|
||||||
import { putFile } from '@documenso/lib/universal/upload/put-file';
|
import { setRecipientsForDocument } from '@documenso/lib/server-only/recipient/set-recipients-for-document';
|
||||||
|
import { getPresignPostUrl } from '@documenso/lib/universal/upload/server-actions';
|
||||||
import { contract } from '@documenso/trpc/api-contract/contract';
|
import { contract } from '@documenso/trpc/api-contract/contract';
|
||||||
import { createNextRoute, createNextRouter } from '@documenso/trpc/server/public-api/ts-rest';
|
import { createNextRoute, createNextRouter } from '@documenso/trpc/server/public-api/ts-rest';
|
||||||
|
|
||||||
@ -35,7 +37,7 @@ const router = createNextRoute(contract, {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const { documents, totalPages } = await getDocuments({ page, perPage, userId: user.id });
|
const { data: documents, totalPages } = await findDocuments({ page, perPage, userId: user.id });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
@ -114,7 +116,30 @@ const router = createNextRoute(contract, {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
createDocument: async (args) => {
|
createDocument: async (args) => {
|
||||||
|
const { body } = args;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { url, key } = await getPresignPostUrl(body.fileName, body.contentType);
|
||||||
|
|
||||||
|
return {
|
||||||
|
status: 200,
|
||||||
|
body: {
|
||||||
|
url,
|
||||||
|
key,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
return {
|
||||||
|
status: 404,
|
||||||
|
body: {
|
||||||
|
message: 'An error has occured while uploading the file',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sendDocumentForSigning: async (args) => {
|
||||||
const { authorization } = args.headers;
|
const { authorization } = args.headers;
|
||||||
|
const { id } = args.params;
|
||||||
const { body } = args;
|
const { body } = args;
|
||||||
|
|
||||||
const user = await validateUserToken(authorization);
|
const user = await validateUserToken(authorization);
|
||||||
@ -128,39 +153,72 @@ const router = createNextRoute(contract, {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const document = await getDocumentById({ id: Number(id), userId: user.id });
|
||||||
|
|
||||||
|
if (!document) {
|
||||||
|
return {
|
||||||
|
status: 404,
|
||||||
|
body: {
|
||||||
|
message: 'Document not found',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.status === 'PENDING') {
|
||||||
|
return {
|
||||||
|
status: 400,
|
||||||
|
body: {
|
||||||
|
message: 'Document is already waiting for signing',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const regexPattern = /filename="(.+?)"/;
|
await setRecipientsForDocument({
|
||||||
const match = body.toString().match(regexPattern);
|
userId: user.id,
|
||||||
const documentTitle = match?.[1] ?? 'Untitled document';
|
documentId: Number(id),
|
||||||
|
recipients: [
|
||||||
const file = new Blob([body], {
|
{
|
||||||
type: 'application/pdf',
|
email: body.signerEmail,
|
||||||
|
name: body.signerName ?? '',
|
||||||
|
},
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const { type, data } = await putFile(file);
|
await setFieldsForDocument({
|
||||||
|
documentId: Number(id),
|
||||||
const { id: documentDataId } = await createDocumentData({
|
userId: user.id,
|
||||||
type,
|
fields: body.fields.map((field) => ({
|
||||||
data,
|
signerEmail: body.signerEmail,
|
||||||
|
type: field.fieldType,
|
||||||
|
pageNumber: field.pageNumber,
|
||||||
|
pageX: field.pageX,
|
||||||
|
pageY: field.pageY,
|
||||||
|
pageWidth: field.pageWidth,
|
||||||
|
pageHeight: field.pageHeight,
|
||||||
|
})),
|
||||||
});
|
});
|
||||||
|
|
||||||
const { id } = await createDocument({
|
if (body.emailBody || body.emailSubject) {
|
||||||
title: documentTitle,
|
await upsertDocumentMeta({
|
||||||
documentDataId,
|
documentId: Number(id),
|
||||||
|
subject: body.emailSubject ?? '',
|
||||||
|
message: body.emailBody ?? '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await sendDocument({
|
||||||
|
documentId: Number(id),
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: {
|
body: {
|
||||||
uploadedFile: {
|
message: 'Document sent for signing successfully',
|
||||||
id,
|
|
||||||
message: 'Document uploaded successfuly',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
|
||||||
return {
|
return {
|
||||||
status: 500,
|
status: 500,
|
||||||
body: {
|
body: {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export type DeleteTokenByIdOptions = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const deleteTokenById = async ({ id, userId }: DeleteTokenByIdOptions) => {
|
export const deleteTokenById = async ({ id, userId }: DeleteTokenByIdOptions) => {
|
||||||
return prisma.apiToken.delete({
|
return await prisma.apiToken.delete({
|
||||||
where: {
|
where: {
|
||||||
id,
|
id,
|
||||||
userId,
|
userId,
|
||||||
|
|||||||
@ -1,25 +0,0 @@
|
|||||||
import { prisma } from '@documenso/prisma';
|
|
||||||
|
|
||||||
type GetDocumentsProps = {
|
|
||||||
page: number;
|
|
||||||
perPage: number;
|
|
||||||
userId: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getDocuments = async ({ page = 1, perPage = 10, userId }: GetDocumentsProps) => {
|
|
||||||
const [documents, count] = await Promise.all([
|
|
||||||
await prisma.document.findMany({
|
|
||||||
where: {
|
|
||||||
userId,
|
|
||||||
},
|
|
||||||
take: perPage,
|
|
||||||
skip: Math.max(page - 1, 0) * perPage,
|
|
||||||
}),
|
|
||||||
await prisma.document.count(),
|
|
||||||
]);
|
|
||||||
|
|
||||||
return {
|
|
||||||
documents,
|
|
||||||
totalPages: Math.ceil(count / perPage),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -38,10 +38,8 @@ export const SendDocumentForSigningMutationSchema = z.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const UploadDocumentSuccessfulSchema = z.object({
|
export const UploadDocumentSuccessfulSchema = z.object({
|
||||||
uploadedFile: z.object({
|
url: z.string(),
|
||||||
url: z.string(),
|
key: z.string(),
|
||||||
key: z.string(),
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const CreateDocumentMutationSchema = z.object({
|
export const CreateDocumentMutationSchema = z.object({
|
||||||
|
|||||||
@ -23,6 +23,7 @@ export const apiTokenRouter = router({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getTokenById: authenticatedProcedure
|
getTokenById: authenticatedProcedure
|
||||||
.input(ZGetApiTokenByIdQuerySchema)
|
.input(ZGetApiTokenByIdQuerySchema)
|
||||||
.query(async ({ input, ctx }) => {
|
.query(async ({ input, ctx }) => {
|
||||||
@ -40,6 +41,7 @@ export const apiTokenRouter = router({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
createToken: authenticatedProcedure
|
createToken: authenticatedProcedure
|
||||||
.input(ZCreateTokenMutationSchema)
|
.input(ZCreateTokenMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
@ -56,6 +58,7 @@ export const apiTokenRouter = router({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
deleteTokenById: authenticatedProcedure
|
deleteTokenById: authenticatedProcedure
|
||||||
.input(ZDeleteTokenByIdMutationSchema)
|
.input(ZDeleteTokenByIdMutationSchema)
|
||||||
.mutation(async ({ input, ctx }) => {
|
.mutation(async ({ input, ctx }) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user