Skip to content

Commit

Permalink
Merge pull request #541 from mfts/feat/remove-doc-dataroom
Browse files Browse the repository at this point in the history
feat(dataroom): remove docs / folders from dataroom
  • Loading branch information
mfts authored Jul 27, 2024
2 parents a330711 + af1bdbb commit dfe9d1c
Show file tree
Hide file tree
Showing 9 changed files with 259 additions and 38 deletions.
23 changes: 23 additions & 0 deletions components/billing/upgrade-plan-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useRouter } from "next/router";

import { useEffect, useMemo, useState } from "react";
import React from "react";

Expand All @@ -13,6 +15,7 @@ import { useAnalytics } from "@/lib/analytics";
import { STAGGER_CHILD_VARIANTS } from "@/lib/constants";
import { getStripe } from "@/lib/stripe/client";
import { PLANS } from "@/lib/stripe/utils";
import { usePlan } from "@/lib/swr/use-billing";
import { capitalize } from "@/lib/utils";

import { DataroomTrialModal } from "../datarooms/dataroom-trial-modal";
Expand All @@ -31,12 +34,14 @@ export function UpgradePlanModal({
setOpen?: React.Dispatch<React.SetStateAction<boolean>>;
children?: React.ReactNode;
}) {
const router = useRouter();
const [plan, setPlan] = useState<"Pro" | "Business" | "Data Rooms">(
clickedPlan,
);
const [period, setPeriod] = useState<"yearly" | "monthly">("yearly");
const [clicked, setClicked] = useState<boolean>(false);
const teamInfo = useTeam();
const { plan: teamPlan } = usePlan();
const analytics = useAnalytics();

const features = useMemo(() => {
Expand Down Expand Up @@ -238,6 +243,23 @@ export function UpgradePlanModal({
// @ts-ignore
// prettier-ignore

if (teamPlan !== "free") {
fetch(
`/api/teams/${teamInfo?.currentTeam?.id}/billing/manage`,
{
method: "POST",
},
)
.then(async (res) => {
const url = await res.json();
router.push(url);
})
.catch((err) => {
alert(err);
setClicked(false);
});
} else {

fetch(
`/api/teams/${
teamInfo?.currentTeam?.id
Expand Down Expand Up @@ -265,6 +287,7 @@ export function UpgradePlanModal({
alert(err);
setClicked(false);
});
}
}}
>{`Upgrade to ${plan} ${capitalize(period)}`}</Button>
<div className="flex items-center justify-center space-x-2">
Expand Down
119 changes: 105 additions & 14 deletions components/datarooms/dataroom-document-card.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Image from "next/image";
import Link from "next/link";
import { useRouter } from "next/router";

import { useEffect, useRef, useState } from "react";

Expand Down Expand Up @@ -34,21 +35,26 @@ import { MoveToDataroomFolderModal } from "./move-dataroom-folder-modal";
type DocumentsCardProps = {
document: DataroomFolderDocument;
teamInfo: TeamContextType | null;
dataroomId: string;
};
export default function DataroomDocumentCard({
document: dataroomDocument,
teamInfo,
dataroomId,
}: DocumentsCardProps) {
const { theme, systemTheme } = useTheme();
const isLight =
theme === "light" || (theme === "system" && systemTheme === "light");
const router = useRouter();

const { isCopied, copyToClipboard } = useCopyToClipboard({});
const [isFirstClick, setIsFirstClick] = useState<boolean>(false);
const [menuOpen, setMenuOpen] = useState<boolean>(false);
const [moveFolderOpen, setMoveFolderOpen] = useState<boolean>(false);
const dropdownRef = useRef<HTMLDivElement | null>(null);

/** current folder name */
const currentFolderPath = router.query.name as string[] | undefined;

// https://github.com/radix-ui/primitives/issues/1241#issuecomment-1888232392
useEffect(() => {
if (!moveFolderOpen) {
Expand All @@ -58,6 +64,89 @@ export default function DataroomDocumentCard({
}
}, [moveFolderOpen]);

useEffect(() => {
function handleClickOutside(event: { target: any }) {
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
setMenuOpen(false);
setIsFirstClick(false);
}
}

document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, []);

const handleButtonClick = (event: any, documentId: string) => {
event.stopPropagation();
event.preventDefault();

console.log("isFirstClick", isFirstClick);
if (isFirstClick) {
handleRemoveDocument(documentId);
setIsFirstClick(false);
setMenuOpen(false); // Close the dropdown after deleting
} else {
setIsFirstClick(true);
}
};

const handleRemoveDocument = async (documentId: string) => {
// Prevent the first click from deleting the document
if (!isFirstClick) {
setIsFirstClick(true);
return;
}

const endpoint = currentFolderPath
? `/folders/documents/${currentFolderPath.join("/")}`
: "/documents";

toast.promise(
fetch(
`/api/teams/${teamInfo?.currentTeam?.id}/datarooms/${dataroomId}/documents/${documentId}`,
{
method: "DELETE",
},
).then(() => {
mutate(
`/api/teams/${teamInfo?.currentTeam?.id}/datarooms/${dataroomId}${endpoint}`,
null,
{
populateCache: (_, docs) => {
return docs.filter(
(doc: DocumentWithLinksAndLinkCountAndViewCount) =>
doc.id !== documentId,
);
},
revalidate: false,
},
);
}),
{
loading: "Removing document...",
success: "Document removed successfully.",
error: "Failed to remove document. Try again.",
},
);
};

const handleMenuStateChange = (open: boolean) => {
if (isFirstClick) {
setMenuOpen(true); // Keep the dropdown open on the first click
return;
}

// If the menu is closed, reset the isFirstClick state
if (!open) {
setIsFirstClick(false);
setMenuOpen(false); // Ensure the dropdown is closed
} else {
setMenuOpen(true); // Open the dropdown
}
};

return (
<>
<li className="group/row relative flex items-center justify-between rounded-lg border-0 p-3 ring-1 ring-gray-200 transition-all hover:bg-secondary hover:ring-gray-300 dark:bg-secondary dark:ring-gray-700 hover:dark:ring-gray-500 sm:p-4">
Expand Down Expand Up @@ -114,7 +203,7 @@ export default function DataroomDocumentCard({
</p>
</Link>

<DropdownMenu>
<DropdownMenu open={menuOpen} onOpenChange={handleMenuStateChange}>
<DropdownMenuTrigger asChild>
<Button
// size="icon"
Expand All @@ -133,18 +222,20 @@ export default function DataroomDocumentCard({
</DropdownMenuItem>
<DropdownMenuSeparator />

{/* <DropdownMenuItem
onClick={(event) => handleButtonClick(event, prismaDocument.id)}
className="text-destructive focus:bg-destructive focus:text-destructive-foreground duration-200"
>
{isFirstClick ? (
"Really delete?"
) : (
<>
<TrashIcon className="w-4 h-4 mr-2" /> Delete document
</>
)}
</DropdownMenuItem> */}
<DropdownMenuItem
onClick={(event) =>
handleButtonClick(event, dataroomDocument.id)
}
className="text-destructive duration-200 focus:bg-destructive focus:text-destructive-foreground"
>
{isFirstClick ? (
"Really remove?"
) : (
<>
<TrashIcon className="mr-2 h-4 w-4" /> Remove document
</>
)}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
Expand Down
27 changes: 26 additions & 1 deletion components/documents/document-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useEffect, useRef, useState } from "react";

import { useTeam } from "@/context/team-context";
import { Document, DocumentVersion } from "@prisma/client";
import { Sparkles, TrashIcon } from "lucide-react";
import { BetweenHorizontalStartIcon, Sparkles, TrashIcon } from "lucide-react";
import { usePlausible } from "next-plausible";
import { useTheme } from "next-themes";
import { toast } from "sonner";
Expand All @@ -32,6 +32,7 @@ import { cn, getExtension } from "@/lib/utils";
import PortraitLandscape from "../shared/icons/portrait-landscape";
import LoadingSpinner from "../ui/loading-spinner";
import { AddDocumentModal } from "./add-document-modal";
import { AddToDataroomModal } from "./move-dataroom-modal";

export default function DocumentHeader({
prismaDocument,
Expand All @@ -54,6 +55,7 @@ export default function DocumentHeader({
const [menuOpen, setMenuOpen] = useState<boolean>(false);
const [isFirstClick, setIsFirstClick] = useState<boolean>(false);
const [orientationLoading, setOrientationLoading] = useState<boolean>(false);
const [addDataroomOpen, setAddDataroomOpen] = useState<boolean>(false);

const nameRef = useRef<HTMLHeadingElement>(null);
const enterPressedRef = useRef<boolean>(false);
Expand All @@ -68,6 +70,15 @@ export default function DocumentHeader({

const plausible = usePlausible();

// https://github.com/radix-ui/primitives/issues/1241#issuecomment-1888232392
useEffect(() => {
if (!addDataroomOpen) {
setTimeout(() => {
document.body.style.pointerEvents = "";
});
}
}, [addDataroomOpen]);

const handleNameSubmit = async () => {
if (enterPressedRef.current) {
enterPressedRef.current = false;
Expand Down Expand Up @@ -442,6 +453,11 @@ export default function DocumentHeader({
</DropdownMenuItem>
))}

<DropdownMenuItem onClick={() => setAddDataroomOpen(true)}>
<BetweenHorizontalStartIcon className="mr-2 h-4 w-4" />
Add to dataroom
</DropdownMenuItem>

<DropdownMenuSeparator />

<DropdownMenuItem
Expand All @@ -455,6 +471,15 @@ export default function DocumentHeader({
</DropdownMenuContent>
</DropdownMenu>
</div>

{addDataroomOpen ? (
<AddToDataroomModal
open={addDataroomOpen}
setOpen={setAddDataroomOpen}
documentId={prismaDocument.id}
documentName={prismaDocument.name}
/>
) : null}
</header>
);
}
1 change: 1 addition & 0 deletions components/documents/documents-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export function DocumentsList({
key={document.id}
document={document as DataroomFolderDocument}
teamInfo={teamInfo}
dataroomId={dataroomId}
/>
);
} else {
Expand Down
15 changes: 10 additions & 5 deletions components/documents/folder-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export default function FolderCard({
},
),
{
loading: "Deleting folder...",
loading: isDataroom ? "Removing folder..." : "Deleting folder...",
success: () => {
mutate(
`/api/teams/${teamInfo?.currentTeam?.id}/${endpointTargetType}?root=true`,
Expand All @@ -114,9 +114,13 @@ export default function FolderCard({
mutate(
`/api/teams/${teamInfo?.currentTeam?.id}/${endpointTargetType}${parentFolderPath}`,
);
return "Folder deleted successfully.";
return isDataroom
? "Folder removed successfully."
: "Folder deleted successfully.";
},
error: "Failed to delete folder. Move documents first.",
error: isDataroom
? "Failed to remove folder."
: "Failed to delete folder. Move documents first.",
},
);
};
Expand Down Expand Up @@ -242,10 +246,11 @@ export default function FolderCard({
className="text-destructive duration-200 focus:bg-destructive focus:text-destructive-foreground"
>
{isFirstClick ? (
"Really delete?"
`Really ${isDataroom ? "remove" : "delete"}?`
) : (
<>
<TrashIcon className="mr-2 h-4 w-4" /> Delete Folder
<TrashIcon className="mr-2 h-4 w-4" />{" "}
{isDataroom ? "Remove Folder" : "Delete Folder"}
</>
)}
</DropdownMenuItem>
Expand Down
6 changes: 6 additions & 0 deletions pages/api/teams/[teamId]/billing/manage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getServerSession } from "next-auth/next";
import { errorhandler } from "@/lib/errorHandler";
import prisma from "@/lib/prisma";
import { stripe } from "@/lib/stripe";
import { CustomUser } from "@/lib/types";

import { authOptions } from "../../../auth/[...nextauth]";

Expand All @@ -25,6 +26,11 @@ export default async function handle(
const team = await prisma.team.findUnique({
where: {
id: teamId,
users: {
some: {
userId: (session.user as CustomUser).id,
},
},
},
select: {
stripeId: true,
Expand Down
Loading

0 comments on commit dfe9d1c

Please sign in to comment.