el.xwx.moe/layouts/LinkLayout.tsx

217 lines
6.9 KiB
TypeScript
Raw Normal View History

2023-10-30 14:20:15 -05:00
import LinkSidebar from "@/components/LinkSidebar";
import { ReactNode, useEffect, useState } from "react";
import ModalManagement from "@/components/ModalManagement";
import useModalStore from "@/store/modals";
import { useRouter } from "next/router";
import ClickAwayHandler from "@/components/ClickAwayHandler";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
2023-11-19 07:12:37 -06:00
import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
2023-10-30 14:20:15 -05:00
import useWindowDimensions from "@/hooks/useWindowDimensions";
2023-10-31 14:44:58 -05:00
import {
faPen,
faBoxesStacked,
faTrashCan,
} from "@fortawesome/free-solid-svg-icons";
import useLinkStore from "@/store/links";
import {
CollectionIncludingMembersAndLinkCount,
LinkIncludingShortenedCollectionAndTags,
} from "@/types/global";
import { useSession } from "next-auth/react";
import useCollectionStore from "@/store/collections";
2023-12-06 15:13:11 -06:00
import EditLinkModal from "@/components/ModalContent/EditLinkModal";
import Link from "next/link";
2023-12-06 23:33:05 -06:00
import PreservedFormatsModal from "@/components/ModalContent/PreservedFormatsModal";
import toast from "react-hot-toast";
import DeleteLinkModal from "@/components/ModalContent/DeleteLinkModal";
2023-10-30 14:20:15 -05:00
interface Props {
children: ReactNode;
}
export default function LinkLayout({ children }: Props) {
const { modal } = useModalStore();
const router = useRouter();
useEffect(() => {
modal
? (document.body.style.overflow = "hidden")
: (document.body.style.overflow = "auto");
}, [modal]);
const [sidebar, setSidebar] = useState(false);
const { width } = useWindowDimensions();
useEffect(() => {
setSidebar(false);
}, [width]);
useEffect(() => {
setSidebar(false);
}, [router]);
const toggleSidebar = () => {
setSidebar(!sidebar);
};
2023-10-31 14:44:58 -05:00
const session = useSession();
const userId = session.data?.user.id;
const { setModal } = useModalStore();
const { links, removeLink } = useLinkStore();
const { collections } = useCollectionStore();
const [linkCollection, setLinkCollection] =
useState<CollectionIncludingMembersAndLinkCount>();
const [link, setLink] = useState<LinkIncludingShortenedCollectionAndTags>();
useEffect(() => {
2023-11-19 07:12:37 -06:00
if (links[0]) setLink(links.find((e) => e.id === Number(router.query.id)));
2023-10-31 14:44:58 -05:00
}, [links]);
useEffect(() => {
if (link)
2023-11-20 14:58:32 -06:00
setLinkCollection(collections.find((e) => e.id === link?.collection?.id));
2023-11-19 07:12:37 -06:00
}, [link, collections]);
2023-10-31 14:44:58 -05:00
2023-12-06 23:33:05 -06:00
const deleteLink = async () => {
const load = toast.loading("Deleting...");
const response = await removeLink(link?.id as number);
toast.dismiss(load);
response.ok && toast.success(`Link Deleted.`);
router.push("/dashboard");
};
2023-12-06 15:13:11 -06:00
const [editLinkModal, setEditLinkModal] = useState(false);
2023-12-06 23:33:05 -06:00
const [deleteLinkModal, setDeleteLinkModal] = useState(false);
const [preservedFormatsModal, setPreservedFormatsModal] = useState(false);
2023-12-06 15:13:11 -06:00
2023-10-30 14:20:15 -05:00
return (
<>
<div className="flex mx-auto">
2023-11-19 07:12:37 -06:00
{/* <div className="hidden lg:block fixed left-5 h-screen">
2023-10-30 14:20:15 -05:00
<LinkSidebar />
2023-11-19 07:12:37 -06:00
</div> */}
2023-10-30 14:20:15 -05:00
<div className="w-full flex flex-col min-h-screen max-w-screen-md mx-auto p-5">
2023-12-06 15:13:11 -06:00
<div className="flex gap-3 mb-3 duration-100 items-center justify-between">
2023-10-31 14:44:58 -05:00
{/* <div
2023-10-30 14:20:15 -05:00
onClick={toggleSidebar}
2023-11-26 04:17:08 -06:00
className="inline-flex lg:hidden gap-1 items-center select-none cursor-pointer p-2 text-neutral rounded-md duration-100 hover:bg-neutral-content"
2023-10-30 14:20:15 -05:00
>
<FontAwesomeIcon icon={faBars} className="w-5 h-5" />
2023-10-31 14:44:58 -05:00
</div> */}
2023-10-30 14:20:15 -05:00
2023-12-06 15:13:11 -06:00
<Link
href={
router.pathname.startsWith("/public")
? `/public/collections/${
2023-12-08 10:01:47 -06:00
linkCollection?.id || link?.collection?.id
2023-11-19 07:12:37 -06:00
}`
2023-12-06 15:13:11 -06:00
: `/dashboard`
}
className="inline-flex gap-1 btn btn-ghost btn-sm text-neutral px-2"
2023-10-30 14:20:15 -05:00
>
<FontAwesomeIcon icon={faChevronLeft} className="w-4 h-4" />
2023-12-06 15:13:11 -06:00
<span className="capitalize">
{router.pathname.startsWith("/public")
? linkCollection?.name || link?.collection?.name
: "Dashboard"}
</span>
2023-12-06 15:13:11 -06:00
</Link>
2023-10-31 14:44:58 -05:00
2023-12-06 15:13:11 -06:00
<div className="flex gap-3">
2023-11-19 07:12:37 -06:00
{link?.collection?.ownerId === userId ||
linkCollection?.members.some(
(e) => e.userId === userId && e.canUpdate
) ? (
2023-10-31 14:44:58 -05:00
<div
2023-11-19 07:12:37 -06:00
title="Edit"
2023-12-06 23:33:05 -06:00
onClick={() => setEditLinkModal(true)}
2023-12-06 15:13:11 -06:00
className={`btn btn-ghost btn-square btn-sm`}
2023-10-31 14:44:58 -05:00
>
<FontAwesomeIcon
2023-11-19 07:12:37 -06:00
icon={faPen}
2023-12-06 15:13:11 -06:00
className="w-4 h-4 text-neutral"
2023-10-31 14:44:58 -05:00
/>
</div>
2023-11-19 07:12:37 -06:00
) : undefined}
<div
2023-12-06 23:33:05 -06:00
onClick={() => setPreservedFormatsModal(true)}
2023-11-19 07:12:37 -06:00
title="Preserved Formats"
2023-12-06 23:33:05 -06:00
className={`btn btn-ghost btn-square btn-sm`}
2023-11-19 07:12:37 -06:00
>
<FontAwesomeIcon
icon={faBoxesStacked}
2023-12-06 23:33:05 -06:00
className="w-4 h-4 text-neutral"
2023-11-19 07:12:37 -06:00
/>
2023-10-31 14:44:58 -05:00
</div>
2023-11-19 07:12:37 -06:00
{link?.collection?.ownerId === userId ||
linkCollection?.members.some(
(e) => e.userId === userId && e.canDelete
) ? (
<div
2023-12-06 23:33:05 -06:00
onClick={(e) => {
(document?.activeElement as HTMLElement)?.blur();
e.shiftKey ? deleteLink() : setDeleteLinkModal(true);
2023-11-19 07:12:37 -06:00
}}
title="Delete"
2023-12-06 23:33:05 -06:00
className={`btn btn-ghost btn-square btn-sm`}
2023-11-19 07:12:37 -06:00
>
<FontAwesomeIcon
icon={faTrashCan}
2023-12-06 23:33:05 -06:00
className="w-4 h-4 text-neutral"
2023-11-19 07:12:37 -06:00
/>
</div>
) : undefined}
2023-10-31 14:44:58 -05:00
</div>
2023-10-30 14:20:15 -05:00
</div>
{children}
{sidebar ? (
2023-11-25 04:54:43 -06:00
<div className="fixed top-0 bottom-0 right-0 left-0 bg-black bg-opacity-10 backdrop-blur-sm flex items-center fade-in z-30">
2023-10-30 14:20:15 -05:00
<ClickAwayHandler
className="h-full"
onClickOutside={toggleSidebar}
>
<div className="slide-right h-full shadow-lg">
<LinkSidebar onClick={() => setSidebar(false)} />
</div>
</ClickAwayHandler>
</div>
) : null}
</div>
2023-12-06 15:13:11 -06:00
{link && editLinkModal ? (
<EditLinkModal
onClose={() => setEditLinkModal(false)}
activeLink={link}
/>
) : undefined}
2023-12-06 23:33:05 -06:00
{link && deleteLinkModal ? (
<DeleteLinkModal
onClose={() => setDeleteLinkModal(false)}
activeLink={link}
/>
) : undefined}
{link && preservedFormatsModal ? (
<PreservedFormatsModal
onClose={() => setPreservedFormatsModal(false)}
activeLink={link}
/>
) : undefined}
2023-10-30 14:20:15 -05:00
</div>
</>
);
}