From f40d65a9f7515580e553a239376575557b1dfe9b Mon Sep 17 00:00:00 2001 From: Jayvin Hernandez Date: Tue, 23 May 2023 22:34:21 -0700 Subject: [PATCH] feat: view other user files (#408) * feat: Add the capability of viewing another user's images as admin. * fix: add columns, oops... * fix: Gotta check if the user's legit before letting them see * fix: made administrators non-viewable * Please don't reference yourself * fix: superAdmin > admin --------- Co-authored-by: dicedtomato <35403473+diced@users.noreply.github.com> --- src/components/File/FileModal.tsx | 4 +- src/components/File/index.tsx | 6 +- src/components/pages/Dashboard/index.tsx | 1 + src/components/pages/Users/UserFiles.tsx | 82 +++++++++++++++++++ src/components/pages/Users/index.tsx | 12 +++ src/pages/api/user/[id].ts | 8 ++ src/pages/dashboard/users/[id].tsx | 42 ++++++++++ .../dashboard/{users.tsx => users/index.tsx} | 2 +- 8 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 src/components/pages/Users/UserFiles.tsx create mode 100644 src/pages/dashboard/users/[id].tsx rename src/pages/dashboard/{users.tsx => users/index.tsx} (93%) diff --git a/src/components/File/FileModal.tsx b/src/components/File/FileModal.tsx index ed57719..b583657 100644 --- a/src/components/File/FileModal.tsx +++ b/src/components/File/FileModal.tsx @@ -49,6 +49,7 @@ export default function FileModal({ reducedActions = false, exifEnabled, compress, + otherUser = false, }: { open: boolean; setOpen: (open: boolean) => void; @@ -58,6 +59,7 @@ export default function FileModal({ reducedActions?: boolean; exifEnabled?: boolean; compress: boolean; + otherUser: boolean; }) { const deleteFile = useFileDelete(); const favoriteFile = useFileFavorite(); @@ -276,7 +278,7 @@ export default function FileModal({ )} - {reducedActions ? null : inFolder && !folders.isLoading ? ( + {reducedActions || otherUser ? null : inFolder && !folders.isLoading ? ( f.id === file.folderId)?.name ?? ''}"`} > diff --git a/src/components/File/index.tsx b/src/components/File/index.tsx index 8ab6a22..7670c44 100644 --- a/src/components/File/index.tsx +++ b/src/components/File/index.tsx @@ -32,9 +32,10 @@ export default function File({ image, disableMediaPreview, exifEnabled, - refreshImages, + refreshImages = undefined, reducedActions = false, onDash, + otherUser = false, }) { const [open, setOpen] = useState(false); const deleteFile = useFileDelete(); @@ -44,7 +45,7 @@ export default function File({ const folders = useFolders(); const refresh = () => { - refreshImages(); + if (!otherUser) refreshImages(); folders.refetch(); }; @@ -59,6 +60,7 @@ export default function File({ reducedActions={reducedActions} exifEnabled={exifEnabled} compress={onDash} + otherUser={otherUser} /> setOpen(true)}> diff --git a/src/components/pages/Dashboard/index.tsx b/src/components/pages/Dashboard/index.tsx index 8de2918..bcbfeff 100644 --- a/src/components/pages/Dashboard/index.tsx +++ b/src/components/pages/Dashboard/index.tsx @@ -126,6 +126,7 @@ export default function Dashboard({ disableMediaPreview, exifEnabled, compress } reducedActions={false} exifEnabled={exifEnabled} compress={compress} + otherUser={false} /> )} diff --git a/src/components/pages/Users/UserFiles.tsx b/src/components/pages/Users/UserFiles.tsx new file mode 100644 index 0000000..0b4cc77 --- /dev/null +++ b/src/components/pages/Users/UserFiles.tsx @@ -0,0 +1,82 @@ +import { ActionIcon, Button, Center, Group, SimpleGrid, Title } from '@mantine/core'; +import { File } from '@prisma/client'; +import { IconArrowLeft, IconFile } from '@tabler/icons-react'; +import FileComponent from 'components/File'; +import MutedText from 'components/MutedText'; +import useFetch from 'hooks/useFetch'; +import { userSelector } from 'lib/recoil/user'; +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import { useRecoilState } from 'recoil'; + +type UserFiles = { + id: number; + username: string; + files?: File[]; + error?: unknown; +}; + +export default function UserFiles({ userId, disableMediaPreview, exifEnabled, compress }) { + const [currentUser, viewUser] = useState({ id: 0, username: 'user' }); + const [self] = useRecoilState(userSelector); + + const { push } = useRouter(); + + useEffect(() => { + if (self.id == userId) push('/dashboard/files'); + (async () => { + const user: UserFiles = await useFetch(`/api/user/${userId}`); + if (!user.error) { + viewUser(user); + } else { + push('/dashboard'); + } + })(); + }, [userId]); + + if (!currentUser.files || currentUser.files.length === 0) { + return ( +
+ +
+ +
+
+ Nothing here + + {currentUser.username} seems to have not uploaded any files... yet + +
+ +
+
+ ); + } + + return ( + <> + + push('/dashboard/users')} color='primary'> + + + {currentUser.username}'s Files + + + + {currentUser.files.map((file) => ( +
+ +
+ ))} +
+ + ); +} diff --git a/src/components/pages/Users/index.tsx b/src/components/pages/Users/index.tsx index 993c6d9..443d0b7 100644 --- a/src/components/pages/Users/index.tsx +++ b/src/components/pages/Users/index.tsx @@ -6,6 +6,7 @@ import type { User } from '@prisma/client'; import { IconClipboardCopy, IconEdit, + IconExternalLink, IconGridDots, IconList, IconUserExclamation, @@ -116,6 +117,10 @@ export default function Users() { } }; + const openUser = async (user) => { + await router.push(`/dashboard/users/${user.id}`); + }; + useEffect(() => { updateUsers(); }, []); @@ -181,6 +186,13 @@ export default function Users() {
+ {(!self.superAdmin && user.superAdmin) || (self.superAdmin && user.superAdmin) ? null : ( + + openUser(user)}> + + + + )} ), }, diff --git a/src/pages/api/user/[id].ts b/src/pages/api/user/[id].ts index 651bc08..5767f3a 100644 --- a/src/pages/api/user/[id].ts +++ b/src/pages/api/user/[id].ts @@ -14,6 +14,10 @@ async function handler(req: NextApiReq, res: NextApiRes, user: UserExtended) { where: { id: Number(id), }, + include: { + files: true, + Folder: true, + }, }); if (!target) return res.notFound('user not found'); @@ -175,6 +179,10 @@ async function handler(req: NextApiReq, res: NextApiRes, user: UserExtended) { } else { delete target.password; + if (user.superAdmin && target.superAdmin) delete target.files; + if (user.administrator && !user.superAdmin && (target.administrator || target.superAdmin)) + delete target.files; + return res.json(target); } } diff --git a/src/pages/dashboard/users/[id].tsx b/src/pages/dashboard/users/[id].tsx new file mode 100644 index 0000000..03fa1bf --- /dev/null +++ b/src/pages/dashboard/users/[id].tsx @@ -0,0 +1,42 @@ +import { LoadingOverlay } from '@mantine/core'; +import Layout from 'components/Layout'; +import UserFiles from 'components/pages/Users/UserFiles'; +import useLogin from 'hooks/useLogin'; +import Head from 'next/head'; +import { getServerSideProps as middlewareProps } from 'middleware/getServerSideProps'; +import { GetServerSideProps } from 'next'; + +export default function UsersId(props) { + const { loading } = useLogin(); + + if (loading) return ; + + const title = `${props.title} - User - ${props.userId}`; + return ( + <> + + {title} + + + + + + ); +} + +export const getServerSideProps: GetServerSideProps = async (context) => { + const { id } = context.params as { id: string }; + // @ts-ignore + const { props } = await middlewareProps(context); + return { + props: { + userId: id, + ...props, + }, + }; +}; diff --git a/src/pages/dashboard/users.tsx b/src/pages/dashboard/users/index.tsx similarity index 93% rename from src/pages/dashboard/users.tsx rename to src/pages/dashboard/users/index.tsx index 676b457..971df81 100644 --- a/src/pages/dashboard/users.tsx +++ b/src/pages/dashboard/users/index.tsx @@ -10,7 +10,7 @@ export default function UsersPage(props) { if (loading) return ; - const title = `${props.title} - User`; + const title = `${props.title} - Users`; return ( <>