diff --git a/components/CollectionCard.tsx b/components/CollectionCard.tsx
index 9a82380..a31f64c 100644
--- a/components/CollectionCard.tsx
+++ b/components/CollectionCard.tsx
@@ -5,10 +5,9 @@ import { CollectionIncludingMembers } from "@/types/global";
import useLinkStore from "@/store/links";
import Dropdown from "./Dropdown";
import { useState } from "react";
-import Modal from "@/components/Modal";
-import CollectionModal from "@/components/Modal/Collection";
import ProfilePhoto from "./ProfilePhoto";
import { faCalendarDays } from "@fortawesome/free-regular-svg-icons";
+import useModalStore from "@/store/modals";
type Props = {
collection: CollectionIncludingMembers;
@@ -16,6 +15,8 @@ type Props = {
};
export default function CollectionCard({ collection, className }: Props) {
+ const { setModal } = useModalStore();
+
const { links } = useLinkStore();
const formattedDate = new Date(collection.createdAt as string).toLocaleString(
"en-US",
@@ -27,21 +28,6 @@ export default function CollectionCard({ collection, className }: Props) {
);
const [expandDropdown, setExpandDropdown] = useState(false);
- const [editCollectionModal, setEditCollectionModal] = useState(false);
- const [collectionMembersModal, setCollectionMembersModal] = useState(false);
- const [deleteCollectionModal, setDeleteCollectionModal] = useState(false);
-
- const toggleEditCollectionModal = () => {
- setEditCollectionModal(!editCollectionModal);
- };
-
- const toggleCollectionMembersModal = () => {
- setCollectionMembersModal(!collectionMembersModal);
- };
-
- const toggleDeleteCollectionModal = () => {
- setDeleteCollectionModal(!deleteCollectionModal);
- };
return (
{
- toggleEditCollectionModal();
+ setModal({
+ modal: "COLLECTION",
+ state: true,
+ method: "UPDATE",
+ active: collection,
+ });
setExpandDropdown(false);
},
},
{
name: "Share/Collaborate",
onClick: () => {
- toggleCollectionMembersModal();
+ setModal({
+ modal: "COLLECTION",
+ state: true,
+ method: "UPDATE",
+ active: collection,
+ defaultIndex: 1,
+ });
setExpandDropdown(false);
},
},
{
name: "Delete Collection",
onClick: () => {
- toggleDeleteCollectionModal();
+ setModal({
+ modal: "COLLECTION",
+ state: true,
+ method: "UPDATE",
+ active: collection,
+ defaultIndex: 2,
+ });
setExpandDropdown(false);
},
},
@@ -130,35 +133,6 @@ export default function CollectionCard({ collection, className }: Props) {
className="absolute top-[3.2rem] right-5 z-10 w-36"
/>
) : null}
- {editCollectionModal ? (
-
-
-
- ) : null}
- {collectionMembersModal ? (
-
-
-
- ) : null}
- {deleteCollectionModal ? (
-
-
-
- ) : null}
);
}
diff --git a/components/LinkCard.tsx b/components/LinkCard.tsx
index 3f9512c..0d49d7b 100644
--- a/components/LinkCard.tsx
+++ b/components/LinkCard.tsx
@@ -13,10 +13,9 @@ import { useEffect, useState } from "react";
import Image from "next/image";
import Dropdown from "./Dropdown";
import useLinkStore from "@/store/links";
-import Modal from "./Modal";
-import LinkModal from "./Modal/LinkModal";
import Link from "next/link";
import useCollectionStore from "@/store/collections";
+import useModalStore from "@/store/modals";
type Props = {
link: LinkIncludingCollectionAndTags;
@@ -25,8 +24,9 @@ type Props = {
};
export default function LinkCard({ link, count, className }: Props) {
+ const { setModal } = useModalStore();
+
const [expandDropdown, setExpandDropdown] = useState(false);
- const [editModal, setEditModal] = useState(false);
const { collections } = useCollectionStore();
@@ -56,25 +56,11 @@ export default function LinkCard({ link, count, className }: Props) {
}
);
- const toggleEditModal = () => {
- setEditModal(!editModal);
- };
-
return (
- {editModal ? (
-
-
-
- ) : null}
-
{
- setEditModal(true);
+ setModal({
+ modal: "LINK",
+ state: true,
+ method: "UPDATE",
+ active: link,
+ });
setExpandDropdown(false);
},
},
diff --git a/components/Modal/User/ProfileSettings.tsx b/components/Modal/User/ProfileSettings.tsx
index 03db59f..b229375 100644
--- a/components/Modal/User/ProfileSettings.tsx
+++ b/components/Modal/User/ProfileSettings.tsx
@@ -80,7 +80,7 @@ export default function ProfileSettings({
{profileStatus && (
diff --git a/components/ModalManagement.tsx b/components/ModalManagement.tsx
new file mode 100644
index 0000000..bad08cb
--- /dev/null
+++ b/components/ModalManagement.tsx
@@ -0,0 +1,51 @@
+import useModalStore from "@/store/modals";
+import Modal from "./Modal";
+import LinkModal from "./Modal/LinkModal";
+import {
+ AccountSettings,
+ CollectionIncludingMembers,
+ LinkIncludingCollectionAndTags,
+} from "@/types/global";
+import CollectionModal from "./Modal/Collection";
+import UserModal from "./Modal/User";
+
+export default function ModalManagement() {
+ const { modal, setModal } = useModalStore();
+
+ const toggleModal = () => {
+ setModal(null);
+ };
+
+ if (modal && modal.modal === "LINK")
+ return (
+
+
+
+ );
+ else if (modal && modal.modal === "COLLECTION")
+ return (
+
+
+
+ );
+ else if (modal && modal.modal === "ACCOUNT")
+ return (
+
+
+
+ );
+ else return <>>;
+}
diff --git a/components/Navbar.tsx b/components/Navbar.tsx
index 49367b2..6d8a77a 100644
--- a/components/Navbar.tsx
+++ b/components/Navbar.tsx
@@ -7,23 +7,21 @@ import {
} from "@fortawesome/free-solid-svg-icons";
import { useEffect, useState } from "react";
import Dropdown from "@/components/Dropdown";
-import Modal from "@/components/Modal";
-import LinkModal from "@/components/Modal/LinkModal";
import ClickAwayHandler from "@/components/ClickAwayHandler";
import Sidebar from "@/components/Sidebar";
import { useRouter } from "next/router";
import Search from "@/components/Search";
-import UserModal from "@/components/Modal/User";
import useAccountStore from "@/store/account";
import ProfilePhoto from "@/components/ProfilePhoto";
+import useModalStore from "@/store/modals";
export default function Navbar() {
+ const { setModal } = useModalStore();
+
const { account } = useAccountStore();
const [profileDropdown, setProfileDropdown] = useState(false);
- const [linkModal, setLinkModal] = useState(false);
- const [settingsModal, setSettingsModal] = useState(false);
const [sidebar, setSidebar] = useState(false);
const router = useRouter();
@@ -38,14 +36,6 @@ export default function Navbar() {
setSidebar(!sidebar);
};
- const toggleLinkModal = () => {
- setLinkModal(!linkModal);
- };
-
- const toggleSettingsModal = () => {
- setSettingsModal(!settingsModal);
- };
-
return (
{
+ setModal({
+ modal: "LINK",
+ state: true,
+ method: "CREATE",
+ });
+ }}
className="inline-flex gap-1 relative sm:w-[7.2rem] items-center font-semibold select-none cursor-pointer p-[0.687rem] sm:p-2 sm:px-3 rounded-md sm:rounded-full hover:bg-sky-100 text-sky-500 sm:text-white sm:bg-sky-500 sm:hover:bg-sky-400 duration-100 group"
>
{
- toggleSettingsModal();
+ setModal({
+ modal: "ACCOUNT",
+ state: true,
+ method: "CREATE",
+ active: account,
+ });
setProfileDropdown(!profileDropdown);
},
},
@@ -122,21 +123,6 @@ export default function Navbar() {
/>
) : null}
- {linkModal ? (
-
-
-
- ) : null}
-
- {settingsModal ? (
-
-
-
- ) : null}
-
{sidebar ? (
diff --git a/layouts/MainLayout.tsx b/layouts/MainLayout.tsx
index 8737fd4..6e099d0 100644
--- a/layouts/MainLayout.tsx
+++ b/layouts/MainLayout.tsx
@@ -5,6 +5,7 @@ import { useSession } from "next-auth/react";
import Loader from "../components/Loader";
import useRedirect from "@/hooks/useRedirect";
import { useRouter } from "next/router";
+import ModalManagement from "@/components/ModalManagement";
interface Props {
children: ReactNode;
@@ -18,16 +19,20 @@ export default function MainLayout({ children }: Props) {
if (status === "authenticated" && !redirect && routeExists)
return (
-
-
-
-
+ <>
+
-
-
- {children}
+
+
+
+
+
+
+
+ {children}
+
-
+ >
);
else if ((status === "unauthenticated" && !redirect) || !routeExists)
return <>{children}>;
diff --git a/pages/collections/[id].tsx b/pages/collections/[id].tsx
index 29be60d..40b606c 100644
--- a/pages/collections/[id].tsx
+++ b/pages/collections/[id].tsx
@@ -1,8 +1,5 @@
import Dropdown from "@/components/Dropdown";
import LinkCard from "@/components/LinkCard";
-import Modal from "@/components/Modal";
-import LinkModal from "@/components/Modal/LinkModal";
-import CollectionModal from "@/components/Modal/Collection";
import useCollectionStore from "@/store/collections";
import useLinkStore from "@/store/links";
import { CollectionIncludingMembers } from "@/types/global";
@@ -18,8 +15,11 @@ import MainLayout from "@/layouts/MainLayout";
import { useSession } from "next-auth/react";
import ProfilePhoto from "@/components/ProfilePhoto";
import SortLinkDropdown from "@/components/SortLinkDropdown";
+import useModalStore from "@/store/modals";
export default function Index() {
+ const { setModal } = useModalStore();
+
const router = useRouter();
const { links } = useLinkStore();
@@ -28,10 +28,6 @@ export default function Index() {
const { data } = useSession();
const [expandDropdown, setExpandDropdown] = useState(false);
- const [linkModal, setLinkModal] = useState(false);
- const [collectionInfoModal, setCollectionInfoModal] = useState(false);
- const [collectionMembersModal, setCollectionMembersModal] = useState(false);
- const [deleteCollectionModal, setDeleteCollectionModal] = useState(false);
const [sortDropdown, setSortDropdown] = useState(false);
const [sortBy, setSortBy] = useState("Name (A-Z)");
@@ -40,22 +36,6 @@ export default function Index() {
const [sortedLinks, setSortedLinks] = useState(links);
- const toggleLinkModal = () => {
- setLinkModal(!linkModal);
- };
-
- const toggleCollectionInfoModal = () => {
- setCollectionInfoModal(!collectionInfoModal);
- };
-
- const toggleCollectionMembersModal = () => {
- setCollectionMembersModal(!collectionMembersModal);
- };
-
- const toggleDeleteCollectionModal = () => {
- setDeleteCollectionModal(!deleteCollectionModal);
- };
-
const handleSortChange = (event: ChangeEvent
) => {
setSortBy(event.target.value);
};
@@ -124,7 +104,16 @@ export default function Index() {
}`}
>
+ activeCollection &&
+ setModal({
+ modal: "COLLECTION",
+ state: true,
+ method: "UPDATE",
+ active: activeCollection,
+ defaultIndex: 1,
+ })
+ }
className="flex justify-center sm:justify-end items-center w-fit mx-auto sm:mr-0 sm:ml-auto group cursor-pointer"
>
{
- toggleLinkModal();
+ setModal({
+ modal: "LINK",
+ state: true,
+ method: "CREATE",
+ });
setExpandDropdown(false);
},
},
{
name: "Edit Collection Info",
onClick: () => {
- toggleCollectionInfoModal();
+ activeCollection &&
+ setModal({
+ modal: "COLLECTION",
+ state: true,
+ method: "UPDATE",
+ active: activeCollection,
+ });
setExpandDropdown(false);
},
},
{
name: "Share/Collaborate",
onClick: () => {
- toggleCollectionMembersModal();
+ activeCollection &&
+ setModal({
+ modal: "COLLECTION",
+ state: true,
+ method: "UPDATE",
+ active: activeCollection,
+ defaultIndex: 1,
+ });
setExpandDropdown(false);
},
},
{
name: "Delete Collection",
onClick: () => {
- toggleDeleteCollectionModal();
+ activeCollection &&
+ setModal({
+ modal: "COLLECTION",
+ state: true,
+ method: "UPDATE",
+ active: activeCollection,
+ defaultIndex: 2,
+ });
setExpandDropdown(false);
},
},
@@ -237,47 +250,6 @@ export default function Index() {
className="absolute top-8 right-0 z-10 w-40"
/>
) : null}
-
- {linkModal ? (
-
-
-
- ) : null}
-
- {collectionInfoModal && activeCollection ? (
-
-
-
- ) : null}
-
- {collectionMembersModal && activeCollection ? (
-
-
-
- ) : null}
-
- {deleteCollectionModal && activeCollection ? (
-
-
-
- ) : null}
diff --git a/pages/collections/index.tsx b/pages/collections/index.tsx
index 5f205c1..3c81f78 100644
--- a/pages/collections/index.tsx
+++ b/pages/collections/index.tsx
@@ -9,12 +9,11 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import CollectionCard from "@/components/CollectionCard";
import Dropdown from "@/components/Dropdown";
import { ChangeEvent, useEffect, useState } from "react";
-import Modal from "@/components/Modal";
import MainLayout from "@/layouts/MainLayout";
import ClickAwayHandler from "@/components/ClickAwayHandler";
import RadioButton from "@/components/RadioButton";
-import CollectionModal from "@/components/Modal/Collection";
import { useSession } from "next-auth/react";
+import useModalStore from "@/store/modals";
export default function Collections() {
const { collections } = useCollectionStore();
@@ -23,13 +22,9 @@ export default function Collections() {
const [sortBy, setSortBy] = useState("Name (A-Z)");
const [sortedCollections, setSortedCollections] = useState(collections);
- const [collectionModal, setCollectionModal] = useState(false);
-
const session = useSession();
- const toggleCollectionModal = () => {
- setCollectionModal(!collectionModal);
- };
+ const { setModal } = useModalStore();
const handleSortChange = (event: ChangeEvent) => {
setSortBy(event.target.value);
@@ -109,7 +104,19 @@ export default function Collections() {
{
name: "New Collection",
onClick: () => {
- toggleCollectionModal();
+ setModal({
+ modal: "COLLECTION",
+ state: true,
+ method: "CREATE",
+ active: {
+ name: "",
+ description: "",
+ color: "#0ea5e9",
+ isPublic: false,
+ ownerId: session.data?.user.id as number,
+ members: [],
+ },
+ });
setExpandDropdown(false);
},
},
@@ -198,7 +205,21 @@ export default function Collections() {
{
+ setModal({
+ modal: "COLLECTION",
+ state: true,
+ method: "CREATE",
+ active: {
+ name: "",
+ description: "",
+ color: "#0ea5e9",
+ isPublic: false,
+ ownerId: session.data?.user.id as number,
+ members: [],
+ },
+ });
+ }}
>
New Collection
@@ -210,23 +231,6 @@ export default function Collections() {
-
- {collectionModal ? (
-
-
-
- ) : null}
);
}
diff --git a/store/modals.ts b/store/modals.ts
new file mode 100644
index 0000000..c88c845
--- /dev/null
+++ b/store/modals.ts
@@ -0,0 +1,48 @@
+import {
+ AccountSettings,
+ CollectionIncludingMembers,
+ LinkIncludingCollectionAndTags,
+} from "@/types/global";
+import { create } from "zustand";
+
+type Modal =
+ | {
+ modal: "ACCOUNT";
+ state: boolean;
+ active: AccountSettings;
+ defaultIndex?: number;
+ }
+ | {
+ modal: "LINK";
+ state: boolean;
+ method: "CREATE";
+ active?: LinkIncludingCollectionAndTags;
+ }
+ | {
+ modal: "LINK";
+ state: boolean;
+ method: "UPDATE";
+ active: LinkIncludingCollectionAndTags;
+ }
+ | {
+ modal: "COLLECTION";
+ state: boolean;
+ method: "CREATE" | "UPDATE";
+ active: CollectionIncludingMembers;
+ defaultIndex?: number;
+ }
+ | null;
+
+type ModalsStore = {
+ modal: Modal;
+ setModal: (modal: Modal) => void;
+};
+
+const useLocalSettingsStore = create
((set) => ({
+ modal: null,
+ setModal: (modal: Modal) => {
+ set({ modal });
+ },
+}));
+
+export default useLocalSettingsStore;