Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overall grade calculator module #17

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 179 additions & 0 deletions app/components/hub/average/AverageForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import Select from '@mui/material/Select'
import MenuItem from '@mui/material/MenuItem'
import Typography from '@mui/material/Typography'
import InputLabel from '@mui/material/InputLabel'
import FormControl from '@mui/material/FormControl'
import { createContext, useEffect, useState } from 'react'

import { Year } from 'global'
import AverageData from './data'

import {
computeUEAverage,
computeSectorAverage,
computeSemesterAverage,
computeYearAverage,
} from './averageComputing'
import Semesters from './Semesters'
import { importAverageData, saveAverageData } from './averageStorage'

export const AverageContext = createContext({
data: AverageData,
updateData: (
yearIndex: number,
semesterIndex: number,
sectorIndex: number,
ueIndex: number,
subjectIndex: number,
mark: number
) => {},
})

function AverageForm() {
const savedData = importAverageData()

const [averageFormState, setAverageFormState] = useState({
currentYearIndex: savedData.currentYearIndex,
currentSectorIndex: savedData.currentSectorIndex,
})

const [averageDataState, setAverageDataState] = useState<Year[]>(savedData.averageData)

const updateSubjectMark = (
yearIndex: number,
semesterIndex: number,
sectorIndex: number,
ueIndex: number,
subjectIndex: number,
mark: number
) => {
let newState: Year[] = [...averageDataState]

{
let year = newState[yearIndex]

{
let semester = year.semesters[semesterIndex]

{
let sector = semester.sectors[sectorIndex]

{
let ue = sector.ues[ueIndex]

ue.subjects[subjectIndex].mark = mark

ue.average = computeUEAverage(ue)
sector.ues[ueIndex] = ue
}

sector.average = computeSectorAverage(sector)
semester.sectors[sectorIndex] = sector
}

semester.average = computeSemesterAverage(semester, averageFormState.currentSectorIndex)
year.semesters[semesterIndex] = semester
}

year.average = computeYearAverage(year)
newState[yearIndex] = year
}

setAverageDataState(newState)
}

useEffect(() => {
saveAverageData(
averageDataState,
averageFormState.currentYearIndex,
averageFormState.currentSectorIndex
)
}, [averageDataState, averageFormState])

const averageContextValue = {
data: averageDataState,
updateData: updateSubjectMark,
}

const handleYearChange = (event) => {
setAverageFormState({
...averageFormState,
currentYearIndex: event.target.value,
})
}

const handleSectorChange = (event) => {
setAverageFormState({
...averageFormState,
currentSectorIndex: event.target.value,
})
}

const yearInput = (
<FormControl className="m-2">
<InputLabel shrink>Année</InputLabel>
<Select value={averageFormState.currentYearIndex} onChange={handleYearChange}>
{averageDataState.map((year, index) => {
return (
<MenuItem key={'avg-year-' + index} value={index}>
{year.name}
</MenuItem>
)
})}
</Select>
</FormControl>
)

const currentYear = averageDataState[averageFormState.currentYearIndex]

const sectorInput = (() => {
const sectors = averageDataState[averageFormState.currentYearIndex].semesters[0].sectors

return (
<FormControl className="m-2">
<InputLabel shrink>Filière</InputLabel>
<Select
value={averageFormState.currentSectorIndex}
onChange={handleSectorChange}
disabled={!(sectors.length > 1)}
>
{averageDataState[averageFormState.currentYearIndex].semesters[0].sectors?.map(
(sector, index) => {
if (index === 0) {
return null
}

return (
<MenuItem key={'avg-sector-' + index} value={index}>
{sector.name}
</MenuItem>
)
}
)}
</Select>
</FormControl>
)
})()

return (
// @ts-ignore
<AverageContext.Provider value={averageContextValue}>
<div>
{yearInput}
{sectorInput}

<Semesters
yearIndex={averageFormState.currentYearIndex}
sectorIndex={averageFormState.currentSectorIndex}
/>

<br />
<Typography align={'center'} variant="h4">
Moyenne de {currentYear.name} : {currentYear.average ?? 'N/A'}
</Typography>
</div>
</AverageContext.Provider>
)
}

export default AverageForm
151 changes: 151 additions & 0 deletions app/components/hub/average/SectorTable.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
import Box from '@mui/material/Box'
import Paper from '@mui/material/Paper'
import Table from '@mui/material/Table'
import { useState, useContext } from 'react'
import Collapse from '@mui/material/Collapse'
import TableRow from '@mui/material/TableRow'
import TableBody from '@mui/material/TableBody'
import TableCell from '@mui/material/TableCell'
import TableHead from '@mui/material/TableHead'
import IconButton from '@mui/material/IconButton'
import Typography from '@mui/material/Typography'
import TableContainer from '@mui/material/TableContainer'

import KeyboardArrowUp from '@mui/icons-material/KeyboardArrowUpTwoTone'
import KeyboardArrowDown from '@mui/icons-material/KeyboardArrowDownTwoTone'

import Subject from './Subject'
import { AverageContext } from './AverageForm'

