diff --git a/client/src/App.tsx b/client/src/App.tsx index a3e33fa..6a2d060 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -29,6 +29,7 @@ import OAuthCallback from './pages/AuthManager/callback/AuthCallback'; const App: React.FC = () => { const [isAuthenticated, setIsAuthenticated] = useState(ApiService.isLoggedIn()); const [isTeacherAuthenticated, setIsTeacherAuthenticated] = useState(ApiService.isLoggedInTeacher()); + const [isAdmin, setIsAdmin] = useState(false); const [isRoomRequireAuthentication, setRoomsRequireAuth] = useState(null); const location = useLocation(); @@ -37,6 +38,7 @@ const App: React.FC = () => { const checkLoginStatus = () => { setIsAuthenticated(ApiService.isLoggedIn()); setIsTeacherAuthenticated(ApiService.isLoggedInTeacher()); + //setIsAdmin(ApiService.isAdmin()); }; const fetchAuthenticatedRooms = async () => { @@ -56,7 +58,7 @@ const App: React.FC = () => { return (
-
+
diff --git a/client/src/__tests__/components/AdminDrawer/AdminDrawer.test.tsx b/client/src/__tests__/components/AdminDrawer/AdminDrawer.test.tsx new file mode 100644 index 0000000..fe68167 --- /dev/null +++ b/client/src/__tests__/components/AdminDrawer/AdminDrawer.test.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { render, screen, fireEvent } from '@testing-library/react'; +import AdminDrawer from '../../../components/AdminDrawer/AdminDrawer'; +import '@testing-library/jest-dom'; + +describe('AdminDrawer Component', () => { + test('renders the Admin button', () => { + render(); + + // Check if the "Admin" button is in the document + const button = screen.getByRole('button', { name: /admin/i }); + expect(button).toBeInTheDocument(); + }); + + test('opens the drawer when the button is clicked', () => { + render(); + + // Click the "Admin" button + const button = screen.getByRole('button', { name: /admin/i }); + fireEvent.click(button); + + // Check if the drawer is open (it should be a right-side drawer, so check for list items) + const statsItem = screen.getByText(/Stats/i); + expect(statsItem).toBeInTheDocument(); + }); + //TODO modify this test as no redirect as of yet +/* + test('closes the drawer when an item is clicked', () => { + render(); + + // Open the drawer by clicking the "Admin" button + const button = screen.getByRole('button', { name: /admin/i }); + fireEvent.click(button); + + // Click on a menu item (Stats, Images, or Users) + const statsItem = screen.getByText(/Stats/i); + expect(statsItem).toBeInTheDocument(); + fireEvent.click(statsItem); + + // Ensure that the drawer is closed after clicking an item + const statsItemAgain = screen.queryByText(/Stats/i); + expect(statsItemAgain).not.toBeInTheDocument(); + }); +*/ + test('menu items render correctly', () => { + render(); + + // Open the drawer + const button = screen.getByRole('button', { name: /admin/i }); + fireEvent.click(button); + + // Check if all the menu items are rendered + expect(screen.getByText(/Stats/i)).toBeInTheDocument(); + expect(screen.getByText(/Images/i)).toBeInTheDocument(); + expect(screen.getByText(/Users/i)).toBeInTheDocument(); + }); +}); diff --git a/client/src/components/AdminDrawer/AdminDrawer.tsx b/client/src/components/AdminDrawer/AdminDrawer.tsx new file mode 100644 index 0000000..d61df5e --- /dev/null +++ b/client/src/components/AdminDrawer/AdminDrawer.tsx @@ -0,0 +1,64 @@ +import * as React from 'react'; +import Box from '@mui/material/Box'; +import Drawer from '@mui/material/Drawer'; +import Button from '@mui/material/Button'; +import List from '@mui/material/List'; +import ListItem from '@mui/material/ListItem'; +import ListItemButton from '@mui/material/ListItemButton'; +import ListItemIcon from '@mui/material/ListItemIcon'; +import ListItemText from '@mui/material/ListItemText'; +import BarChartIcon from '@mui/icons-material/BarChart'; +import ImageIcon from '@mui/icons-material/Image'; +import PeopleIcon from '@mui/icons-material/People'; + +const styles = { + drawerBg: 'rgba(82, 113, 255, 0.85)', + drawerTxtColor: 'white', + btnBg: 'rgba(82, 113, 255, 1)', + btnHover: 'rgba(65, 105, 225, 0.7)', + height: '100%' +}; + +export default function AdminDrawer() { + const [open, setOpen] = React.useState(false); + + const toggleDrawer = (isOpen: boolean) => () => { + setOpen(isOpen); + }; + + const menuItems = [ + { text: 'Stats', icon: }, + { text: 'Images', icon: }, + { text: 'Users', icon: }, + ]; + + const list = ( + + + {menuItems.map(({ text, icon }) => ( + + + {icon} + + + + ))} + + + ); + + return ( +
+ + + {list} + +
+ ); +} diff --git a/client/src/components/Header/Header.tsx b/client/src/components/Header/Header.tsx index 016d23e..368fc7d 100644 --- a/client/src/components/Header/Header.tsx +++ b/client/src/components/Header/Header.tsx @@ -2,13 +2,15 @@ import { Link, useNavigate } from 'react-router-dom'; import * as React from 'react'; import './header.css'; import { Button } from '@mui/material'; +import AdminDrawer from '../AdminDrawer/AdminDrawer'; interface HeaderProps { isLoggedIn: boolean; + isAdmin: boolean; handleLogout: () => void; } -const Header: React.FC = ({ isLoggedIn, handleLogout }) => { +const Header: React.FC = ({ isLoggedIn, isAdmin, handleLogout }) => { const navigate = useNavigate(); return ( @@ -21,18 +23,24 @@ const Header: React.FC = ({ isLoggedIn, handleLogout }) => { /> {isLoggedIn && ( - +
+ + { isAdmin && } + + +
)} + {!isLoggedIn && (
diff --git a/client/src/components/Header/header.css b/client/src/components/Header/header.css index 379a60d..07aa8cf 100644 --- a/client/src/components/Header/header.css +++ b/client/src/components/Header/header.css @@ -11,4 +11,10 @@ .header img { cursor: pointer; +} + +.button-group { + display: flex; + flex-wrap: wrap; + gap: 10px; } \ No newline at end of file