Merge branch 'client' of gitlab.stud.idi.ntnu.no:felixalb/dcst1008-2022-group1 into client
This commit is contained in:
commit
76b8d06641
@ -3,10 +3,12 @@ import { BrowserRouter as Router, Link, Route, Routes, useParams } from "react-r
|
|||||||
import Appbar from "./components/AsuraBar";
|
import Appbar from "./components/AsuraBar";
|
||||||
import ErrorSnackbar from "./components/ErrorSnackbar";
|
import ErrorSnackbar from "./components/ErrorSnackbar";
|
||||||
import LoginPage from "./LoginPage";
|
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 AddCircleIcon from '@mui/icons-material/AddCircle';
|
||||||
import DeleteIcon from '@mui/icons-material/Delete';
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
import EditIcon from '@mui/icons-material/Edit';
|
import EditIcon from '@mui/icons-material/Edit';
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
function AdminCreator(props){
|
function AdminCreator(props){
|
||||||
function postCreate(){
|
function postCreate(){
|
||||||
@ -37,17 +39,17 @@ function AdminCreator(props){
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper sx={{width: "90vw", margin: "10px auto", padding: "15px"}} component={Stack} direction="column">
|
<Paper sx={{width: "90vw", margin: "10px auto", padding: "15px", align:'center', justifyContent:'center', flexGrow:1}} component={Stack} direction={['column']} spacing={2}>
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<form>
|
<form>
|
||||||
<TextField id="adminEmailInput" sx={{ width: "70%" }} label="Admin Email" variant="outlined" type="email" />
|
<TextField id="adminEmailInput" label="Admin Email" variant="outlined" type="email" sx={{width:['auto','50%','60%','70%']}} />
|
||||||
{/* <Button variant="contained" color="primary" onClick={postCreate}>Create Team</Button> */}
|
{/* <Button variant="contained" color="primary" onClick={postCreate}>Create Team</Button> */}
|
||||||
<Button type="submit" variant="contained" color="success" onClick={postCreate} sx={{width: "20%", marginLeft: "5px"}}>
|
<Button type="submit" variant="contained" color="success" onClick={postCreate} sx={{marginLeft:['5px'],width:['fit-content','40%','30%','20%']}}>
|
||||||
<Box sx={{padding: "10px"}}>
|
<Box sx={{padding: "10px"}}>
|
||||||
Create Admin
|
Create Admin
|
||||||
</Box>
|
</Box>
|
||||||
<AddCircleIcon />
|
<AddCircleIcon />
|
||||||
</Button>
|
</Button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</Paper>
|
</Paper>
|
||||||
@ -55,17 +57,20 @@ function AdminCreator(props){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function UserList(props){
|
function UserList(props){
|
||||||
const deleteUsers = (userId) => {
|
const deleteUser = (userId) => {
|
||||||
|
openConfirmDialog(function() {
|
||||||
fetch(process.env.REACT_APP_API_URL + `/users/${userId}`, {method: "DELETE"})
|
fetch(process.env.REACT_APP_API_URL + `/users/${userId}`, {method: "DELETE"})
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if(data.status !== "OK"){
|
if(data.status !== "OK"){
|
||||||
showError(data.data);
|
showError(data.data);
|
||||||
|
console.log("UWU")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
props.setUsers(props.users.filter(user => user.id !== userId));
|
props.onUserUpdated();
|
||||||
})
|
})
|
||||||
.catch(error => showError(error));
|
.catch(error => showError(error));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let updateRank = (asuraId) => event => {
|
let updateRank = (asuraId) => event => {
|
||||||
@ -92,52 +97,99 @@ function UserList(props){
|
|||||||
return(
|
return(
|
||||||
<Paper sx={{minHeight: "30vh", width:"90vw", margin:"10px auto"}} component={Stack} direction="column" justifycontent="center">
|
<Paper sx={{minHeight: "30vh", width:"90vw", margin:"10px auto"}} component={Stack} direction="column" justifycontent="center">
|
||||||
<div align="center">
|
<div align="center">
|
||||||
{/* TODO: scroll denne menyen, eventuelt søkefelt */}
|
<Table aria-label="simple table">
|
||||||
<Table aria-label="simple table">
|
<TableHead>
|
||||||
<TableHead>
|
<TableRow>
|
||||||
<TableRow>
|
<TableCell>Name</TableCell>
|
||||||
<TableCell>Name</TableCell>
|
<TableCell>Email</TableCell>
|
||||||
<TableCell>Email</TableCell>
|
<TableCell>Rank</TableCell>
|
||||||
<TableCell>Rank</TableCell>
|
<TableCell align="center">Actions</TableCell>
|
||||||
<TableCell align="center">Actions</TableCell>
|
</TableRow>
|
||||||
|
</TableHead>
|
||||||
|
<TableBody>
|
||||||
|
{props.users.map((user) => (
|
||||||
|
<TableRow key={user.asuraId}>
|
||||||
|
<TableCell component="th" scope="row">
|
||||||
|
<b>
|
||||||
|
{user.name}
|
||||||
|
</b>
|
||||||
|
</TableCell>
|
||||||
|
<TableCell>{user.email}</TableCell>
|
||||||
|
{/* TODO Drop down menu for selecting rank */}
|
||||||
|
<TableCell>
|
||||||
|
<FormControl variant="standard">
|
||||||
|
<Select onChange={updateRank(user.asuraId)} value={user.isManager ? "manager" : "admin"} aria-label="rank" id="rankSelect">
|
||||||
|
<MenuItem value={"manager"}>Manager</MenuItem>
|
||||||
|
<MenuItem value={"admin"}>Admin</MenuItem>
|
||||||
|
</Select>
|
||||||
|
</FormControl>
|
||||||
|
</TableCell>
|
||||||
|
{/* <TableCell align="right">{team.members}</TableCell> */}
|
||||||
|
<TableCell align="center">
|
||||||
|
{/* <Button variant="contained" sx={{margin: "auto 5px"}} color="primary" onClick={() => props.setSelectedTeamId(team.id)} endIcon={<EditIcon />}>Edit</Button> */}
|
||||||
|
<Button variant="contained" sx={{margin: "auto 5px"}} color="error" onClick={() => {deleteUser(user.asuraId)}} endIcon={<DeleteIcon />}>Delete</Button>
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
))}
|
||||||
<TableBody>
|
</TableBody>
|
||||||
{props.users.map((user) => (
|
</Table>
|
||||||
<TableRow key={user.asuraId}>
|
|
||||||
<TableCell component="th" scope="row">
|
|
||||||
<b>
|
|
||||||
{user.name}
|
|
||||||
</b>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell>{user.email}</TableCell>
|
|
||||||
{/* TODO Drop down menu for selecting rank */}
|
|
||||||
<TableCell>
|
|
||||||
<FormControl variant="standard">
|
|
||||||
<Select onChange={updateRank(user.asuraId)} value={user.isManager ? "manager" : "admin"} label="rank" labelId="rankSelect" id="rankSelect">
|
|
||||||
<MenuItem value={"manager"}>Manager</MenuItem>
|
|
||||||
<MenuItem value={"admin"}>Admin</MenuItem>
|
|
||||||
</Select>
|
|
||||||
</FormControl>
|
|
||||||
</TableCell>
|
|
||||||
{/* <TableCell align="right">{team.members}</TableCell> */}
|
|
||||||
<TableCell align="center">
|
|
||||||
{/* <Button variant="contained" sx={{margin: "auto 5px"}} color="primary" onClick={() => props.setSelectedTeamId(team.id)} endIcon={<EditIcon />}>Edit</Button> */}
|
|
||||||
<Button variant="contained" sx={{margin: "auto 5px"}} color="error" onClick={() => {deleteUsers(user.asuraId)}} endIcon={<DeleteIcon />}>Delete</Button>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
))}
|
|
||||||
</TableBody>
|
|
||||||
</Table>
|
|
||||||
</div>
|
</div>
|
||||||
</Paper>
|
</Paper>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 (
|
||||||
|
<Dialog
|
||||||
|
sx={{ '& .MuiDialog-paper': { width: '80%', maxHeight: 435 } }}
|
||||||
|
maxWidth="xs"
|
||||||
|
open={open}
|
||||||
|
keepMounted
|
||||||
|
>
|
||||||
|
<DialogTitle>Delete administrator?</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
Are you sure you want to delete the administrator? This action is not reversible!
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button autoFocus onClick={handleCancel}>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
<Button onClick={handleConfirm}>Confirm</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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) => {};
|
let showError = (message) => {};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function Users(props) {
|
export default function Users(props) {
|
||||||
|
|
||||||
const [openError, setOpenError] = React.useState(false);
|
const [openError, setOpenError] = React.useState(false);
|
||||||
@ -149,6 +201,12 @@ export default function Users(props) {
|
|||||||
}
|
}
|
||||||
const [users, setUsers] = React.useState([]);
|
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() {
|
function getUsers() {
|
||||||
fetch(process.env.REACT_APP_API_URL + `/users/getUsers`)
|
fetch(process.env.REACT_APP_API_URL + `/users/getUsers`)
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
@ -186,6 +244,13 @@ export default function Users(props) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ErrorSnackbar message={errorMessage} open={openError} setOpen={setOpenError} />
|
<ErrorSnackbar message={errorMessage} open={openError} setOpen={setOpenError} />
|
||||||
|
<ConfirmationDialogRaw
|
||||||
|
id="confirmation-dialog"
|
||||||
|
keepMounted
|
||||||
|
open={dialogOpen}
|
||||||
|
onClose={handleDialogClose}
|
||||||
|
handleconfirm={dialogOnConfirm}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
@ -85,7 +85,7 @@ function TournamentListItem(props) {
|
|||||||
</Box>)
|
</Box>)
|
||||||
} else {
|
} else {
|
||||||
return(<Box>
|
return(<Box>
|
||||||
<Typography variant="body"> Starts in: </Typography>
|
<Typography variant="body"> Starts in: </Typography> <br />
|
||||||
{ remainingDays > 0 ? <Typography variant="body"> {remainingDays} days</Typography> : null }
|
{ remainingDays > 0 ? <Typography variant="body"> {remainingDays} days</Typography> : null }
|
||||||
{ remainingHours > 0 ? <Typography variant="body"> {remainingHours} hours</Typography> : null }
|
{ remainingHours > 0 ? <Typography variant="body"> {remainingHours} hours</Typography> : null }
|
||||||
{ remainingMins > 0 ? <Typography variant="body"> {remainingMins} mins</Typography> : null }
|
{ remainingMins > 0 ? <Typography variant="body"> {remainingMins} mins</Typography> : null }
|
||||||
@ -105,26 +105,26 @@ function TournamentListItem(props) {
|
|||||||
image="banner2.png"
|
image="banner2.png"
|
||||||
/>
|
/>
|
||||||
<CardContent align="left">
|
<CardContent align="left">
|
||||||
<Typography variant="h3" component="div" align="center">{props.tournament.name} </Typography>
|
<Typography sx={{fontSize:['2rem','2.5rem','3rem']}} component="div" align="center">{props.tournament.name} </Typography>
|
||||||
|
|
||||||
<Box component={Stack} direction="column">
|
<Box component={Stack} direction="column">
|
||||||
<Typography variant="body"> Start: {props.tournament.startTime.toLocaleString()} </Typography>
|
<Typography variant="body"> Start: {props.tournament.startTime.toLocaleString()} </Typography>
|
||||||
<Typography variant="body"> End: {props.tournament.endTime.toLocaleString()} </Typography>
|
<Typography variant="body"> End: {props.tournament.endTime.toLocaleString()} </Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Typography variant="h5" color="text.primary" gutterBottom> Players: {props.tournament.teamCount} / {props.tournament.teamLimit} </Typography>
|
<Typography variant="h5" color="text.primary" gutterBottom> Particpants: {props.tournament.teamCount} / {props.tournament.teamLimit} </Typography>
|
||||||
<Description />
|
<Description />
|
||||||
<Typography variant="body" color="text.primary"><EmojiEventsIcon alt="A trohpy" color="gold"/> Prize: {props.tournament.prize} </Typography>
|
<Typography variant="body" color="text.primary"><EmojiEventsIcon alt="A trohpy" color="gold"/> Prize: {props.tournament.prize} </Typography>
|
||||||
<Countdown />
|
<Countdown />
|
||||||
|
|
||||||
<Box sx={{flexGrow: 1, marginTop: "20px"}}>
|
<Box sx={{flexGrow: 1, marginTop: "20px"}}>
|
||||||
<Grid container spacing={4} justifyContent="center" wrap="wrap">
|
<Grid container spacing={2} justifyContent="center" wrap="wrap">
|
||||||
{ props.user.isLoggedIn ?
|
{ props.user.isLoggedIn &&
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Link to={`/tournament/${props.tournament.id}/manage`}>
|
<Link to={`/tournament/${props.tournament.id}/manage`}>
|
||||||
<Button className="ManageButton" variant="contained" color="primary" endIcon={<EditIcon />}>Edit Tournament</Button>
|
<Button className="ManageButton" variant="contained" color="primary" endIcon={<EditIcon />}>Edit Tournament</Button>
|
||||||
</Link>
|
</Link>
|
||||||
</Grid> : null
|
</Grid>
|
||||||
}
|
}
|
||||||
<Grid item >
|
<Grid item >
|
||||||
<Link to={`/tournament/${props.tournament.id}`} >
|
<Link to={`/tournament/${props.tournament.id}`} >
|
||||||
@ -182,7 +182,7 @@ function Home(props) {
|
|||||||
<>
|
<>
|
||||||
<Appbar user={props.user} pageTitle="Asura Tournaments" />
|
<Appbar user={props.user} pageTitle="Asura Tournaments" />
|
||||||
<Container sx={{minHeight: "30vh", width: "90vw", padding: "20px 20px"}} component={Container} direction="column" align="center">
|
<Container sx={{minHeight: "30vh", width: "90vw", padding: "20px 20px"}} component={Container} direction="column" align="center">
|
||||||
<Box component={Stack} direction="row" align="center" justifyContent="space-between" alignItems="center" sx={{flexGrow: 1}}>
|
<Box component={Stack} direction={['column','row']} sx={{align:'center', justifyContent:'space-between', flexGrow:1}}>
|
||||||
<Typography sx={{fontSize:['1.5rem','2rem','2rem']}}>Tournaments</Typography>
|
<Typography sx={{fontSize:['1.5rem','2rem','2rem']}}>Tournaments</Typography>
|
||||||
{ props.user.isLoggedIn ?
|
{ props.user.isLoggedIn ?
|
||||||
<CreateButton /> : null
|
<CreateButton /> : null
|
||||||
|
@ -12,7 +12,6 @@ export default function ProfilePage(props) {
|
|||||||
|
|
||||||
return (<>
|
return (<>
|
||||||
<Appbar user={props.user} pageTitle="Profile" />
|
<Appbar user={props.user} pageTitle="Profile" />
|
||||||
<Container sx={{minHeight: "30vh", width: "90vw", padding: "20px 20px"}} component={Container} direction="column" align="center">
|
|
||||||
<Paper sx={{minHeight: "30vh", width: "90vw", margin: "10px auto"}} component={Stack} direction="column" justifyContent="center">
|
<Paper sx={{minHeight: "30vh", width: "90vw", margin: "10px auto"}} component={Stack} direction="column" justifyContent="center">
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<h2><b>Your profile</b></h2>
|
<h2><b>Your profile</b></h2>
|
||||||
@ -23,6 +22,5 @@ export default function ProfilePage(props) {
|
|||||||
</Box>
|
</Box>
|
||||||
</div>
|
</div>
|
||||||
</Paper>
|
</Paper>
|
||||||
</Container>
|
|
||||||
</>)
|
</>)
|
||||||
}
|
}
|
@ -113,7 +113,7 @@ function TournamentForm(props) {
|
|||||||
<TextField type="text" id="prizeInput" label="Prize" placeholder="Prize" InputLabelProps={{shrink: true}}/>
|
<TextField type="text" id="prizeInput" label="Prize" placeholder="Prize" InputLabelProps={{shrink: true}}/>
|
||||||
<Box flexGrow={1}>
|
<Box flexGrow={1}>
|
||||||
<Grid container spacing={2} justifyContent="center">
|
<Grid container spacing={2} justifyContent="center">
|
||||||
<Grid item xs={4}>
|
<Grid item xs={6}>
|
||||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
<DateTimePicker label={"Start Time"} inputVariant="outlined" ampm={false} mask="____-__-__ __:__" format="yyyy-MM-dd HH:mm" inputFormat="yyyy-MM-dd HH:mm" value={startTime}
|
<DateTimePicker label={"Start Time"} inputVariant="outlined" ampm={false} mask="____-__-__ __:__" format="yyyy-MM-dd HH:mm" inputFormat="yyyy-MM-dd HH:mm" value={startTime}
|
||||||
onChange={setStartTime}
|
onChange={setStartTime}
|
||||||
@ -121,8 +121,7 @@ function TournamentForm(props) {
|
|||||||
/>
|
/>
|
||||||
</LocalizationProvider>
|
</LocalizationProvider>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={4}>
|
<Grid item xs={6}>
|
||||||
|
|
||||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
<DateTimePicker label={"End Time"} inputVariant="outlined" ampm={false} mask="____-__-__ __:__" format="yyyy-MM-dd HH:mm" inputFormat="yyyy-MM-dd HH:mm" value={endTime}
|
<DateTimePicker label={"End Time"} inputVariant="outlined" ampm={false} mask="____-__-__ __:__" format="yyyy-MM-dd HH:mm" inputFormat="yyyy-MM-dd HH:mm" value={endTime}
|
||||||
onChange={setEndTime}
|
onChange={setEndTime}
|
||||||
|
@ -54,7 +54,7 @@ function shorten(description, maxLength) {
|
|||||||
<Typography variant="body"> End: {props.tournament.endTime.toLocaleString()} </Typography>
|
<Typography variant="body"> End: {props.tournament.endTime.toLocaleString()} </Typography>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Typography variant="h5" color="text.primary" gutterBottom> Players: {props.tournament.teamCount} / {props.tournament.teamLimit} </Typography>
|
<Typography variant="h5" color="text.primary" gutterBottom> Participants: {props.tournament.teamCount} / {props.tournament.teamLimit} </Typography>
|
||||||
<Description />
|
<Description />
|
||||||
<Typography variant="body" color="text.primary"><EmojiEventsIcon alt="A trohpy" color="gold" align="vertical-center"/> Prize: {props.tournament.prize} </Typography>
|
<Typography variant="body" color="text.primary"><EmojiEventsIcon alt="A trohpy" color="gold" align="vertical-center"/> Prize: {props.tournament.prize} </Typography>
|
||||||
|
|
||||||
@ -150,8 +150,8 @@ export default function TournamentHistory(props) {
|
|||||||
<>
|
<>
|
||||||
<Appbar user={props.user} pageTitle="Tournament History" />
|
<Appbar user={props.user} pageTitle="Tournament History" />
|
||||||
<Container sx={{minHeight: "30vh", width: "90vw", padding: "20px 20px"}} component={Container} direction="column" align="center">
|
<Container sx={{minHeight: "30vh", width: "90vw", padding: "20px 20px"}} component={Container} direction="column" align="center">
|
||||||
<Box component={Stack} direction="row" align="center" justifyContent="space-between" alignItems="center" sx={{flexGrow: 1}}>
|
<Box component={Stack} direction="row" align="center" justifyContent="center" alignItems="center" sx={{flexGrow: 1, margin:'2.5% 0'}}>
|
||||||
<Typography variant="h3">Past Tournaments</Typography>
|
<Typography sx={{fontSize:['1.5rem','2rem','2rem']}}>Past Tournaments</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
<TournamentList />
|
<TournamentList />
|
||||||
</Container>
|
</Container>
|
||||||
|
@ -134,13 +134,13 @@ function ManageTournament(props) {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<form>
|
<form>
|
||||||
<Stack sx={{minHeight: "30vh", margin: "10px auto"}} direction="column" justifyContent="center" spacing={2} align="center">
|
<Stack sx={{minHeight: "30vh", margin: "1.5%"}} direction="column" justifyContent="center" spacing={2} align="center">
|
||||||
<TextField type="text" id="editName" label="Edit Name:" placeholder="Edit Name" InputLabelProps={{shrink: true}}/>
|
<TextField type="text" id="editName" label="Edit Name:" placeholder="Edit Name" InputLabelProps={{shrink: true}}/>
|
||||||
<TextField type="text" multiline={true} id="editDesc" label="Edit Description:" placeholder="Edit Description" InputLabelProps={{shrink: true}} />
|
<TextField type="text" multiline={true} id="editDesc" label="Edit Description:" placeholder="Edit Description" InputLabelProps={{shrink: true}} />
|
||||||
<TextField type="text" id="editPrize" label="Edit Prize:" placeholder="Edit Prize" InputLabelProps={{shrink: true}}/>
|
<TextField type="text" id="editPrize" label="Edit Prize:" placeholder="Edit Prize" InputLabelProps={{shrink: true}}/>
|
||||||
<Box sx={{flexGrow: 1}}>
|
<Box sx={{flexGrow: 1}}>
|
||||||
<Grid container spacing={2} justifyContent="center">
|
<Grid container spacing={2} justifyContent="center">
|
||||||
<Grid item xs={4}>
|
<Grid item xs={6}>
|
||||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
<DateTimePicker label={"Start Time"} inputVariant="outlined" ampm={false} mask="____-__-__ __:__" format="yyyy-MM-dd HH:mm" inputFormat="yyyy-MM-dd HH:mm" value={startTime}
|
<DateTimePicker label={"Start Time"} inputVariant="outlined" ampm={false} mask="____-__-__ __:__" format="yyyy-MM-dd HH:mm" inputFormat="yyyy-MM-dd HH:mm" value={startTime}
|
||||||
onChange={setStartTime}
|
onChange={setStartTime}
|
||||||
@ -148,7 +148,7 @@ function ManageTournament(props) {
|
|||||||
/>
|
/>
|
||||||
</LocalizationProvider>
|
</LocalizationProvider>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={4}>
|
<Grid item xs={6}>
|
||||||
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
<LocalizationProvider dateAdapter={AdapterDateFns}>
|
||||||
<DateTimePicker label={"End Time"} inputVariant="outlined" ampm={false} mask="____-__-__ __:__" format="yyyy-MM-dd HH:mm:" inputFormat="yyyy-MM-dd HH:mm" value={endTime}
|
<DateTimePicker label={"End Time"} inputVariant="outlined" ampm={false} mask="____-__-__ __:__" format="yyyy-MM-dd HH:mm:" inputFormat="yyyy-MM-dd HH:mm" value={endTime}
|
||||||
onChange={setEndTime}
|
onChange={setEndTime}
|
||||||
@ -219,8 +219,13 @@ export default function TournamentManager(props) {
|
|||||||
const handleDialogClickListItem = () => { setDialogOpen(true); };
|
const handleDialogClickListItem = () => { setDialogOpen(true); };
|
||||||
const handleDialogClose = () => { setDialogOpen(false); };
|
const handleDialogClose = () => { setDialogOpen(false); };
|
||||||
|
|
||||||
showError = props.showError;
|
const [openError, setOpenError] = React.useState(false);
|
||||||
showSuccess = props.showSuccess;
|
const [errorMessage, setErrorMessage] = React.useState("");
|
||||||
|
showError = (message) => {
|
||||||
|
setOpenError(false);
|
||||||
|
setErrorMessage(message);
|
||||||
|
setOpenError(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (!props.user.isLoggedIn) { return <LoginPage user={props.user} />; }
|
if (!props.user.isLoggedIn) { return <LoginPage user={props.user} />; }
|
||||||
|
|
||||||
@ -229,7 +234,7 @@ export default function TournamentManager(props) {
|
|||||||
<Appbar user={props.user} pageTitle="Edit Tournament" />
|
<Appbar user={props.user} pageTitle="Edit Tournament" />
|
||||||
<TournamentBar pageTitle="Edit Tournament"/>
|
<TournamentBar pageTitle="Edit Tournament"/>
|
||||||
<Paper sx={{minHeight: "30vh", width: "90vw", margin: "20px auto", padding: "20px 0"}} component={Container} direction="column" align="center">
|
<Paper sx={{minHeight: "30vh", width: "90vw", margin: "20px auto", padding: "20px 0"}} component={Container} direction="column" align="center">
|
||||||
<ManageTournament tournamentId={tournamentId} showError={showError} />
|
<ManageTournament tournamentId={tournamentId} />
|
||||||
{/* <AnnounceButton /> */}
|
{/* <AnnounceButton /> */}
|
||||||
<Box sx={{width: "100%"}}>
|
<Box sx={{width: "100%"}}>
|
||||||
<Button variant="contained" color="error" onClick={handleDialogClickListItem} sx={{margin: "auto 5px"}} endIcon={<DeleteIcon />}>
|
<Button variant="contained" color="error" onClick={handleDialogClickListItem} sx={{margin: "auto 5px"}} endIcon={<DeleteIcon />}>
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
import * as React from "react";
|
|
||||||
import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
|
|
||||||
import Appbar from './components/AsuraBar';
|
|
||||||
|
|
||||||
function MatchHistory() {
|
|
||||||
|
|
||||||
return(
|
|
||||||
`Hei på deg din gamle sei`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function TournamentMatches(props) {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Appbar user={props.user} />
|
|
||||||
<MatchHistory />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -16,12 +16,12 @@ function TournamentTier(props){
|
|||||||
let roundTypes = ["finals", "semifinals", "quarterfinals", "eighthfinals", "sixteenthfinals", "thirtysecondfinals"];
|
let roundTypes = ["finals", "semifinals", "quarterfinals", "eighthfinals", "sixteenthfinals", "thirtysecondfinals"];
|
||||||
let matches = [];
|
let matches = [];
|
||||||
for (let i = 0; i < props.matches.length; i++) {
|
for (let i = 0; i < props.matches.length; i++) {
|
||||||
matches.push(<Match tournament={props.tournament} user={props.user} tier={props.tier} roundTypes={roundTypes} teams={props.teams} match={props.matches[i]} key={i} />);
|
matches.push(<Match tournament={props.tournament} user={props.user} tier={props.tier} roundTypes={roundTypes} teams={props.teams} match={props.matches[i]} key={i} onwinnerchange={props.onwinnerchange} />);
|
||||||
}
|
}
|
||||||
return(
|
return(
|
||||||
<>
|
<>
|
||||||
<Box className={`round ${roundTypes[props.tier]}`} sx={{width:['100px', '150px', '200px', '250px', '400px']}}>
|
<Box component='ul' className={`round ${roundTypes[props.tier]}`} sx={{width:['125px','200px','250px','300px','350px']}}>
|
||||||
<li className="spacer"> </li>
|
<Box component='li' className="spacer"> </Box>
|
||||||
{matches}
|
{matches}
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
@ -40,7 +40,6 @@ function Match(props){
|
|||||||
|
|
||||||
let setWinner = curryTeamId => event => {
|
let setWinner = curryTeamId => event => {
|
||||||
let teamId = curryTeamId;
|
let teamId = curryTeamId;
|
||||||
// console.log(teamId)
|
|
||||||
if (!teamId || teamId == null) {
|
if (!teamId || teamId == null) {
|
||||||
showError("No team selected");
|
showError("No team selected");
|
||||||
return;
|
return;
|
||||||
@ -56,7 +55,7 @@ function Match(props){
|
|||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.status === "OK") {
|
if (data.status === "OK") {
|
||||||
//Refresh when winner is set successfully
|
//Refresh when winner is set successfully
|
||||||
window.location.reload();
|
props.onwinnerchange();
|
||||||
} else {
|
} else {
|
||||||
showError(data.data)
|
showError(data.data)
|
||||||
}
|
}
|
||||||
@ -65,11 +64,9 @@ function Match(props){
|
|||||||
};
|
};
|
||||||
|
|
||||||
let curryUnsetContestant = teamId => (e) => {
|
let curryUnsetContestant = teamId => (e) => {
|
||||||
// console.log("wack")
|
|
||||||
let formData = new FormData();
|
let formData = new FormData();
|
||||||
formData.append("teamId", teamId);
|
formData.append("teamId", teamId);
|
||||||
let body = new URLSearchParams(formData);
|
let body = new URLSearchParams(formData);
|
||||||
// console.log(props.match)
|
|
||||||
fetch(process.env.REACT_APP_API_URL + `/match/${props.match.id}/unsetContestant`, {
|
fetch(process.env.REACT_APP_API_URL + `/match/${props.match.id}/unsetContestant`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: body
|
body: body
|
||||||
@ -77,8 +74,9 @@ function Match(props){
|
|||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.status === "OK") {
|
if (data.status === "OK") {
|
||||||
// console.log("wacky smacky");
|
props.onwinnerchange()
|
||||||
window.location.reload();
|
} else {
|
||||||
|
showError(data.data);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => showError(error));
|
.catch(error => showError(error));
|
||||||
@ -87,51 +85,94 @@ function Match(props){
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* Team 1 (Winner-status?) (Team name) */}
|
{/* Team 1 (Winner-status?) (Team name) */}
|
||||||
<li className={`game game-top`}>
|
<Box component='li' className={`game game-top`}>
|
||||||
<Stack direction={"row"} alignItems="center" spacing={1}>
|
<Stack direction={"row"} alignItems="center" spacing={1} sx={{justifyContent:['start','space-between']}}>
|
||||||
<Typography noWrap className={`${props.match.winnerId !== null ? (props.match.team1Id === props.match.winnerId) ? "winner" : "loser" : ""}`} align={'center'} sx={{ maxWidth:'70%', overflow:'hidden', wordWrap:'none', fontSize:['2vh', '1.5vh', '2vh', '3vh', '3.5vh', '4vh']}}>
|
<Typography noWrap className={`${props.match.winnerId !== null ? (props.match.team1Id === props.match.winnerId) ? "winner" : "loser" : ""}`} align={'center'} sx={{ maxWidth:'70%', overflow:'hidden', wordWrap:'none', fontSize:['1em','1em','1.5em','1.75em']}}>
|
||||||
{team1Name}
|
{team1Name}
|
||||||
</Typography>
|
</Typography>
|
||||||
{ props.match.winnerId && (props.match.team1Id === props.match.winnerId) &&
|
{ props.match.winnerId && (props.match.team1Id === props.match.winnerId) &&
|
||||||
<EmojiEventsIcon alt="A trohpy" />
|
<EmojiEventsIcon alt="A trohpy" sx={{width:['0.75em','1em','1.25em'], height:['0.75em','1em','1.25em']}} />
|
||||||
}
|
}
|
||||||
|
<Box component={Stack} direction={'row'} spacing={-1.25}>
|
||||||
{ 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.tournament.hasEnded && props.match.tier !== Math.log2(props.tournament.teamLimit) - 1 && props.match.winnerId === null && props.user.isLoggedIn &&
|
||||||
<IconButton color="error" aria-label="remove winner" component="span" onClick={curryUnsetContestant(props.match.team1Id)}><BackspaceIcon /></IconButton>
|
<IconButton color="error" aria-label="remove winner" component="span" onClick={curryUnsetContestant(props.match.team1Id)}><BackspaceIcon sx={{width:['0.75em','1em','1.25em'], height:['0.75em','1em','1.25em']}} /></IconButton>
|
||||||
}
|
}
|
||||||
{ props.match.team1Id !== null && props.match.winnerId === null && !props.tournament.hasEnded && props.user.isLoggedIn &&
|
{ props.match.team1Id !== null && props.match.winnerId === null && !props.tournament.hasEnded && props.user.isLoggedIn &&
|
||||||
<IconButton onClick={setWinner(props.match.team1Id)} color="success" aria-label="select winner" component="span"><AddCircleIcon /></IconButton>
|
<IconButton onClick={setWinner(props.match.team1Id)} color="success" aria-label="select winner" component="span"><AddCircleIcon sx={{width:['0.75em','1em','1.25em'], height:['0.75em','1em','1.25em']}} /></IconButton>
|
||||||
}
|
}
|
||||||
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
</li>
|
</Box>
|
||||||
<li className="game game-spacer"> </li>
|
<Box component='li' className="game game-spacer"> </Box>
|
||||||
{/* Team 2 (Winner-status?) (Team name) */}
|
{/* Team 2 (Winner-status?) (Team name) */}
|
||||||
<li className={`game game-bottom`}>
|
<Box component='li' className={`game game-bottom`}>
|
||||||
<Stack direction={"row"} alignItems="center">
|
<Stack direction={"row"} alignItems="center" sx={{justifyContent:['start','space-between']}}>
|
||||||
<Typography noWrap className={`${props.match.winnerId !== null ? (props.match.team2Id === props.match.winnerId) ? "winner" : "loser" : ""}`} sx={{maxWidth:'70%', overflow:'hidden', wordWrap:'none',fontSize:['2vh', '1.5vh', '2vh', '3vh', '3.5vh', '4vh']}}>
|
<Typography noWrap className={`${props.match.winnerId !== null ? (props.match.team2Id === props.match.winnerId) ? "winner" : "loser" : ""}`} sx={{maxWidth:'70%', overflow:'hidden', wordWrap:'none',fontSize:['1em','1em','1.5em','1.75em']}}>
|
||||||
{team2Name}
|
{team2Name}
|
||||||
</Typography>
|
</Typography>
|
||||||
{ props.match.winnerId && (props.match.team2Id === props.match.winnerId) &&
|
{ props.match.winnerId && (props.match.team2Id === props.match.winnerId) &&
|
||||||
<EmojiEventsIcon alt="A trohpy" />
|
<EmojiEventsIcon alt="A trohpy" sx={{width:['0.75em','1em','1.25em'], height:['0.75em','1em','1.25em']}} />
|
||||||
}
|
}
|
||||||
{ 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.tournament.hasEnded && props.match.tier !== Math.log2(props.tournament.teamLimit) - 1 && props.match.winnerId === null && props.user.isLoggedIn &&
|
||||||
<IconButton color="error" aria-label="remove winner" component="span" onClick={curryUnsetContestant(props.match.team2Id)}><BackspaceIcon /></IconButton>
|
<IconButton color="error" aria-label="remove winner" component="span" onClick={curryUnsetContestant(props.match.team2Id)}><BackspaceIcon sx={{width:['0.75em','1em','1.25em'], height:['0.75em','1em','1.25em']}} /></IconButton>
|
||||||
}
|
}
|
||||||
{ props.match.team2Id !== null && props.match.winnerId === null && !props.tournament.hasEnded && props.user.isLoggedIn &&
|
{ props.match.team2Id !== null && props.match.winnerId === null && !props.tournament.hasEnded && props.user.isLoggedIn &&
|
||||||
<IconButton onClick={setWinner(props.match.team2Id)} color="success" aria-label="select winner" component="span"><AddCircleIcon /></IconButton>
|
<IconButton onClick={setWinner(props.match.team2Id)} color="success" aria-label="select winner" component="span" ><AddCircleIcon sx={{width:['0.75em','1em','1.25em'], height:['0.75em','1em','1.25em']}} /></IconButton>
|
||||||
}
|
}
|
||||||
</Stack>
|
</Stack>
|
||||||
</li>
|
</Box>
|
||||||
<li className="spacer"> </li>
|
<Box component='li' className="spacer"> </Box>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function WinnerDisplay(props) {
|
||||||
|
let unsetWinner = event => {
|
||||||
|
let formData = new FormData();
|
||||||
|
formData.append("winnerId","null");
|
||||||
|
let body = new URLSearchParams(formData);
|
||||||
|
fetch(process.env.REACT_APP_API_URL + `/match/${props.finalMatch.id}/setWinner`, {
|
||||||
|
method: "POST",
|
||||||
|
body: body
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.status !== "OK") { showError(data.data); return;}
|
||||||
|
props.onwinnerchange();
|
||||||
|
})
|
||||||
|
.catch(error => showError(error));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!props.team) {
|
||||||
|
// Winner is not yet chosen
|
||||||
|
return <div className="winnerDisplay">
|
||||||
|
<Typography sx={{fontSize:['1em','1em','1.5em','2em']}}>
|
||||||
|
Winner is not chosen.<br /> Will it be you?
|
||||||
|
</Typography>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="winnerDisplay">
|
||||||
|
<Typography align="center">
|
||||||
|
{props.user.isLoggedIn && !props.tournament.hasEnded && <IconButton color="error" aria-label="remove winner" component="span" onClick={unsetWinner}><BackspaceIcon /></IconButton>}
|
||||||
|
</Typography>
|
||||||
|
<Typography sx={{fontSize:['1em','1em','1.5em','2em']}} className="winner">
|
||||||
|
{props.team.name}
|
||||||
|
</Typography>
|
||||||
|
<EmojiEventsIcon alt="A trohpy" />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function BracketViewer(props){
|
function BracketViewer(props){
|
||||||
|
|
||||||
const [matches, setMatches] = React.useState(null);
|
const [matches, setMatches] = React.useState(null);
|
||||||
const [teams, setTeams] = React.useState(null);
|
const [teams, setTeams] = React.useState(null);
|
||||||
|
|
||||||
React.useEffect(() => {
|
let getMatches = () => {
|
||||||
fetch(process.env.REACT_APP_API_URL + `/tournament/${props.tournamentId}/getMatches`)
|
fetch(process.env.REACT_APP_API_URL + `/tournament/${props.tournamentId}/getMatches`)
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
@ -140,20 +181,18 @@ function BracketViewer(props){
|
|||||||
console.error(data);
|
console.error(data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let matches = data.data;
|
let allMatches = data.data;
|
||||||
// Group all matches by their round/tier
|
// Group all matches by their round/tier
|
||||||
let tiers = matches.reduce((tiers, match) => {
|
let tiers = allMatches.reduce((tiers, match) => {
|
||||||
if (!tiers[match.tier]) {
|
if (!tiers[match.tier]) {
|
||||||
tiers[match.tier] = [];
|
tiers[match.tier] = [];
|
||||||
}
|
}
|
||||||
tiers[match.tier].push(match);
|
tiers[match.tier].push(match);
|
||||||
console.log(tiers)
|
|
||||||
return tiers;
|
return tiers;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
tiers = Object.values(tiers);
|
tiers = Object.values(tiers);
|
||||||
tiers = tiers.reverse();
|
tiers = tiers.reverse();
|
||||||
|
|
||||||
setMatches(tiers);
|
setMatches(tiers);
|
||||||
})
|
})
|
||||||
.catch(err => showError(err));
|
.catch(err => showError(err));
|
||||||
@ -169,19 +208,35 @@ function BracketViewer(props){
|
|||||||
setTeams(teams);
|
setTeams(teams);
|
||||||
})
|
})
|
||||||
.catch(err => showError(err));
|
.catch(err => showError(err));
|
||||||
|
}
|
||||||
|
React.useEffect(() => {
|
||||||
|
getMatches();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
let getFinalMatch = (tierMatches) => {
|
||||||
|
let finalMatch = tierMatches[tierMatches.length - 1][0];
|
||||||
|
return finalMatch;
|
||||||
|
};
|
||||||
|
let getWinnerTeam = (tierMatches) => {
|
||||||
|
let finalMatch = getFinalMatch(tierMatches);
|
||||||
|
if (finalMatch.winnerId === null) { return null;}
|
||||||
|
let winnerTeam = teams.find(team => team.id === finalMatch.winnerId);
|
||||||
|
return winnerTeam;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
||||||
(props.tournament && matches && teams) ?
|
(props.tournament && matches && teams) ?
|
||||||
// <div sx={{width: "100vw", height: "80vh", overflow: "scroll"}} className="bracket">
|
// <div sx={{width: "100vw", height: "80vh", overflow: "scroll"}} className="bracket">
|
||||||
<>
|
<>
|
||||||
<div className="bracket">
|
<div className="bracket">
|
||||||
{matches.map(tier => {
|
{matches.map(tierMatches => {
|
||||||
let tierNum = tier[0].tier;
|
let tierNum = tierMatches[0].tier;
|
||||||
return <TournamentTier user={props.user} tournament={props.tournament} key={tierNum} tier={tierNum} matches={tier} teams={teams} />
|
return <TournamentTier user={props.user} tournament={props.tournament} key={tierNum} tier={tierNum} matches={tierMatches} teams={teams} onwinnerchange={getMatches} />
|
||||||
})}
|
})}
|
||||||
|
|
||||||
|
<WinnerDisplay team={getWinnerTeam(matches)} user={props.user} finalMatch={getFinalMatch(matches)} onwinnerchange={getMatches} tournament={props.tournament} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
: <Box sx={{display:'flex', justifyContent:'center', alignItems:'center', position:'relative', marginTop:'5%'}}><CircularProgress size={"20vw"}/></Box>
|
: <Box sx={{display:'flex', justifyContent:'center', alignItems:'center', position:'relative', marginTop:'5%'}}><CircularProgress size={"20vw"}/></Box>
|
||||||
);
|
);
|
||||||
|
@ -39,12 +39,12 @@ function TeamCreator(props) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper sx={{width: "90vw", margin: "10px auto", padding: "15px"}} component={Stack} direction="column">
|
<Paper sx={{width: "90vw", margin: "10px auto", padding: "15px", align:'center', justifyContent:'center', flexGrow:1}} component={Stack} direction={['column']} spacing={2}>
|
||||||
<div align="center">
|
<div align="center">
|
||||||
<form>
|
<form>
|
||||||
<TextField id="teamNameInput" sx={{ width: "70%" }} label="Team Name" variant="outlined" />
|
<TextField id="teamNameInput" sx={{width:['auto','50%','60%','70%'], margin:'1% 0'}} label="Team Name" variant="outlined" />
|
||||||
{/* <Button variant="contained" color="primary" onClick={postCreate}>Create Team</Button> */}
|
{/* <Button variant="contained" color="primary" onClick={postCreate}>Create Team</Button> */}
|
||||||
<Button type="submit" variant="contained" color="success" onClick={postCreate} sx={{width: "20%", marginLeft: "5px"}}>
|
<Button type="submit" variant="contained" color="success" onClick={postCreate} sx={{ margin:'1% 1%',width:['fit-content','40%','30%','20%']}}>
|
||||||
<Box sx={{padding: "10px"}}>
|
<Box sx={{padding: "10px"}}>
|
||||||
Create Team
|
Create Team
|
||||||
</Box>
|
</Box>
|
||||||
|
@ -31,10 +31,10 @@ function LoggedInMenu(props) {
|
|||||||
<Menu anchorEl={anchorEl} open={open} onClose={handleClose} MenuListProps={{'aria-labelledby': 'basic-button',}} sx={{position:"absolute"}}>
|
<Menu anchorEl={anchorEl} open={open} onClose={handleClose} MenuListProps={{'aria-labelledby': 'basic-button',}} sx={{position:"absolute"}}>
|
||||||
<Link to="/profile" style={{color:"black"}}><MenuItem onClick={handleClose}><Button startIcon={<AccountCircleIcon />}>{props.user.name}</Button></MenuItem></Link>
|
<Link to="/profile" style={{color:"black"}}><MenuItem onClick={handleClose}><Button startIcon={<AccountCircleIcon />}>{props.user.name}</Button></MenuItem></Link>
|
||||||
<Link to="/history" style={{color:"black"}}><MenuItem onClick={handleClose}><Button startIcon={<HistoryIcon />}>History</Button></MenuItem></Link>
|
<Link to="/history" style={{color:"black"}}><MenuItem onClick={handleClose}><Button startIcon={<HistoryIcon />}>History</Button></MenuItem></Link>
|
||||||
<Link to="/api/logout" style={{color:"black"}}><MenuItem onClick={logout}><Button startIcon={<LogoutIcon />} >Logout</Button></MenuItem></Link>
|
|
||||||
{ props.user.isManager &&
|
{ props.user.isManager &&
|
||||||
<Link to="/admins" style={{color:"black"}}><MenuItem onClick={handleClose}><Button startIcon={<EditIcon />} >Admins</Button></MenuItem></Link>
|
<Link to="/admins" style={{color:"black"}}><MenuItem onClick={handleClose}><Button startIcon={<EditIcon />} >Admins</Button></MenuItem></Link>
|
||||||
}
|
}
|
||||||
|
<a href={`${process.env.REACT_APP_API_URL}/users/logout`} style={{color:"black"}}><MenuItem onClick={logout}><Button startIcon={<LogoutIcon />} >Logout</Button></MenuItem></a>
|
||||||
</Menu>
|
</Menu>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@ -67,19 +67,19 @@ export default function Appbar(props) {
|
|||||||
<Grid item xs={2}>
|
<Grid item xs={2}>
|
||||||
<Box sx={{ width:"100%", height: "100%", justifyContent:"left", align: "center", alignItems:"center", margin: "none", padding: "none", color: "white" ,display: "flex", flexFlow: "row"}}>
|
<Box sx={{ width:"100%", height: "100%", justifyContent:"left", align: "center", alignItems:"center", margin: "none", padding: "none", color: "white" ,display: "flex", flexFlow: "row"}}>
|
||||||
<Link to="/">
|
<Link to="/">
|
||||||
<img sx={{width: "10%"}} src={logo} alt="Tournament logo" className="mainIcon"></img>
|
<Box component="img" src={logo} alt="Tournament logo" className="mainIcon" sx={{height:['55px','65px'], width:['55px','65px']}}></Box>
|
||||||
</Link>
|
</Link>
|
||||||
{ props.pageTitle !== "Asura Tournaments" &&
|
{ props.pageTitle !== "Asura Tournaments" &&
|
||||||
<Link to="/" style={{color:"white"}}>
|
<Link to="/" style={{color:"white"}}>
|
||||||
<Typography component="div" align="center">
|
<Typography component="div" align="center" sx={{fontSize:['1em','1em','1.5em','2em']}}>
|
||||||
Home
|
Home
|
||||||
</Typography>
|
</Typography>
|
||||||
</Link>
|
</Link>
|
||||||
}
|
}
|
||||||
</Box>
|
</Box>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item xs={2} sm={3} md={4} lg={6} xl={8}>
|
<Grid item xs={4} md={6} lg={8}>
|
||||||
<Typography component="div" sx={{fontSize:['0.5rem','1rem','1.5rem','2rem']}}>{props.pageTitle || ""}</Typography>
|
<Typography component="div" sx={{fontSize:['1em','1em','1.5em','2em']}}>{props.pageTitle || ""}</Typography>
|
||||||
</Grid>
|
</Grid>
|
||||||
{ props.pageTitle !== "Login" ?
|
{ props.pageTitle !== "Login" ?
|
||||||
<Grid item xs={2}>
|
<Grid item xs={2}>
|
||||||
|
@ -3,6 +3,11 @@ import { useParams } from "react-router-dom";
|
|||||||
import { BrowserRouter as Router, Link, Route, Routes, History } 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 { Stack, Paper, Typography, Box, Button, Grid, Snackbar, IconButton } from "@mui/material"
|
||||||
import CloseIcon from '@mui/icons-material/Close';
|
import CloseIcon from '@mui/icons-material/Close';
|
||||||
|
import MuiAlert from '@mui/material/Alert';
|
||||||
|
|
||||||
|
const Alert = React.forwardRef(function Alert(props, ref) {
|
||||||
|
return <MuiAlert elevation={6} ref={ref} variant="filled" {...props} />;
|
||||||
|
});
|
||||||
|
|
||||||
function ClipboardButton(props) {
|
function ClipboardButton(props) {
|
||||||
const [open, setOpen] = React.useState(false);
|
const [open, setOpen] = React.useState(false);
|
||||||
@ -22,8 +27,12 @@ function ClipboardButton(props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button onClick={copyString} variant="outlined" color="primary" sx={{margin: "auto 5px"}} >Copy {props.name}</Button>
|
<Button onClick={copyString} variant="outlined" color="primary" sx={{margin:'1.5%', fontSize:['0.75em']}} >Copy {props.name}</Button>
|
||||||
<Snackbar open={open} autoHideDuration={1500} onClose={handleClose} message={props.name + " copied to clipboard"} action={closeAction} />
|
<Snackbar open={open} autoHideDuration={1500} onClose={handleClose} action={closeAction}>
|
||||||
|
<Alert onClose={handleClose} severity="info" sx={{ width: '100%' }}>
|
||||||
|
{props.name + " copied to clipboard"}
|
||||||
|
</Alert>
|
||||||
|
</Snackbar>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -31,7 +40,7 @@ function ClipboardButton(props) {
|
|||||||
function ButtonLink(props) {
|
function ButtonLink(props) {
|
||||||
return (
|
return (
|
||||||
<Link to={`/tournament/${props.tournamentId}` + props.targetPath} >
|
<Link to={`/tournament/${props.tournamentId}` + props.targetPath} >
|
||||||
<Button variant="contained" color="primary" disabled={props.activeTitle === props.title || props.viewTournament} sx={{margin: "1.5vw", fontSize: "1.2em"}} >{props.title}</Button>
|
<Button variant="contained" color="primary" disabled={props.activeTitle === props.title || props.viewTournament} sx={{fontSize:['0.7em','0.75em']}} >{props.title}</Button>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -39,9 +48,9 @@ function ButtonLink(props) {
|
|||||||
export default function TournamentBar(props) {
|
export default function TournamentBar(props) {
|
||||||
const { tournamentId } = useParams();
|
const { tournamentId } = useParams();
|
||||||
return (
|
return (
|
||||||
<Paper sx={{width: ["90vw",], margin: "1.5% auto"}} component={Stack} direction="column" justifyContent="center" alignItems="center">
|
<Paper sx={{width: ["90vw",], fontSize:['1rem','1rem','1.5rem','2rem'], margin: "1.5% auto"}} component={Stack} direction="column" justifyContent="center" alignItems="center">
|
||||||
<Stack direction="row" paddingTop={'0.5%'}>
|
<Stack direction="row" paddingTop={'0.5%'} sx={{fontSize:['1rem','1rem','1.5rem','2rem'], margin:'1.5%'}} spacing={2}>
|
||||||
<ButtonLink targetPath="" tournamentId={tournamentId} activeTitle={props.pageTitle} title="View Tournament" viewTournament={props.viewTournament} sx={{}}/>
|
<ButtonLink targetPath="" tournamentId={tournamentId} activeTitle={props.pageTitle} title="View Tournament" viewTournament={props.viewTournament}/>
|
||||||
<ButtonLink targetPath="/manage" tournamentId={tournamentId} activeTitle={props.pageTitle} title="Edit Tournament" />
|
<ButtonLink targetPath="/manage" tournamentId={tournamentId} activeTitle={props.pageTitle} title="Edit Tournament" />
|
||||||
<ButtonLink targetPath="/teams" tournamentId={tournamentId} activeTitle={props.pageTitle} title="Manage Teams" />
|
<ButtonLink targetPath="/teams" tournamentId={tournamentId} activeTitle={props.pageTitle} title="Manage Teams" />
|
||||||
</Stack>
|
</Stack>
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
flex-direction:row;
|
flex-direction:row;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.round{
|
.round{
|
||||||
display:flex;
|
display:flex;
|
||||||
flex-direction:column;
|
flex-direction:column;
|
||||||
justify-content:center;
|
justify-content:center;
|
||||||
@ -14,13 +14,13 @@
|
|||||||
list-style:none;
|
list-style:none;
|
||||||
padding:0;
|
padding:0;
|
||||||
/* font-size: 1.5rem; */
|
/* font-size: 1.5rem; */
|
||||||
}
|
}
|
||||||
.round .spacer{ flex-grow:1;}
|
.round .spacer{ flex-grow:1;}
|
||||||
.round .spacer:first-child,
|
.round .spacer:first-child,
|
||||||
.round .spacer:last-child{ flex-grow:.5; }
|
.round .spacer:last-child{ flex-grow:.5; }
|
||||||
.round .game-spacer{
|
.round .game-spacer{
|
||||||
flex-grow:1;
|
flex-grow:1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* General Styles
|
* General Styles
|
||||||
@ -32,26 +32,44 @@
|
|||||||
line-height:1.4em;
|
line-height:1.4em;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
li.game{
|
li.game{
|
||||||
padding-left:20px;
|
padding-left:20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.winner{
|
.winner{
|
||||||
color:green;
|
color:green;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.loser{
|
.loser{
|
||||||
color:grey;
|
color:grey;
|
||||||
}
|
}
|
||||||
|
|
||||||
li.game-top{ border-bottom:1px solid #aaa; }
|
li.game-top{ border-bottom:1px solid #aaa; }
|
||||||
|
|
||||||
li.game-spacer{
|
li.game-spacer{
|
||||||
border-right:1px solid #aaa;
|
border-right:1px solid #aaa;
|
||||||
min-height:10vh;
|
min-height:10vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
li.game-bottom{
|
li.game-bottom{
|
||||||
border-top:1px solid #aaa;
|
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 > p.winner {
|
||||||
|
color:green;
|
||||||
|
}
|
||||||
|
.winnerDisplay > div.winner {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
@ -24,8 +24,6 @@ code {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.mainIcon{
|
.mainIcon{
|
||||||
height: 65px;
|
|
||||||
width: 65px;
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
/* border: 5px dotted salmon; */
|
/* border: 5px dotted salmon; */
|
||||||
border: 3px solid #1ab35a;
|
border: 3px solid #1ab35a;
|
||||||
|
Loading…
Reference in New Issue
Block a user