mirror of
https://github.com/documenso/documenso.git
synced 2025-11-17 02:01:33 +10:00
Merge branch 'main' into feat/DOC-170-add-name-field
This commit is contained in:
@ -1,4 +0,0 @@
|
||||
{
|
||||
"presets": ["next/babel"],
|
||||
"plugins": []
|
||||
}
|
||||
@ -1,3 +1,8 @@
|
||||
{
|
||||
"extends": ["next/babel", "next/core-web-vitals"]
|
||||
}
|
||||
"extends": [
|
||||
"next/core-web-vitals"
|
||||
],
|
||||
"rules": {
|
||||
"react/no-unescaped-entities": "off"
|
||||
}
|
||||
}
|
||||
@ -198,12 +198,11 @@ export default function PDFSigner(props: any) {
|
||||
: props.document.User.email}{" "}
|
||||
would like you to sign this document.
|
||||
</p>
|
||||
<p className="mt-3 text-sm md:mt-0 md:ml-6">
|
||||
<p className="mt-3 text-sm md:mt-0 md:ml-6 text-right md:text-inherit">
|
||||
<Button
|
||||
disabled={!signingDone}
|
||||
color="secondary"
|
||||
icon={CheckBadgeIcon}
|
||||
className="float-right"
|
||||
onClick={() => {
|
||||
signDocument(props.document, localSignatures, `${router.query.token}`).then(
|
||||
() => {
|
||||
|
||||
@ -5,6 +5,7 @@ import { Button, IconButton } from "@documenso/ui";
|
||||
import { Dialog, Transition } from "@headlessui/react";
|
||||
import { LanguageIcon, PencilIcon, TrashIcon } from "@heroicons/react/24/outline";
|
||||
import SignatureCanvas from "react-signature-canvas";
|
||||
import { useDebouncedValue } from "../../hooks/use-debounced-value";
|
||||
|
||||
const tabs = [
|
||||
{ name: "Type", icon: LanguageIcon, current: true },
|
||||
@ -15,6 +16,9 @@ export default function SignatureDialog(props: any) {
|
||||
const [currentTab, setCurrentTab] = useState(tabs[0]);
|
||||
const [typedSignature, setTypedSignature] = useState("");
|
||||
const [signatureEmpty, setSignatureEmpty] = useState(true);
|
||||
// This is a workaround to prevent the canvas from being rendered when the dialog is closed
|
||||
// we also need the debounce to avoid rendering while transitions are occuring.
|
||||
const showCanvas = useDebouncedValue<boolean>(props.open, 1);
|
||||
let signCanvasRef: any | undefined;
|
||||
|
||||
useEffect(() => {
|
||||
@ -85,7 +89,7 @@ export default function SignatureDialog(props: any) {
|
||||
</div>
|
||||
{isCurrentTab("Type") ? (
|
||||
<div>
|
||||
<div className="my-8 mb-3 border-b border-gray-300">
|
||||
<div className="my-7 mb-3 border-b border-gray-300">
|
||||
<input
|
||||
value={typedSignature}
|
||||
onChange={(e) => {
|
||||
@ -98,7 +102,7 @@ export default function SignatureDialog(props: any) {
|
||||
placeholder="Kindly type your name"
|
||||
/>
|
||||
</div>
|
||||
<div className="float-right">
|
||||
<div className="flex flex-row-reverse items-center gap-x-3">
|
||||
<Button
|
||||
color="secondary"
|
||||
onClick={() => {
|
||||
@ -126,47 +130,55 @@ export default function SignatureDialog(props: any) {
|
||||
""
|
||||
)}
|
||||
{isCurrentTab("Draw") ? (
|
||||
<div className="">
|
||||
<SignatureCanvas
|
||||
ref={(ref) => {
|
||||
signCanvasRef = ref;
|
||||
}}
|
||||
canvasProps={{
|
||||
className: "sigCanvas border-b b-2 border-slate w-full h-full mb-3",
|
||||
}}
|
||||
clearOnResize={true}
|
||||
onEnd={() => {
|
||||
setSignatureEmpty(signCanvasRef?.isEmpty());
|
||||
}}
|
||||
/>
|
||||
<IconButton
|
||||
className="float-left block"
|
||||
icon={TrashIcon}
|
||||
onClick={() => {
|
||||
signCanvasRef?.clear();
|
||||
setSignatureEmpty(signCanvasRef?.isEmpty());
|
||||
}}></IconButton>
|
||||
<div className="float-right mt-10">
|
||||
<Button
|
||||
color="secondary"
|
||||
onClick={() => {
|
||||
props.onClose();
|
||||
props.setOpen(false);
|
||||
setCurrent(tabs[0]);
|
||||
}}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
className="ml-3"
|
||||
onClick={() => {
|
||||
props.onClose({
|
||||
type: "draw",
|
||||
signatureImage: signCanvasRef.toDataURL("image/png"),
|
||||
});
|
||||
<div className="" key={props.open ? "closed" : "open"}>
|
||||
{showCanvas && (
|
||||
<SignatureCanvas
|
||||
ref={(ref) => {
|
||||
signCanvasRef = ref;
|
||||
}}
|
||||
disabled={signatureEmpty}>
|
||||
Sign
|
||||
</Button>
|
||||
canvasProps={{
|
||||
className: "sigCanvas border-b b-2 border-slate w-full h-full mb-3",
|
||||
}}
|
||||
clearOnResize={true}
|
||||
onEnd={() => {
|
||||
setSignatureEmpty(signCanvasRef?.isEmpty());
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<IconButton
|
||||
className="block"
|
||||
icon={TrashIcon}
|
||||
onClick={() => {
|
||||
signCanvasRef?.clear();
|
||||
setSignatureEmpty(signCanvasRef?.isEmpty());
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className="flex flex-row-reverse items-center gap-x-3">
|
||||
<Button
|
||||
color="secondary"
|
||||
onClick={() => {
|
||||
props.onClose();
|
||||
props.setOpen(false);
|
||||
setCurrent(tabs[0]);
|
||||
}}>
|
||||
Cancel
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
className="ml-3"
|
||||
onClick={() => {
|
||||
props.onClose({
|
||||
type: "draw",
|
||||
signatureImage: signCanvasRef.toDataURL("image/png"),
|
||||
});
|
||||
}}
|
||||
disabled={signatureEmpty}>
|
||||
Sign
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
|
||||
@ -111,7 +111,7 @@ export default function Login(props: any) {
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="text-sm">
|
||||
<a href="#" className="text-neon hover:text-neon font-medium">
|
||||
<a href="#" className="text-gray-500 hover:text-neon-700 font-medium">
|
||||
Forgot your password?
|
||||
</a>
|
||||
</div>
|
||||
@ -123,7 +123,7 @@ export default function Login(props: any) {
|
||||
className="group relative flex w-full">
|
||||
<span className="absolute inset-y-0 left-0 flex items-center pl-3">
|
||||
<LockClosedIcon
|
||||
className="text-neon-dark group-hover:text-neon h-5 w-5 disabled:disabled:bg-gray-600 disabled:group-hover:bg-gray-600"
|
||||
className="text-neon-700 group-hover:text-neon-dark-700 h-5 w-5 disabled:disabled:bg-gray-600 disabled:group-hover:bg-gray-600 duration-200"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</span>
|
||||
@ -141,7 +141,7 @@ export default function Login(props: any) {
|
||||
{props.allowSignup ? (
|
||||
<p className="mt-2 text-center text-sm text-gray-600">
|
||||
Are you new here?{" "}
|
||||
<Link href="/signup" className="text-neon hover:text-neon font-medium">
|
||||
<Link href="/signup" className="text-gray-500 hover:text-neon-700 duration-200 font-medium">
|
||||
Create a new Account
|
||||
</Link>
|
||||
</p>
|
||||
@ -151,7 +151,7 @@ export default function Login(props: any) {
|
||||
<Link
|
||||
href="https://documenso.com"
|
||||
className="text-neon hover:text-neon font-medium">
|
||||
Hosted Documenso will be availible soon™
|
||||
Hosted Documenso will be available soon™
|
||||
</Link>
|
||||
</p>
|
||||
)}
|
||||
|
||||
@ -187,7 +187,7 @@ export default function Signup(props: { source: string }) {
|
||||
</div>
|
||||
<p className="mt-2 text-center text-sm text-gray-600">
|
||||
Already have an account?{" "}
|
||||
<Link href="/login" className="text-neon hover:text-neon font-medium">
|
||||
<Link href="/login" className="text-gray-500 hover:text-neon-700 font-medium">
|
||||
Sign In
|
||||
</Link>
|
||||
</p>
|
||||
|
||||
18
apps/web/hooks/use-debounced-value.ts
Normal file
18
apps/web/hooks/use-debounced-value.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export function useDebouncedValue<T>(value: T, delay: number) {
|
||||
// State and setters for debounced value
|
||||
const [debouncedValue, setDebouncedValue] = useState(value);
|
||||
|
||||
useEffect(() => {
|
||||
const handler = setTimeout(() => {
|
||||
setDebouncedValue(value);
|
||||
}, delay);
|
||||
|
||||
return () => {
|
||||
clearTimeout(handler);
|
||||
};
|
||||
}, [value, delay]);
|
||||
|
||||
return debouncedValue;
|
||||
}
|
||||
@ -16,27 +16,16 @@
|
||||
"@headlessui/react": "^1.7.4",
|
||||
"@heroicons/react": "^2.0.13",
|
||||
"@pdf-lib/fontkit": "^1.1.1",
|
||||
"@tailwindcss/forms": "^0.5.3",
|
||||
"@types/bcryptjs": "^2.4.2",
|
||||
"@types/filesystem": "^0.0.32",
|
||||
"@types/react-dom": "18.0.9",
|
||||
"avatar-from-initials": "^1.0.3",
|
||||
"base64-arraybuffer": "^1.0.2",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"dotenv": "^16.0.3",
|
||||
"eslint": "8.27.0",
|
||||
"eslint-config-next": "13.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"formidable": "^3.2.5",
|
||||
"install": "^0.13.0",
|
||||
"next": "13.0.3",
|
||||
"next-auth": ">=4.20.1",
|
||||
"next-transpile-modules": "^10.0.0",
|
||||
"next": "13.2.4",
|
||||
"next-auth": "^4.22.0",
|
||||
"node-forge": "^1.3.1",
|
||||
"node-signpdf": "^1.5.0",
|
||||
"nodemailer": "^6.9.0",
|
||||
"nodemailer-sendgrid": "^1.0.3",
|
||||
"npm": "^9.1.3",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"placeholder-loading": "^0.6.0",
|
||||
"react": "18.2.0",
|
||||
@ -46,12 +35,14 @@
|
||||
"react-pdf": "^6.2.2",
|
||||
"react-resizable": "^3.0.4",
|
||||
"react-tooltip": "^5.7.2",
|
||||
"sass": "^1.57.1",
|
||||
"short-uuid": "^4.2.2",
|
||||
"string-to-color": "^2.2.2",
|
||||
"typescript": "4.8.4"
|
||||
"string-to-color": "^2.2.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/forms": "^0.5.3",
|
||||
"@types/bcryptjs": "^2.4.2",
|
||||
"@types/filesystem": "^0.0.32",
|
||||
"@types/react-dom": "18.0.9",
|
||||
"@types/formidable": "^2.0.5",
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/nodemailer": "^6.4.7",
|
||||
@ -59,7 +50,14 @@
|
||||
"@types/react-pdf": "^6.2.0",
|
||||
"@types/react-resizable": "^3.0.3",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"dotenv": "^16.0.3",
|
||||
"eslint": "8.27.0",
|
||||
"eslint-config-next": "13.0.3",
|
||||
"file-loader": "^6.2.0",
|
||||
"next-transpile-modules": "^10.0.0",
|
||||
"postcss": "^8.4.19",
|
||||
"tailwindcss": "^3.2.4"
|
||||
"sass": "^1.57.1",
|
||||
"tailwindcss": "^3.2.4",
|
||||
"typescript": "4.8.4"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -63,6 +63,7 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
|
||||
},
|
||||
data: {
|
||||
signingStatus: SigningStatus.SIGNED,
|
||||
signedAt: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
@ -86,7 +87,11 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
|
||||
where: {
|
||||
documentId: document.id,
|
||||
type: { in: [FieldType.DATE, FieldType.TEXT] },
|
||||
recipientId: { in: signedRecipients.map((r) => r.id) },
|
||||
},
|
||||
include: {
|
||||
Recipient: true,
|
||||
}
|
||||
});
|
||||
|
||||
// Insert fields other than signatures
|
||||
@ -98,7 +103,7 @@ async function postHandler(req: NextApiRequest, res: NextApiResponse) {
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
}).format(new Date())
|
||||
}).format(field.Recipient?.signedAt ?? new Date())
|
||||
: field.customText || "",
|
||||
field.positionX,
|
||||
field.positionY,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ReactElement } from "react";
|
||||
import { ChangeEvent, ReactElement } from "react";
|
||||
import Head from "next/head";
|
||||
import Link from "next/link";
|
||||
import { uploadDocument } from "@documenso/features";
|
||||
@ -62,26 +62,27 @@ const DashboardPage: NextPageWithLayout = (props: any) => {
|
||||
<dl className="mt-8 grid gap-5 md:grid-cols-3 ">
|
||||
{stats.map((item) => (
|
||||
<Link href={item.link} key={item.name}>
|
||||
<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 ">
|
||||
<div className="overflow-hidden rounded-lg bg-white px-4 py-3 shadow hover:shadow-lg duration-300 sm:py-5 md:p-6">
|
||||
<dt className="truncate text-sm font-medium text-gray-700 ">
|
||||
<item.icon
|
||||
className="text-neon mr-3 inline h-5 w-5 flex-shrink-0 sm:h-6 sm:w-6"
|
||||
className="text-neon-600 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">
|
||||
<dd className="mt-3 text-2xl font-semibold tracking-tight text-gray-900 sm:text-3xl">
|
||||
{getStat(item.name, props)}
|
||||
</dd>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</dl>
|
||||
|
||||
<div className="mt-12">
|
||||
<input
|
||||
id="fileUploadHelper"
|
||||
type="file"
|
||||
accept="application/pdf"
|
||||
onChange={(event: any) => {
|
||||
onChange={(event: ChangeEvent) => {
|
||||
uploadDocument(event);
|
||||
}}
|
||||
hidden
|
||||
@ -91,9 +92,10 @@ const DashboardPage: NextPageWithLayout = (props: any) => {
|
||||
onClick={() => {
|
||||
document?.getElementById("fileUploadHelper")?.click();
|
||||
}}
|
||||
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">
|
||||
className="group hover:border-neon-600 duration-200 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="mx-auto h-12 w-12 text-gray-400"
|
||||
className="mx-auto h-12 w-12 text-gray-400 group-hover:text-gray-700 duration-200"
|
||||
stroke="currentColor"
|
||||
fill="none"
|
||||
viewBox="0 00 20 25"
|
||||
@ -104,7 +106,8 @@ const DashboardPage: NextPageWithLayout = (props: any) => {
|
||||
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="text-neon mt-2 block text-sm font-medium">
|
||||
|
||||
<span id="add_document" className="text-gray-500 group-hover:text-neon-700 mt-2 block text-sm font-medium duration-200">
|
||||
Add a new PDF document.
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@ -142,26 +142,26 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-3 mb-12">
|
||||
<div className="float-right ml-3 mt-7 block w-fit">
|
||||
<div className="mt-3 mb-12 flex flex-row-reverse items-center gap-x-4">
|
||||
<div className="pt-5 block w-fit">
|
||||
{filteredDocuments.length != 1 ? filteredDocuments.length + " Documents" : "1 Document"}
|
||||
</div>
|
||||
<SelectBox
|
||||
className="float-right block w-1/4"
|
||||
className="block w-1/4"
|
||||
label="Created"
|
||||
options={createdFilter}
|
||||
value={selectedCreatedFilter}
|
||||
onChange={setSelectedCreatedFilter}
|
||||
/>
|
||||
<SelectBox
|
||||
className="float-right ml-3 block w-1/4"
|
||||
className="block w-1/4"
|
||||
label="Status"
|
||||
options={statusFilters}
|
||||
value={selectedStatusFilter}
|
||||
onChange={handleStatusFilterChange}
|
||||
/>
|
||||
</div>
|
||||
<div className="mt-20 max-w-[1100px]" hidden={!loading}>
|
||||
<div className="mt-8 max-w-[1100px]" hidden={!loading}>
|
||||
<div className="ph-item">
|
||||
<div className="ph-col-12">
|
||||
<div className="ph-picture"></div>
|
||||
@ -178,7 +178,7 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-28 flex flex-col" hidden={!documents.length || loading}>
|
||||
<div className="mt-8 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}>
|
||||
@ -221,13 +221,13 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
{document.title || "#" + document.id}
|
||||
</td>
|
||||
<td className="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
<td className="whitespace-nowrap inline-flex py-3 gap-x-2 gap-y-1 flex-wrap max-w-[250px] text-sm text-gray-500">
|
||||
{document.Recipient.map((item: any) => (
|
||||
<div key={item.id}>
|
||||
{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">
|
||||
className="flex-shrink-0 h-6 inline-flex items-center 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>
|
||||
) : (
|
||||
@ -237,8 +237,8 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
|
||||
<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="mr-1 inline h-5"></EnvelopeIcon>
|
||||
className="flex-shrink-0 h-6 inline-flex items-center rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-yellow-800">
|
||||
<EnvelopeIcon className="mr-1 inline h-4"></EnvelopeIcon>
|
||||
{item.name ? item.name + " <" + item.email + ">" : item.email}
|
||||
</span>
|
||||
</span>
|
||||
@ -250,9 +250,9 @@ const DocumentsPage: NextPageWithLayout = (props: any) => {
|
||||
<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="-mr-2 inline h-5"></CheckIcon>
|
||||
<CheckIcon className="mr-1 inline h-5"></CheckIcon>
|
||||
className="flex-shrink-0 h-6 inline-flex items-center rounded-full bg-yellow-200 px-2 py-0.5 text-xs font-medium text-yellow-800">
|
||||
<CheckIcon className="-mr-2 inline h-4"></CheckIcon>
|
||||
<CheckIcon className="mr-1 inline h-4"></CheckIcon>
|
||||
{item.name ? item.name + " <" + item.email + ">" : item.email}
|
||||
</span>
|
||||
</span>
|
||||
@ -261,7 +261,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">
|
||||
<span className="flex-shrink-0 h-6 inline-flex items-center 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>{" "}
|
||||
{item.email}
|
||||
</span>
|
||||
|
||||
@ -4,7 +4,7 @@ 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 { Breadcrumb, Button, Dialog, IconButton, Tooltip } from "@documenso/ui";
|
||||
import Layout from "../../../components/layout";
|
||||
import { NextPageWithLayout } from "../../_app";
|
||||
import {
|
||||
@ -264,38 +264,46 @@ const RecipientsPage: NextPageWithLayout = (props: any) => {
|
||||
</div>
|
||||
{props.document.status !== DocumentStatus.COMPLETED && (
|
||||
<div className="mr-1 flex">
|
||||
<IconButton
|
||||
icon={PaperAirplaneIcon}
|
||||
disabled={
|
||||
!item.id ||
|
||||
item.sendStatus !== "SENT" ||
|
||||
item.signingStatus === "SIGNED" ||
|
||||
loading
|
||||
}
|
||||
color="secondary"
|
||||
className="my-auto mr-4 h-9"
|
||||
onClick={() => {
|
||||
if (confirm("Resend this signing request?")) {
|
||||
setLoading(true);
|
||||
sendSigningRequests(props.document, [item.id]).finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
<Tooltip label="Resend">
|
||||
<IconButton
|
||||
icon={PaperAirplaneIcon}
|
||||
disabled={
|
||||
!item.id ||
|
||||
item.sendStatus !== "SENT" ||
|
||||
item.signingStatus === "SIGNED" ||
|
||||
loading
|
||||
}
|
||||
}}>
|
||||
Resend
|
||||
</IconButton>
|
||||
<IconButton
|
||||
icon={TrashIcon}
|
||||
disabled={!item.id || item.sendStatus === "SENT" || loading}
|
||||
onClick={() => {
|
||||
const removedItem = { ...fields }[index];
|
||||
remove(index);
|
||||
deleteRecipient(item)?.catch((err) => {
|
||||
append(removedItem);
|
||||
});
|
||||
}}
|
||||
className="group-hover:text-neon-dark group-hover:disabled:text-gray-400"
|
||||
/>
|
||||
onClick={(event: any) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (confirm("Resend this signing request?")) {
|
||||
setLoading(true);
|
||||
sendSigningRequests(props.document, [item.id]).finally(() => {
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
}}
|
||||
className="mx-1 group-hover:text-neon-dark group-hover:disabled:text-gray-400"
|
||||
/>
|
||||
</Tooltip>
|
||||
<Tooltip label="Delete">
|
||||
<IconButton
|
||||
icon={TrashIcon}
|
||||
disabled={!item.id || item.sendStatus === "SENT" || loading}
|
||||
onClick={(event: any) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
if (confirm("Delete this signing request?")) {
|
||||
const removedItem = { ...fields }[index];
|
||||
remove(index);
|
||||
deleteRecipient(item)?.catch((err) => {
|
||||
append(removedItem);
|
||||
});
|
||||
}
|
||||
}}
|
||||
className="mx-1 group-hover:text-neon-dark group-hover:disabled:text-gray-400"
|
||||
/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -16,9 +16,48 @@ module.exports = {
|
||||
qwigley: ["Qwigley", "serif"],
|
||||
},
|
||||
colors: {
|
||||
neon: "#37f095",
|
||||
"neon-dark": "#2CC077",
|
||||
brown: "#353434",
|
||||
neon: {
|
||||
DEFAULT: "#37F095",
|
||||
50: "#E2FDF0",
|
||||
100: "#CFFBE5",
|
||||
200: "#A9F9D1",
|
||||
300: "#83F6BD",
|
||||
400: "#5DF3A9",
|
||||
500: "#37F095",
|
||||
600: "#11DE79",
|
||||
700: "#0DAA5D",
|
||||
800: "#097640",
|
||||
900: "#054224",
|
||||
950: "#032816",
|
||||
},
|
||||
"neon-dark": {
|
||||
DEFAULT: "#2CC077",
|
||||
50: "#B5EED2",
|
||||
100: "#A5EAC8",
|
||||
200: "#84E3B4",
|
||||
300: "#62DBA0",
|
||||
400: "#41D48B",
|
||||
500: "#2CC077",
|
||||
600: "#22925B",
|
||||
700: "#17653E",
|
||||
800: "#0D3722",
|
||||
900: "#020906",
|
||||
950: "#000000",
|
||||
},
|
||||
brown: {
|
||||
DEFAULT: "#353434",
|
||||
50: "#918F8F",
|
||||
100: "#878585",
|
||||
200: "#737171",
|
||||
300: "#5E5C5C",
|
||||
400: "#4A4848",
|
||||
500: "#353434",
|
||||
600: "#191818",
|
||||
700: "#000000",
|
||||
800: "#000000",
|
||||
900: "#000000",
|
||||
950: "#000000",
|
||||
},
|
||||
},
|
||||
borderRadius: {
|
||||
"4xl": "2rem",
|
||||
|
||||
Reference in New Issue
Block a user