speed-flowchart-web/src/pages/SpeedFlowchartPage.tsx

185 lines
5.9 KiB
TypeScript

import { Context } from '../data/Context';
import { useContext, useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import {
convertResultsToSpeedFlowchartResult,
SpeedFlowchartResult,
SpeedRoundPair,
} from '../data/SpeedFlowchart';
import { Card, CardContent, Grid, Skeleton, Typography } from '@mui/material';
import { theme } from '../utils/Theme';
import { QRCode } from 'react-qrcode-logo';
import { bgcolor } from '@mui/system';
import '../css/SpeedFlowchartPage.css';
interface SpeedRoundPairDummy extends SpeedRoundPair {
dummy: boolean;
}
/**
*
* @return {JSX.Element} speed flowchart page
*/
export default function SpeedFlowchartPage() {
const { competitionId, categoryId } = useParams();
const { api, setTitle, setContainerMaxWidth } = useContext(Context);
const [loading, setLoading] = useState(true);
const [flowchartResult, setFlowchartResult] =
useState<SpeedFlowchartResult>();
useEffect(() => {
setTitle('');
setContainerMaxWidth(false);
loadData();
const interval = setInterval(loadData, 2000);
return () => clearInterval(interval);
}, []);
const loadData = () => {
if (competitionId === undefined || categoryId === undefined) {
setLoading(false);
return;
}
api.getCompetitionResults(competitionId, categoryId).then(r => {
setTitle(
`${r.comp_name} - ${
r.categorys.filter(cat => cat.GrpId === categoryId)[0]?.name ?? ''
}`,
);
setLoading(false);
const flowchartResult = convertResultsToSpeedFlowchartResult(r);
const l = flowchartResult.rounds.length;
const dummy: SpeedRoundPairDummy = { dummy: true };
flowchartResult.rounds[l - 2].pairs = [
dummy,
...flowchartResult.rounds[l - 1].pairs,
...flowchartResult.rounds[l - 2].pairs,
];
flowchartResult.rounds[l - 2].roundName = `${
flowchartResult.rounds[l - 1].roundName
} / ${flowchartResult.rounds[l - 2].roundName}`;
flowchartResult.rounds.pop();
setFlowchartResult(flowchartResult);
});
};
return (
<>
<Grid
container
spacing={2}
direction={{ xs: 'column-reverse', md: 'row' }}
>
{flowchartResult?.rounds.map((round, roundKey) => (
<Grid
key={`flowchart-column-${roundKey}`}
item
xs={12}
md={12 / flowchartResult.rounds.length}
>
<Grid item className='center-children' xs={12}>
<Typography variant='h6' fontWeight={'bold'} gutterBottom>
{round.roundName}
</Typography>
</Grid>
<Grid
container
spacing={2}
sx={{
height: '100%',
justifyContent: 'space-around',
position: 'relative',
}}
direction={'column'}
>
{round.pairs.length === 2 && (
<div
style={{
position: 'absolute',
width: '100%',
display: 'flex',
justifyContent: 'center',
}}
>
<QRCode
value={`https://l.bluerock.dev/?comp=${competitionId}&cat=${categoryId}`}
logoImage={'/logo192.png'}
logoWidth={100}
logoHeight={100}
bgColor={theme.palette.background.default}
fgColor={theme.palette.text.secondary}
size={250}
ecLevel={'H'}
eyeRadius={5}
qrStyle={'dots'}
/>
</div>
)}
{round.pairs.map((pair, pairKey) => (
<Grid key={`flowchart-column-${roundKey}-pair-${pairKey}`} item>
<Card
sx={{
opacity: (pair as SpeedRoundPairDummy).dummy ? 0 : 1,
[theme.breakpoints.down('md')]: (
pair as SpeedRoundPairDummy
).dummy
? {
display: 'none',
}
: undefined,
}}
>
<CardContent>
<Typography
sx={{
fontWeight: pair.winner === 'A' ? 'bold' : 'plain',
color: pair.winner === 'A' ? '#4CAF50' : '',
}}
>
A: {pair.laneA?.participant.firstName}{' '}
{pair.laneA?.participant.lastName}:{' '}
{pair.laneA?.result?.result}
</Typography>
<Typography
sx={{
fontWeight: pair.winner === 'B' ? 'bold' : 'plain',
color: pair.winner === 'B' ? '#4CAF50' : '',
}}
>
B: {pair.laneB?.participant.firstName}{' '}
{pair.laneB?.participant.lastName}:{' '}
{pair.laneB?.result?.result}
</Typography>
</CardContent>
</Card>
</Grid>
))}
</Grid>
</Grid>
))}
{flowchartResult === undefined && !loading && (
<Grid item xs={12} className={'center-children'}>
This competition or category does not have a speed tree!
</Grid>
)}
{loading &&
new Array(5).fill(0).map((_, i) => (
<Grid key={`flowchart-column-skeleton-${i}`} item xs={12 / 5}>
<Skeleton height={50}></Skeleton>
</Grid>
))}
</Grid>
</>
);
}