mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 08:13:56 +10:00
🧹✨ Resend Signing Request UI
This commit is contained in:
@ -23,7 +23,7 @@ import { NextPageContext } from "next";
|
|||||||
const DocumentsPage: NextPageWithLayout = (props: any) => {
|
const DocumentsPage: NextPageWithLayout = (props: any) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [documents, setDocuments]: any[] = useState([]);
|
const [documents, setDocuments]: any[] = useState([]);
|
||||||
const [filterdDocuments, setFilteredDocuments] = useState([]);
|
const [filteredDocuments, setFilteredDocuments] = useState([]);
|
||||||
|
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const statusFilters = [
|
const statusFilters = [
|
||||||
@ -138,8 +138,8 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="mt-3 mb-12">
|
<div className="mt-3 mb-12">
|
||||||
<div className="w-fit block float-right ml-3 mt-7">
|
<div className="w-fit block float-right ml-3 mt-7">
|
||||||
{filterdDocuments.length != 1
|
{filteredDocuments.length != 1
|
||||||
? filterdDocuments.length + " Documents"
|
? filteredDocuments.length + " Documents"
|
||||||
: "1 Document"}
|
: "1 Document"}
|
||||||
</div>
|
</div>
|
||||||
<SelectBox
|
<SelectBox
|
||||||
@ -220,7 +220,7 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-gray-200 bg-white">
|
<tbody className="divide-y divide-gray-200 bg-white">
|
||||||
{filterdDocuments.map((document: any, index: number) => (
|
{filteredDocuments.map((document: any, index: number) => (
|
||||||
<tr
|
<tr
|
||||||
key={document.id}
|
key={document.id}
|
||||||
className="hover:bg-gray-100 cursor-pointer"
|
className="hover:bg-gray-100 cursor-pointer"
|
||||||
@ -330,9 +330,7 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
router.push("/documents/" + document.id);
|
router.push("/documents/" + document.id);
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
Edit
|
|
||||||
</IconButton>
|
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={ArrowDownTrayIcon}
|
icon={ArrowDownTrayIcon}
|
||||||
className="mr-2"
|
className="mr-2"
|
||||||
@ -341,9 +339,7 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
router.push("/api/documents/" + document.id);
|
router.push("/api/documents/" + document.id);
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
Download
|
|
||||||
</IconButton>
|
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={TrashIcon}
|
icon={TrashIcon}
|
||||||
onClick={(event: any) => {
|
onClick={(event: any) => {
|
||||||
@ -384,7 +380,7 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
|
|||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
hidden={filterdDocuments.length > 0}
|
hidden={filteredDocuments.length > 0}
|
||||||
className="mx-auto w-fit mt-12 p-3"
|
className="mx-auto w-fit mt-12 p-3"
|
||||||
>
|
>
|
||||||
<FunnelIcon className="w-5 inline mr-1 align-middle" /> Nothing
|
<FunnelIcon className="w-5 inline mr-1 align-middle" /> Nothing
|
||||||
|
|||||||
@ -10,8 +10,8 @@ import {
|
|||||||
EnvelopeIcon,
|
EnvelopeIcon,
|
||||||
PaperAirplaneIcon,
|
PaperAirplaneIcon,
|
||||||
PencilSquareIcon,
|
PencilSquareIcon,
|
||||||
|
TrashIcon,
|
||||||
UserPlusIcon,
|
UserPlusIcon,
|
||||||
XMarkIcon,
|
|
||||||
} from "@heroicons/react/24/outline";
|
} from "@heroicons/react/24/outline";
|
||||||
import { getUserFromToken } from "@documenso/lib/server";
|
import { getUserFromToken } from "@documenso/lib/server";
|
||||||
import { getDocument } from "@documenso/lib/query";
|
import { getDocument } from "@documenso/lib/query";
|
||||||
@ -236,9 +236,30 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="ml-auto flex">
|
<div className="ml-auto flex mr-1">
|
||||||
<IconButton
|
<IconButton
|
||||||
icon={XMarkIcon}
|
icon={PaperAirplaneIcon}
|
||||||
|
disabled={
|
||||||
|
!item.id ||
|
||||||
|
item.sendStatus !== "SENT" ||
|
||||||
|
item.signingStatus === "SIGNED" ||
|
||||||
|
loading
|
||||||
|
}
|
||||||
|
color="secondary"
|
||||||
|
className="mr-4 h-9 my-auto"
|
||||||
|
onClick={() => {
|
||||||
|
if (confirm("Resend this signing request?")) {
|
||||||
|
setLoading(true);
|
||||||
|
send(props.document, [item.id]).finally(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Resend
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
icon={TrashIcon}
|
||||||
disabled={
|
disabled={
|
||||||
!item.id || item.sendStatus === "SENT" || loading
|
!item.id || item.sendStatus === "SENT" || loading
|
||||||
}
|
}
|
||||||
@ -254,7 +275,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
className="group-hover:text-neon-dark group-hover:disabled:text-gray-400"
|
className="group-hover:text-neon-dark group-hover:disabled:text-gray-400"
|
||||||
></IconButton>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@ -445,17 +466,13 @@ export async function getServerSideProps(context: any) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function send(document: any) {
|
async function send(document: any, resendTo: number[] = []) {
|
||||||
// todo toast
|
|
||||||
// loading
|
|
||||||
if (!document || !document.id) return;
|
if (!document || !document.id) return;
|
||||||
try {
|
try {
|
||||||
const sent = await toast.promise(
|
const sent = await toast.promise(
|
||||||
fetch(`/api/documents/${document.id}/send`, {
|
fetch(`/api/documents/${document.id}/send`, {
|
||||||
body: "",
|
body: JSON.stringify({ resendTo: resendTo }),
|
||||||
headers: {
|
headers: { "Content-Type": "application/json" },
|
||||||
"Content-Type": "application/json",
|
|
||||||
},
|
|
||||||
method: "POST",
|
method: "POST",
|
||||||
})
|
})
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import prisma from "@documenso/prisma";
|
import prisma from "@documenso/prisma";
|
||||||
import { sendMail } from "./sendMail";
|
import { sendMail } from "./sendMail";
|
||||||
import { SendStatus, DocumentStatus } from "@prisma/client";
|
import { SendStatus, ReadStatus, DocumentStatus } from "@prisma/client";
|
||||||
import { NEXT_PUBLIC_WEBAPP_URL } from "../constants";
|
import { NEXT_PUBLIC_WEBAPP_URL } from "../constants";
|
||||||
import { signingRequestTemplate } from "@documenso/lib/mail";
|
import { signingRequestTemplate } from "@documenso/lib/mail";
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ export const sendSigningRequest = async (
|
|||||||
where: {
|
where: {
|
||||||
id: recipient.id,
|
id: recipient.id,
|
||||||
},
|
},
|
||||||
data: { sendStatus: SendStatus.SENT },
|
data: { sendStatus: SendStatus.SENT, readStatus: ReadStatus.NOT_OPENED },
|
||||||
});
|
});
|
||||||
|
|
||||||
await prisma.document.update({
|
await prisma.document.update({
|
||||||
|
|||||||
Reference in New Issue
Block a user