Skip to content

Commit

Permalink
feat: add upload agreement
Browse files Browse the repository at this point in the history
  • Loading branch information
mfts committed Jun 11, 2024
1 parent 6e1fb18 commit fa8b6ca
Show file tree
Hide file tree
Showing 6 changed files with 282 additions and 48 deletions.
2 changes: 1 addition & 1 deletion components/document-upload.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo, useState } from "react";
import { useMemo } from "react";

import {
Upload as ArrowUpTrayIcon,
Expand Down
145 changes: 109 additions & 36 deletions components/links/link-sheet/agreement-panel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useRouter } from "next/router";

import {
Dispatch,
FormEvent,
Expand All @@ -11,13 +9,11 @@ import {
import { useTeam } from "@/context/team-context";
import { toast } from "sonner";
import { mutate } from "swr";
import { set } from "ts-pattern/dist/patterns";

import DocumentUpload from "@/components/document-upload";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Separator } from "@/components/ui/separator";
import {
Sheet,
SheetContent,
Expand All @@ -27,12 +23,12 @@ import {
SheetTitle,
} from "@/components/ui/sheet";

import { useAnalytics } from "@/lib/analytics";
import { usePlan } from "@/lib/swr/use-billing";
import { useDocumentLinks } from "@/lib/swr/use-document";
import { useDomains } from "@/lib/swr/use-domains";
import { LinkWithViews } from "@/lib/types";
import { convertDataUrlToFile, uploadImage } from "@/lib/utils";
import {
DocumentData,
createAgreementDocument,
} from "@/lib/documents/create-document";
import { putFile } from "@/lib/files/put-file";
import { getSupportedContentType } from "@/lib/utils/get-content-type";

export default function AgreementSheet({
isOpen,
Expand All @@ -45,6 +41,62 @@ export default function AgreementSheet({
const teamId = teamInfo?.currentTeam?.id;
const [data, setData] = useState({ name: "", link: "" });
const [isLoading, setIsLoading] = useState<boolean>(false);
const [currentFile, setCurrentFile] = useState<File | null>(null);
const [currentLink, setCurrentLink] = useState<string | null>(null);

const handleBrowserUpload = async () => {
// event.preventDefault();
// event.stopPropagation();

// Check if the file is chosen
if (!currentFile) {
toast.error("Please select a file to upload.");
return; // prevent form from submitting
}

try {
setIsLoading(true);

const contentType = getSupportedContentType(currentFile.type);

if (!contentType || currentFile.type !== "application/pdf") {
toast.error("Unsupported file format. Please upload a PDF file.");
return;
}

const { type, data, numPages } = await putFile({
file: currentFile,
teamId: teamId!,
});

const documentData: DocumentData = {
name: currentFile.name,
key: data!,
storageType: type!,
contentType: contentType,
};
// create a document in the database
const response = await createAgreementDocument({
documentData,
teamId: teamId!,
numPages,
});

if (response) {
const document = await response.json();
const linkId = document.links[0].id;
setData((prevData) => ({
...prevData,
link: "https://www.papermark.io/view/" + linkId,
}));
}
} catch (error) {
console.error("An error occurred while uploading the file: ", error);
} finally {
setCurrentFile(null);
setIsLoading(false);
}
};

const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
Expand Down Expand Up @@ -77,9 +129,16 @@ export default function AgreementSheet({
} finally {
setIsLoading(false);
setIsOpen(false);
setData({ name: "", link: "" });
}
};

useEffect(() => {
if (currentFile) {
handleBrowserUpload();
}
}, [currentFile]);

return (
<Sheet open={isOpen} onOpenChange={setIsOpen}>
<SheetContent className="flex w-[85%] flex-col justify-between bg-background px-4 text-foreground sm:w-[500px] md:px-5">
Expand Down Expand Up @@ -114,31 +173,45 @@ export default function AgreementSheet({
/>
</div>

<div className="w-full space-y-2">
<Label htmlFor="link">Link</Label>
<Input
className="flex w-full rounded-md border-0 bg-background py-1.5 text-foreground shadow-sm ring-1 ring-inset ring-input placeholder:text-muted-foreground focus:ring-2 focus:ring-inset focus:ring-gray-400 sm:text-sm sm:leading-6"
id="link"
type="url"
pattern="https://.*"
name="link"
required
autoComplete="off"
data-1p-ignore
placeholder="https://www.papermark.io/nda"
value={data.link || ""}
onChange={(e) =>
setData({
...data,
link: e.target.value,
})
}
onInvalid={(e) =>
e.currentTarget.setCustomValidity(
"Please enter a valid URL starting with https://",
)
}
/>
<div className="space-y-4">
<div className="w-full space-y-2">
<Label htmlFor="link">Link to an agreement</Label>
<Input
className="flex w-full rounded-md border-0 bg-background py-1.5 text-foreground shadow-sm ring-1 ring-inset ring-input placeholder:text-muted-foreground focus:ring-2 focus:ring-inset focus:ring-gray-400 sm:text-sm sm:leading-6"
id="link"
type="url"
pattern="https://.*"
name="link"
required
autoComplete="off"
data-1p-ignore
placeholder="https://www.papermark.io/nda"
value={data.link || ""}
onChange={(e) =>
setData({
...data,
link: e.target.value,
})
}
onInvalid={(e) =>
e.currentTarget.setCustomValidity(
"Please enter a valid URL starting with https://",
)
}
/>
</div>

<div className="space-y-12">
<div className="space-y-2 pb-6">
<Label>Or upload an agreement</Label>
<div className="grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
<DocumentUpload
currentFile={currentFile}
setCurrentFile={setCurrentFile}
/>
</div>
</div>
</div>
</div>
</div>

Expand Down
10 changes: 1 addition & 9 deletions components/links/link-sheet/agreement-section.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
import {
Dispatch,
SetStateAction,
useCallback,
useEffect,
useState,
} from "react";
import { Dispatch, SetStateAction, useEffect, useState } from "react";

import { Button } from "@react-email/components";
import { motion } from "framer-motion";

import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
Expand Down
34 changes: 34 additions & 0 deletions lib/documents/create-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,40 @@ export const createDocument = async ({
return response;
};

export const createAgreementDocument = async ({
documentData,
teamId,
numPages,
folderPathName,
}: {
documentData: DocumentData;
teamId: string;
numPages?: number;
folderPathName?: string;
}) => {
// create a document in the database with the blob url
const response = await fetch(`/api/teams/${teamId}/documents/agreement`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
name: documentData.name,
url: documentData.key,
storageType: documentData.storageType,
numPages: numPages,
folderPathName: folderPathName,
type: documentData.contentType,
}),
});

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

return response;
};

// create a new version in the database
export const createNewDocumentVersion = async ({
documentData,
Expand Down
4 changes: 2 additions & 2 deletions pages/api/teams/[teamId]/agreements/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ export default async function handle(

const { name, link } = req.body as { name: string; link: string };

const response = await prisma.agreement.create({
const agreement = await prisma.agreement.create({
data: {
teamId,
name,
content: link,
},
});

return res.status(201).json(response);
return res.status(201).json(agreement);
} catch (error) {
log({
message: `Failed to add agreement. \n\n ${error} \n\n*Metadata*: \`{teamId: ${teamId}, userId: ${userId}}\``,
Expand Down
Loading

0 comments on commit fa8b6ca

Please sign in to comment.