diff --git a/prisma/schema.prisma b/prisma/schema.prisma index a53c78c..edcd219 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1,8 +1,3 @@ -enum RoleValue { - USER - ADMIN -} - generator client { provider = "prisma-client-js" } @@ -46,7 +41,6 @@ model Session { model User { id String @id @default(cuid()) - role RoleValue @default(USER) createdAt DateTime @default(now()) name String? email String? @unique @@ -57,6 +51,9 @@ model User { rooms Room[] votes Vote[] logs Log[] + isAdmin Boolean @default(false) + isVIP Boolean @default(false) + } model VerificationToken { diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index 9c06a7d..ddfe9d3 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -85,7 +85,7 @@ const Navbar: React.FC = ({ title }) => { Profile - {sessionData.user.role === "ADMIN" && ( + {sessionData.user.isAdmin && (
  • { @@ -22,7 +22,7 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => { }; } - if (session.user.role !== "ADMIN") { + if (!session.user.isAdmin) { ctx.res.statusCode = 403; return { redirect: { @@ -90,7 +90,8 @@ const AdminBody: React.FC = () => { id: string; }[]; id: string; - role: Role; + isAdmin: boolean; + isVIP: boolean; name: string | null; email: string | null; }) => { @@ -119,7 +120,13 @@ const AdminBody: React.FC = () => { }, }); - const setRoleMutation = api.user.setRole.useMutation({ + const setAdminMutation = api.user.setAdmin.useMutation({ + onSuccess: async () => { + await refetchData(); + }, + }); + + const setVIPMutation = api.user.setVIP.useMutation({ onSuccess: async () => { await refetchData(); }, @@ -137,8 +144,12 @@ const AdminBody: React.FC = () => { await clearSessionsMutation.mutateAsync(); }; - const setUserRoleHandler = async (userId: string, role: Role) => { - await setRoleMutation.mutateAsync({ userId, role }); + const setAdmin = async (userId: string, value: boolean) => { + await setAdminMutation.mutateAsync({ userId, value }); + }; + + const setVIP = async (userId: string, value: boolean) => { + await setVIPMutation.mutateAsync({ userId, value }); }; const refetchData = async () => { @@ -158,70 +169,70 @@ const AdminBody: React.FC = () => {
    Users
    - { usersCountLoading || usersCountFetching ? ( + {usersCountLoading || usersCountFetching ? ( ) : ( - <>{ usersCount ? usersCount : "0" } - ) } + <>{usersCount ? usersCount : "0"} + )}
    Rooms
    - { roomsCountLoading || roomsCountFetching ? ( + {roomsCountLoading || roomsCountFetching ? ( ) : ( - <>{ roomsCount ? roomsCount : "0" } - ) } + <>{roomsCount ? roomsCount : "0"} + )}
    Votes
    - { votesCountLoading || votesCountFetching ? ( + {votesCountLoading || votesCountFetching ? ( ) : ( - <>{ votesCount ? votesCount : "0" } - ) } + <>{votesCount ? votesCount : "0"} + )}
    - { usersCountFetching || - usersFetching || - roomsCountFetching || - votesCountFetching ? ( + {usersCountFetching || + usersFetching || + roomsCountFetching || + votesCountFetching ? ( ) : (
    - ) } + )}

    Users:

    - { usersLoading || usersFetching ? ( + {usersLoading || usersFetching ? ( ) : (
    - {/* head */ } + {/* head */} @@ -233,55 +244,64 @@ const AdminBody: React.FC = () => { - { users + {users ?.sort((user1, user2) => user2.createdAt > user1.createdAt ? 1 : -1 ) .map((user) => { return ( - + ); - }) } + })}
    ID
    - { user.id } + {user.id} - { user.name } + {user.name} - { user.createdAt.toLocaleDateString() } + {user.createdAt.toLocaleDateString()} - { user.sessions.length } + {user.sessions.length} - { getProviders(user).includes("google") && ( + {getProviders(user).includes("google") && ( - ) } - { getProviders(user).includes("github") && ( + )} + {getProviders(user).includes("github") && ( - ) } + )} +
    - ) } + )}
    diff --git a/src/pages/dashboard/index.tsx b/src/pages/dashboard/index.tsx index 6ad31f0..7e20c68 100644 --- a/src/pages/dashboard/index.tsx +++ b/src/pages/dashboard/index.tsx @@ -8,6 +8,7 @@ import Link from "next/link"; import { useEffect, useState } from "react"; import { FaShieldAlt } from "react-icons/fa"; import { getServerAuthSession } from "~/server/auth"; +import { GiStarFormation } from "react-icons/gi"; export const getServerSideProps: GetServerSideProps = async (ctx) => { const session = await getServerAuthSession(ctx); @@ -57,20 +58,23 @@ const HomePageBody: React.FC = () => { return ( <>

    - Hi, { sessionData?.user.name }!{ " " } - { sessionData?.user.role === "ADMIN" && ( + Hi, {sessionData?.user.name}!{" "} + {sessionData?.user.isAdmin && ( - ) } + )} + {sessionData?.user.isVIP && ( + + )}

    { + onClick={() => { setTabIndex(0); localStorage.setItem("dashboardTabIndex", "0"); - } } + }} > Join a Room @@ -78,36 +82,36 @@ const HomePageBody: React.FC = () => { className={ tabIndex === 1 ? "tab no-underline tab-active" : "tab no-underline" } - onClick={ () => { + onClick={() => { setTabIndex(1); localStorage.setItem("dashboardTabIndex", "1"); - } } + }} > Room List
    - { tabIndex === 0 && ( + {tabIndex === 0 && ( <> { + onChange={(event) => { console.log(event.target.value); setJoinRoomTextBox(event.target.value); - } } + }} /> 0 ? `/room/${joinRoomTextBox}` : "/" } + href={joinRoomTextBox.length > 0 ? `/room/${joinRoomTextBox}` : "/"} className="btn btn-secondary" > Join Room - ) } + )} - { tabIndex === 1 && } + {tabIndex === 1 && } ); }; diff --git a/src/pages/profile/index.tsx b/src/pages/profile/index.tsx index e7196e9..27b53ac 100644 --- a/src/pages/profile/index.tsx +++ b/src/pages/profile/index.tsx @@ -9,6 +9,7 @@ import { FaShieldAlt } from "react-icons/fa"; import { SiGithub, SiGoogle } from "react-icons/si"; import { api } from "~/utils/api"; import { getServerAuthSession } from "../../server/auth"; +import { GiStarFormation } from "react-icons/gi"; export const getServerSideProps: GetServerSideProps = async (ctx) => { const session = await getServerAuthSession(ctx); @@ -103,7 +104,7 @@ const ProfileBody: React.FC = () => { @@ -114,79 +115,82 @@ const ProfileBody: React.FC = () => {

    Profile:

    - { sessionData.user.image && ( -
    - { sessionData.user.role === "ADMIN" && ( - -
    - -
    -
    - ) } + {sessionData.user.image && ( + Profile picture. + )} - Profile picture. -
    - ) } +
    + {sessionData.user.isAdmin && ( +
    + +
    + )} + {sessionData.user.isVIP && ( +
    + +
    + )} +
    - { providersLoading ? ( + {providersLoading ? (
    - { " " } + {" "}
    ) : (
    - ) } + )} - { sessionData.user.name && ( + {sessionData.user.name && ( setNameText(event.target.value) } + value={nameText} + onChange={(event) => setNameText(event.target.value)} /> - ) } + )} - { sessionData.user.email && ( + {sessionData.user.email && ( - ) } + )} - {/* */ } + {/* */}