Skip to content

Commit

Permalink
Merge pull request #426 from Twenty-Three-Fifty-Nine/75-a-page-to-sho…
Browse files Browse the repository at this point in the history
…w-upcoming-handins-or-assignments-missing-grades

Upcoming assessments page
  • Loading branch information
JJeeff248 authored Apr 17, 2023
2 parents 4936982 + c28d42a commit 74bbb7d
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 10 deletions.
14 changes: 11 additions & 3 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
} from "@mui/material";

import AccountMenu from "./account-menu/AccountMenu";
import AssessmentsOverview from "./overview/AssessmentsOverview";
import Axios from "axios";
import Cookies from "universal-cookie";
import CourseViewer from "./course-viewer/CourseViewer";
Expand Down Expand Up @@ -68,7 +69,7 @@ const App = () => {
const [viewedCourse, setViewedCourse] = React.useState(null);
const [sessionData, setSessionData] = React.useState(null);
const [courseList, setCourseList] = React.useState(null);

const [viewAssessments, setViewAssessments] = React.useState(null);
// Email verification/reset related states.
const location = useLocation();
const [resetData, setResetData] = React.useState(null);
Expand Down Expand Up @@ -156,6 +157,9 @@ const App = () => {
if (isMobile) return viewedCourse ? viewedCourse.code : userDetails.displayName;

const name = userDetails.displayName + (userDetails.displayName[userDetails.displayName.length - 1] === "s" ? "'" : "'s")

if (viewAssessments && !viewedCourse) return name + " Upcoming Assessments";

return viewedCourse ? name + " " + viewedCourse.code : name + " Overview";
};

Expand All @@ -166,13 +170,16 @@ const App = () => {

if (viewedCourse)
return <CourseViewer courseData={viewedCourse} setViewedCourse={setViewedCourse} userDetails={userDetails}
setSessionData={setSessionData} sessionData={sessionData} setCourseList={setCourseList}/>;
setSessionData={setSessionData} sessionData={sessionData} setCourseList={setCourseList} viewAssessments={viewAssessments} />;

if (viewAssessments)
return <AssessmentsOverview setViewAssessments={setViewAssessments} viewAssessments={viewAssessments} setViewedCourse={setViewedCourse} />;

if (!verifying)
return <GradesOverview userEmail={userDetails.email} userName={userDetails.name} verifiedEmail={userDetails.verifiedEmail} activateTab={activateTab}
sessionData={sessionData} setSessionData={setSessionData} courseList={courseList} setCourseList={setCourseList} setActivateTab={setActivateTab}
selectedYear={selectedYear} setYear={setYear} setViewedCourse={setViewedCourse} activeTri={activeTri} accordionsOpen={accordionsOpen}
setAccordionsOpen={setAccordionsOpen} updatedYear={updatedYear} setUpdatedYear={setUpdatedYear}/>;
setAccordionsOpen={setAccordionsOpen} updatedYear={updatedYear} setUpdatedYear={setUpdatedYear} setViewAssessments={setViewAssessments} />;

return null;
}
Expand Down Expand Up @@ -215,6 +222,7 @@ const App = () => {
lightMode={lightMode}
inCourseViewer={viewedCourse}
deletedAccount={() => setDeletedAccount(true)}
setViewAssessments={setViewAssessments}
/>
) : (
<FormControlLabel
Expand Down
4 changes: 3 additions & 1 deletion src/account-menu/AccountMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const AccountMenu = (props) => {
setNewLogout,
setSessionData,
setUserDetails,
setViewAssessments,
setViewedCourse,
toggleTheme,
userDetails,
Expand All @@ -82,11 +83,12 @@ const AccountMenu = (props) => {
setSessionData(null);
setCourseList(null)
setViewedCourse(null);
setViewAssessments(null);
setConfirmDeleteAccount(false);
setNewLogout(true);

new Cookies().remove("userDetails", { path: "/", sameSite: "strict" });
}, [setIsLoggedIn, setUserDetails, setSessionData, setCourseList, setViewedCourse, setNewLogout]);
}, [setIsLoggedIn, setUserDetails, setSessionData, setCourseList, setViewedCourse, setViewAssessments, setNewLogout]);

