Skip to content

Commit

Permalink
Merge pull request #163 from cisagov/RSC-Dashboard
Browse files Browse the repository at this point in the history
Optimizations for ReadySetCyber Header, Dashboard, and Assessment
  • Loading branch information
cduhn17 authored Apr 15, 2024
2 parents b27dfa2 + a5d54f7 commit 59d8647
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 34 deletions.
16 changes: 8 additions & 8 deletions frontend/src/components/ReadySetCyber/RSCDashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import Stack from '@mui/material/Stack';
import Divider from '@mui/material/Divider';
import { RSCSideNav } from './RSCSideNav';
import { RSCResult } from './RSCResult';

import { dummyResults } from './dummyData';

const results = dummyResults;
Expand All @@ -14,10 +13,10 @@ export const RSCDashboard: React.FC = () => {
return (
<Box sx={{ flexGrow: 1, padding: 2 }}>
<Grid container spacing={2}>
<Grid item xs={4}>
<Grid item sm={4} sx={{ display: { xs: 'none', sm: 'grid' } }}>
<RSCSideNav />
</Grid>
<Grid item xs={8}>
<Grid item xs={12} sm={8}>
<Box sx={{ flexGrow: 1, padding: 2, backgroundColor: 'white' }}>
<Stack>
<h2>Assessment Results</h2>
Expand All @@ -34,18 +33,19 @@ export const RSCDashboard: React.FC = () => {
platform, for free vulnerability scanning services to kickstart
or enhance your cybersecurity measures.
</p>
{results.map((result) => (
<Stack key={result.id} spacing={2}>
<Stack spacing={2}>
{results.map((result) => (
<RSCResult
key={result.id}
id={result.id}
type={result.type}
date={result.date}
categories={result.categories}
questions={result.questions}
/>
<Divider />
</Stack>
))}
))}
</Stack>
<Divider />
</Stack>
</Box>
</Grid>
Expand Down
41 changes: 33 additions & 8 deletions frontend/src/components/ReadySetCyber/RSCDetail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@ import { RSCSideNav } from './RSCSideNav';
import { RSCResult } from './RSCResult';
import { RSCQuestion } from './RSCQuestion';
import { dummyResults } from './dummyData';
import { Typography } from '@mui/material';
import {
Accordion,
AccordionSummary,
AccordionDetails,
Typography
} from '@mui/material';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';

export const RSCDetail: React.FC = () => {
const { id } = useParams<{ id: string }>();
Expand All @@ -21,13 +27,17 @@ export const RSCDetail: React.FC = () => {
const { questions } = dummyResults.find(
(result) => result.id === parseInt(id)
) || { questions: [] };

const categories =
dummyResults.find((result) => result.id === parseInt(id))?.categories || [];

return (
<Box sx={{ flexGrow: 1, padding: 2 }}>
<Grid container spacing={2}>
<Grid item xs={4}>
<Grid item sm={4} sx={{ display: { xs: 'none', sm: 'grid' } }}>
<RSCSideNav />
</Grid>
<Grid item xs={8}>
<Grid item xs={12} sm={8}>
<Box sx={{ flexGrow: 1, padding: 2, backgroundColor: 'white' }}>
<Stack>
<Stack
Expand Down Expand Up @@ -66,12 +76,27 @@ export const RSCDetail: React.FC = () => {
/>
</Box>
<br />
{questions.map((question) => (
<>
<Accordion sx={{ display: { xs: 'block', sm: 'none' } }}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
{' '}
Categories
</AccordionSummary>
{categories.map((category) => (
<AccordionDetails key={category.id}>
{category.name}
</AccordionDetails>
))}
</Accordion>
<br />
<Stack spacing={2}>
{questions.map((question) => (
<RSCQuestion key={question.id} question={question} />
<br />
</>
))}
))}
</Stack>
</Stack>
</Box>
</Grid>
Expand Down
190 changes: 179 additions & 11 deletions frontend/src/components/ReadySetCyber/RSCHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,189 @@
import React from 'react';
import { AppBar } from '@mui/material';
import { Toolbar } from '@mui/material';
import { Typography } from '@mui/material';
import { useHistory } from 'react-router-dom';
import { useAuthContext } from 'context';
import {
AppBar,
Toolbar,
Container,
Box,
Typography,
IconButton,
Menu,
MenuItem,
Tooltip
} from '@mui/material';
import AccountCircle from '@mui/icons-material/AccountCircle';
import MenuIcon from '@mui/icons-material/Menu';
import RSCLogo from 'components/ReadySetCyber/assets/ReadySetCyberLogo.png';

export const RSCHeader: React.FC = () => {
const history = useHistory();
const handleClick = () => {
const handleNavHome = () => {
history.push('/readysetcyber');
};
const { logout, user } = useAuthContext();

const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const [anchorElNav, setAnchorElNav] = React.useState<null | HTMLElement>(
null
);

const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorElNav(event.currentTarget);
};

const handleMenu = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(event.currentTarget);
};

const handleCloseNavMenu = () => {
setAnchorElNav(null);
};

const handleClose = () => {
setAnchorEl(null);
};

return (
<AppBar position="static">
<Toolbar>
<Typography variant="h6" onClick={handleClick}>
Ready Set Cyber
</Typography>
</Toolbar>
</AppBar>
<Box sx={{ flexGrow: 1 }}>
<AppBar position="static" sx={{ bgcolor: 'white' }}>
<Container maxWidth="xl">
<Toolbar disableGutters>
<Tooltip title="Go to Ready Set Cyber" arrow>
<IconButton
onClick={handleNavHome}
sx={{ display: { xs: 'none', md: 'flex' }, mr: 1 }}
style={{ backgroundColor: 'white', outline: 'none' }}
disableFocusRipple
>
<img
src={RSCLogo}
alt="Ready Set Cyber Logo"
style={{
width: '4em',
height: '2em'
}}
/>
</IconButton>
</Tooltip>
<Typography
variant="h6"
component="div"
sx={{
flexGrow: 1,
color: '#07648D',
display: { xs: 'none', md: 'flex' },
mr: 2
}}
>
Dashboard
</Typography>
<Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}>
<Tooltip title="Go to Ready Set Cyber" arrow>
<IconButton
onClick={handleNavHome}
sx={{ display: { xs: 'flex', md: 'none' }, mr: 0 }}
style={{ backgroundColor: 'white', outline: 'none' }}
>
<img
src={RSCLogo}
alt="Ready Set Cyber Logo"
style={{
width: '4em',
height: '2em'
}}
/>
</IconButton>
</Tooltip>
</Box>
{user && (
<>
<IconButton
size="large"
aria-label="nav menu"
aria-controls="menu-navbar"
aria-haspopup="true"
color="primary"
onClick={handleOpenNavMenu}
style={{ outline: 'none' }}
sx={{ display: { xs: 'block', md: 'none' } }}
>
<MenuIcon />
</IconButton>
<Menu
id="menu-appbar"
anchorEl={anchorElNav}
anchorOrigin={{
vertical: 'top',
horizontal: 'right'
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right'
}}
open={Boolean(anchorElNav)}
onClose={handleCloseNavMenu}
sx={{ display: { xs: 'block', md: 'none' } }}
>
<MenuItem style={{ outline: 'none' }}>
{' '}
Welcome, user
</MenuItem>
<MenuItem style={{ outline: 'none' }} onClick={handleNavHome}>
Dashboard
</MenuItem>
<MenuItem style={{ outline: 'none' }}>
{' '}
Take Questionnaire Again{' '}
</MenuItem>
<MenuItem style={{ outline: 'none' }} onClick={logout}>
Logout
</MenuItem>
</Menu>
</>
)}
{user && (
<Box sx={{ flexGrow: 0, display: { xs: 'none', md: 'flex' } }}>
<Tooltip title="Open Menu" arrow>
<IconButton
sx={{ p: 0 }}
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
color="primary"
onClick={handleMenu}
style={{ outline: 'none' }}
>
<AccountCircle />
</IconButton>
</Tooltip>
<Menu
sx={{ marginTop: '40px' }}
id="menu-appbar"
anchorEl={anchorEl}
anchorOrigin={{
vertical: 'top',
horizontal: 'right'
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right'
}}
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem style={{ outline: 'none' }} onClick={logout}>
Logout
</MenuItem>
</Menu>
</Box>
)}
</Toolbar>
</Container>
</AppBar>
</Box>
);
};
33 changes: 26 additions & 7 deletions frontend/src/components/ReadySetCyber/RSCQuestion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Stack from '@mui/material/Stack';
import Button from '@mui/material/Button';
import Grid from '@mui/material/Grid';

interface Props {
question: {
Expand All @@ -21,23 +22,41 @@ export const RSCQuestion: React.FC<Props> = (props) => {
const question = props.question;
const answers = props.question.answers;
return (
<div>
<Box
sx={{ width: '100%', bgcolor: '#D3D3D3', padding: 2, borderRadius: 2 }}
>
<Box
sx={{ width: 'auto', bgcolor: '#D3D3D3', padding: 2, borderRadius: 2 }}
>
<Stack spacing={2}>
<Typography variant="h6" gutterBottom component="div">
Question {question.id}
</Typography>
<Typography variant="h6" gutterBottom component="div">
{question.title}
</Typography>
<Stack direction="row" spacing={2} padding={2} paddingLeft={0}>
<Stack
direction="row"
spacing={2}
sx={{ display: { xs: 'none', sm: 'flex' } }}
>
{answers.map((answer) => (
<Button key={answer.id} variant="contained" color="primary">
{answer.name}{' '}
</Button>
))}
</Stack>
<Grid container spacing={2} alignSelf={'flex-end'}>
{answers.map((answer) => (
<Grid
item
xs={6}
key={answer.id}
sx={{ display: { xs: 'grid', sm: 'none' } }}
>
<Button variant="contained" color="primary">
{answer.name}{' '}
</Button>
</Grid>
))}
</Grid>
<Box
sx={{
width: '100%',
Expand All @@ -51,7 +70,7 @@ export const RSCQuestion: React.FC<Props> = (props) => {
<h5>Resource Title</h5>
<p>Resource Description</p>
</Box>
</Box>
</div>
</Stack>
</Box>
);
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 59d8647

Please sign in to comment.