Apply prettier config to all files

This commit is contained in:
Ephraim Atta-Duncan
2023-04-04 22:02:32 +00:00
parent 85f2b5e84a
commit 84b57d715c
94 changed files with 956 additions and 1386 deletions

View File

@ -1,31 +1,27 @@
import { ArrowSmallLeftIcon } from "@heroicons/react/20/solid";
import { Button } from "@documenso/ui";
import Logo from "../components/logo";
import { ArrowSmallLeftIcon } from "@heroicons/react/20/solid";
export default function Custom404() {
return (
<>
<main className="relative min-h-full bg-gray-100 isolate">
<main className="relative isolate min-h-full bg-gray-100">
<div className="absolute top-10 left-10">
<Logo className="w-10 md:w-20" />
</div>
<div className="px-6 py-48 mx-auto text-center max-w-7xl sm:py-40 lg:px-8">
<p className="text-base font-semibold leading-8 text-brown">404</p>
<h1 className="mt-4 text-3xl font-bold tracking-tight text-brown sm:text-5xl">
Page not found
</h1>
<div className="mx-auto max-w-7xl px-6 py-48 text-center sm:py-40 lg:px-8">
<p className="text-brown text-base font-semibold leading-8">404</p>
<h1 className="text-brown mt-4 text-3xl font-bold tracking-tight sm:text-5xl">Page not found</h1>
<p className="mt-4 text-base text-gray-700 sm:mt-6">
Sorry, we couldnt find the page youre looking for.
</p>
<div className="flex justify-center mt-10">
<div className="mt-10 flex justify-center">
<Button
color="secondary"
href="/"
icon={ArrowSmallLeftIcon}
className="text-base font-semibold leading-7 text-brown"
>
className="text-brown text-base font-semibold leading-7">
Back to home
</Button>
</div>

View File

@ -1,27 +1,23 @@
import Logo from "../components/logo";
import { Button } from "@documenso/ui";
import Logo from "../components/logo";
import { ArrowSmallLeftIcon } from "@heroicons/react/20/solid";
import { EllipsisVerticalIcon } from "@heroicons/react/20/solid";
export default function Custom500() {
return (
<>
<div className="relative flex flex-col items-center justify-center min-h-full text-white bg-black">
<div className="relative flex min-h-full flex-col items-center justify-center bg-black text-white">
<div className="absolute top-10 left-10">
<Logo dark className="w-10 md:w-20" />
</div>
<div className="px-4 py-10 mt-20 max-w-7xl">
<div className="mt-20 max-w-7xl px-4 py-10">
<p className="inline-flex items-center text-3xl font-bold sm:text-5xl">
500
<span className="relative px-3 font-thin sm:text-6xl -top-1.5">
|
</span>{" "}
<span className="text-base font-semibold align-middle sm:text-2xl">
Something went wrong.
</span>
<span className="relative -top-1.5 px-3 font-thin sm:text-6xl">|</span>{" "}
<span className="align-middle text-base font-semibold sm:text-2xl">Something went wrong.</span>
</p>
<div className="flex justify-center mt-10">
<div className="mt-10 flex justify-center">
<Button color="secondary" href="/" icon={ArrowSmallLeftIcon}>
Back to home
</Button>

View File

@ -1,13 +1,14 @@
import "../styles/tailwind.css";
import { ReactElement, ReactNode } from "react";
import { NextPage } from "next";
import type { AppProps } from "next/app";
import "../../../node_modules/placeholder-loading/src/scss/placeholder-loading.scss";
import "../../../node_modules/react-resizable/css/styles.css";
import "react-tooltip/dist/react-tooltip.css";
import { ReactElement, ReactNode } from "react";
import type { AppProps } from "next/app";
import { NextPage } from "next";
import "../styles/tailwind.css";
import { SessionProvider } from "next-auth/react";
export { coloredConsole } from "@documenso/lib";
import { Toaster } from "react-hot-toast";
import "react-tooltip/dist/react-tooltip.css";
export { coloredConsole } from "@documenso/lib";
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
getLayout?: (page: ReactElement) => ReactNode;
@ -17,10 +18,7 @@ type AppPropsWithLayout = AppProps & {
Component: NextPageWithLayout;
};
export default function App({
Component,
pageProps: { session, ...pageProps },
}: AppPropsWithLayout) {
export default function App({ Component, pageProps: { session, ...pageProps } }: AppPropsWithLayout) {
const getLayout = Component.getLayout || ((page: any) => page);
return (
<SessionProvider session={session}>

View File

@ -5,10 +5,7 @@ export default function Document(props) {
let pageProps = props.__NEXT_DATA__?.props?.pageProps;
return (
<Html
className="h-full bg-gray-100 scroll-smooth font-normal antialiased"
lang="en"
>
<Html className="h-full scroll-smooth bg-gray-100 font-normal antialiased" lang="en">
<Head>
<meta name="color-scheme"></meta>
</Head>

View File

@ -1,9 +1,9 @@
import NextAuth, { Session } from "next-auth";
import GitHubProvider from "next-auth/providers/github";
import CredentialsProvider from "next-auth/providers/credentials";
import { ErrorCode } from "@documenso/lib/auth";
import prisma from "@documenso/prisma";
import { verifyPassword } from "@documenso/lib/auth";
import prisma from "@documenso/prisma";
import NextAuth, { Session } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import GitHubProvider from "next-auth/providers/github";
export default NextAuth({
secret: process.env.AUTH_SECRET,
@ -27,8 +27,7 @@ export default NextAuth({
password: {
label: "Password",
type: "password",
placeholder:
"Select a password. Here is some inspiration: https://xkcd.com/936/",
placeholder: "Select a password. Here is some inspiration: https://xkcd.com/936/",
},
},
async authorize(credentials: any) {
@ -57,10 +56,7 @@ export default NextAuth({
throw new Error(ErrorCode.UserMissingPassword);
}
const isCorrectPassword = await verifyPassword(
credentials.password,
user.password
);
const isCorrectPassword = await verifyPassword(credentials.password, user.password);
if (!isCorrectPassword) {
throw new Error(ErrorCode.IncorrectPassword);

View File

@ -1,9 +1,8 @@
import { IdentityProvider } from "@prisma/client";
import { NextApiRequest, NextApiResponse } from "next";
import prisma from "@documenso/prisma";
import { hashPassword } from "@documenso/lib/auth";
import { defaultHandler, defaultResponder } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { IdentityProvider } from "@prisma/client";
async function postHandler(req: NextApiRequest, res: NextApiResponse) {
const { email, password, source } = req.body;

View File

@ -1,13 +1,9 @@
import {
defaultHandler,
defaultResponder,
getUserFromToken,
} from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { NextApiRequest, NextApiResponse } from "next";
import { Document as PrismaDocument } from "@prisma/client";
import { getDocument } from "@documenso/lib/query";
import { defaultHandler, defaultResponder, getUserFromToken } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { addDigitalSignature } from "@documenso/signing/addDigitalSignature";
import { Document as PrismaDocument } from "@prisma/client";
async function getHandler(req: NextApiRequest, res: NextApiResponse) {
const { id: documentId } = req.query;
@ -46,8 +42,7 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) {
document = await getDocument(+documentId, req, res);
}
if (!document)
res.status(404).end(`No document with id ${documentId} found.`);
if (!document) res.status(404).end(`No document with id ${documentId} found.`);
const signaturesCount = await prisma.signature.count({
where: {
@ -61,18 +56,13 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) {
// No need to add a signature, if no one signed yet.
if (signaturesCount > 0) {
signedDocumentAsBase64 = await addDigitalSignature(
document?.document || ""
);
signedDocumentAsBase64 = await addDigitalSignature(document?.document || "");
}
const buffer: Buffer = Buffer.from(signedDocumentAsBase64, "base64");
res.setHeader("Content-Type", "application/pdf");
res.setHeader("Content-Length", buffer.length);
res.setHeader(
"Content-Disposition",
`attachment; filename=${document?.title}`
);
res.setHeader("Content-Disposition", `attachment; filename=${document?.title}`);
return res.status(200).send(buffer);
}

View File

@ -1,13 +1,9 @@
import {
defaultHandler,
defaultResponder,
getUserFromToken,
} from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { NextApiRequest, NextApiResponse } from "next";
import short from "short-uuid";
import { Document as PrismaDocument, FieldType } from "@prisma/client";
import { getDocument } from "@documenso/lib/query";
import { defaultHandler, defaultResponder, getUserFromToken } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { FieldType, Document as PrismaDocument } from "@prisma/client";
import short from "short-uuid";
async function deleteHandler(req: NextApiRequest, res: NextApiResponse) {
const user = await getUserFromToken(req, res);

View File

@ -1,12 +1,8 @@
import {
defaultHandler,
defaultResponder,
getUserFromToken,
} from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { NextApiRequest, NextApiResponse } from "next";
import { Document as PrismaDocument, FieldType } from "@prisma/client";
import { getDocument } from "@documenso/lib/query";
import { defaultHandler, defaultResponder, getUserFromToken } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { FieldType, Document as PrismaDocument } from "@prisma/client";
async function getHandler(req: NextApiRequest, res: NextApiResponse) {
const user = await getUserFromToken(req, res);
@ -61,18 +57,14 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
});
if (!recipient || recipient?.documentId !== +documentId)
return res
.status(401)
.send("Recipient does not have access to this document.");
return res.status(401).send("Recipient does not have access to this document.");
}
if (user) {
const document: PrismaDocument = await getDocument(+documentId, req, res);
// todo entity ownerships checks
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

@ -1,13 +1,9 @@
import {
defaultHandler,
defaultResponder,
getUserFromToken,
} from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { NextApiRequest, NextApiResponse } from "next";
import short from "short-uuid";
import { Document as PrismaDocument } from "@prisma/client";
import { getDocument } from "@documenso/lib/query";
import { defaultHandler, defaultResponder, getUserFromToken } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { Document as PrismaDocument } from "@prisma/client";
import short from "short-uuid";
async function deleteHandler(req: NextApiRequest, res: NextApiResponse) {
const user = await getUserFromToken(req, res);

View File

@ -1,13 +1,9 @@
import {
defaultHandler,
defaultResponder,
getUserFromToken,
} from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { NextApiRequest, NextApiResponse } from "next";
import short from "short-uuid";
import { Document as PrismaDocument } from "@prisma/client";
import { getDocument } from "@documenso/lib/query";
import { defaultHandler, defaultResponder, getUserFromToken } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { Document as PrismaDocument } from "@prisma/client";
import short from "short-uuid";
async function postHandler(req: NextApiRequest, res: NextApiResponse) {
const user = await getUserFromToken(req, res);

View File

@ -1,12 +1,8 @@
import {
defaultHandler,
defaultResponder,
getUserFromToken,
} from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { NextApiRequest, NextApiResponse } from "next";
import { sendSigningRequest } from "@documenso/lib/mail";
import { getDocument } from "@documenso/lib/query";
import { defaultHandler, defaultResponder, getUserFromToken } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { Document as PrismaDocument, SendStatus } from "@prisma/client";
async function postHandler(req: NextApiRequest, res: NextApiResponse) {
@ -23,8 +19,7 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
const document: PrismaDocument = await getDocument(+documentId, req, res);
if (!document)
res.status(404).end(`No document with id ${documentId} found.`);
if (!document) res.status(404).end(`No document with id ${documentId} found.`);
let recipientCondition: any = {
documentId: +documentId,

View File

@ -1,11 +1,11 @@
import { defaultHandler, defaultResponder } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { NextApiRequest, NextApiResponse } from "next";
import { SigningStatus, DocumentStatus } from "@prisma/client";
import { getDocument } from "@documenso/lib/query";
import { Document as PrismaDocument, FieldType } from "@prisma/client";
import { insertImageInPDF, insertTextInPDF } from "@documenso/pdf";
import { sendSigningDoneMail } from "@documenso/lib/mail";
import { getDocument } from "@documenso/lib/query";
import { defaultHandler, defaultResponder } from "@documenso/lib/server";
import { insertImageInPDF, insertTextInPDF } from "@documenso/pdf";
import prisma from "@documenso/prisma";
import { DocumentStatus, SigningStatus } from "@prisma/client";
import { FieldType, Document as PrismaDocument } from "@prisma/client";
async function postHandler(req: NextApiRequest, res: NextApiResponse) {
const { token: recipientToken } = req.query;
@ -115,10 +115,7 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
},
data: {
document: documentWithInserts,
status:
unsignedRecipients.length > 0
? DocumentStatus.PENDING
: DocumentStatus.COMPLETED,
status: unsignedRecipients.length > 0 ? DocumentStatus.PENDING : DocumentStatus.COMPLETED,
},
});
@ -129,8 +126,7 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
});
document.document = documentWithInserts;
if (documentOwner)
await sendSigningDoneMail(recipient, document, documentOwner);
if (documentOwner) await sendSigningDoneMail(recipient, document, documentOwner);
}
return res.status(200).end();
@ -139,9 +135,7 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
if (signedField?.Signature?.signatureImageAsBase64) {
documentWithInserts = await insertImageInPDF(
documentWithInserts,
signedField.Signature
? signedField.Signature?.signatureImageAsBase64
: "",
signedField.Signature ? signedField.Signature?.signatureImageAsBase64 : "",
signedField.positionX,
signedField.positionY,
signedField.page
@ -169,12 +163,8 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
create: {
recipientId: recipient.id,
fieldId: signature.fieldId,
signatureImageAsBase64: signature.signatureImage
? signature.signatureImage
: null,
typedSignature: signature.typedSignature
? signature.typedSignature
: null,
signatureImageAsBase64: signature.signatureImage ? signature.signatureImage : null,
typedSignature: signature.typedSignature ? signature.typedSignature : null,
},
});
}

View File

@ -1,9 +1,9 @@
import { defaultHandler, defaultResponder } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { NextApiRequest, NextApiResponse } from "next";
import { getUserFromToken } from "@documenso/lib/server";
import formidable from "formidable";
import { getDocumentsForUserFromToken } from "@documenso/lib/query";
import { defaultHandler, defaultResponder } from "@documenso/lib/server";
import { getUserFromToken } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import formidable from "formidable";
export const config = {
api: {

View File

@ -1,5 +1,4 @@
import type { NextApiRequest, NextApiResponse } from "next";
import { defaultHandler, defaultResponder } from "@documenso/lib/server";
import prisma from "@documenso/prisma";

View File

@ -1,13 +1,9 @@
import {
defaultHandler,
defaultResponder,
getUserFromToken,
} from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { NextApiRequest, NextApiResponse } from "next";
import { Document as PrismaDocument } from "@prisma/client";
import { getDocument } from "@documenso/lib/query";
import { defaultHandler, defaultResponder, getUserFromToken } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import { addDigitalSignature } from "@documenso/signing/addDigitalSignature";
import { Document as PrismaDocument } from "@prisma/client";
// todo remove before launch
@ -17,10 +13,7 @@ async function getHandler(req: NextApiRequest, res: NextApiResponse) {
const signedDocument = await addDigitalSignature(document.document);
res.setHeader("Content-Type", "application/pdf");
res.setHeader("Content-Length", signedDocument.length);
res.setHeader(
"Content-Disposition",
`attachment; filename=${document.title}`
);
res.setHeader("Content-Disposition", `attachment; filename=${document.title}`);
return res.status(200).send(signedDocument);
}

View File

@ -1,11 +1,6 @@
import {
defaultHandler,
defaultResponder,
getUserFromToken,
} from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import type { NextApiRequest, NextApiResponse } from "next";
import { defaultHandler, defaultResponder, getUserFromToken } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
async function postHandler(req: NextApiRequest, res: NextApiResponse) {
const { method, body } = req;

View File

@ -1,11 +1,6 @@
import {
defaultHandler,
defaultResponder,
getUserFromToken,
} from "@documenso/lib/server";
import prisma from "@documenso/prisma";
import type { NextApiRequest, NextApiResponse } from "next";
import { defaultHandler, defaultResponder, getUserFromToken } from "@documenso/lib/server";
import prisma from "@documenso/prisma";
async function getHandler(req: NextApiRequest, res: NextApiResponse) {
const user = await getUserFromToken(req, res);

View File

@ -1,7 +1,10 @@
import Head from "next/head";
import { ReactElement } from "react";
import Layout from "../components/layout";
import Head from "next/head";
import Link from "next/link";
import { uploadDocument } from "@documenso/features";
import { getDocumentsForUserFromToken } from "@documenso/lib/query";
import { getUserFromToken } from "@documenso/lib/server";
import Layout from "../components/layout";
import type { NextPageWithLayout } from "./_app";
import {
CheckBadgeIcon,
@ -9,15 +12,7 @@ import {
ExclamationTriangleIcon,
UsersIcon,
} from "@heroicons/react/24/outline";
import { uploadDocument } from "@documenso/features";
import {
DocumentStatus,
SendStatus,
SigningStatus,
Document as PrismaDocument,
} from "@prisma/client";
import { getUserFromToken } from "@documenso/lib/server";
import { getDocumentsForUserFromToken } from "@documenso/lib/query";
import { DocumentStatus, Document as PrismaDocument, SendStatus, SigningStatus } from "@prisma/client";
import { truncate } from "fs";
import { Tooltip as ReactTooltip } from "react-tooltip";
@ -55,19 +50,16 @@ const DashboardPage: NextPageWithLayout = (props: any) => {
<div className="py-10 max-sm:px-4">
<header>
<h1 className="text-3xl font-bold leading-tight tracking-tight text-gray-900">
Dashboard
</h1>
<h1 className="text-3xl font-bold leading-tight tracking-tight text-gray-900">Dashboard</h1>
</header>
<dl className="grid gap-5 mt-8 md:grid-cols-3 ">
<dl className="mt-8 grid gap-5 md:grid-cols-3 ">
{stats.map((item) => (
<Link href={item.link} key={item.name}>
<div className="px-4 py-3 overflow-hidden bg-white rounded-lg shadow md:p-6 sm:py-5">
<dt className="text-sm font-medium text-gray-500 truncate ">
<div className="overflow-hidden rounded-lg bg-white px-4 py-3 shadow sm:py-5 md:p-6">
<dt className="truncate text-sm font-medium text-gray-500 ">
<item.icon
className="flex-shrink-0 inline w-5 h-5 mr-3 text-neon sm:w-6 sm:h-6"
aria-hidden="true"
></item.icon>
className="text-neon mr-3 inline h-5 w-5 flex-shrink-0 sm:h-6 sm:w-6"
aria-hidden="true"></item.icon>
{item.name}
</dt>
<dd className="mt-1 text-2xl font-semibold tracking-tight text-gray-900 sm:text-3xl">
@ -92,25 +84,20 @@ const DashboardPage: NextPageWithLayout = (props: any) => {
onClick={() => {
document?.getElementById("fileUploadHelper")?.click();
}}
className="relative block w-full p-12 text-center border-2 border-gray-300 border-dashed rounded-lg cursor-pointer hover:border-neon focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
>
className="hover:border-neon relative block w-full cursor-pointer rounded-lg border-2 border-dashed border-gray-300 p-12 text-center focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">
<svg
className="w-12 h-12 mx-auto text-gray-400"
className="mx-auto h-12 w-12 text-gray-400"
stroke="currentColor"
fill="none"
viewBox="0 00 20 25"
aria-hidden="true"
>
aria-hidden="true">
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m3.75 9v6m3-3H9m1.5-12H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z"
/>
</svg>
<span
id="add_document"
className="mt-2 block text-sm font-medium text-neon"
>
<span id="add_document" className="text-neon mt-2 block text-sm font-medium">
Add a new PDF document.
</span>
</div>
@ -147,9 +134,7 @@ export async function getServerSideProps(context: any) {
const documents: any[] = await getDocumentsForUserFromToken(context);
const drafts: PrismaDocument[] = documents.filter(
(d) => d.status === DocumentStatus.DRAFT
);
const drafts: PrismaDocument[] = documents.filter((d) => d.status === DocumentStatus.DRAFT);
const waiting: any[] = documents.filter(
(e) =>
@ -158,9 +143,7 @@ export async function getServerSideProps(context: any) {
e.Recipient.some((r: any) => r.signingStatus === SigningStatus.NOT_SIGNED)
);
const completed: PrismaDocument[] = documents.filter(
(d) => d.status === DocumentStatus.COMPLETED
);
const completed: PrismaDocument[] = documents.filter((d) => d.status === DocumentStatus.COMPLETED);
return {
props: {

View File

@ -1,7 +1,12 @@
import { ReactElement, useEffect, useState } from "react";
import { NextPageContext } from "next";
import Head from "next/head";
import { useRouter } from "next/router";
import { uploadDocument } from "@documenso/features";
import { deleteDocument, getDocuments } from "@documenso/lib/api";
import { Button, IconButton, SelectBox } from "@documenso/ui";
import Layout from "../components/layout";
import type { NextPageWithLayout } from "./_app";
import Head from "next/head";
import {
ArrowDownTrayIcon,
CheckBadgeIcon,
@ -13,12 +18,7 @@ import {
PlusIcon,
TrashIcon,
} from "@heroicons/react/24/outline";
import { useRouter } from "next/router";
import { uploadDocument } from "@documenso/features";
import { DocumentStatus } from "@prisma/client";
import { Button, IconButton, SelectBox } from "@documenso/ui";
import { NextPageContext } from "next";
import { deleteDocument, getDocuments } from "@documenso/lib/api";
import { Tooltip as ReactTooltip } from "react-tooltip";
const DocumentsPage: NextPageWithLayout = (props: any) => {
@ -42,12 +42,8 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
{ label: "Last 12 months", value: 366 },
];
const [selectedStatusFilter, setSelectedStatusFilter] = useState(
statusFilters[0]
);
const [selectedCreatedFilter, setSelectedCreatedFilter] = useState(
createdFilter[0]
);
const [selectedStatusFilter, setSelectedStatusFilter] = useState(statusFilters[0]);
const [selectedCreatedFilter, setSelectedCreatedFilter] = useState(createdFilter[0]);
const loadDocuments = async () => {
if (!documents.length) setLoading(true);
@ -62,9 +58,7 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
useEffect(() => {
loadDocuments().finally(() => {
setSelectedStatusFilter(
statusFilters.filter(
(status) => status.value === props.filter.toUpperCase()
)[0]
statusFilters.filter((status) => status.value === props.filter.toUpperCase())[0]
);
});
}, []);
@ -79,9 +73,7 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
function filterDocumentes(documents: []): any {
let filteredDocuments = documents.filter(
(d: any) =>
d.status === selectedStatusFilter.value ||
selectedStatusFilter.value === "ALL"
(d: any) => d.status === selectedStatusFilter.value || selectedStatusFilter.value === "ALL"
);
filteredDocuments = filteredDocuments.filter((document: any) =>
@ -98,9 +90,7 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
const today: Date = new Date(); // Today's date
// Calculate the difference between the two dates in days
const diffInDays = Math.floor(
(today.getTime() - documentDate.getTime()) / millisecondsInDay
);
const diffInDays = Math.floor((today.getTime() - documentDate.getTime()) / millisecondsInDay);
console.log(diffInDays);
@ -114,12 +104,10 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
<title>Documents | Documenso</title>
</Head>
<div className="px-4 sm:px-6 lg:px-8">
<div className="sm:flex sm:items-center mt-10">
<div className="mt-10 sm:flex sm:items-center">
<div className="sm:flex-auto">
<header>
<h1 className="text-3xl font-bold leading-tight tracking-tight text-gray-900">
Documents
</h1>
<h1 className="text-3xl font-bold leading-tight tracking-tight text-gray-900">Documents</h1>
</header>
</div>
<div className="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
@ -127,27 +115,24 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
icon={DocumentPlusIcon}
onClick={() => {
document?.getElementById("fileUploadHelper")?.click();
}}
>
}}>
Add Document
</Button>
</div>
</div>
<div className="mt-3 mb-12">
<div className="w-fit block float-right ml-3 mt-7">
{filteredDocuments.length != 1
? filteredDocuments.length + " Documents"
: "1 Document"}
<div className="float-right ml-3 mt-7 block w-fit">
{filteredDocuments.length != 1 ? filteredDocuments.length + " Documents" : "1 Document"}
</div>
<SelectBox
className="w-1/4 block float-right"
className="float-right block w-1/4"
label="Created"
options={createdFilter}
value={selectedCreatedFilter}
onChange={setSelectedCreatedFilter}
/>
<SelectBox
className="w-1/4 block float-right ml-3"
className="float-right ml-3 block w-1/4"
label="Status"
options={statusFilters}
value={selectedStatusFilter}
@ -171,47 +156,28 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
</div>
</div>
</div>
<div
className="mt-28 flex flex-col"
hidden={!documents.length || loading}
>
<div className="mt-28 flex flex-col" hidden={!documents.length || loading}>
<div
className="-my-2 -mx-4 overflow-x-auto sm:-mx-6 lg:-mx-8"
hidden={!documents.length || loading}
>
hidden={!documents.length || loading}>
<div className="inline-block min-w-full py-2 align-middle md:px-6 lg:px-8">
<div className="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
<table className="min-w-full divide-y divide-gray-300">
<thead className="bg-gray-50">
<tr>
<th
scope="col"
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
>
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
Title
</th>
<th
scope="col"
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
>
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
Recipients
</th>
<th
scope="col"
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
>
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
Status
</th>
<th
scope="col"
className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900"
>
<th scope="col" className="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
Created
</th>
<th
scope="col"
className="relative py-3.5 pl-3 pr-4 sm:pr-6"
>
<th scope="col" className="relative py-3.5 pl-3 pr-4 sm:pr-6">
<span className="sr-only">Delete</span>
</th>
</tr>
@ -220,9 +186,8 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
{filteredDocuments.map((document: any, index: number) => (
<tr
key={document.id}
className="hover:bg-gray-100 cursor-pointer"
onClick={(event) => showDocument(document.id)}
>
className="cursor-pointer hover:bg-gray-100"
onClick={(event) => showDocument(document.id)}>
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
{document.title || "#" + document.id}
</td>
@ -232,43 +197,32 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
{item.sendStatus === "NOT_SENT" ? (
<span
id="sent_icon"
className="inline-block flex-shrink-0 rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800"
>
{item.name
? item.name + " <" + item.email + ">"
: item.email}
className="inline-block flex-shrink-0 rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800">
{item.name ? item.name + " <" + item.email + ">" : item.email}
</span>
) : (
""
)}
{item.sendStatus === "SENT" &&
item.readStatus !== "OPENED" ? (
{item.sendStatus === "SENT" && item.readStatus !== "OPENED" ? (
<span id="sent_icon">
<span
id="sent_icon"
className="inline-block flex-shrink-0 rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-green-800"
>
<EnvelopeIcon className="inline h-5 mr-1"></EnvelopeIcon>
{item.name
? item.name + " <" + item.email + ">"
: item.email}
className="inline-block flex-shrink-0 rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-green-800">
<EnvelopeIcon className="mr-1 inline h-5"></EnvelopeIcon>
{item.name ? item.name + " <" + item.email + ">" : item.email}
</span>
</span>
) : (
""
)}
{item.readStatus === "OPENED" &&
item.signingStatus === "NOT_SIGNED" ? (
{item.readStatus === "OPENED" && item.signingStatus === "NOT_SIGNED" ? (
<span id="read_icon">
<span
id="sent_icon"
className="inline-block flex-shrink-0 rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-green-800"
>
<CheckIcon className="inline h-5 -mr-2"></CheckIcon>
<CheckIcon className="inline h-5 mr-1"></CheckIcon>
{item.name
? item.name + " <" + item.email + ">"
: item.email}
className="inline-block flex-shrink-0 rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-green-800">
<CheckIcon className="-mr-2 inline h-5"></CheckIcon>
<CheckIcon className="mr-1 inline h-5"></CheckIcon>
{item.name ? item.name + " <" + item.email + ">" : item.email}
</span>
</span>
) : (
@ -277,8 +231,7 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
{item.signingStatus === "SIGNED" ? (
<span id="signed_icon">
<span className="inline-block flex-shrink-0 rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800">
<CheckBadgeIcon className="inline h-5 mr-1"></CheckBadgeIcon>{" "}
{item.email}
<CheckBadgeIcon className="mr-1 inline h-5"></CheckBadgeIcon> {item.email}
</span>
</span>
) : (
@ -307,9 +260,8 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
{formatDocumentStatus(document.status)}
<p>
<small hidden={document.Recipient.length === 0}>
{document.Recipient.filter(
(r: any) => r.signingStatus === "SIGNED"
).length || 0}
{document.Recipient.filter((r: any) => r.signingStatus === "SIGNED").length ||
0}
/{document.Recipient.length || 0}
</small>
</p>
@ -342,30 +294,20 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
onClick={(event: any) => {
event.preventDefault();
event.stopPropagation();
if (
confirm(
"Are you sure you want to delete this document"
)
) {
if (confirm("Are you sure you want to delete this document")) {
const documentsWithoutIndex = [...documents];
const removedItem: any =
documentsWithoutIndex.splice(index, 1);
const removedItem: any = documentsWithoutIndex.splice(index, 1);
setDocuments(documentsWithoutIndex);
deleteDocument(document.id)
.catch((err) => {
documentsWithoutIndex.splice(
index,
0,
removedItem
);
documentsWithoutIndex.splice(index, 0, removedItem);
setDocuments(documentsWithoutIndex);
})
.then(() => {
loadDocuments();
});
}
}}
></IconButton>
}}></IconButton>
<span className="sr-only">, {document.name}</span>
</div>
</td>
@ -374,29 +316,21 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
</tbody>
</table>
</div>
<div
hidden={filteredDocuments.length > 0}
className="mx-auto w-fit mt-12 p-3"
>
<FunnelIcon className="w-5 inline mr-1 align-middle" /> Nothing
here. Maybe try a different filter.
<div hidden={filteredDocuments.length > 0} className="mx-auto mt-12 w-fit p-3">
<FunnelIcon className="mr-1 inline w-5 align-middle" /> Nothing here. Maybe try a different
filter.
</div>
</div>
</div>
</div>
</div>
<div
className="text-center mt-24"
id="empty"
hidden={documents.length > 0 || loading}
>
<div className="mt-24 text-center" id="empty" hidden={documents.length > 0 || loading}>
<svg
className="mx-auto h-12 w-12 text-gray-400"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
aria-hidden="true"
>
aria-hidden="true">
<path
strokeLinecap="round"
strokeLinejoin="round"
@ -405,16 +339,13 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
</svg>
<h3 className="mt-2 text-sm font-medium text-gray-900">No documents</h3>
<p className="mt-1 text-sm text-gray-500">
Get started by adding a document. Any PDF will do.
</p>
<p className="mt-1 text-sm text-gray-500">Get started by adding a document. Any PDF will do.</p>
<div className="mt-6">
<Button
icon={PlusIcon}
onClick={() => {
document?.getElementById("fileUploadHelper")?.click();
}}
>
}}>
Add Document
</Button>
<input
@ -428,11 +359,7 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
/>
</div>
</div>
<ReactTooltip
anchorId="empty"
place="bottom"
content="No preparation needed. Any PDF will do."
/>
<ReactTooltip anchorId="empty" place="bottom" content="No preparation needed. Any PDF will do." />
</>
);
};

View File

@ -1,20 +1,16 @@
import { ReactElement } from "react";
import Layout from "../../../components/layout";
import { NextPageWithLayout } from "../../_app";
import Link from "next/link";
import { useRouter } from "next/router";
import { NEXT_PUBLIC_WEBAPP_URL } from "@documenso/lib";
import { getUserFromToken } from "@documenso/lib/server";
import Link from "next/link";
import { DocumentStatus } from "@prisma/client";
import {
InformationCircleIcon,
PaperAirplaneIcon,
UsersIcon,
} from "@heroicons/react/24/outline";
import { getDocument } from "@documenso/lib/query";
import { Document as PrismaDocument } from "@prisma/client";
import { Button, Breadcrumb } from "@documenso/ui";
import { getUserFromToken } from "@documenso/lib/server";
import { Breadcrumb, Button } from "@documenso/ui";
import PDFEditor from "../../../components/editor/pdf-editor";
import Layout from "../../../components/layout";
import { NextPageWithLayout } from "../../_app";
import { InformationCircleIcon, PaperAirplaneIcon, UsersIcon } from "@heroicons/react/24/outline";
import { DocumentStatus } from "@prisma/client";
import { Document as PrismaDocument } from "@prisma/client";
const DocumentsDetailPage: NextPageWithLayout = (props: any) => {
const router = useRouter();
@ -32,8 +28,7 @@ const DocumentsDetailPage: NextPageWithLayout = (props: any) => {
},
{
title: props.document.title,
href:
NEXT_PUBLIC_WEBAPP_URL + "/documents/" + props.document.id,
href: NEXT_PUBLIC_WEBAPP_URL + "/documents/" + props.document.id,
},
]}
/>
@ -45,10 +40,7 @@ const DocumentsDetailPage: NextPageWithLayout = (props: any) => {
</h2>
<div className="mt-1 flex flex-col sm:mt-0 sm:flex-row sm:flex-wrap sm:space-x-6">
<div className="mt-2 flex items-center text-sm text-gray-500">
<UsersIcon
className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400"
aria-hidden="true"
/>
<UsersIcon className="mr-1.5 h-5 w-5 flex-shrink-0 text-gray-400" aria-hidden="true" />
<Link href={`/documents/${props.document.id}/recipients`}>
{props?.document?.Recipient?.length} Recipients
@ -67,21 +59,11 @@ const DocumentsDetailPage: NextPageWithLayout = (props: any) => {
<Button
icon={PaperAirplaneIcon}
className="ml-3"
href={
NEXT_PUBLIC_WEBAPP_URL +
"/documents/" +
props.document.id +
"/recipients"
}
href={NEXT_PUBLIC_WEBAPP_URL + "/documents/" + props.document.id + "/recipients"}
onClick={() => {
if (
confirm(
`Send document out to ${props?.document?.Recipient?.length} recipients?`
)
) {
if (confirm(`Send document out to ${props?.document?.Recipient?.length} recipients?`)) {
}
}}
>
}}>
Prepare to Send
</Button>
</div>
@ -120,11 +102,7 @@ export async function getServerSideProps(context: any) {
const { id: documentId } = context.query;
try {
const document: PrismaDocument = await getDocument(
+documentId,
context.req,
context.res
);
const document: PrismaDocument = await getDocument(+documentId, context.req, context.res);
return {
props: {

View File

@ -1,25 +1,24 @@
import Head from "next/head";
import { ReactElement, useRef, useState } from "react";
import Head from "next/head";
import { NEXT_PUBLIC_WEBAPP_URL, classNames } from "@documenso/lib";
import { createOrUpdateRecipient, deleteRecipient, sendSigningRequests } from "@documenso/lib/api";
import { getDocument } from "@documenso/lib/query";
import { getUserFromToken } from "@documenso/lib/server";
import { Breadcrumb, Button, Dialog, IconButton } from "@documenso/ui";
import Layout from "../../../components/layout";
import { NextPageWithLayout } from "../../_app";
import { classNames, NEXT_PUBLIC_WEBAPP_URL } from "@documenso/lib";
import {
ArrowDownTrayIcon,
CheckBadgeIcon,
CheckIcon,
EnvelopeIcon,
PaperAirplaneIcon,
PencilSquareIcon,
TrashIcon,
UserPlusIcon,
EnvelopeIcon,
XMarkIcon,
} from "@heroicons/react/24/outline";
import { getUserFromToken } from "@documenso/lib/server";
import { getDocument } from "@documenso/lib/query";
import { Document as PrismaDocument, DocumentStatus } from "@prisma/client";
import { Breadcrumb, Button, Dialog, IconButton } from "@documenso/ui";
import { createOrUpdateRecipient, deleteRecipient, sendSigningRequests } from "@documenso/lib/api";
import { DocumentStatus, Document as PrismaDocument } from "@prisma/client";
import { FormProvider, useFieldArray, useForm, useWatch } from "react-hook-form";
export type FormValues = {
@ -71,23 +70,22 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
<Head>
<title>{title}</title>
</Head>
<div className="px-6 mt-10 sm:px-0">
<div className="mt-10 px-6 sm:px-0">
<div>
<Breadcrumb document={props.document} items={breadcrumbItems} />
</div>
<div className="mt-2 md:flex md:items-center md:justify-between">
<div className="flex-1 min-w-0">
<div className="min-w-0 flex-1">
<h2 className="text-2xl font-bold leading-7 text-gray-900 sm:truncate sm:text-3xl sm:tracking-tight">
{props.document.title}
</h2>
</div>
<div className="flex flex-shrink-0 mt-4 md:mt-0 md:ml-4">
<div className="mt-4 flex flex-shrink-0 md:mt-0 md:ml-4">
<Button
icon={ArrowDownTrayIcon}
color="secondary"
className="mr-2"
href={"/api/documents/" + props.document.id}
>
href={"/api/documents/" + props.document.id}>
Download
</Button>
<Button
@ -95,8 +93,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
disabled={props.document.status === DocumentStatus.COMPLETED}
color={props.document.status === DocumentStatus.COMPLETED ? "primary" : "secondary"}
className="mr-2"
href={breadcrumbItems[1].href}
>
href={breadcrumbItems[1].href}>
Edit Document
</Button>
<Button
@ -108,43 +105,33 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
}}
disabled={
(formValues.length || 0) === 0 ||
!formValues.some(
(r: any) => r.email && !hasEmailError(r) && r.sendStatus === "NOT_SENT"
) ||
!formValues.some((r: any) => r.email && !hasEmailError(r) && r.sendStatus === "NOT_SENT") ||
loading
}
>
}>
Send
</Button>
</div>
</div>
<div className="p-4 mt-10 overflow-hidden bg-white rounded-md shadow sm:p-6">
<div className="pb-3 border-b border-gray-200 sm:pb-5">
<div className="mt-10 overflow-hidden rounded-md bg-white p-4 shadow sm:p-6">
<div className="border-b border-gray-200 pb-3 sm:pb-5">
<h3 className="text-lg font-medium leading-6 text-gray-900 ">Signers</h3>
<p className="max-w-4xl mt-2 text-sm text-gray-500">
The people who will sign the document.
</p>
<p className="mt-2 max-w-4xl text-sm text-gray-500">The people who will sign the document.</p>
</div>
<FormProvider {...form}>
<form
onChange={() => {
trigger();
}}
>
}}>
<ul role="list" className="divide-y divide-gray-200">
{fields.map((item: any, index: number) => (
<li
key={index}
className="w-full px-2 py-3 border-0 hover:bg-green-50 group sm:py-4"
>
<li key={index} className="group w-full border-0 px-2 py-3 hover:bg-green-50 sm:py-4">
<div id="container" className="block w-full lg:flex lg:justify-between">
<div className="block space-y-2 md:space-x-2 md:space-y-0 md:flex">
<div className="block space-y-2 md:flex md:space-x-2 md:space-y-0">
<div
className={classNames(
"md:w-[250px] rounded-md border border-gray-300 px-3 py-2 shadow-sm focus-within:border-neon focus-within:ring-1 focus-within:ring-neon",
"focus-within:border-neon focus-within:ring-neon rounded-md border border-gray-300 px-3 py-2 shadow-sm focus-within:ring-1 md:w-[250px]",
item.sendStatus === "SENT" ? "bg-gray-100" : ""
)}
>
)}>
<label htmlFor="name" className="block text-xs font-medium text-gray-900">
Email
</label>
@ -170,7 +157,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
documentId: props.document.id,
});
}}
className="block w-full p-0 text-gray-900 placeholder-gray-500 disabled:bg-neutral-100 border-0 outline-none sm:text-sm bg-inherit"
className="block w-full border-0 bg-inherit p-0 text-gray-900 placeholder-gray-500 outline-none disabled:bg-neutral-100 sm:text-sm"
placeholder="john.dorian@loremipsum.com"
/>
{errors?.signers?.[index] ? (
@ -183,10 +170,9 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
</div>
<div
className={classNames(
"md:w-[250px] rounded-md border border-gray-300 px-3 py-2 shadow-sm focus-within:border-neon focus-within:ring-1 focus-within:ring-neon",
"focus-within:border-neon focus-within:ring-neon rounded-md border border-gray-300 px-3 py-2 shadow-sm focus-within:ring-1 md:w-[250px]",
item.sendStatus === "SENT" ? "bg-gray-100" : ""
)}
>
)}>
<label htmlFor="name" className="block text-xs font-medium text-gray-900">
Name (optional)
</label>
@ -209,19 +195,18 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
documentId: props.document.id,
});
}}
className="block w-full p-0 text-gray-900 placeholder-gray-500 disabled:bg-neutral-100 border-0 outline-none sm:text-sm bg-inherit"
className="block w-full border-0 bg-inherit p-0 text-gray-900 placeholder-gray-500 outline-none disabled:bg-neutral-100 sm:text-sm"
placeholder="John Dorian"
/>
</div>
</div>
<div className="flex items-center space-x-2 lg:ml-2">
<div className="flex mb-2 mr-2 lg:mr-0">
<div className="mb-2 mr-2 flex lg:mr-0">
<div key={item.id} className="space-x-2">
{item.sendStatus === "NOT_SENT" ? (
<span
id="sent_icon"
className="inline-block mt-3 flex-shrink-0 rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-gray-800"
>
className="mt-3 inline-block flex-shrink-0 rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-gray-800">
Not Sent
</span>
) : (
@ -231,9 +216,8 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
<span id="sent_icon">
<span
id="sent_icon"
className="inline-block mt-3 flex-shrink-0 rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-gray-800 "
>
<CheckIcon className="inline h-5 mr-1" /> Sent
className="mt-3 inline-block flex-shrink-0 rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-gray-800 ">
<CheckIcon className="mr-1 inline h-5" /> Sent
</span>
</span>
) : (
@ -243,10 +227,9 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
<span id="read_icon">
<span
id="sent_icon"
className="inline-block mt-3 flex-shrink-0 rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-gray-800"
>
<CheckIcon className="inline h-5 -mr-2"></CheckIcon>
<CheckIcon className="inline h-5 mr-1"></CheckIcon>
className="mt-3 inline-block flex-shrink-0 rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-gray-800">
<CheckIcon className="-mr-2 inline h-5"></CheckIcon>
<CheckIcon className="mr-1 inline h-5"></CheckIcon>
Seen
</span>
</span>
@ -257,9 +240,8 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
<span id="signed_icon">
<span
id="sent_icon"
className="inline-block mt-3 flex-shrink-0 rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800"
>
<CheckBadgeIcon className="inline h-5 mr-1"></CheckBadgeIcon>
className="mt-3 inline-block flex-shrink-0 rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800">
<CheckBadgeIcon className="mr-1 inline h-5"></CheckBadgeIcon>
Signed
</span>
</span>
@ -268,7 +250,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
)}
</div>
</div>
<div className="flex mr-1">
<div className="mr-1 flex">
<IconButton
icon={PaperAirplaneIcon}
disabled={
@ -286,8 +268,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
setLoading(false);
});
}
}}
>
}}>
Resend
</IconButton>
<IconButton
@ -320,8 +301,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
}).then((res) => {
append(res);
});
}}
>
}}>
Add Signer
</Button>
</form>
@ -336,7 +316,7 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
open={open}
setLoading={setLoading}
setOpen={setOpen}
icon={<EnvelopeIcon className="w-6 h-6 text-green-600" aria-hidden="true" />}
icon={<EnvelopeIcon className="h-6 w-6 text-green-600" aria-hidden="true" />}
/>
</>
);

View File

@ -1,11 +1,11 @@
import prisma from "@documenso/prisma";
import Head from "next/head";
import { NextPageWithLayout } from "../../_app";
import { ReadStatus } from "@prisma/client";
import PDFSigner from "../../../components/editor/pdf-signer";
import Link from "next/link";
import prisma from "@documenso/prisma";
import PDFSigner from "../../../components/editor/pdf-signer";
import { NextPageWithLayout } from "../../_app";
import { ClockIcon } from "@heroicons/react/24/outline";
import { FieldType, DocumentStatus } from "@prisma/client";
import { ReadStatus } from "@prisma/client";
import { DocumentStatus, FieldType } from "@prisma/client";
const SignPage: NextPageWithLayout = (props: any) => {
return (
@ -14,36 +14,22 @@ const SignPage: NextPageWithLayout = (props: any) => {
<title>Sign | Documenso</title>
</Head>
{!props.expired ? (
<PDFSigner
document={props.document}
recipient={props.recipient}
fields={props.fields}
/>
<PDFSigner document={props.document} recipient={props.recipient} fields={props.fields} />
) : (
<>
<div className="mx-auto w-fit px-4 py-16 sm:px-6 sm:py-24 lg:px-8">
<ClockIcon className="text-neon w-10 inline mr-1"></ClockIcon>
<h1 className="text-base font-medium text-neon inline align-middle">
Time flies.
</h1>
<p className="mt-2 text-4xl font-bold tracking-tight">
This signing link is expired.
</p>
<ClockIcon className="text-neon mr-1 inline w-10"></ClockIcon>
<h1 className="text-neon inline align-middle text-base font-medium">Time flies.</h1>
<p className="mt-2 text-4xl font-bold tracking-tight">This signing link is expired.</p>
<p className="mt-2 text-base text-gray-500">
Please ask{" "}
{props.document.User.name
? `${props.document.User.name}`
: `the sender`}{" "}
to resend it.
Please ask {props.document.User.name ? `${props.document.User.name}` : `the sender`} to resend
it.
</p>
<div className="mx-auto w-fit text-xl pt-20"></div>
<div className="mx-auto w-fit pt-20 text-xl"></div>
</div>
<div>
<div className="relative mx-96">
<div
className="absolute inset-0 flex items-center"
aria-hidden="true"
>
<div className="absolute inset-0 flex items-center" aria-hidden="true">
<div className="w-full border-t border-gray-300" />
</div>
<div className="relative flex justify-center"></div>
@ -51,10 +37,7 @@ const SignPage: NextPageWithLayout = (props: any) => {
</div>
<p className="mt-4 text-center text-sm text-gray-600">
Want to send of your own?{" "}
<Link
href="/signup?source=expired"
className="font-medium text-neon hover:text-neon"
>
<Link href="/signup?source=expired" className="text-neon hover:text-neon font-medium">
Create your own Account
</Link>
</p>
@ -118,13 +101,9 @@ export async function getServerSideProps(context: any) {
return {
props: {
recipient: JSON.parse(JSON.stringify(recipient)),
document: JSON.parse(
JSON.stringify({ ...recipient.Document, document: "" })
),
document: JSON.parse(JSON.stringify({ ...recipient.Document, document: "" })),
fields: JSON.parse(JSON.stringify(unsignedFields)),
expired: recipient.expired
? new Date(recipient.expired) < new Date()
: false,
expired: recipient.expired ? new Date(recipient.expired) < new Date() : false,
},
};
}

View File

@ -1,16 +1,14 @@
import prisma from "@documenso/prisma";
import Head from "next/head";
import { NextPageWithLayout } from "../../_app";
import { ArrowDownTrayIcon, CheckBadgeIcon } from "@heroicons/react/24/outline";
import { Button, IconButton } from "@documenso/ui";
import Link from "next/link";
import { useRouter } from "next/router";
import prisma from "@documenso/prisma";
import { Button, IconButton } from "@documenso/ui";
import { NextPageWithLayout } from "../../_app";
import { ArrowDownTrayIcon, CheckBadgeIcon } from "@heroicons/react/24/outline";
const Signed: NextPageWithLayout = (props: any) => {
const router = useRouter();
const allRecipientsSigned = props.document.Recipient?.every(
(r: any) => r.signingStatus === "SIGNED"
);
const allRecipientsSigned = props.document.Recipient?.every((r: any) => r.signingStatus === "SIGNED");
return (
<>
@ -18,53 +16,31 @@ const Signed: NextPageWithLayout = (props: any) => {
<title>Sign | Documenso</title>
</Head>
<div className="mx-auto w-fit px-4 py-16 sm:px-6 sm:py-24 lg:px-8">
<CheckBadgeIcon className="text-neon w-10 inline mr-1"></CheckBadgeIcon>
<h1 className="text-base font-medium text-neon inline align-middle">
It's done!
</h1>
<p className="mt-2 text-4xl font-bold tracking-tight">
You signed "{props.document.title}"
</p>
<p
className="mt-2 text-base text-gray-500 max-w-sm"
hidden={allRecipientsSigned}
>
<CheckBadgeIcon className="text-neon mr-1 inline w-10"></CheckBadgeIcon>
<h1 className="text-neon inline align-middle text-base font-medium">It's done!</h1>
<p className="mt-2 text-4xl font-bold tracking-tight">You signed "{props.document.title}"</p>
<p className="mt-2 max-w-sm text-base text-gray-500" hidden={allRecipientsSigned}>
You will be notfied when all recipients have signed.
</p>
<p
className="mt-2 text-base text-gray-500 max-w-sm"
hidden={!allRecipientsSigned}
>
<p className="mt-2 max-w-sm text-base text-gray-500" hidden={!allRecipientsSigned}>
All recipients signed.
</p>
<div
className="mx-auto w-fit text-xl pt-20"
hidden={!allRecipientsSigned}
>
<div className="mx-auto w-fit pt-20 text-xl" hidden={!allRecipientsSigned}>
<Button
icon={ArrowDownTrayIcon}
color="secondary"
onClick={(event: any) => {
event.preventDefault();
event.stopPropagation();
router.push(
"/api/documents/" +
props.document.id +
"?token=" +
props.recipient.token
);
}}
>
router.push("/api/documents/" + props.document.id + "?token=" + props.recipient.token);
}}>
Download "{props.document.title}"
</Button>
</div>
</div>
<div>
<div className="relative mx-96">
<div
className="absolute inset-0 flex items-center"
aria-hidden="true"
>
<div className="absolute inset-0 flex items-center" aria-hidden="true">
<div className="w-full border-t border-gray-300" />
</div>
<div className="relative flex justify-center"></div>
@ -72,10 +48,7 @@ const Signed: NextPageWithLayout = (props: any) => {
</div>
<p className="mt-4 text-center text-sm text-gray-600">
Want to send slick signing links like this one?{" "}
<Link
href="https://documenso.com"
className="font-medium text-neon hover:text-neon"
>
<Link href="https://documenso.com" className="text-neon hover:text-neon font-medium">
Hosted Documenso is coming soon
</Link>
</p>

View File

@ -1,2 +1,3 @@
import SettingsPage from ".";
export default SettingsPage;

View File

@ -1,2 +1,3 @@
import SettingsPage from ".";
export default SettingsPage;

View File

@ -1,2 +1,3 @@
import SettingsPage from ".";
export default SettingsPage;