return (
<Box sx={{ mr: 2 }}>
Expand Down
3 changes: 2 additions & 1 deletion src/course-viewer/CourseViewer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const CourseViewer = (props) => {
setSessionData,
setViewedCourse,
userDetails,
viewAssessments,
} = props;

// Tracks whether the user can perform a valid, non-empty save.
Expand Down Expand Up @@ -432,7 +433,7 @@ const CourseViewer = (props) => {

{ !isMobile &&
<Box>
<Tooltip title={<h3> Return to overview </h3>} placement="right" arrow>
<Tooltip title={viewAssessments ? <h3> Return to assessments </h3> : <h3> Return to overview </h3>} placement="right" arrow>
<Fab color="primary" onClick={attemptClose} sx={{ position: "fixed", bottom: 32, left: 32 }}>
<KeyboardArrowLeftIcon fontSize="large" />
</Fab>
Expand Down
148 changes: 148 additions & 0 deletions src/overview/AssessmentsOverview.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
/**
* Twenty Three Fifty Nine - Grade tracking tool
* Copyright (C) 2023 Abdulrahman Asfari and Christopher E Sa
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>
*/

import React, { useCallback } from "react";
import {
AppBar,
Box,
Button,
Card,
CardContent,
Fab,
IconButton,
Stack,
Toolbar,
Tooltip,
Typography,
} from "@mui/material";

import dayjs from "dayjs";
import { isMobile } from "react-device-detect";

import CloseRoundedIcon from '@mui/icons-material/CloseRounded';
import KeyboardArrowLeftIcon from "@mui/icons-material/KeyboardArrowLeft";

const AssessmentsOverview = (props) => {
const {
setViewedCourse,
setViewAssessments,
viewAssessments,
} = props;

const { triInfo, courses } = viewAssessments;

/** The assessments to display */
const [assessments, setAssessments] = React.useState([]);

/** Alternative to clicking the return button. */
const handleKeyDown = useCallback((event) => {
if (event.key === "Escape") {
setViewAssessments(null)
}
}, [setViewAssessments]);

React.useEffect(() => {
const asses = courses.map((course) => course.assessments.map((assessment) => {
assessment.course = course.code;
return assessment;
})).flat().filter((assessment) => {
return isNaN(assessment.grade);
}).sort((a, b) => {
return new dayjs(a.deadline).isBefore(new dayjs(b.deadline)) ? -1 : 1;
})
setAssessments(asses);
}, [courses, handleKeyDown])

/** Adds and removes keylistener when the component mounts or unmounts */
React.useEffect(() => {
document.addEventListener("keydown", handleKeyDown, false);
return () => {
document.removeEventListener("keydown", handleKeyDown, false);
};
}, [handleKeyDown]);

return (
<Box>
{ isMobile && (
<AppBar position="fixed" component="nav">
<Toolbar>
<IconButton color="inherit" onClick={() => setViewAssessments(null)}>
<CloseRoundedIcon />
</IconButton>
<Typography variant="body1" sx={{ mx: .5, textAlign: "center" }}>
Assessments for Trimester {triInfo.tri}, {triInfo.year}
</Typography>
</Toolbar>
</AppBar>
)}

<Box sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}}>

{!isMobile && <Typography variant="h4" sx={{ my: 3, textAlign: "center" }}>
Assessments for Trimester {triInfo.tri}, {triInfo.year}
</Typography>}

<Stack spacing={2} sx={{ mb: 5 }}>
{assessments.map((assessment) => (
<Card key={assessment.deadline + assessment.name + assessment.course} sx={{ width: isMobile ? 300 : 500}}>
<CardContent sx={{ "&:last-child": { pb: 2 }, py: 2 }}>
<Box sx={{ display: "flex", flexDirection: "row", justifyContent: "space-between", alignItems: "center" }}>
<Typography variant="h6" sx={[{ flexGrow: 1, width: isMobile ? 200 : 275, mr: 1, overflow: "hidden", whiteSpace: "nowrap", textOverflow: "ellipsis" }]}>
{assessment.name}
</Typography>
<Typography variant="body1" color="text.secondary">{assessment.course}</Typography>
</Box>

<Box>
<Typography variant={"body1"} component="div" >
Due: {new dayjs(assessment.deadline).format("DD/MM/YYYY")}
{new dayjs(assessment.deadline).isBefore(new dayjs()) && <Typography color="error">Overdue</Typography>}
</Typography>
<Box sx={{ display: "flex", flexDirection: "row", justifyContent: "space-between", alignItems: "center" }}>
<Typography variant={"body1"} component="div">
Worth: {assessment.weight}%
</Typography>
<Button variant="text" onClick={() => {
setViewedCourse(courses.find((course) => course.code === assessment.course));
}}>Update</Button>
</Box>
</Box>
</CardContent>
</Card>
))
}
</Stack>

{ !isMobile && (
<Tooltip title={<h3> Return to overview </h3>} placement="right" arrow>
<Fab color="primary" sx={{ position: "fixed", bottom: 32, left: 32 }} onClick={() => {setViewAssessments(null)}}>
<KeyboardArrowLeftIcon fontSize="large" />
</Fab>
</Tooltip>
)}
</Box>
</Box>
)
}

export default AssessmentsOverview;
3 changes: 2 additions & 1 deletion src/overview/GradesOverview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ const GradesOverview = (props) => {
setCourseList,
setSessionData,
setUpdatedYear,
setViewAssessments,
setViewedCourse,
setYear,
updatedYear,
Expand Down Expand Up @@ -174,7 +175,7 @@ const GradesOverview = (props) => {
{ !courseCreator &&
<Box>
<YearOverview setViewedCourse={setViewedCourse} updatedYear={updatedYear} setUpdatedYear={setUpdatedYear}
accordionsOpen={accordionsOpen} setAccordionsOpen={setAccordionsOpen} />
accordionsOpen={accordionsOpen} setAccordionsOpen={setAccordionsOpen} setViewAssessments={setViewAssessments} />

<Tooltip title={ isMobile ? "" : <h3> Add a new course </h3> } placement="left" arrow>
<Box>
Expand Down
8 changes: 7 additions & 1 deletion src/overview/TrimesterOverview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
AccordionDetails,
Alert,
Box,
Button,
Chip,
Skeleton,
Stack,
Expand All @@ -48,6 +49,7 @@ const getActiveChip = (triInfo) => {
const TrimesterOverview = (props) => {
const {
open,
setViewAssessments,
setViewedCourse,
toggleAccordion,
triInfo,
Expand All @@ -62,7 +64,11 @@ const TrimesterOverview = (props) => {
<Accordion expanded={open} onChange={() => toggleAccordion(triInfo.tri)} key={triInfo.tri}>
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
<Typography sx={{ pt: 0.5 }}> Trimester {triInfo.tri} </Typography>
{ getActiveChip(triInfo) }
{ getActiveChip(triInfo) }
{ triInfo.isActive && <Button variant="outlined" size="small" sx={{ mx: 2 }} onClick={(e) => {
e.stopPropagation();
setViewAssessments({triInfo, courses: courses[triInfo.year][triInfo.tri - 1]});
}}>Assessments</Button> }
</AccordionSummary>

<AccordionDetails>
Expand Down
7 changes: 4 additions & 3 deletions src/overview/YearOverview.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const YearOverview = (props) => {
accordionsOpen,
setAccordionsOpen,
setUpdatedYear,
setViewAssessments,
setViewedCourse,
updatedYear,
} = props;
Expand Down Expand Up @@ -101,9 +102,9 @@ const YearOverview = (props) => {
return (
<Box>
<Stack spacing={1} sx={{ zIndex: 0 }}>
<TrimesterOverview triInfo={getTriInfo(1)} open={accordionsOpen ? accordionsOpen[0] : false} toggleAccordion={toggleAccordion} setViewedCourse={setViewedCourse} />
<TrimesterOverview triInfo={getTriInfo(2)} open={accordionsOpen ? accordionsOpen[1] : false} toggleAccordion={toggleAccordion} setViewedCourse={setViewedCourse} />
<TrimesterOverview triInfo={getTriInfo(3)} open={accordionsOpen ? accordionsOpen[2] : false} toggleAccordion={toggleAccordion} setViewedCourse={setViewedCourse} />
<TrimesterOverview triInfo={getTriInfo(1)} open={accordionsOpen ? accordionsOpen[0] : false} toggleAccordion={toggleAccordion} setViewedCourse={setViewedCourse} setViewAssessments={setViewAssessments} />
<TrimesterOverview triInfo={getTriInfo(2)} open={accordionsOpen ? accordionsOpen[1] : false} toggleAccordion={toggleAccordion} setViewedCourse={setViewedCourse} setViewAssessments={setViewAssessments} />
<TrimesterOverview triInfo={getTriInfo(3)} open={accordionsOpen ? accordionsOpen[2] : false} toggleAccordion={toggleAccordion} setViewedCourse={setViewedCourse} setViewAssessments={setViewAssessments} />
</Stack>

<Alert severity="info" sx={{ mt: 1, mb: isMobile ? 10 : 2 }} iconMapping={{ info: <InfoOutlinedIcon sx={{ "&:hover": { cursor: "pointer" } }} onClick={() => { setGPAClicked(true) }}/> }}> Current GPA for the Year: {getGPA()} </Alert>
Expand Down

0 comments on commit 74bbb7d

Please sign in to comment.