SLIGHT change to the role...

This commit is contained in:
Atridad Lahiji 2023-07-29 13:18:14 -06:00
parent f1806ef4a2
commit c402732f0a
No known key found for this signature in database
GPG key ID: 7CB8245F56BC3880
6 changed files with 80 additions and 54 deletions

View file

@ -1,7 +1,7 @@
enum RoleValue { enum RoleValue {
USER USER
ADMIN ADMIN
MATT VIP
} }
generator client { generator client {

View file

@ -5,6 +5,7 @@ import { AiOutlineClear } from "react-icons/ai";
import { FaShieldAlt } from "react-icons/fa"; import { FaShieldAlt } from "react-icons/fa";
import { IoTrashBinOutline } from "react-icons/io5"; import { IoTrashBinOutline } from "react-icons/io5";
import { SiGithub, SiGoogle } from "react-icons/si"; import { SiGithub, SiGoogle } from "react-icons/si";
import { GiStarFormation } from "react-icons/gi";
import { api } from "~/utils/api"; import { api } from "~/utils/api";
import type { Role } from "~/utils/types"; import type { Role } from "~/utils/types";
import { getServerAuthSession } from "../../server/auth"; import { getServerAuthSession } from "../../server/auth";
@ -158,70 +159,70 @@ const AdminBody: React.FC = () => {
<div className="stat"> <div className="stat">
<div className="stat-title">Users</div> <div className="stat-title">Users</div>
<div className="stat-value"> <div className="stat-value">
{ usersCountLoading || usersCountFetching ? ( {usersCountLoading || usersCountFetching ? (
<span className="loading loading-dots loading-lg"></span> <span className="loading loading-dots loading-lg"></span>
) : ( ) : (
<>{ usersCount ? usersCount : "0" }</> <>{usersCount ? usersCount : "0"}</>
) } )}
</div> </div>
</div> </div>
<div className="stat"> <div className="stat">
<div className="stat-title">Rooms</div> <div className="stat-title">Rooms</div>
<div className="stat-value"> <div className="stat-value">
{ roomsCountLoading || roomsCountFetching ? ( {roomsCountLoading || roomsCountFetching ? (
<span className="loading loading-dots loading-lg"></span> <span className="loading loading-dots loading-lg"></span>
) : ( ) : (
<>{ roomsCount ? roomsCount : "0" }</> <>{roomsCount ? roomsCount : "0"}</>
) } )}
</div> </div>
</div> </div>
<div className="stat"> <div className="stat">
<div className="stat-title">Votes</div> <div className="stat-title">Votes</div>
<div className="stat-value"> <div className="stat-value">
{ votesCountLoading || votesCountFetching ? ( {votesCountLoading || votesCountFetching ? (
<span className="loading loading-dots loading-lg"></span> <span className="loading loading-dots loading-lg"></span>
) : ( ) : (
<>{ votesCount ? votesCount : "0" }</> <>{votesCount ? votesCount : "0"}</>
) } )}
</div> </div>
</div> </div>
</div> </div>
{ usersCountFetching || {usersCountFetching ||
usersFetching || usersFetching ||
roomsCountFetching || roomsCountFetching ||
votesCountFetching ? ( votesCountFetching ? (
<span className="loading loading-dots loading-lg"></span> <span className="loading loading-dots loading-lg"></span>
) : ( ) : (
<div className="flex flex-row flex-wrap text-center items-center justify-center gap-2"> <div className="flex flex-row flex-wrap text-center items-center justify-center gap-2">
<button <button
className="btn btn-primary m-2" className="btn btn-primary m-2"
onClick={ () => void clearSessionsHandler() } onClick={() => void clearSessionsHandler()}
> >
Delete All Sessions Delete All Sessions
</button> </button>
<button <button
className="btn btn-primary" className="btn btn-primary"
onClick={ () => void refetchData() } onClick={() => void refetchData()}
> >
Re-fetch Re-fetch
</button> </button>
</div> </div>
) } )}
<div className="card max-w-[80vw] bg-neutral shadow-xl m-4"> <div className="card max-w-[80vw] bg-neutral shadow-xl m-4">
<div className="card-body"> <div className="card-body">
<h2 className="card-title">Users:</h2> <h2 className="card-title">Users:</h2>
{ usersLoading || usersFetching ? ( {usersLoading || usersFetching ? (
<span className="loading loading-dots loading-lg"></span> <span className="loading loading-dots loading-lg"></span>
) : ( ) : (
<div className="overflow-x-scroll"> <div className="overflow-x-scroll">
<table className="table text-center"> <table className="table text-center">
{/* head */ } {/* head */}
<thead> <thead>
<tr className="border-white"> <tr className="border-white">
<th>ID</th> <th>ID</th>
@ -233,55 +234,72 @@ const AdminBody: React.FC = () => {
</tr> </tr>
</thead> </thead>
<tbody className=""> <tbody className="">
{ users {users
?.sort((user1, user2) => ?.sort((user1, user2) =>
user2.createdAt > user1.createdAt ? 1 : -1 user2.createdAt > user1.createdAt ? 1 : -1
) )
.map((user) => { .map((user) => {
return ( return (
<tr key={ user.id } className="hover"> <tr key={user.id} className="hover">
<td className="max-w-[100px] break-words"> <td className="max-w-[100px] break-words">
{ user.id } {user.id}
</td> </td>
<td className="max-w-[100px] break-normal"> <td className="max-w-[100px] break-normal">
{ user.name } {user.name}
</td> </td>
<td className="max-w-[100px] break-normal"> <td className="max-w-[100px] break-normal">
{ user.createdAt.toLocaleDateString() } {user.createdAt.toLocaleDateString()}
</td> </td>
<td className="max-w-[100px] break-normal"> <td className="max-w-[100px] break-normal">
{ user.sessions.length } {user.sessions.length}
</td> </td>
<td className="max-w-[100px] break-normal"> <td className="max-w-[100px] break-normal">
{ getProviders(user).includes("google") && ( {getProviders(user).includes("google") && (
<SiGoogle className="text-xl m-1 inline-block hover:text-secondary" /> <SiGoogle className="text-xl m-1 inline-block hover:text-secondary" />
) } )}
{ getProviders(user).includes("github") && ( {getProviders(user).includes("github") && (
<SiGithub className="text-xl m-1 inline-block hover:text-secondary" /> <SiGithub className="text-xl m-1 inline-block hover:text-secondary" />
) } )}
</td> </td>
<td> <td>
<button className="m-2"> <button className="m-2">
{ user.role === "ADMIN" ? ( {user.role === "ADMIN" ? (
<FaShieldAlt <FaShieldAlt
className="text-xl inline-block text-primary" className="text-xl inline-block text-primary"
onClick={ () => onClick={() =>
void setUserRoleHandler(user.id, "USER") void setUserRoleHandler(user.id, "USER")
} }
/> />
) : ( ) : (
<FaShieldAlt <FaShieldAlt
className="text-xl inline-block" className="text-xl inline-block"
onClick={ () => onClick={() =>
void setUserRoleHandler(user.id, "ADMIN") void setUserRoleHandler(user.id, "ADMIN")
} }
/> />
) } )}
</button>
<button className="m-2">
{user.role === "VIP" ? (
<GiStarFormation
className="text-xl inline-block text-secondary"
onClick={() =>
void setUserRoleHandler(user.id, "USER")
}
/>
) : (
<GiStarFormation
className="text-xl inline-block"
onClick={() =>
void setUserRoleHandler(user.id, "VIP")
}
/>
)}
</button> </button>
<button <button
className="m-2" className="m-2"
onClick={ () => onClick={() =>
void clearSessionsByUserHandler(user.id) void clearSessionsByUserHandler(user.id)
} }
> >
@ -289,18 +307,18 @@ const AdminBody: React.FC = () => {
</button> </button>
<button <button
className="m-2" className="m-2"
onClick={ () => void deleteUserHandler(user.id) } onClick={() => void deleteUserHandler(user.id)}
> >
<IoTrashBinOutline className="text-xl inline-block hover:text-error" /> <IoTrashBinOutline className="text-xl inline-block hover:text-error" />
</button> </button>
</td> </td>
</tr> </tr>
); );
}) } })}
</tbody> </tbody>
</table> </table>
</div> </div>
) } )}
</div> </div>
</div> </div>
</> </>

View file

@ -8,6 +8,7 @@ import Link from "next/link";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { FaShieldAlt } from "react-icons/fa"; import { FaShieldAlt } from "react-icons/fa";
import { getServerAuthSession } from "~/server/auth"; import { getServerAuthSession } from "~/server/auth";
import { GiStarFormation } from "react-icons/gi";
export const getServerSideProps: GetServerSideProps = async (ctx) => { export const getServerSideProps: GetServerSideProps = async (ctx) => {
const session = await getServerAuthSession(ctx); const session = await getServerAuthSession(ctx);
@ -57,20 +58,23 @@ const HomePageBody: React.FC = () => {
return ( return (
<> <>
<h1 className="flex flex-row flex-wrap text-center justify-center items-center gap-1 text-4xl font-bold mx-auto"> <h1 className="flex flex-row flex-wrap text-center justify-center items-center gap-1 text-4xl font-bold mx-auto">
Hi, { sessionData?.user.name }!{ " " } Hi, {sessionData?.user.name}!{" "}
{ sessionData?.user.role === "ADMIN" && ( {sessionData?.user.role === "ADMIN" && (
<FaShieldAlt className="inline-block text-primary" /> <FaShieldAlt className="inline-block text-primary" />
) } )}
{sessionData?.user.role === "VIP" && (
<GiStarFormation className="inline-block text-secondary" />
)}
</h1> </h1>
<div className="tabs tabs-boxed border-2 border-cyan-500 mb-4"> <div className="tabs tabs-boxed border-2 border-cyan-500 mb-4">
<a <a
className={ className={
tabIndex === 0 ? "tab no-underline tab-active" : "tab no-underline" tabIndex === 0 ? "tab no-underline tab-active" : "tab no-underline"
} }
onClick={ () => { onClick={() => {
setTabIndex(0); setTabIndex(0);
localStorage.setItem("dashboardTabIndex", "0"); localStorage.setItem("dashboardTabIndex", "0");
} } }}
> >
Join a Room Join a Room
</a> </a>
@ -78,36 +82,36 @@ const HomePageBody: React.FC = () => {
className={ className={
tabIndex === 1 ? "tab no-underline tab-active" : "tab no-underline" tabIndex === 1 ? "tab no-underline tab-active" : "tab no-underline"
} }
onClick={ () => { onClick={() => {
setTabIndex(1); setTabIndex(1);
localStorage.setItem("dashboardTabIndex", "1"); localStorage.setItem("dashboardTabIndex", "1");
} } }}
> >
Room List Room List
</a> </a>
</div> </div>
{ tabIndex === 0 && ( {tabIndex === 0 && (
<> <>
<input <input
type="text" type="text"
placeholder="Enter Room ID" placeholder="Enter Room ID"
className="input input-bordered input-primary mb-4" className="input input-bordered input-primary mb-4"
onChange={ (event) => { onChange={(event) => {
console.log(event.target.value); console.log(event.target.value);
setJoinRoomTextBox(event.target.value); setJoinRoomTextBox(event.target.value);
} } }}
/> />
<Link <Link
href={ joinRoomTextBox.length > 0 ? `/room/${joinRoomTextBox}` : "/" } href={joinRoomTextBox.length > 0 ? `/room/${joinRoomTextBox}` : "/"}
className="btn btn-secondary" className="btn btn-secondary"
> >
Join Room Join Room
</Link> </Link>
</> </>
) } )}
{ tabIndex === 1 && <RoomList /> } {tabIndex === 1 && <RoomList />}
</> </>
); );
}; };

View file

@ -311,10 +311,10 @@ const RoomBody: React.FC = ({}) => {
<FaShieldAlt className="inline-block text-primary" /> <FaShieldAlt className="inline-block text-primary" />
</div> </div>
)}{" "} )}{" "}
{presenceItem.data.role === "MATT" && ( {presenceItem.data.role === "VIP" && (
<div <div
className="tooltip tooltip-secondary" className="tooltip tooltip-secondary"
data-tip="Matt" data-tip="VIP"
> >
<GiStarFormation className="inline-block text-secondary" /> <GiStarFormation className="inline-block text-secondary" />
</div> </div>

View file

@ -153,7 +153,11 @@ export const userRouter = createTRPCRouter({
.input( .input(
z.object({ z.object({
userId: z.string(), userId: z.string(),
role: z.union([z.literal("ADMIN"), z.literal("USER")]), role: z.union([
z.literal("ADMIN"),
z.literal("USER"),
z.literal("VIP"),
]),
}) })
) )
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {

View file

@ -10,7 +10,7 @@ export type EventType = BetterEnum<typeof EventTypes>;
const RoleValues = { const RoleValues = {
ADMIN: "ADMIN", ADMIN: "ADMIN",
USER: "USER", USER: "USER",
MATT: "MATT", VIP: "VIP",
} as const; } as const;
export type Role = BetterEnum<typeof RoleValues>; export type Role = BetterEnum<typeof RoleValues>;