diff --git a/client/src/pages/admin/users/EditUser.tsx b/client/src/pages/admin/users/EditUser.tsx index a1be7c875b031080ccc16ca854a77ae7c2534cb0..7db5aeecd2be0c3f3f94c22a0c459a71cbc47aa4 100644 --- a/client/src/pages/admin/users/EditUser.tsx +++ b/client/src/pages/admin/users/EditUser.tsx @@ -1,6 +1,11 @@ import { Button, createStyles, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, FormControl, InputLabel, makeStyles, @@ -8,6 +13,8 @@ import { Popover, TextField, Theme, + useMediaQuery, + useTheme, } from '@material-ui/core' import MoreHorizIcon from '@material-ui/icons/MoreHoriz' import { Alert, AlertTitle } from '@material-ui/lab' @@ -62,6 +69,11 @@ type UserIdProps = { } const EditUser = ({ user }: UserIdProps) => { + // for dialog alert + const [openAlert, setOpen] = React.useState(false) + const theme = useTheme() + const fullScreen = useMediaQuery(theme.breakpoints.down('sm')) + const dispatch = useAppDispatch() const classes = useStyles() @@ -87,21 +99,25 @@ const EditUser = ({ user }: UserIdProps) => { setAnchorEl(event.currentTarget) } const handleClose = () => { + setOpen(false) setAnchorEl(null) } + const handleVerifyDelete = () => { + setOpen(true) + } + const handleDeleteUsers = async () => { - if (confirm('Are u sure?')) { - await axios - .delete(`/auth/delete/${user.id}`) - .then(() => { - setAnchorEl(null) - dispatch(getSearchUsers()) - }) - .catch(({ response }) => { - console.warn(response.data) - }) - } + setOpen(false) + await axios + .delete(`/auth/delete/${user.id}`) + .then(() => { + setAnchorEl(null) + dispatch(getSearchUsers()) + }) + .catch(({ response }) => { + console.warn(response.data) + }) } const handleSubmit = async (values: formType, actions: FormikHelpers<formType>) => { @@ -273,7 +289,7 @@ const EditUser = ({ user }: UserIdProps) => { Ändra </Button> <Button - onClick={handleDeleteUsers} + onClick={handleVerifyDelete} className={classes.deleteButton} fullWidth variant="contained" @@ -281,6 +297,27 @@ const EditUser = ({ user }: UserIdProps) => { > Ta bort </Button> + <Dialog + fullScreen={fullScreen} + open={openAlert} + onClose={handleClose} + aria-labelledby="responsive-dialog-title" + > + <DialogTitle id="responsive-dialog-title">{'Ta bort användare?'}</DialogTitle> + <DialogContent> + <DialogContentText> + Är du säker på att du vill ta bort användaren och all dess information från systemet? + </DialogContentText> + </DialogContent> + <DialogActions> + <Button autoFocus onClick={handleClose} color="primary"> + Avbryt + </Button> + <Button onClick={handleDeleteUsers} color="primary" autoFocus> + Ta bort + </Button> + </DialogActions> + </Dialog> {formik.errors.error && ( <Alert severity="error"> diff --git a/client/src/pages/admin/users/ResponsiveDialog.tsx b/client/src/pages/admin/users/ResponsiveDialog.tsx new file mode 100644 index 0000000000000000000000000000000000000000..e29a6786826e854bebf888be5b7cd904e0ec1063 --- /dev/null +++ b/client/src/pages/admin/users/ResponsiveDialog.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import Button from '@material-ui/core/Button'; +import Dialog from '@material-ui/core/Dialog'; +import DialogActions from '@material-ui/core/DialogActions'; +import DialogContent from '@material-ui/core/DialogContent'; +import DialogContentText from '@material-ui/core/DialogContentText'; +import DialogTitle from '@material-ui/core/DialogTitle'; +import useMediaQuery from '@material-ui/core/useMediaQuery'; +import { useTheme } from '@material-ui/core/styles'; + +export default function ResponsiveDialog() { + const [open, setOpen] = React.useState(false); + const theme = useTheme(); + const fullScreen = useMediaQuery(theme.breakpoints.down('sm')); + + const handleClickOpen = () => { + setOpen(true); + }; + + const handleClose = () => { + setOpen(false); + }; + + return ( + <div> + <Button variant="outlined" color="primary" onClick={handleClickOpen}> + Open responsive dialog + </Button> + <Dialog + fullScreen={fullScreen} + open={open} + onClose={handleClose} + aria-labelledby="responsive-dialog-title" + > + <DialogTitle id="responsive-dialog-title">{"Use Google's location service?"}</DialogTitle> + <DialogContent> + <DialogContentText> + Let Google help apps determine location. This means sending anonymous location data to + Google, even when no apps are running. + </DialogContentText> + </DialogContent> + <DialogActions> + <Button autoFocus onClick={handleClose} color="primary"> + Disagree + </Button> + <Button onClick={handleClose} color="primary" autoFocus> + Agree + </Button> + </DialogActions> + </Dialog> + </div> + ); +} \ No newline at end of file diff --git a/client/src/pages/views/PresenterViewPage.tsx b/client/src/pages/views/PresenterViewPage.tsx index ff61343f35f9ffb5beef13f62271d814f6ccb112..346aabcf5eb5ed131b2d2f44c7c57a9f1d5ce035 100644 --- a/client/src/pages/views/PresenterViewPage.tsx +++ b/client/src/pages/views/PresenterViewPage.tsx @@ -1,4 +1,18 @@ -import { List, ListItem, Popover, Tooltip, Typography } from '@material-ui/core' +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + List, + ListItem, + Popover, + Tooltip, + Typography, + useMediaQuery, + useTheme, +} from '@material-ui/core' import AssignmentIcon from '@material-ui/icons/Assignment' import BackspaceIcon from '@material-ui/icons/Backspace' import ChevronLeftIcon from '@material-ui/icons/ChevronLeft' @@ -31,6 +45,11 @@ import { } from './styled' const PresenterViewPage: React.FC = () => { + // for dialog alert + const [openAlert, setOpen] = React.useState(false) + const theme = useTheme() + const fullScreen = useMediaQuery(theme.breakpoints.down('sm')) + const teams = useAppSelector((state) => state.presentation.teams) const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null) const { id, code }: ViewParams = useParams() @@ -50,9 +69,14 @@ const PresenterViewPage: React.FC = () => { setAnchorEl(event.currentTarget) } const handleClose = () => { + setOpen(false) setAnchorEl(null) } + const handleVerifyExit = () => { + setOpen(true) + } + const startCompetition = () => { socketStartPresentation() const haveStarted = true @@ -61,22 +85,42 @@ const PresenterViewPage: React.FC = () => { } const endCompetition = () => { - if (confirm('Är du säker på att du vill avsluta tävlingen för alla?')) { - const haveStarted = false - socketEndPresentation() - history.push('/admin') - window.location.reload(false) // TODO: fix this ugly hack, we "need" to refresh site to be able to run the competition correctly again - } + setOpen(false) + const haveStarted = false + socketEndPresentation() + history.push('/admin') + window.location.reload(false) // TODO: fix this ugly hack, we "need" to refresh site to be able to run the competition correctly again } return ( <PresenterContainer> <PresenterHeader> <Tooltip title="Avsluta tävling" arrow> - <PresenterButton onClick={endCompetition} variant="contained" color="secondary"> + <PresenterButton onClick={handleVerifyExit} variant="contained" color="secondary"> <BackspaceIcon fontSize="large" /> </PresenterButton> </Tooltip> + <Dialog + fullScreen={fullScreen} + open={openAlert} + onClose={handleClose} + aria-labelledby="responsive-dialog-title" + > + <DialogTitle id="responsive-dialog-title">{'Vill du avsluta tävlingen?'}</DialogTitle> + <DialogContent> + <DialogContentText> + Genom att avsluta tävlingen kommer den avslutas för alla. Du kommer gå tillbaka till startsidan. + </DialogContentText> + </DialogContent> + <DialogActions> + <Button autoFocus onClick={handleClose} color="primary"> + Avbryt + </Button> + <Button onClick={endCompetition} color="primary" autoFocus> + Avsluta tävling + </Button> + </DialogActions> + </Dialog> <SlideCounter> <Typography variant="h3"> {presentation.slide.id} / {presentation.competition.slides.length} diff --git a/client/src/pages/views/components/SlideDisplay.tsx b/client/src/pages/views/components/SlideDisplay.tsx index b7e6dcbec1c0de97e46790654db40c994f065b7e..7ecffac50a735eade79ebcad046040045e37dd93 100644 --- a/client/src/pages/views/components/SlideDisplay.tsx +++ b/client/src/pages/views/components/SlideDisplay.tsx @@ -1,12 +1,10 @@ import { Typography } from '@material-ui/core' -import React, { useEffect } from 'react' -import { useAppDispatch, useAppSelector } from '../../../hooks' +import React from 'react' +import { useAppSelector } from '../../../hooks' import { SlideContainer } from './styled' const SlideDisplay: React.FC = () => { const currentSlide = useAppSelector((state) => state.presentation.slide) - const dispatch = useAppDispatch() - useEffect(() => {}, []) return ( <div>