From 4204723a8481c38d7e5110cf8a96ad971c486b2a Mon Sep 17 00:00:00 2001 From: Josef Olsson <josol381@student.liu.se> Date: Mon, 26 Apr 2021 16:42:03 +0200 Subject: [PATCH 1/7] =?UTF-8?q?Fix=20Gymnasieskola=20->=20H=C3=B6gstadie?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/populate.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/populate.py b/server/populate.py index 6a4be4ef..f323a525 100644 --- a/server/populate.py +++ b/server/populate.py @@ -17,7 +17,7 @@ def _add_items(): roles = ["Admin", "Editor"] cities = ["Linköping", "Stockholm", "Norrköping", "Örkelljunga"] - teams = ["Gymnasieskola A", "Gymnasieskola B", "Gymnasieskola C"] + teams = ["Högstadie A", "Högstadie B", "Högstadie C"] for name in media_types: dbc.add.mediaType(name) @@ -76,8 +76,8 @@ def _add_items(): ) """ - for i in range(3): - dbc.add.question_alternative(f"Alternative {i}", 0, item_slide.questions[0].id) + for k in range(3): + dbc.add.question_alternative(f"Alternative {k}", 0, item_slide.questions[0].id) # Add text components # TODO: Add images as components -- GitLab From 2a83ca95f3eacc2a22d6633814b5ae855dd4a3e0 Mon Sep 17 00:00:00 2001 From: Sebastian Karlsson <sebka991@student.liu.se> Date: Wed, 28 Apr 2021 10:15:24 +0200 Subject: [PATCH 2/7] Show competition codes in admin view --- .../admin/competitions/CompetitionManager.tsx | 91 ++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/client/src/pages/admin/competitions/CompetitionManager.tsx b/client/src/pages/admin/competitions/CompetitionManager.tsx index 83f399b9..fc36347e 100644 --- a/client/src/pages/admin/competitions/CompetitionManager.tsx +++ b/client/src/pages/admin/competitions/CompetitionManager.tsx @@ -1,4 +1,17 @@ -import { Button, Menu, TablePagination, TextField, Typography } from '@material-ui/core' +import { + Button, + Menu, + List, + ListItem, + TablePagination, + TextField, + Typography, + Dialog, + DialogTitle, + DialogContent, + DialogActions, + DialogContentText, +} from '@material-ui/core' import FormControl from '@material-ui/core/FormControl' import InputLabel from '@material-ui/core/InputLabel' import MenuItem from '@material-ui/core/MenuItem' @@ -36,13 +49,29 @@ const useStyles = makeStyles((theme: Theme) => margin: { margin: theme.spacing(1), }, + paper: { + backgroundColor: theme.palette.background.paper, + boxShadow: theme.shadows[5], + padding: 4, + outline: 'none', + }, }) ) +interface Code { + id: number + code: string + view_type_id: number + competition_id: number + team_id: number +} + const CompetitionManager: React.FC = (props: any) => { const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null) const [activeId, setActiveId] = React.useState<number | undefined>(undefined) const [timerHandle, setTimerHandle] = React.useState<number | undefined>(undefined) + const [dialogIsOpen, setDialogIsOpen] = React.useState(false) + const [codes, setCodes] = React.useState<Code[]>([]) const loading = useAppSelector((state) => state.user.userInfo === null) const competitions = useAppSelector((state) => state.competitions.competitions) const filterParams = useAppSelector((state) => state.competitions.filterParams) @@ -98,6 +127,53 @@ const CompetitionManager: React.FC = (props: any) => { console.log('GLHF!') } + const getCodes = async () => { + await axios + .get(`/api/competitions/${activeId}/codes`) + .then((response) => { + console.log(response.data[0]) + setCodes(response.data[0].items as Code[]) + }) + .catch(console.log) + } + + const printCodes = () => { + if (codes) { + return codes.map((code) => { + let viewType = '' + switch (code.view_type_id) { + case 1: + viewType = 'Team' + break + case 2: + viewType = 'Judge' + break + case 3: + viewType = 'Audience' + break + case 4: + viewType = 'Operator' + break + default: + viewType = 'Type not found' + break + } + return <ListItem key={code.id}>{`${viewType} : ${code.code}`}</ListItem> + }) + } + } + + const handleOpenDialog = () => { + //Sätt staten manuellt till Retriveing Codes + getCodes() + setDialogIsOpen(true) + } + + const handleCloseDialog = () => { + setDialogIsOpen(false) + setAnchorEl(null) + } + const handleDuplicateCompetition = async () => { if (activeId) { await axios @@ -207,9 +283,22 @@ const CompetitionManager: React.FC = (props: any) => { /> <Menu id="simple-menu" anchorEl={anchorEl} keepMounted open={Boolean(anchorEl)} onClose={handleClose}> <MenuItem onClick={handleStartCompetition}>Starta</MenuItem> + <MenuItem onClick={handleOpenDialog}>Visa koder</MenuItem> <MenuItem onClick={handleDuplicateCompetition}>Duplicera</MenuItem> <RemoveMenuItem onClick={handleDeleteCompetition}>Ta bort</RemoveMenuItem> </Menu> + <Dialog open={dialogIsOpen} onClose={handleCloseDialog}> + <DialogTitle className={classes.paper}>Koder för {activeId}</DialogTitle> + <DialogContent> + <DialogContentText>Här visas tävlingskoderna till den valda tävlingen.</DialogContentText> + <List>{printCodes()}</List> + </DialogContent> + <DialogActions> + <Button onClick={handleCloseDialog} color="primary"> + Stäng + </Button> + </DialogActions> + </Dialog> </div> ) } -- GitLab From 35968a5f2daa55ff210e5d49c5aa2e62195565e1 Mon Sep 17 00:00:00 2001 From: Sebastian Karlsson <sebka991@student.liu.se> Date: Wed, 28 Apr 2021 11:20:31 +0200 Subject: [PATCH 3/7] Get team names for competition codes in admin view --- .../admin/competitions/CompetitionManager.tsx | 43 +++++++++++++------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/client/src/pages/admin/competitions/CompetitionManager.tsx b/client/src/pages/admin/competitions/CompetitionManager.tsx index fc36347e..fe48bab9 100644 --- a/client/src/pages/admin/competitions/CompetitionManager.tsx +++ b/client/src/pages/admin/competitions/CompetitionManager.tsx @@ -30,6 +30,7 @@ import React, { useEffect } from 'react' import { Link, useHistory } from 'react-router-dom' import { getCompetitions, setFilterParams } from '../../../actions/competitions' import { useAppDispatch, useAppSelector } from '../../../hooks' +import { Team } from '../../../interfaces/ApiModels' import { CompetitionFilterParams } from '../../../interfaces/FilterParams' import { FilterContainer, RemoveMenuItem, TopBar, YearFilterTextField } from '../styledComp' import AddCompetition from './AddCompetition' @@ -72,6 +73,7 @@ const CompetitionManager: React.FC = (props: any) => { const [timerHandle, setTimerHandle] = React.useState<number | undefined>(undefined) const [dialogIsOpen, setDialogIsOpen] = React.useState(false) const [codes, setCodes] = React.useState<Code[]>([]) + const [teams, setTeams] = React.useState<Team[]>([]) const loading = useAppSelector((state) => state.user.userInfo === null) const competitions = useAppSelector((state) => state.competitions.competitions) const filterParams = useAppSelector((state) => state.competitions.filterParams) @@ -132,40 +134,57 @@ const CompetitionManager: React.FC = (props: any) => { .get(`/api/competitions/${activeId}/codes`) .then((response) => { console.log(response.data[0]) - setCodes(response.data[0].items as Code[]) + setCodes(response.data[0].items) }) .catch(console.log) } + const getTeams = async () => { + await axios + .get(`/api/competitions/${activeId}/teams`) + .then((response) => { + console.log(response.data.items) + setTeams(response.data.items) + }) + .catch((err) => { + console.log(err) + }) + } + const printCodes = () => { - if (codes) { + if (codes !== [] && teams !== []) { return codes.map((code) => { - let viewType = '' + let typeName = '' switch (code.view_type_id) { case 1: - viewType = 'Team' + const team = teams.find((team) => team.id === code.team_id) + if (team) { + typeName = team.name + } else { + typeName = 'Team name not found' + } break case 2: - viewType = 'Judge' + typeName = 'Judge' break case 3: - viewType = 'Audience' + typeName = 'Audience' break case 4: - viewType = 'Operator' + typeName = 'Operator' break default: - viewType = 'Type not found' + typeName = 'Type not found' break } - return <ListItem key={code.id}>{`${viewType} : ${code.code}`}</ListItem> + return <ListItem key={code.id}>{`${typeName} : ${code.code}`}</ListItem> }) } } - const handleOpenDialog = () => { - //Sätt staten manuellt till Retriveing Codes - getCodes() + const handleOpenDialog = async () => { + await getCodes() + await getTeams() setDialogIsOpen(true) } -- GitLab From 4f580a6f89be7d17a7ca2cf30dc4a74c2f96f889 Mon Sep 17 00:00:00 2001 From: Sebastian Karlsson <sebka991@student.liu.se> Date: Wed, 28 Apr 2021 11:51:17 +0200 Subject: [PATCH 4/7] Add grid to competition codes dialog box --- .../admin/competitions/CompetitionManager.tsx | 76 ++++++++++++------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/client/src/pages/admin/competitions/CompetitionManager.tsx b/client/src/pages/admin/competitions/CompetitionManager.tsx index fe48bab9..a95c1935 100644 --- a/client/src/pages/admin/competitions/CompetitionManager.tsx +++ b/client/src/pages/admin/competitions/CompetitionManager.tsx @@ -11,6 +11,7 @@ import { DialogContent, DialogActions, DialogContentText, + Grid, } from '@material-ui/core' import FormControl from '@material-ui/core/FormControl' import InputLabel from '@material-ui/core/InputLabel' @@ -151,35 +152,32 @@ const CompetitionManager: React.FC = (props: any) => { }) } - const printCodes = () => { - if (codes !== [] && teams !== []) { - return codes.map((code) => { - let typeName = '' - switch (code.view_type_id) { - case 1: - const team = teams.find((team) => team.id === code.team_id) - if (team) { - typeName = team.name - } else { - typeName = 'Team name not found' - } - break - case 2: - typeName = 'Judge' - break - case 3: - typeName = 'Audience' - break - case 4: - typeName = 'Operator' - break - default: - typeName = 'Type not found' - break + const getTypeName = (code: Code) => { + let typeName = '' + switch (code.view_type_id) { + case 1: + const team = teams.find((team) => team.id === code.team_id) + if (team) { + typeName = team.name + } else { + typeName = 'Lagnamn hittades ej' } - return <ListItem key={code.id}>{`${typeName} : ${code.code}`}</ListItem> - }) + break + case 2: + typeName = 'Domare' + break + case 3: + typeName = 'Publik' + break + case 4: + typeName = 'Tävlingsoperator' + break + default: + typeName = 'Typ hittades ej' + break } + return typeName + //return <ListItem key={code.id}>{`${typeName} : ${code.code}`}</ListItem> } const handleOpenDialog = async () => { @@ -309,8 +307,28 @@ const CompetitionManager: React.FC = (props: any) => { <Dialog open={dialogIsOpen} onClose={handleCloseDialog}> <DialogTitle className={classes.paper}>Koder för {activeId}</DialogTitle> <DialogContent> - <DialogContentText>Här visas tävlingskoderna till den valda tävlingen.</DialogContentText> - <List>{printCodes()}</List> + <DialogContentText style={{ width: 1000 }}> + Här visas tävlingskoderna till den valda tävlingen. + </DialogContentText> + + <Grid> + {codes.map((code) => ( + <Grid key={code.id} container item xs={12} spacing={1}> + <Grid item xs={3}> + {getTypeName(code)} + </Grid> + <Grid item xs={3}> + {code.code} + </Grid> + <Grid item xs={3}> + Kopiera kod + </Grid> + <Grid item xs={3}> + Ny kod + </Grid> + </Grid> + ))} + </Grid> </DialogContent> <DialogActions> <Button onClick={handleCloseDialog} color="primary"> -- GitLab From c27aff8370f055f70f85388f9a78935f3769e78e Mon Sep 17 00:00:00 2001 From: Sebastian Karlsson <sebka991@student.liu.se> Date: Wed, 28 Apr 2021 16:00:43 +0200 Subject: [PATCH 5/7] Improve styling for competition codes dialog box --- .../admin/competitions/CompetitionManager.tsx | 92 ++++++++++++++++--- 1 file changed, 80 insertions(+), 12 deletions(-) diff --git a/client/src/pages/admin/competitions/CompetitionManager.tsx b/client/src/pages/admin/competitions/CompetitionManager.tsx index a95c1935..65e37352 100644 --- a/client/src/pages/admin/competitions/CompetitionManager.tsx +++ b/client/src/pages/admin/competitions/CompetitionManager.tsx @@ -1,7 +1,6 @@ import { Button, Menu, - List, ListItem, TablePagination, TextField, @@ -10,8 +9,8 @@ import { DialogTitle, DialogContent, DialogActions, - DialogContentText, - Grid, + ListItemText, + Tooltip, } from '@material-ui/core' import FormControl from '@material-ui/core/FormControl' import InputLabel from '@material-ui/core/InputLabel' @@ -35,6 +34,8 @@ import { Team } from '../../../interfaces/ApiModels' import { CompetitionFilterParams } from '../../../interfaces/FilterParams' import { FilterContainer, RemoveMenuItem, TopBar, YearFilterTextField } from '../styledComp' import AddCompetition from './AddCompetition' +import FileCopyIcon from '@material-ui/icons/FileCopy' +import RefreshIcon from '@material-ui/icons/Refresh' /** * Component description: @@ -127,7 +128,6 @@ const CompetitionManager: React.FC = (props: any) => { const handleStartCompetition = () => { history.push(`/presenter/id=${activeId}&code=123123`) - console.log('GLHF!') } const getCodes = async () => { @@ -210,6 +210,10 @@ const CompetitionManager: React.FC = (props: any) => { dispatch(getCompetitions()) } + const doSomething = () => { + console.log('lol') + } + return ( <div> <TopBar> @@ -304,14 +308,77 @@ const CompetitionManager: React.FC = (props: any) => { <MenuItem onClick={handleDuplicateCompetition}>Duplicera</MenuItem> <RemoveMenuItem onClick={handleDeleteCompetition}>Ta bort</RemoveMenuItem> </Menu> - <Dialog open={dialogIsOpen} onClose={handleCloseDialog}> - <DialogTitle className={classes.paper}>Koder för {activeId}</DialogTitle> + <Dialog + open={dialogIsOpen} + onClose={handleCloseDialog} + aria-labelledby="max-width-dialog-title" + maxWidth="xl" + fullWidth={false} + fullScreen={false} + > + <DialogTitle id="max-width-dialog-title" className={classes.paper}> + Koder för tävling {activeId} + </DialogTitle> <DialogContent> - <DialogContentText style={{ width: 1000 }}> - Här visas tävlingskoderna till den valda tävlingen. - </DialogContentText> + {/* <DialogContentText>Här visas tävlingskoderna till den valda tävlingen.</DialogContentText> */} + {/* <ListItem> + <ListItemText primary={`${getTypeName(codes[1])}: `} /> + <ListItemText primary={'bbbbbb'} /> + <Tooltip title="Kopiera kod" arrow> + <Button + onClick={() => { + navigator.clipboard.writeText('bbbbbb') + }} + > + <FileCopyIcon fontSize="small" /> + </Button> + </Tooltip> + <ListItemText primary="Generera ny kod" /> + </ListItem> + <ListItem> + <ListItemText primary={`${getTypeName(codes[2])}: `} /> + <ListItemText primary={'aa'} /> + <Tooltip title="Kopiera kod" arrow> + <Button + onClick={() => { + navigator.clipboard.writeText('aa') + }} + > + <FileCopyIcon fontSize="small" /> + </Button> + </Tooltip> + <ListItemText primary="Generera ny kod" /> + </ListItem> */} + + {codes.map((code) => ( + <ListItem key={code.id} style={{ display: 'flex' }}> + <ListItemText primary={`${getTypeName(code)}: `} /> + + <ListItemText style={{ textAlign: 'right', marginLeft: '10px' }} primary={code.code} /> + <Tooltip title="Generera ny kod" arrow> + <Button + margin-right="0px" + onClick={() => { + doSomething() + }} + > + <RefreshIcon fontSize="small" /> + </Button> + </Tooltip> + <Tooltip title="Kopiera kod" arrow> + <Button + margin-right="0px" + onClick={() => { + navigator.clipboard.writeText(code.code) + }} + > + <FileCopyIcon fontSize="small" /> + </Button> + </Tooltip> + </ListItem> + ))} - <Grid> + {/* <Grid> {codes.map((code) => ( <Grid key={code.id} container item xs={12} spacing={1}> <Grid item xs={3}> @@ -321,14 +388,15 @@ const CompetitionManager: React.FC = (props: any) => { {code.code} </Grid> <Grid item xs={3}> - Kopiera kod + Kopiera kod Kopiera kodKopiera kodKopiera kodKopiera kodKopiera kodKopiera kodKopiera kodKopiera + kodKopiera kodKopiera kod </Grid> <Grid item xs={3}> Ny kod </Grid> </Grid> ))} - </Grid> + </Grid> */} </DialogContent> <DialogActions> <Button onClick={handleCloseDialog} color="primary"> -- GitLab From 78a08a7318a1548d63c78131167e17dbb3ba0db5 Mon Sep 17 00:00:00 2001 From: Sebastian Karlsson <sebka991@student.liu.se> Date: Wed, 28 Apr 2021 16:39:52 +0200 Subject: [PATCH 6/7] Add monospace font to competition codes, clean up comments and show competition name --- .../admin/competitions/CompetitionManager.tsx | 76 ++++++------------- 1 file changed, 23 insertions(+), 53 deletions(-) diff --git a/client/src/pages/admin/competitions/CompetitionManager.tsx b/client/src/pages/admin/competitions/CompetitionManager.tsx index 65e37352..d0320cb2 100644 --- a/client/src/pages/admin/competitions/CompetitionManager.tsx +++ b/client/src/pages/admin/competitions/CompetitionManager.tsx @@ -11,6 +11,7 @@ import { DialogActions, ListItemText, Tooltip, + Box, } from '@material-ui/core' import FormControl from '@material-ui/core/FormControl' import InputLabel from '@material-ui/core/InputLabel' @@ -76,6 +77,7 @@ const CompetitionManager: React.FC = (props: any) => { const [dialogIsOpen, setDialogIsOpen] = React.useState(false) const [codes, setCodes] = React.useState<Code[]>([]) const [teams, setTeams] = React.useState<Team[]>([]) + const [competitionName, setCompetitionName] = React.useState<string | undefined>(undefined) const loading = useAppSelector((state) => state.user.userInfo === null) const competitions = useAppSelector((state) => state.competitions.competitions) const filterParams = useAppSelector((state) => state.competitions.filterParams) @@ -152,6 +154,18 @@ const CompetitionManager: React.FC = (props: any) => { }) } + const getCompetitionName = async () => { + await axios + .get(`/api/competitions/${activeId}`) + .then((response) => { + console.log(response.data.name) + setCompetitionName(response.data.name) + }) + .catch((err) => { + console.log(err) + }) + } + const getTypeName = (code: Code) => { let typeName = '' switch (code.view_type_id) { @@ -177,12 +191,12 @@ const CompetitionManager: React.FC = (props: any) => { break } return typeName - //return <ListItem key={code.id}>{`${typeName} : ${code.code}`}</ListItem> } const handleOpenDialog = async () => { await getCodes() await getTeams() + await getCompetitionName() setDialogIsOpen(true) } @@ -317,44 +331,20 @@ const CompetitionManager: React.FC = (props: any) => { fullScreen={false} > <DialogTitle id="max-width-dialog-title" className={classes.paper}> - Koder för tävling {activeId} + Koder för {competitionName} </DialogTitle> <DialogContent> {/* <DialogContentText>Här visas tävlingskoderna till den valda tävlingen.</DialogContentText> */} - {/* <ListItem> - <ListItemText primary={`${getTypeName(codes[1])}: `} /> - <ListItemText primary={'bbbbbb'} /> - <Tooltip title="Kopiera kod" arrow> - <Button - onClick={() => { - navigator.clipboard.writeText('bbbbbb') - }} - > - <FileCopyIcon fontSize="small" /> - </Button> - </Tooltip> - <ListItemText primary="Generera ny kod" /> - </ListItem> - <ListItem> - <ListItemText primary={`${getTypeName(codes[2])}: `} /> - <ListItemText primary={'aa'} /> - <Tooltip title="Kopiera kod" arrow> - <Button - onClick={() => { - navigator.clipboard.writeText('aa') - }} - > - <FileCopyIcon fontSize="small" /> - </Button> - </Tooltip> - <ListItemText primary="Generera ny kod" /> - </ListItem> */} - {codes.map((code) => ( <ListItem key={code.id} style={{ display: 'flex' }}> <ListItemText primary={`${getTypeName(code)}: `} /> - - <ListItemText style={{ textAlign: 'right', marginLeft: '10px' }} primary={code.code} /> + <Typography component="div"> + <ListItemText style={{ textAlign: 'right', marginLeft: '10px' }}> + <Box fontFamily="Monospace" fontWeight="fontWeightBold"> + {code.code} + </Box> + </ListItemText> + </Typography> <Tooltip title="Generera ny kod" arrow> <Button margin-right="0px" @@ -377,26 +367,6 @@ const CompetitionManager: React.FC = (props: any) => { </Tooltip> </ListItem> ))} - - {/* <Grid> - {codes.map((code) => ( - <Grid key={code.id} container item xs={12} spacing={1}> - <Grid item xs={3}> - {getTypeName(code)} - </Grid> - <Grid item xs={3}> - {code.code} - </Grid> - <Grid item xs={3}> - Kopiera kod Kopiera kodKopiera kodKopiera kodKopiera kodKopiera kodKopiera kodKopiera kodKopiera - kodKopiera kodKopiera kod - </Grid> - <Grid item xs={3}> - Ny kod - </Grid> - </Grid> - ))} - </Grid> */} </DialogContent> <DialogActions> <Button onClick={handleCloseDialog} color="primary"> -- GitLab From 782cc824be528fa41adcf8da55ac42518eb7fa1b Mon Sep 17 00:00:00 2001 From: Sebastian Karlsson <sebka991@student.liu.se> Date: Wed, 28 Apr 2021 16:49:01 +0200 Subject: [PATCH 7/7] Add functionality for refreshing codes --- .../admin/competitions/CompetitionManager.tsx | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/client/src/pages/admin/competitions/CompetitionManager.tsx b/client/src/pages/admin/competitions/CompetitionManager.tsx index d0320cb2..95b74766 100644 --- a/client/src/pages/admin/competitions/CompetitionManager.tsx +++ b/client/src/pages/admin/competitions/CompetitionManager.tsx @@ -224,8 +224,16 @@ const CompetitionManager: React.FC = (props: any) => { dispatch(getCompetitions()) } - const doSomething = () => { - console.log('lol') + const refreshCode = async (code: Code) => { + await axios + .put(`/api/competitions/${activeId}/codes/${code.id}`) + .then(() => { + getCodes() + dispatch(getCompetitions()) + }) + .catch(({ response }) => { + console.warn(response.data) + }) } return ( @@ -349,7 +357,7 @@ const CompetitionManager: React.FC = (props: any) => { <Button margin-right="0px" onClick={() => { - doSomething() + refreshCode(code) }} > <RefreshIcon fontSize="small" /> -- GitLab