diff --git a/src/app/dashboard/team/_components/FileList.tsx b/src/app/dashboard/team/_components/FileList.tsx new file mode 100644 index 0000000..87d5ecc --- /dev/null +++ b/src/app/dashboard/team/_components/FileList.tsx @@ -0,0 +1,394 @@ +import { useState, useEffect } from "react"; +import { + Loader2, + Trash2, + ChevronsUpDown, + ArchiveIcon, + ArchiveRestore, + Clock, + Edit, + CheckCircle2, + EyeIcon, + Edit3Icon, +} from "lucide-react"; +import moment from "moment"; +import Image from "next/image"; +import { usePathname, useRouter } from "next/navigation"; +import { useConvex, useMutation } from "convex/react"; +import { Button } from "@/components/ui/button"; +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from "@/components/ui/alert-dialog"; +import { Badge } from "@/components/ui/badge"; + +export interface FILE { + archive: boolean; + createdBy: string; + document: string; + fileName: string; + teamId: string; + whiteboard: string; + _id: string; + _creationTime: number; + private: boolean; + read: boolean; + write: boolean; + readBy: string[]; + writtenBy: string[]; +} + +const ActionDialog = ({ + buttonIcon: ButtonIcon, + dialogTitle, + dialogDescription, + onAction, + buttonVariant = "secondary", + isSubmitted, + successTitle, +}: { + buttonIcon: typeof ArchiveIcon; + dialogTitle: string; + dialogDescription: string; + onAction: (e: any) => void; + buttonVariant?: + | "secondary" + | "link" + | "default" + | "destructive" + | "outline" + | "ghost" + | null; + isSubmitted: boolean; + successTitle: string; +}) => ( + + + + + + {!isSubmitted && ( + <> + + {dialogTitle} + {dialogDescription} + + + Cancel + + + + )} + {isSubmitted && ( + <> + + +

{successTitle}

+
+
+ + { + window.location.reload(); + }} + > + Continue + + + + )} +
+
+); + +const FileRow = ({ + file, + router, + user +}: { + file: FILE; + user:any; + router: ReturnType; +}) => ( + + router.push("/workspace/" + file._id)} + > + {file.fileName} + + router.push("/workspace/" + file._id)} + > + {file.createdBy} + + router.push("/workspace/" + file._id)} + > + {file.readBy && file.readBy.includes(user.email) && Read} + {file.writtenBy && file.writtenBy.includes(user.email) && Write} + {!file.readBy && !file.writtenBy && No Access} + + + + + {/* + {pathname === "/dashboard" && ( + onArchive(e, file._id)} + /> + )} + {pathname === "/dashboard/archive" && ( + onUnarchive(e, file._id)} + buttonVariant="destructive" + /> + )} + onDelete(e, file._id)} + buttonVariant="destructive" + /> */} + + +); + +function FileList({ + fileList, + user +}: { + fileList?: FILE[]; + user:any; +}) { + const router = useRouter(); + const convex = useConvex(); + const [sortConfig, setSortConfig] = useState<{ + key: keyof FILE; + direction: string; + } | null>(null); + const [isSmallScreen, setIsSmallScreen] = useState(false); + const [isSubmitted, setIsSubmitted] = useState(false); + const [authorData, setAuthorData] = useState([]); + const safeFileList = Array.isArray(fileList) ? fileList : []; + const pathname = usePathname(); + + console.log(fileList) + + const sortedFiles = [...safeFileList]; + if (sortConfig !== null) { + sortedFiles.sort((a, b) => { + if (a[sortConfig.key] < b[sortConfig.key]) { + return sortConfig.direction === "ascending" ? -1 : 1; + } + if (a[sortConfig.key] > b[sortConfig.key]) { + return sortConfig.direction === "ascending" ? 1 : -1; + } + return 0; + }); + } + + const requestSort = (key: keyof FILE) => { + let direction = "ascending"; + if ( + sortConfig && + sortConfig.key === key && + sortConfig.direction === "ascending" + ) { + direction = "descending"; + } + setSortConfig({ key, direction }); + }; + + useEffect(() => { + const handleResize = () => { + setIsSmallScreen(window.innerWidth < 768); + }; + handleResize(); + window.addEventListener("resize", handleResize); + + return () => { + window.removeEventListener("resize", handleResize); + }; + }, []); + + return ( +
+
+ {!isSmallScreen ? ( + + + + + + + + + + {!fileList && ( + + + + )} + {fileList && !safeFileList.length && ( + + + + )} + {(sortedFiles.length > 0 ? sortedFiles : safeFileList).map( + (file, index) => ( + + ) + )} + +
requestSort("fileName")} + > + File Name + + Author + + Access +
+ {" "} + Loading... Please wait +
+ No files found +
+ ) : ( +
+
+
requestSort("fileName")} + > + File Name +
+
requestSort("_creationTime")} + > + Created At +
+
+ {sortedFiles.map((file, index) => ( +
router.push("/workspace/" + file._id)} + key={index} + className={`border p-4 mb-4 rounded ${index % 2 === 0 ? "bg-muted/50" : ""}`} + > +
+ {file.fileName} +
+ {/* + {pathname === "/dashboard" && ( + archiveFunc(e, file._id)} + /> + )} + {pathname === "/dashboard/archive" && ( + unarchiveFunc(e, file._id)} + buttonVariant="destructive" + /> + )} + deleteFunc(e, file._id)} + buttonVariant="destructive" + /> */} +
+
+
+
+
+ + {moment(file._creationTime).format("YYYY-MM-DD")} +
+
+ + {moment(file._creationTime).format("YYYY-MM-DD")} +
+
+ {/* */} +
+ +
+ {/* user */} +
+
+ ))} +
+ )} +
+
+ ); +} + +export default FileList; \ No newline at end of file diff --git a/src/app/dashboard/team/page.tsx b/src/app/dashboard/team/page.tsx index 07c1556..55c08d1 100644 --- a/src/app/dashboard/team/page.tsx +++ b/src/app/dashboard/team/page.tsx @@ -1,6 +1,54 @@ +"use client"; +import { RootState } from "@/app/store"; +import MemberCarousel, { USER } from "@/components/shared/MemberCarousel"; +import axiosInstance from "@/config/AxiosInstance"; +import { getTeamMembersData } from "@/lib/API-URLs"; +import { useContext, useEffect, useState } from "react"; +import { useSelector } from "react-redux"; +import FileList from "./_components/FileList"; +import { FileListContext } from "@/app/_context/FilesListContext"; export default function Page() { + const teamId = useSelector((state: RootState) => state.team.teamId); + const [teamMembersData, setData] = useState(null); + const [focusedUser, setFocusedUser] = useState(null); + const [fileList, setFileList] = useState(); + const { fileList_ } = useContext(FileListContext); + + useEffect(() => { + if (fileList_) { + setFileList(fileList_); + } + }, [fileList_]); + + useEffect(() => { + const getData = async () => { + try { + const res = await axiosInstance.get(`${getTeamMembersData}/${teamId}`); + console.log(res.data); + setData(res.data.memberData); + } catch (err) { + console.log(err); + } + }; + if (teamId) { + getData(); + } + }, [teamId]); + return ( -
Page
- ) -} \ No newline at end of file +
+

