[Study programme] Rewrite progress section with MUI

This commit is contained in:
Riku Rauhala
2025-03-11 13:46:13 +02:00
parent 3b58c13f4a
commit 1ee4fb8bcf
5 changed files with 89 additions and 163 deletions
@@ -1,62 +0,0 @@
import accessibility from 'highcharts/modules/accessibility'
import exportData from 'highcharts/modules/export-data'
import exporting from 'highcharts/modules/exporting'
import ReactHighcharts from 'react-highcharts'
import { generateGradientColors } from '@/util/color'
exporting(ReactHighcharts.Highcharts)
exportData(ReactHighcharts.Highcharts)
accessibility(ReactHighcharts.Highcharts)
interface BarChartProps {
data: {
creditGraphStats: Record<string, { name: string; data: number[] }[]>
years: string[]
}
track: string
}
export const BarChart = ({ data, track }: BarChartProps) => {
if (!data?.creditGraphStats?.[track]) {
return null
}
const correctData = data.creditGraphStats[track]
const colors = generateGradientColors(correctData.length)
const dataWithColors = Object.values(correctData).map((series, index) => ({
...series,
color: colors[index],
type: 'column' as const,
}))
const config = {
series: dataWithColors,
xAxis: {
categories: data?.years,
},
chart: {
type: 'column',
height: '450px',
},
plotOptions: {
column: {
stacking: 'percent' as const,
dataLabels: {
enabled: true,
format: '{point.percentage:.1f}%',
},
},
},
exporting: {
filename: `oodikone_progress_of_students_of_the_studyprogramme_${track}_by_starting_year`,
},
yAxis: {
title: {
text: '',
},
},
}
return <ReactHighcharts config={config} />
}
@@ -1,49 +0,0 @@
import { Table } from 'semantic-ui-react'
interface BasicDataTableProps {
data: Record<string, Array<Array<string | number>>>
titles: string[]
track: string
}
export const BasicDataTable = ({ data, titles, track }: BasicDataTableProps) => {
if (!data?.[track]?.length || !titles) {
return null
}
const sortedData = data[track].toSorted((a, b) => {
if (a[0] === 'Total') return 1
if (b[0] === 'Total') return -1
return parseInt(String(b[0]).split(' - ')[0], 10) - parseInt(String(a[0]).split(' - ')[0], 10)
})
return (
<Table celled compact data-cy="study-track-progress-basic-data-table">
<Table.Header>
<Table.Row>
{titles?.map(title => (
<Table.HeaderCell key={title} textAlign="center">
{title}
</Table.HeaderCell>
))}
</Table.Row>
</Table.Header>
<Table.Body>
{sortedData.map(row => (
<Table.Row key={row[0]}>
{row.map((value, index) => (
<Table.Cell
className={row[0] === 'Total' ? 'total-row-cell' : ''}
// eslint-disable-next-line react/no-array-index-key
key={`${index}-${value}`}
textAlign={index === 0 ? 'center' : 'right'}
>
{value}
</Table.Cell>
))}
</Table.Row>
))}
</Table.Body>
</Table>
)
}
@@ -1,64 +1,58 @@
import { BarChart } from './BarChart'
import { BasicDataTable } from './BasicDataTable'
import { Stack, Typography } from '@mui/material'
interface ProgressStats {
chartStats: Array<{ data: number[]; name: string }>
tableStats: Array<Array<string | number>>
import { ProgressBarChart } from '@/components/material/ProgressBarChart'
import { ProgressTable } from './ProgressTable'
type ProgressStats = {
chartStats: {
data: number[]
name: string
}[]
tableStats: (string | number)[][]
tableTitles: string[]
}
interface ProgressOfStudentsProps {
progressStats: ProgressStats
progressComboStats: ProgressStats
track: string
export const ProgressOfStudents = ({
progressComboStats,
progressStats,
studyProgramme,
years,
}: {
progressComboStats: ProgressStats | null
progressStats: ProgressStats | null
studyProgramme: string
years: string[]
}
export const ProgressOfStudents = ({ progressStats, progressComboStats, track, years }: ProgressOfStudentsProps) => {
}) => {
return (
<div style={{ marginBottom: '4rem', textAlign: 'center' }}>
{progressComboStats != null && (
<>
<h2 style={{ margin: '0 0 1rem 0' }}>Bachelor + master study right</h2>
<div style={{ display: 'flex', alignItems: 'center', gap: '2rem', flexWrap: 'wrap' }}>
<div data-cy="study-track-progress-combo-bar-chart" style={{ flex: '2 1 600px', minWidth: '600px' }}>
<BarChart
data={{
creditGraphStats: { [track]: progressComboStats.chartStats },
years,
}}
track={track}
/>
</div>
<div style={{ flex: '1 2 1000px', minWidth: '1000px' }}>
<BasicDataTable
data={{ [track]: progressComboStats.tableStats }}
titles={progressComboStats.tableTitles}
track={track}
/>
</div>
</div>
</>
)}
{progressComboStats != null && <h2 style={{ margin: '2rem 0 1rem 0' }}>Master study right</h2>}
<div style={{ display: 'flex', alignItems: 'center', gap: '2rem', flexWrap: 'wrap' }}>
<div data-cy="study-track-progress-bar-chart" style={{ flex: '2 1 600px', minWidth: '600px' }}>
<BarChart
<Stack gap={2}>
{progressComboStats !== null && (
<Stack gap={2}>
<Typography variant="h6">Bachelor + master study right</Typography>
<ProgressBarChart
cypress="programme-bachelor-masters"
data={{
creditGraphStats: { [track]: progressStats.chartStats },
id: studyProgramme,
stats: progressComboStats.chartStats,
years,
}}
track={track}
/>
</div>
<div style={{ flex: '1 2 1000px', minWidth: '1000px' }}>
<BasicDataTable
data={{ [track]: progressStats.tableStats }}
titles={progressStats.tableTitles}
track={track}
<ProgressTable data={progressComboStats.tableStats} titles={progressComboStats.tableTitles} />
</Stack>
)}
{progressStats !== null && (
<Stack gap={2}>
{progressComboStats != null && <Typography variant="h6">Master study right</Typography>}
<ProgressBarChart
cypress="programme"
data={{
id: studyProgramme,
stats: progressStats.chartStats,
years,
}}
/>
</div>
</div>
</div>
<ProgressTable data={progressStats.tableStats} titles={progressStats.tableTitles} />
</Stack>
)}
</Stack>
)
}
@@ -0,0 +1,43 @@
import { Paper, TableBody, TableCell, TableContainer, TableHead, TableRow } from '@mui/material'
import { StyledTable } from '@/components/material/StyledTable'
import { getCellKey, getRowKey } from './StudyTrackDataTable/util'
export const ProgressTable = ({ data, titles }: { data: (string | number)[][]; titles: string[] }) => {
if (!data.length || !titles) {
return null
}
const sortedData = data.toSorted((a, b) => {
if (a[0] === 'Total') return 1
if (b[0] === 'Total') return -1
return parseInt(String(b[0]).split(' - ')[0], 10) - parseInt(String(a[0]).split(' - ')[0], 10)
})
return (
<TableContainer component={Paper} variant="outlined">
<StyledTable data-cy="study-programme-progress-table" showCellBorders size="small">
<TableHead>
<TableRow>
{titles?.map((title, index) => (
<TableCell align="center" key={getCellKey(title, index)}>
{title}
</TableCell>
))}
</TableRow>
</TableHead>
<TableBody>
{sortedData.map((row, index) => (
<TableRow key={getRowKey(row[0].toString(), index)}>
{row.map((value, index) => (
<TableCell align={index === 0 ? 'center' : 'right'} key={getCellKey(value.toString(), index)}>
{value}
</TableCell>
))}
</TableRow>
))}
</TableBody>
</StyledTable>
</TableContainer>
)
}
@@ -45,7 +45,7 @@ export const SingleStudyTrackRow = ({
)
}
return (
<TableCell align="left" key={getCellKey(code, index)}>
<TableCell align="right" key={getCellKey(code, index)}>
{value}
{index === 0 &&
(fullAccessToStudentData ||