101 lines
No EOL
4.7 KiB
TypeScript
101 lines
No EOL
4.7 KiB
TypeScript
/**
|
|
* Grades interface
|
|
*/
|
|
import {Ascending, Assignment, Page, Section, SortSettings} from "../interfaces";
|
|
import React, {useContext, useMemo, useState} from "react";
|
|
import AssignmentsTable, {AssignmentsTableColumn} from "../components/tables/AssignmentsTable";
|
|
import Button from "react-bootstrap/Button";
|
|
import {ArrowLeft} from "react-bootstrap-icons";
|
|
import Row from "react-bootstrap/Row";
|
|
import Col from "react-bootstrap/Col";
|
|
import Alert from "react-bootstrap/Alert";
|
|
import FinalGradesTable from "../components/tables/FinalGradesTable";
|
|
import {FormattedDate, TimeRange} from "../components/datetime";
|
|
import {globalContext} from "../contexts";
|
|
import {Accordion} from "react-bootstrap";
|
|
import Table from "react-bootstrap/Table";
|
|
import SortSelect from "../components/input/SortSelect";
|
|
|
|
const columns = [AssignmentsTableColumn.DUEDATE, AssignmentsTableColumn.NAME, AssignmentsTableColumn.CATEGORY, AssignmentsTableColumn.WEIGHT, AssignmentsTableColumn.SCORE];
|
|
|
|
// TODO: Sorting is fucked
|
|
|
|
export default function GradesInterface({section}: { section: Section }) {
|
|
const {setCurrentPage} = useContext(globalContext);
|
|
// @ts-ignore
|
|
const assignments: Assignment[] = section.assignments;
|
|
const [sortSetings, setSortSettings] = useState<SortSettings<AssignmentsTableColumn>>({
|
|
by: AssignmentsTableColumn.DUEDATE,
|
|
order: Ascending
|
|
});
|
|
|
|
const currentTime = useMemo(() => new Date(), []);
|
|
const upcomingClasses = useMemo(() => section.startStopDates
|
|
.filter(s => currentTime.getTime() < s.stop.getTime())
|
|
.sort((a, b) => a.start.getTime() - b.start.getTime())
|
|
, [section.startStopDates, currentTime]);
|
|
|
|
return (
|
|
<>
|
|
<Alert variant="warning">The current grades table does not show assignment flags (missing, late, etc)</Alert>
|
|
<Button variant="outline-secondary" onClick={() => setCurrentPage(Page.sections)}>
|
|
<ArrowLeft/> Courses
|
|
</Button>
|
|
<Row>
|
|
<Col>
|
|
<h1>{section.schoolCourseTitle}</h1>
|
|
<p>Yeah this page is sorta ugly. This is temporary.</p>
|
|
</Col>
|
|
{/* Accordion with grades and upcoming classes. This is probably big enough to warrant a separate component */}
|
|
<Col className="my-2">
|
|
<Accordion>
|
|
<Accordion.Item eventKey="0">
|
|
<Accordion.Header>Current Grades</Accordion.Header>
|
|
<Accordion.Body>
|
|
<FinalGradesTable section={section}/>
|
|
</Accordion.Body>
|
|
</Accordion.Item>
|
|
<Accordion.Item eventKey="1">
|
|
<Accordion.Header>Upcoming Classes</Accordion.Header>
|
|
<Accordion.Body>
|
|
<Table striped>
|
|
<thead>
|
|
<tr>
|
|
<th>Date</th>
|
|
<th>Time</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{upcomingClasses.map(c =>
|
|
<tr key={c.sectionEnrollmentId}>
|
|
<td><FormattedDate date={c.start}/></td>
|
|
<td><TimeRange date1={c.start} date2={c.stop}/></td>
|
|
</tr>
|
|
)}
|
|
</tbody>
|
|
</Table>
|
|
</Accordion.Body>
|
|
</Accordion.Item>
|
|
</Accordion>
|
|
</Col>
|
|
</Row>
|
|
<Row className="justify-content-end">
|
|
<Col>
|
|
<h2>Assignments</h2>
|
|
</Col>
|
|
{/* Grade sort thing. Only display if the table also displays */}
|
|
{assignments.length !== 0 &&
|
|
<Col sm={4} md={4}>
|
|
<SortSelect settings={sortSetings} setSettings={setSortSettings} sortByOptions={columns}/>
|
|
</Col>
|
|
}
|
|
</Row>
|
|
{assignments.length === 0
|
|
? <p>No assignments!</p>
|
|
: <AssignmentsTable assignments={assignments} columns={columns} sort={sortSetings}/>
|
|
}
|
|
</>
|
|
// TODO: Display flags (missing, collected, incomplete, etc)
|
|
// TODO: Deal with extra credit (2/0). That fucks everything up and I'm too tired to figure it out
|
|
)
|
|
}; |