function UERow(props: {
yearIndex: number
semesterIndex: number
sectorIndex: number
ueIndex: number
}) {
const { yearIndex, semesterIndex, sectorIndex, ueIndex } = props

const [open, setOpen] = useState(false)
const averageContext = useContext(AverageContext)
const ue =
averageContext.data[yearIndex].semesters[semesterIndex].sectors[sectorIndex].ues[ueIndex]

return (
<>
<TableRow>
<TableCell>
<IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)}>
{open ? <KeyboardArrowUp /> : <KeyboardArrowDown />}
</IconButton>
</TableCell>
<TableCell component="th" scope="row">
{ue.name}
</TableCell>
<TableCell align={'center'}>{ue.average ?? 'N/A'}</TableCell>
<TableCell align="right">{ue.ects}</TableCell>
</TableRow>
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}>
<Collapse in={open} timeout="auto" unmountOnExit>
<Box>
<Table>
<TableHead>
<TableRow>
<TableCell>Nom</TableCell>
<TableCell>Coefficient</TableCell>
<TableCell align="right">Note</TableCell>
</TableRow>
</TableHead>
<TableBody>
{ue.subjects.map((subject, subjectIndex) => (
<Subject
key={
'sem_' +
semesterIndex +
'sect_' +
sectorIndex +
'_ue_' +
ueIndex +
'_subj_' +
subjectIndex
}
yearIndex={yearIndex}
semesterIndex={semesterIndex}
sectorIndex={sectorIndex}
ueIndex={ueIndex}
subjectIndex={subjectIndex}
/>
))}
<TableRow>
<TableCell component="th" scope="row">
Moyenne
</TableCell>
<TableCell align="center" colSpan={2}>
{ue.average ?? 'N/A'}
</TableCell>
</TableRow>
</TableBody>
</Table>
</Box>
</Collapse>
</TableCell>
</TableRow>
</>
)
}

export default function SectorTable(props: {
yearIndex: number
semesterIndex: number
sectorIndex: number
}) {
const { yearIndex, semesterIndex, sectorIndex } = props

const averageContext = useContext(AverageContext)
const sector = averageContext.data[yearIndex].semesters[semesterIndex].sectors[sectorIndex]

if (sector == null) {
return null
}

return (
<>
<Typography className="pl-4 pt-4" variant="subtitle1">
{sector.name}
</Typography>

<TableContainer component={Paper}>
<Table aria-label="collapsible table">
<TableHead>
<TableRow>
<TableCell />
<TableCell>Nom UE</TableCell>
<TableCell align={'center'}>Moyenne</TableCell>
<TableCell align="right">ETC</TableCell>
</TableRow>
</TableHead>
<TableBody>
{sector.ues.map((ue, ueIndex) => (
<UERow
key={'sem_' + semesterIndex + 'sect_' + sectorIndex + '_ue_' + ueIndex}
yearIndex={yearIndex}
semesterIndex={semesterIndex}
sectorIndex={sectorIndex}
ueIndex={ueIndex}
/>
))}
<TableRow>
<TableCell component="th" scope="row" />
<TableCell component="th" scope="row">
Moyenne de la filière
</TableCell>
<TableCell component="th" scope="row" align={'center'}>
{sector.average ?? 'N/A'}
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</>
)
}
64 changes: 64 additions & 0 deletions app/components/hub/average/Semesters.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useContext } from 'react'
import Typography from '@mui/material/Typography'

import SectorTable from './SectorTable'
import { AverageContext } from './AverageForm'

function Semester(props: { yearIndex: number; semesterIndex: number; sectorIndex: number }) {
const { yearIndex, semesterIndex, sectorIndex } = props

const averageContext = useContext(AverageContext)
const semester = averageContext.data[yearIndex].semesters[semesterIndex]

return (
<>
<br key={'semester_index_' + semesterIndex} />

<Typography key={'semester_title_' + semesterIndex} variant="h4">
Semestre {semesterIndex + 1}
</Typography>

<SectorTable
key={'semester_sector_common_' + semesterIndex}
yearIndex={yearIndex}
semesterIndex={semesterIndex}
sectorIndex={0}
/>

{sectorIndex !== 0 ? (
<SectorTable
key={'semester_sector_' + semesterIndex}
yearIndex={yearIndex}
semesterIndex={semesterIndex}
sectorIndex={sectorIndex}
/>
) : null}

<br />
<Typography key={'semester_avg_' + semesterIndex} variant="h6">
Moyenne du semestre {semesterIndex + 1} : {semester.average ?? 'N/A'}
</Typography>
</>
)
}

export default function Semesters(props: { yearIndex: number; sectorIndex: number }) {
const { yearIndex, sectorIndex } = props

const averageContext = useContext(AverageContext)
const year = averageContext.data[yearIndex]

return (
<>
<br />
{year.semesters.map((semester, semesterIndex) => (
<Semester
key={'semester_' + semesterIndex}
yearIndex={yearIndex}
semesterIndex={semesterIndex}
sectorIndex={sectorIndex}
/>
))}
</>
)
}
Loading