From 021f7c94810da19c9a777b73e54e6d8eba861381 Mon Sep 17 00:00:00 2001 From: daniel31x13 Date: Wed, 15 Nov 2023 23:31:13 -0500 Subject: [PATCH] added view team modal --- .../Modal/Collection/CollectionInfo.tsx | 2 +- components/Modal/Collection/ViewTeam.tsx | 102 ++++++++++++++++ components/Modal/Collection/index.tsx | 75 +++++++----- docker-compose.yml | 2 +- pages/public/collections/[id].tsx | 113 +++++++++++++----- store/modals.ts | 12 +- 6 files changed, 242 insertions(+), 64 deletions(-) create mode 100644 components/Modal/Collection/ViewTeam.tsx diff --git a/components/Modal/Collection/CollectionInfo.tsx b/components/Modal/Collection/CollectionInfo.tsx index f0e71b2..962e9ee 100644 --- a/components/Modal/Collection/CollectionInfo.tsx +++ b/components/Modal/Collection/CollectionInfo.tsx @@ -18,7 +18,7 @@ type Props = { SetStateAction >; collection: CollectionIncludingMembersAndLinkCount; - method: "CREATE" | "UPDATE"; + method: "CREATE" | "UPDATE" | "VIEW_TEAM"; }; export default function CollectionInfo({ diff --git a/components/Modal/Collection/ViewTeam.tsx b/components/Modal/Collection/ViewTeam.tsx new file mode 100644 index 0000000..c22971d --- /dev/null +++ b/components/Modal/Collection/ViewTeam.tsx @@ -0,0 +1,102 @@ +import { useEffect, useState } from "react"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faCrown } from "@fortawesome/free-solid-svg-icons"; +import { CollectionIncludingMembersAndLinkCount } from "@/types/global"; +import ProfilePhoto from "@/components/ProfilePhoto"; +import { toast } from "react-hot-toast"; +import getPublicUserData from "@/lib/client/getPublicUserData"; + +type Props = { + collection: CollectionIncludingMembersAndLinkCount; +}; + +export default function ViewTeam({ collection }: Props) { + const currentURL = new URL(document.URL); + + const publicCollectionURL = `${currentURL.origin}/public/collections/${collection.id}`; + + const [collectionOwner, setCollectionOwner] = useState({ + id: null, + name: "", + username: "", + image: "", + }); + + useEffect(() => { + const fetchOwner = async () => { + const owner = await getPublicUserData(collection.ownerId as number); + setCollectionOwner(owner); + }; + + fetchOwner(); + }, []); + + return ( +
+

Team

+ +

Here's all the members that are collaborating in this collection.

+ +
+
+ +
+
+

+ {collectionOwner.name} +

+
+ + Admin +
+
+

+ @{collectionOwner.username} +

+
+
+
+ + {collection?.members[0]?.user && ( + <> +
+ {collection.members + .sort((a, b) => (a.userId as number) - (b.userId as number)) + .map((e, i) => { + return ( +
+
+ +
+

+ {e.user.name} +

+

+ @{e.user.username} +

+
+
+
+ ); + })} +
+ + )} +
+ ); +} diff --git a/components/Modal/Collection/index.tsx b/components/Modal/Collection/index.tsx index 747a742..a535b30 100644 --- a/components/Modal/Collection/index.tsx +++ b/components/Modal/Collection/index.tsx @@ -4,6 +4,7 @@ import { CollectionIncludingMembersAndLinkCount } from "@/types/global"; import TeamManagement from "./TeamManagement"; import { useState } from "react"; import DeleteCollection from "./DeleteCollection"; +import ViewTeam from "./ViewTeam"; type Props = | { @@ -21,6 +22,14 @@ type Props = isOwner: boolean; className?: string; defaultIndex?: number; + } + | { + toggleCollectionModal: Function; + activeCollection: CollectionIncludingMembersAndLinkCount; + method: "VIEW_TEAM"; + isOwner: boolean; + className?: string; + defaultIndex?: number; }; export default function CollectionModal({ @@ -46,14 +55,25 @@ export default function CollectionModal({
{method === "CREATE" && ( -

+

New Collection

)} - - {method === "UPDATE" && ( - <> - {isOwner && ( + {method !== "VIEW_TEAM" && ( + + {method === "UPDATE" && ( + <> + {isOwner && ( + + selected + ? "px-2 py-1 bg-sky-200 dark:bg-sky-800 dark:text-white duration-100 rounded-md outline-none" + : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 hover:dark:text-white rounded-md duration-100 outline-none" + } + > + Collection Info + + )} selected @@ -61,30 +81,21 @@ export default function CollectionModal({ : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 hover:dark:text-white rounded-md duration-100 outline-none" } > - Collection Info + {isOwner ? "Share & Collaborate" : "View Team"} - )} - - selected - ? "px-2 py-1 bg-sky-200 dark:bg-sky-800 dark:text-white duration-100 rounded-md outline-none" - : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 hover:dark:text-white rounded-md duration-100 outline-none" - } - > - {isOwner ? "Share & Collaborate" : "View Team"} - - - selected - ? "px-2 py-1 bg-sky-200 dark:bg-sky-800 dark:text-white duration-100 rounded-md outline-none" - : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 hover:dark:text-white rounded-md duration-100 outline-none" - } - > - {isOwner ? "Delete Collection" : "Leave Collection"} - - - )} - + + selected + ? "px-2 py-1 bg-sky-200 dark:bg-sky-800 dark:text-white duration-100 rounded-md outline-none" + : "px-2 py-1 hover:bg-slate-200 hover:dark:bg-neutral-700 hover:dark:text-white rounded-md duration-100 outline-none" + } + > + {isOwner ? "Delete Collection" : "Leave Collection"} + + + )} + + )} {(isOwner || method === "CREATE") && ( @@ -115,6 +126,14 @@ export default function CollectionModal({ )} + + {method === "VIEW_TEAM" && ( + <> + + + + + )}
diff --git a/docker-compose.yml b/docker-compose.yml index 2a400df..f1ff559 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: "3.5" services: postgres: - image: postgres + image: postgres:16-alpine env_file: .env restart: always volumes: diff --git a/pages/public/collections/[id].tsx b/pages/public/collections/[id].tsx index 01fab2c..3317cfc 100644 --- a/pages/public/collections/[id].tsx +++ b/pages/public/collections/[id].tsx @@ -8,6 +8,9 @@ import { motion, Variants } from "framer-motion"; import Head from "next/head"; import useLinks from "@/hooks/useLinks"; import useLinkStore from "@/store/links"; +import ProfilePhoto from "@/components/ProfilePhoto"; +import useModalStore from "@/store/modals"; +import ModalManagement from "@/components/ModalManagement"; const cardVariants: Variants = { offscreen: { @@ -25,6 +28,7 @@ const cardVariants: Variants = { export default function PublicCollections() { const { links } = useLinkStore(); + const { setModal } = useModalStore(); const router = useRouter(); @@ -73,7 +77,13 @@ export default function PublicCollections() { }, []); return collection ? ( -
+
+ {collection ? ( {collection.name} | Linkwarden @@ -84,41 +94,80 @@ export default function PublicCollections() { /> ) : undefined} -
-

{collection.name}

+
+
+

+ {collection.name} +

+
[Logo]
+
- {collection.description && ( - <> -
-

{collection.description}

- - )} -
+
+
+
+ setModal({ + modal: "COLLECTION", + state: true, + method: "VIEW_TEAM", + isOwner: false, + active: collection, + defaultIndex: 0, + }) + } + className="hover:opacity-80 duration-100 flex justify-center sm:justify-end items-center w-fit sm:mr-0 sm:ml-auto cursor-pointer" + > + {collection.members + .sort((a, b) => (a.userId as number) - (b.userId as number)) + .map((e, i) => { + return ( + + ); + }) + .slice(0, 4)} + {collection?.members.length && + collection.members.length - 4 > 0 ? ( +
+ +{collection?.members?.length - 4} +
+ ) : null} +
+
+
-
- {links - ?.filter((e) => e.collectionId === Number(router.query.id)) - .map((e, i) => { - return ( - - - +

{collection.description}

+ +
+ +
+ {links + ?.filter((e) => e.collectionId === Number(router.query.id)) + .map((e, i) => { + return ( + + + + - - ); - })} -
+ ); + })} +
- {/*

- List created with Linkwarden. -

*/} + {/*

+ List created with Linkwarden. +

*/} +
) : ( <> diff --git a/store/modals.ts b/store/modals.ts index 71ecef0..f709d70 100644 --- a/store/modals.ts +++ b/store/modals.ts @@ -39,6 +39,14 @@ type Modal = active?: CollectionIncludingMembersAndLinkCount; defaultIndex?: number; } + | { + modal: "COLLECTION"; + state: boolean; + method: "VIEW_TEAM"; + isOwner?: boolean; + active?: CollectionIncludingMembersAndLinkCount; + defaultIndex?: number; + } | null; type ModalsStore = { @@ -46,11 +54,11 @@ type ModalsStore = { setModal: (modal: Modal) => void; }; -const useLocalSettingsStore = create((set) => ({ +const useModalStore = create((set) => ({ modal: null, setModal: (modal: Modal) => { set({ modal }); }, })); -export default useLocalSettingsStore; +export default useModalStore;