♻️ 🧹 upsert reciient, deleteRecipient, send

This commit is contained in:
Timur Ercan
2023-03-01 15:41:43 +01:00
parent 891f032468
commit 10b81bc757
8 changed files with 119 additions and 106 deletions

View File

@ -25,7 +25,7 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) {
return; return;
} }
// todo encapsulate entity ownerships checks // todo entity ownerships checks
const fields = await prisma.field.findMany({ const fields = await prisma.field.findMany({
where: { documentId: +documentId }, where: { documentId: +documentId },
@ -57,7 +57,7 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
const document: PrismaDocument = await getDocument(+documentId, req, res); const document: PrismaDocument = await getDocument(+documentId, req, res);
// todo encapsulate entity ownerships checks // todo entity ownerships checks
if (document.userId !== user.id) { if (document.userId !== user.id) {
return res.status(401).send("User does not have access to this document."); return res.status(401).send("User does not have access to this document.");
} }

View File

@ -23,7 +23,7 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
const document: PrismaDocument = await getDocument(+documentId, req, res); const document: PrismaDocument = await getDocument(+documentId, req, res);
// todo encapsulate entity ownerships checks // todo entity ownerships checks
if (document.userId !== user.id) { if (document.userId !== user.id) {
return res.status(401).send("User does not have access to this document."); return res.status(401).send("User does not have access to this document.");
} }

View File

@ -351,7 +351,6 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
const removedItem: any = const removedItem: any =
documentsWithoutIndex.splice(index, 1); documentsWithoutIndex.splice(index, 1);
setDocuments(documentsWithoutIndex); setDocuments(documentsWithoutIndex);
// todo encapsulate
deleteDocument(document.id) deleteDocument(document.id)
.catch((err) => { .catch((err) => {
documentsWithoutIndex.splice( documentsWithoutIndex.splice(

View File

@ -17,8 +17,12 @@ import { getUserFromToken } from "@documenso/lib/server";
import { getDocument } from "@documenso/lib/query"; import { getDocument } from "@documenso/lib/query";
import { Document as PrismaDocument } from "@prisma/client"; import { Document as PrismaDocument } from "@prisma/client";
import { Breadcrumb, Button, IconButton } from "@documenso/ui"; import { Breadcrumb, Button, IconButton } from "@documenso/ui";
import toast from "react-hot-toast";
import { Dialog, Transition } from "@headlessui/react"; import { Dialog, Transition } from "@headlessui/react";
import {
createOrUpdateRecipient,
deleteRecipient,
sendSigningRequests,
} from "@documenso/lib/api";
const RecipientsPage: NextPageWithLayout = (props: any) => { const RecipientsPage: NextPageWithLayout = (props: any) => {
const title: string = const title: string =
@ -138,10 +142,11 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
}} }}
onBlur={() => { onBlur={() => {
item.documentId = props.document.id; item.documentId = props.document.id;
upsertRecipient(item); createOrUpdateRecipient(item);
}} }}
onKeyDown={(event: any) => { onKeyDown={(event: any) => {
if (event.key === "Enter") upsertRecipient(item); if (event.key === "Enter")
createOrUpdateRecipient(item);
}} }}
className="block w-full border-0 p-0 text-gray-900 placeholder-gray-500 sm:text-sm outline-none bg-inherit" className="block w-full border-0 p-0 text-gray-900 placeholder-gray-500 sm:text-sm outline-none bg-inherit"
placeholder="john.dorian@loremipsum.com" placeholder="john.dorian@loremipsum.com"
@ -171,10 +176,11 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
}} }}
onBlur={() => { onBlur={() => {
item.documentId = props.document.id; item.documentId = props.document.id;
upsertRecipient(item); createOrUpdateRecipient(item);
}} }}
onKeyDown={(event: any) => { onKeyDown={(event: any) => {
if (event.key === "Enter") upsertRecipient(item); if (event.key === "Enter")
createOrUpdateRecipient(item);
}} }}
className="block w-full border-0 p-0 text-gray-900 placeholder-gray-500 sm:text-sm outline-none bg-inherit" className="block w-full border-0 p-0 text-gray-900 placeholder-gray-500 sm:text-sm outline-none bg-inherit"
placeholder="John Dorian" placeholder="John Dorian"
@ -250,7 +256,9 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
onClick={() => { onClick={() => {
if (confirm("Resend this signing request?")) { if (confirm("Resend this signing request?")) {
setLoading(true); setLoading(true);
send(props.document, [item.id]).finally(() => { sendSigningRequests(props.document, [
item.id,
]).finally(() => {
setLoading(false); setLoading(false);
}); });
} }
@ -270,7 +278,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
1 1
); );
setSigners(signersWithoutIndex); setSigners(signersWithoutIndex);
deleteRecipient(item).catch((err) => { deleteRecipient(item)?.catch((err) => {
setSigners(signersWithoutIndex.concat(removedItem)); setSigners(signersWithoutIndex.concat(removedItem));
}); });
}} }}
@ -285,7 +293,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
icon={UserPlusIcon} icon={UserPlusIcon}
className="mt-3" className="mt-3"
onClick={() => { onClick={() => {
upsertRecipient({ createOrUpdateRecipient({
id: "", id: "",
email: "", email: "",
name: "", name: "",
@ -365,7 +373,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
<Button <Button
onClick={() => { onClick={() => {
setOpen(false); setOpen(false);
send(props.document).finally(() => { sendSigningRequests(props.document).finally(() => {
setLoading(false); setLoading(false);
}); });
}} }}
@ -383,69 +391,6 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
); );
}; };
// todo encapsulate
async function deleteRecipient(recipient: any) {
if (!recipient.id) {
return;
}
return toast.promise(
fetch(
"/api/documents/" + recipient.documentId + "/recipients/" + recipient.id,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(recipient),
}
),
{
loading: "Deleting...",
success: "Deleted.",
error: "Could not delete :/",
},
{
id: "delete",
style: {
minWidth: "200px",
},
}
);
}
// todo encapsulate
async function upsertRecipient(recipient: any): Promise<any> {
try {
const created = await toast.promise(
fetch("/api/documents/" + recipient.documentId + "/recipients", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(recipient),
}).then((res) => {
if (!res.ok) {
throw new Error(res.status.toString());
}
return res.json();
}),
{
loading: "Saving...",
success: "Saved.",
error: "Could not save :/",
},
{
id: "saving",
style: {
minWidth: "200px",
},
}
);
return created;
} catch (error) {}
}
RecipientsPage.getLayout = function getLayout(page: ReactElement) { RecipientsPage.getLayout = function getLayout(page: ReactElement) {
return <Layout>{page}</Layout>; return <Layout>{page}</Layout>;
}; };
@ -468,33 +413,4 @@ export async function getServerSideProps(context: any) {
}; };
} }
// todo encapsulate
async function send(document: any, resendTo: number[] = []) {
if (!document || !document.id) return;
try {
const sent = await toast.promise(
fetch(`/api/documents/${document.id}/send`, {
body: JSON.stringify({ resendTo: resendTo }),
headers: { "Content-Type": "application/json" },
method: "POST",
})
.then((res: any) => {
if (!res.ok) {
throw new Error(res.status.toString());
}
})
.finally(() => {
location.reload();
}),
{
loading: "Sending...",
success: `Sent!`,
error: "Could not send :/",
}
);
} catch (err) {
console.log(err);
}
}
export default RecipientsPage; export default RecipientsPage;

View File

@ -0,0 +1,32 @@
import toast from "react-hot-toast";
export const createOrUpdateRecipient = async (recipient: any): Promise<any> => {
try {
const created = await toast.promise(
fetch("/api/documents/" + recipient.documentId + "/recipients", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(recipient),
}).then((res) => {
if (!res.ok) {
throw new Error(res.status.toString());
}
return res.json();
}),
{
loading: "Saving...",
success: "Saved.",
error: "Could not save :/",
},
{
id: "saving",
style: {
minWidth: "200px",
},
}
);
return created;
} catch (error) {}
};