Team Settings

+ + {teamMembersData !== null && ( +
+ +
+ )} + +
+ {focusedUser !== null && } +
+
+ ); +} diff --git a/src/components/shared/MemberCarousel.tsx b/src/components/shared/MemberCarousel.tsx index fc5b58a..494a0f6 100644 --- a/src/components/shared/MemberCarousel.tsx +++ b/src/components/shared/MemberCarousel.tsx @@ -1,7 +1,79 @@ -import React from 'react' +"use client"; +import { + Carousel, + CarouselContent, + CarouselItem, + CarouselNext, + CarouselPrevious, +} from "@/components/ui/carousel"; +import { + Card, + CardContent, + CardDescription, + CardHeader, +} from "@/components/ui/card"; +import { Avatar, AvatarFallback, AvatarImage } from "../ui/avatar"; +import { Button } from "../ui/button"; +import { Trash2 } from "lucide-react"; +import { SetStateAction, useState } from "react"; + + export type USER = { + name: string; + _id: string; + email: string; + image: string; +}; + +type Props = { + teamMembersData: USER[]; + focusedUser:USER | null; + setFocusedUser:React.Dispatch>; +}; + +export default function MemberCarousel({ teamMembersData,focusedUser,setFocusedUser }: Props) { -export default function MemberCarousel() { return ( -
MemberCarousel
- ) -} \ No newline at end of file +
+ + + + {teamMembersData !== null && + teamMembersData.map((user: USER, index) => ( + setFocusedUser(user)} + key={index} + className="w-full group cursor-pointer sm:basis-1/2 md:basis-1/2" + > + + + + + + {user.name.charAt(0)} + + + {user.name} + + + +

Email : {user.email}

+ +
+
+
+
+ ))} +
+ +
+
+ ); +} diff --git a/src/components/shared/MemberModal.tsx b/src/components/shared/MemberModal.tsx index fdfa3e4..0290ec7 100644 --- a/src/components/shared/MemberModal.tsx +++ b/src/components/shared/MemberModal.tsx @@ -47,6 +47,7 @@ export default function MemberModal({ return ( diff --git a/src/lib/API-URLs.ts b/src/lib/API-URLs.ts index 1abae95..dd55a95 100644 --- a/src/lib/API-URLs.ts +++ b/src/lib/API-URLs.ts @@ -1,2 +1,3 @@ export const changeToPrivateUrl = "/api/files/private" -export const changeToPublicUrl = "/api/files/public" \ No newline at end of file +export const changeToPublicUrl = "/api/files/public" +export const getTeamMembersData = "/api/teams/members"; \ No newline at end of file