From d4a2190a5a5876a387beb01f83c27cfb644534e1 Mon Sep 17 00:00:00 2001 From: Felix Albrigtsen Date: Mon, 25 Apr 2022 13:20:54 +0200 Subject: [PATCH 1/4] Dev session --- src/client/src/AdminsOverview.js | 147 +++++++++++++----- src/client/src/FrontPage.js | 2 +- src/client/src/TournamentManager.js | 11 +- src/client/src/TournamentMatches.js | 19 --- src/client/src/TournamentOverview.js | 85 ++++++++-- src/client/src/components/AsuraBar.js | 2 +- src/client/src/components/TournamentBar.js | 11 +- .../src/components/tournamentBracket.css | 70 +++++---- 8 files changed, 239 insertions(+), 108 deletions(-) delete mode 100644 src/client/src/TournamentMatches.js diff --git a/src/client/src/AdminsOverview.js b/src/client/src/AdminsOverview.js index ff13fbf..5af86a4 100644 --- a/src/client/src/AdminsOverview.js +++ b/src/client/src/AdminsOverview.js @@ -3,10 +3,12 @@ import { BrowserRouter as Router, Link, Route, Routes, useParams } from "react-r import Appbar from "./components/AsuraBar"; import ErrorSnackbar from "./components/ErrorSnackbar"; import LoginPage from "./LoginPage"; -import {Button, Box, TextField, Stack, InputLabel, Paper, TableContainer, Table, TableBody, TableHead, TableCell, TableRow, Typography, Select, MenuItem, FormControl} from '@mui/material'; +import { Button, Box, TextField, Stack, InputLabel, Paper, TableContainer, Table, TableBody, TableHead, TableCell, TableRow, Typography, Select, MenuItem, FormControl } from '@mui/material'; +import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"; import AddCircleIcon from '@mui/icons-material/AddCircle'; import DeleteIcon from '@mui/icons-material/Delete'; import EditIcon from '@mui/icons-material/Edit'; +import PropTypes from 'prop-types' function AdminCreator(props){ function postCreate(){ @@ -55,17 +57,20 @@ function AdminCreator(props){ } function UserList(props){ - const deleteUsers = (userId) => { + const deleteUser = (userId) => { + openConfirmDialog(function() { fetch(process.env.REACT_APP_API_URL + `/users/${userId}`, {method: "DELETE"}) .then(res => res.json()) .then(data => { if(data.status !== "OK"){ showError(data.data); + console.log("UWU") return; } - props.setUsers(props.users.filter(user => user.id !== userId)); + props.onUserUpdated(); }) .catch(error => showError(error)); + }); } let updateRank = (asuraId) => event => { @@ -92,52 +97,99 @@ function UserList(props){ return(
- {/* TODO: scroll denne menyen, eventuelt søkefelt */} - - - - Name - Email - Rank - Actions +
+ + + Name + Email + Rank + Actions + + + + {props.users.map((user) => ( + + + + {user.name} + + + {user.email} + {/* TODO Drop down menu for selecting rank */} + + + + + + {/* {team.members} */} + + {/* */} + + - - - {props.users.map((user) => ( - - - - {user.name} - - - {user.email} - {/* TODO Drop down menu for selecting rank */} - - - - - - {/* {team.members} */} - - {/* */} - - - - ))} - -
+ ))} + +
) } +function ConfirmationDialogRaw(props) { + const { userId } = useParams(); + const { onClose, value: valueProp, open, ...other } = props; + const [value, setValue] = React.useState(valueProp); + + React.useEffect(() => { + if (!open) { + setValue(valueProp); + } + }, [valueProp, open]); + + const handleCancel = () => { + onClose(); + }; + const handleConfirm = () => { + onClose(); + props.handleconfirm(); + }; + + return ( + + Delete administrator? + + Are you sure you want to delete the administrator? This action is not reversible! + + + + + + + ); +} + +ConfirmationDialogRaw.propTypes = { + onClose: PropTypes.func.isRequired, + open: PropTypes.bool.isRequired, +}; + +// Confirmation window for "Delete user" +function openConfirmDialog(callback) {g_setDialogCallback(callback); g_setDialogOpen(true);} +let g_setDialogOpen = () => {}; +let g_setDialogCallback = (callback) => {}; + let showError = (message) => {}; - - export default function Users(props) { const [openError, setOpenError] = React.useState(false); @@ -149,6 +201,12 @@ export default function Users(props) { } const [users, setUsers] = React.useState([]); + const [dialogOpen, setDialogOpen] = React.useState(false); + const handleDialogClose = () => { setDialogOpen(false); }; + const [dialogOnConfirm, setDialogOnConfirm] = React.useState(() => {return function(){}}); + g_setDialogCallback = (callback) => { setDialogOnConfirm(()=>{ return callback })}; + g_setDialogOpen = (value) => { setDialogOpen(value); }; + function getUsers() { fetch(process.env.REACT_APP_API_URL + `/users/getUsers`) .then((res) => res.json()) @@ -186,6 +244,13 @@ export default function Users(props) { + ); } \ No newline at end of file diff --git a/src/client/src/FrontPage.js b/src/client/src/FrontPage.js index 4f79a25..7f39591 100644 --- a/src/client/src/FrontPage.js +++ b/src/client/src/FrontPage.js @@ -182,7 +182,7 @@ function Home(props) { <> - + Tournaments { props.user.isLoggedIn ? : null diff --git a/src/client/src/TournamentManager.js b/src/client/src/TournamentManager.js index cbae582..02f9a8e 100644 --- a/src/client/src/TournamentManager.js +++ b/src/client/src/TournamentManager.js @@ -219,8 +219,13 @@ export default function TournamentManager(props) { const handleDialogClickListItem = () => { setDialogOpen(true); }; const handleDialogClose = () => { setDialogOpen(false); }; - showError = props.showError; - showSuccess = props.showSuccess; + const [openError, setOpenError] = React.useState(false); + const [errorMessage, setErrorMessage] = React.useState(""); + showError = (message) => { + setOpenError(false); + setErrorMessage(message); + setOpenError(true); + } if (!props.user.isLoggedIn) { return ; } @@ -229,7 +234,7 @@ export default function TournamentManager(props) { - + {/* */} - { props.user.isManager && } + ); diff --git a/src/client/src/components/TournamentBar.js b/src/client/src/components/TournamentBar.js index 06914a4..62afe4d 100644 --- a/src/client/src/components/TournamentBar.js +++ b/src/client/src/components/TournamentBar.js @@ -3,6 +3,11 @@ import { useParams } from "react-router-dom"; import { BrowserRouter as Router, Link, Route, Routes, History } from "react-router-dom"; import { Stack, Paper, Typography, Box, Button, Grid, Snackbar, IconButton } from "@mui/material" import CloseIcon from '@mui/icons-material/Close'; +import MuiAlert from '@mui/material/Alert'; + +const Alert = React.forwardRef(function Alert(props, ref) { + return ; +}); function ClipboardButton(props) { const [open, setOpen] = React.useState(false); @@ -23,7 +28,11 @@ function ClipboardButton(props) { return ( <> - + + + {props.name + " copied to clipboard"} + + ); } diff --git a/src/client/src/components/tournamentBracket.css b/src/client/src/components/tournamentBracket.css index 2823d19..193154f 100644 --- a/src/client/src/components/tournamentBracket.css +++ b/src/client/src/components/tournamentBracket.css @@ -6,7 +6,7 @@ flex-direction:row; justify-content: center; } - .round{ +.round{ display:flex; flex-direction:column; justify-content:center; @@ -14,13 +14,13 @@ list-style:none; padding:0; /* font-size: 1.5rem; */ - } - .round .spacer{ flex-grow:1;} - .round .spacer:first-child, - .round .spacer:last-child{ flex-grow:.5; } - .round .game-spacer{ - flex-grow:1; - } +} +.round .spacer{ flex-grow:1;} +.round .spacer:first-child, +.round .spacer:last-child{ flex-grow:.5; } +.round .game-spacer{ + flex-grow:1; +} /* * General Styles @@ -32,26 +32,44 @@ line-height:1.4em; } */ - li.game{ +li.game{ padding-left:20px; - } +} - .winner{ - color:green; - font-weight: bold; - } - .loser{ - color:grey; - } +.winner{ + color:green; + font-weight: bold; +} +.loser{ + color:grey; +} - li.game-top{ border-bottom:1px solid #aaa; } +li.game-top{ border-bottom:1px solid #aaa; } - li.game-spacer{ - border-right:1px solid #aaa; - min-height:10vh; - } +li.game-spacer{ + border-right:1px solid #aaa; + min-height:10vh; +} - li.game-bottom{ - border-top:1px solid #aaa; - } - \ No newline at end of file +li.game-bottom{ + border-top:1px solid #aaa; +} + + +.winnerDisplay { + display:flex; + flex-direction:row; + align-items: center; + border: 2px solid gray; + border-radius: 15px; + min-height: 10vh; + max-height: 40vh; + margin: auto 5px; + padding: 10px; +} +.winnerDisplay.winner { + border: 2px solid green; +} +.winnerDisplay > h2 { + margin-right: 10px; +} \ No newline at end of file From 60c6c6530aabd8f9b33f863da04e976f992214a2 Mon Sep 17 00:00:00 2001 From: Felix Albrigtsen Date: Mon, 25 Apr 2022 13:24:53 +0200 Subject: [PATCH 2/4] oops, forgot to disable test user --- src/client/src/FrontPage.js | 56 ++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/client/src/FrontPage.js b/src/client/src/FrontPage.js index 7f39591..36a9a8b 100644 --- a/src/client/src/FrontPage.js +++ b/src/client/src/FrontPage.js @@ -205,36 +205,36 @@ let showError = (message) => {}; export default function App() { const [user, setUser] = React.useState({}); - // let fetchUser = () => { - // fetch(process.env.REACT_APP_API_URL + `/users/getSavedUser`) - // .then(res => res.json()) - // .then(data => { - // if (data.status !== "OK") { - // setUser({ isManager: false, isLoggedIn: false }); - // console.log(data.data); // "No user logged in" - // return; - // } - // let u = data.data; - // u.isLoggedIn = true; - // console.log("User is logged in") - // setUser(u); - // }) - // .catch((err) => { - // showError(err.message); - // setUser({ isManager: false, isLoggedIn: false }); - // }); - // } - // // Debug mode, allow all: let fetchUser = () => { - setUser({ - name: "TEST USERTEST", - isManager: true, - isLoggedIn: true, - email: "testesen@gmail.com", - asuraId: "123456789", - googleId: "234" - }); + fetch(process.env.REACT_APP_API_URL + `/users/getSavedUser`) + .then(res => res.json()) + .then(data => { + if (data.status !== "OK") { + setUser({ isManager: false, isLoggedIn: false }); + console.log(data.data); // "No user logged in" + return; + } + let u = data.data; + u.isLoggedIn = true; + console.log("User is logged in") + setUser(u); + }) + .catch((err) => { + showError(err.message); + setUser({ isManager: false, isLoggedIn: false }); + }); } + // // Debug mode, allow all: + // let fetchUser = () => { + // setUser({ + // name: "TEST USERTEST", + // isManager: true, + // isLoggedIn: true, + // email: "testesen@gmail.com", + // asuraId: "123456789", + // googleId: "234" + // }); + // } React.useEffect(() => { fetchUser(); From 4786bfbd59846f92ab0ffcf961eb683dada40f78 Mon Sep 17 00:00:00 2001 From: Felix Albrigtsen Date: Mon, 25 Apr 2022 14:17:27 +0200 Subject: [PATCH 3/4] Change winner after tournament end --- src/client/src/TournamentOverview.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client/src/TournamentOverview.js b/src/client/src/TournamentOverview.js index bce37ba..0279305 100644 --- a/src/client/src/TournamentOverview.js +++ b/src/client/src/TournamentOverview.js @@ -155,7 +155,7 @@ function WinnerDisplay(props) { return (
- {props.user.isLoggedIn && } + {props.user.isLoggedIn && !props.tournament.hasEnded && } Winner: @@ -233,7 +233,7 @@ function BracketViewer(props){ return })} - +
: From 1e9b30ba8e89f3d770414fa3edbdda9d76d931e2 Mon Sep 17 00:00:00 2001 From: Kristoffer Juelsen Date: Mon, 25 Apr 2022 21:52:35 +0200 Subject: [PATCH 4/4] MUI Scaling & Responsive Design Finished --- src/client/src/AdminsOverview.js | 20 +++--- src/client/src/FrontPage.js | 70 +++++++++---------- src/client/src/ProfilePage.js | 2 - src/client/src/TournamentCreator.js | 5 +- src/client/src/TournamentHistory.js | 6 +- src/client/src/TournamentManager.js | 6 +- src/client/src/TournamentOverview.js | 50 ++++++------- src/client/src/TournamentTeams.js | 6 +- src/client/src/components/AsuraBar.js | 8 +-- src/client/src/components/TournamentBar.js | 10 +-- .../src/components/tournamentBracket.css | 6 +- src/client/src/index.css | 2 - 12 files changed, 94 insertions(+), 97 deletions(-) diff --git a/src/client/src/AdminsOverview.js b/src/client/src/AdminsOverview.js index 5af86a4..c9a7962 100644 --- a/src/client/src/AdminsOverview.js +++ b/src/client/src/AdminsOverview.js @@ -39,17 +39,17 @@ function AdminCreator(props){ } return ( - +
- - {/* */} - + + {/* */} +
@@ -118,7 +118,7 @@ function UserList(props){ {/* TODO Drop down menu for selecting rank */} - Manager Admin diff --git a/src/client/src/FrontPage.js b/src/client/src/FrontPage.js index 36a9a8b..ea05bab 100644 --- a/src/client/src/FrontPage.js +++ b/src/client/src/FrontPage.js @@ -85,7 +85,7 @@ function TournamentListItem(props) {
) } else { return( - Starts in: + Starts in:
{ remainingDays > 0 ? {remainingDays} days : null } { remainingHours > 0 ? {remainingHours} hours : null } { remainingMins > 0 ? {remainingMins} mins : null } @@ -105,26 +105,26 @@ function TournamentListItem(props) { image="banner2.png" /> - {props.tournament.name} + {props.tournament.name} Start: {props.tournament.startTime.toLocaleString()} End: {props.tournament.endTime.toLocaleString()} - Players: {props.tournament.teamCount} / {props.tournament.teamLimit} + Particpants: {props.tournament.teamCount} / {props.tournament.teamLimit} Prize: {props.tournament.prize} - - { props.user.isLoggedIn ? + + { props.user.isLoggedIn && - : null + } @@ -182,7 +182,7 @@ function Home(props) { <> - + Tournaments { props.user.isLoggedIn ? : null @@ -205,36 +205,36 @@ let showError = (message) => {}; export default function App() { const [user, setUser] = React.useState({}); - let fetchUser = () => { - fetch(process.env.REACT_APP_API_URL + `/users/getSavedUser`) - .then(res => res.json()) - .then(data => { - if (data.status !== "OK") { - setUser({ isManager: false, isLoggedIn: false }); - console.log(data.data); // "No user logged in" - return; - } - let u = data.data; - u.isLoggedIn = true; - console.log("User is logged in") - setUser(u); - }) - .catch((err) => { - showError(err.message); - setUser({ isManager: false, isLoggedIn: false }); - }); - } - // // Debug mode, allow all: // let fetchUser = () => { - // setUser({ - // name: "TEST USERTEST", - // isManager: true, - // isLoggedIn: true, - // email: "testesen@gmail.com", - // asuraId: "123456789", - // googleId: "234" - // }); + // fetch(process.env.REACT_APP_API_URL + `/users/getSavedUser`) + // .then(res => res.json()) + // .then(data => { + // if (data.status !== "OK") { + // setUser({ isManager: false, isLoggedIn: false }); + // console.log(data.data); // "No user logged in" + // return; + // } + // let u = data.data; + // u.isLoggedIn = true; + // console.log("User is logged in") + // setUser(u); + // }) + // .catch((err) => { + // showError(err.message); + // setUser({ isManager: false, isLoggedIn: false }); + // }); // } + // Debug mode, allow all: + let fetchUser = () => { + setUser({ + name: "TEST USERTEST", + isManager: true, + isLoggedIn: true, + email: "testesen@gmail.com", + asuraId: "123456789", + googleId: "234" + }); + } React.useEffect(() => { fetchUser(); diff --git a/src/client/src/ProfilePage.js b/src/client/src/ProfilePage.js index 16f1ee2..39195bf 100644 --- a/src/client/src/ProfilePage.js +++ b/src/client/src/ProfilePage.js @@ -12,7 +12,6 @@ export default function ProfilePage(props) { return (<> -

Your profile

@@ -23,6 +22,5 @@ export default function ProfilePage(props) {
-
) } \ No newline at end of file diff --git a/src/client/src/TournamentCreator.js b/src/client/src/TournamentCreator.js index ca3fe6a..93e3c02 100644 --- a/src/client/src/TournamentCreator.js +++ b/src/client/src/TournamentCreator.js @@ -113,7 +113,7 @@ function TournamentForm(props) { - + - - + End: {props.tournament.endTime.toLocaleString()} - Players: {props.tournament.teamCount} / {props.tournament.teamLimit} + Participants: {props.tournament.teamCount} / {props.tournament.teamLimit} Prize: {props.tournament.prize} @@ -150,8 +150,8 @@ export default function TournamentHistory(props) { <> - - Past Tournaments + + Past Tournaments diff --git a/src/client/src/TournamentManager.js b/src/client/src/TournamentManager.js index 02f9a8e..d0cddba 100644 --- a/src/client/src/TournamentManager.js +++ b/src/client/src/TournamentManager.js @@ -134,13 +134,13 @@ function ManageTournament(props) { return ( <>
- + - + - + - -
  •  
  • + +   {matches} @@ -85,41 +85,43 @@ function Match(props){ return ( <> {/* Team 1 (Winner-status?) (Team name) */} -
  • - - + + + {team1Name} { props.match.winnerId && (props.match.team1Id === props.match.winnerId) && - + } + { props.match.team1Id !== null && !props.tournament.hasEnded && props.match.tier !== Math.log2(props.tournament.teamLimit) - 1 && props.match.winnerId === null && props.user.isLoggedIn && - + } { props.match.team1Id !== null && props.match.winnerId === null && !props.tournament.hasEnded && props.user.isLoggedIn && - + } + -
  • -
  •  
  • +
    +   {/* Team 2 (Winner-status?) (Team name) */} -
  • - - + + + {team2Name} { props.match.winnerId && (props.match.team2Id === props.match.winnerId) && - + } { props.match.team2Id !== null && !props.tournament.hasEnded && props.match.tier !== Math.log2(props.tournament.teamLimit) - 1 && props.match.winnerId === null && props.user.isLoggedIn && - + } { props.match.team2Id !== null && props.match.winnerId === null && !props.tournament.hasEnded && props.user.isLoggedIn && - + } -
  • -
  •  
  • +
    +   ); } @@ -146,21 +148,21 @@ function WinnerDisplay(props) { if (!props.team) { // Winner is not yet chosen return
    - + Winner is not chosen.
    Will it be you?
    ; } return ( -
    - +
    + {props.user.isLoggedIn && !props.tournament.hasEnded && } - Winner: - - {props.team.name} + + {props.team.name} +
    ) } diff --git a/src/client/src/TournamentTeams.js b/src/client/src/TournamentTeams.js index fe914bb..9ce878f 100644 --- a/src/client/src/TournamentTeams.js +++ b/src/client/src/TournamentTeams.js @@ -39,12 +39,12 @@ function TeamCreator(props) { } return ( - +
    - + {/* */} - + {props.name + " copied to clipboard"} @@ -40,7 +40,7 @@ function ClipboardButton(props) { function ButtonLink(props) { return ( - + ); } @@ -48,9 +48,9 @@ function ButtonLink(props) { export default function TournamentBar(props) { const { tournamentId } = useParams(); return ( - - - + + + diff --git a/src/client/src/components/tournamentBracket.css b/src/client/src/components/tournamentBracket.css index 193154f..ac8f64f 100644 --- a/src/client/src/components/tournamentBracket.css +++ b/src/client/src/components/tournamentBracket.css @@ -67,9 +67,9 @@ li.game-bottom{ margin: auto 5px; padding: 10px; } -.winnerDisplay.winner { - border: 2px solid green; +.winnerDisplay > p.winner { + color:green; } -.winnerDisplay > h2 { +.winnerDisplay > div.winner { margin-right: 10px; } \ No newline at end of file diff --git a/src/client/src/index.css b/src/client/src/index.css index 8a0b7ef..6565c77 100644 --- a/src/client/src/index.css +++ b/src/client/src/index.css @@ -24,8 +24,6 @@ code { } .mainIcon{ - height: 65px; - width: 65px; border-radius: 50%; /* border: 5px dotted salmon; */ border: 3px solid #1ab35a;