View File

@ -0,0 +1,31 @@
import toast from "react-hot-toast";
export const deleteRecipient = (recipient: any) => {
if (!recipient.id) {
return;
}
return toast.promise(
fetch(
"/api/documents/" + recipient.documentId + "/recipients/" + recipient.id,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(recipient),
}
),
{
loading: "Deleting...",
success: "Deleted.",
error: "Could not delete :/",
},
{
id: "delete",
style: {
minWidth: "200px",
},
}
);
};

View File

@ -4,4 +4,7 @@ export { signDocument } from "./signDocument";
export { getUser } from "./getUser"; export { getUser } from "./getUser";
export { signup } from "./signup"; export { signup } from "./signup";
export { getDocuments } from "./getDocuments"; export { getDocuments } from "./getDocuments";
export { deleteDocument } from "./deleteDocument"; export { deleteDocument } from "./deleteDocument";
export { deleteRecipient } from "./deleteRecipient";
export { createOrUpdateRecipient } from "./createOrUpdateRecipient";
export { sendSigningRequests } from "./sendSigningRequests";

View File

@ -0,0 +1,32 @@
import toast from "react-hot-toast";
export const sendSigningRequests = async (
document: any,
resendTo: number[] = []
) => {
if (!document || !document.id) return;
try {
const sent = await toast.promise(
fetch(`/api/documents/${document.id}/send`, {
body: JSON.stringify({ resendTo: resendTo }),
headers: { "Content-Type": "application/json" },
method: "POST",
})
.then((res: any) => {
if (!res.ok) {
throw new Error(res.status.toString());
}
})
.finally(() => {
location.reload();
}),
{
loading: "Sending...",
success: `Sent!`,
error: "Could not send :/",
}
);
} catch (err) {
console.log(err);
}
};