Merge branch 'client' into 'client-kristofferTournament'
# Conflicts: # src/client/src/TournamentCreator.js # src/client/src/TournamentOverview.js
This commit is contained in:
commit
7865e97c28
|
@ -1,2 +1,3 @@
|
|||
REACT_APP_API_URL=https://asura.feal.no/api
|
||||
REACT_APP_LOGIN_URL=http://localhost:3001/auth/google
|
||||
BROWSER=none
|
||||
|
|
|
@ -4869,6 +4869,7 @@
|
|||
"dependencies": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
"fsevents": "~2.3.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
|
@ -6116,7 +6117,8 @@
|
|||
"esprima": "^4.0.1",
|
||||
"estraverse": "^5.2.0",
|
||||
"esutils": "^2.0.2",
|
||||
"optionator": "^0.8.1"
|
||||
"optionator": "^0.8.1",
|
||||
"source-map": "~0.6.1"
|
||||
},
|
||||
"bin": {
|
||||
"escodegen": "bin/escodegen.js",
|
||||
|
@ -8724,6 +8726,7 @@
|
|||
"@types/node": "*",
|
||||
"anymatch": "^3.0.3",
|
||||
"fb-watchman": "^2.0.0",
|
||||
"fsevents": "^2.3.2",
|
||||
"graceful-fs": "^4.2.9",
|
||||
"jest-regex-util": "^27.5.1",
|
||||
"jest-serializer": "^27.5.1",
|
||||
|
@ -10029,9 +10032,14 @@
|
|||
"integrity": "sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA==",
|
||||
"dependencies": {
|
||||
"copy-anything": "^2.0.1",
|
||||
"errno": "^0.1.1",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"image-size": "~0.5.0",
|
||||
"make-dir": "^2.1.0",
|
||||
"mime": "^1.4.1",
|
||||
"needle": "^2.5.2",
|
||||
"parse-node-version": "^1.0.1",
|
||||
"source-map": "~0.6.0",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
"bin": {
|
||||
|
@ -12407,6 +12415,7 @@
|
|||
"eslint-webpack-plugin": "^3.1.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"fsevents": "^2.3.2",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"jest": "^27.4.3",
|
||||
|
@ -12826,6 +12835,9 @@
|
|||
"version": "2.70.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.70.1.tgz",
|
||||
"integrity": "sha512-CRYsI5EuzLbXdxC6RnYhOuRdtz4bhejPMSWjsFLfVM/7w/85n2szZv6yExqUXsBdz5KT8eoubeyDUDjhLHEslA==",
|
||||
"dependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
},
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 7.8 KiB |
|
@ -0,0 +1,134 @@
|
|||
import * as React from "react";
|
||||
import { BrowserRouter as Router, Link, Route, Routes, useParams } from "react-router-dom";
|
||||
import Appbar from "./components/AsuraBar";
|
||||
import ErrorSnackbar from "./components/ErrorSnackbar";
|
||||
|
||||
import {Button, Box, TextField, Stack, InputLabel, Paper, TableContainer, Table, TableBody, TableHead, TableCell, TableRow, Typography} from '@mui/material';
|
||||
import AddCircleIcon from '@mui/icons-material/AddCircle';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import EditIcon from '@mui/icons-material/Edit';
|
||||
|
||||
function showError(error) {
|
||||
alert("Something went wrong. \n" + error);
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
function AdminCreator(props){
|
||||
function postCreate(){
|
||||
let adminEmail = document.getElementById("adminEmailInput").value;
|
||||
if (!adminEmail) {
|
||||
showError("Admin email is required");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let formData = new FormData();
|
||||
formData.append("email", adminEmail)
|
||||
let body = new URLSearchParams(formData)
|
||||
|
||||
fetch(process.env.REACT_APP_API_URL + `/admins/create`, {
|
||||
method: "POST",
|
||||
body: body
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.status !== "OK") {
|
||||
showError(data.data);
|
||||
return;
|
||||
}
|
||||
document.getElementById("adminEmailInput").value = "";
|
||||
props.onAdminCreated();
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Paper sx={{width: "90vw", margin: "10px auto", padding: "15px"}} component={Stack} direction="column">
|
||||
<div align="center">
|
||||
<TextField id="adminEmailInput" sx={{ width: "70%" }} label="Admin Email" variant="outlined" />
|
||||
{/* <Button variant="contained" color="primary" onClick={postCreate}>Create Team</Button> */}
|
||||
<Button variant="contained" color="success" onClick={postCreate} sx={{width: "20%", marginLeft: "5px"}}>
|
||||
<Box sx={{padding: "10px"}}>
|
||||
Create Admin
|
||||
</Box>
|
||||
<AddCircleIcon />
|
||||
</Button>
|
||||
</div>
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
||||
function AdminList(props){
|
||||
const deleteAdmin = adminId => {
|
||||
fetch(process.env.REACT_APP_API_URL + `/admins/${adminId}`, {method: "DELETE"})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if(data.status !== "OK"){
|
||||
showError(data.data);
|
||||
return;
|
||||
}
|
||||
props.setAdmins(props.admins.filter(admin => admin.id !== adminId));
|
||||
})
|
||||
.catch(error => showError(error));
|
||||
}
|
||||
|
||||
return(
|
||||
<Paper sx={{minHeight: "30vh", width:"90vw", margin:"10px auto"}} component={Stack} direction="column" justifycontent="center">
|
||||
<div align="center">
|
||||
{/* TODO: scroll denne menyen, eventuelt søkefelt */}
|
||||
<Table aria-label="simple table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Admin</TableCell>
|
||||
<TableCell align="center">Actions</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{props.admins.map((admin) => (
|
||||
<TableRow key={admin.id}>
|
||||
<TableCell component="th" scope="row"> <b>
|
||||
{admin.name}
|
||||
</b></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={() => {deleteAdmin(admin.id)}} endIcon={<DeleteIcon />}>Delete</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
||||
export default function Admins(props) {
|
||||
const [admins, setAdmins] = React.useState([]);
|
||||
const { adminId } = useParams();
|
||||
|
||||
function getAdmins() {
|
||||
fetch(process.env.REACT_APP_API_URL + `/admins/getAdmins`)
|
||||
.then((res) => res.json())
|
||||
.then((data) =>{
|
||||
if(data.status !== "OK") {
|
||||
showError(data.data);
|
||||
}
|
||||
setAdmins(data.data);
|
||||
})
|
||||
.catch((err) => showError(err));
|
||||
}
|
||||
React.useEffect(() => {
|
||||
getAdmins()
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Appbar pageTitle="Admins" />
|
||||
<div className="admins">
|
||||
<AdminCreator />
|
||||
<AdminList />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -3,9 +3,9 @@ import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
|
|||
import TournamentCreator from "./TournamentCreator.js";
|
||||
import TournamentOverview from "./TournamentOverview.js";
|
||||
import TournamentManager from "./TournamentManager.js";
|
||||
import TournamentAnnouncement from "./TournamentAnnouncement";
|
||||
import TournamentHistory from "./TournamentHistory";
|
||||
import TournamentTeams from "./TournamentTeams";
|
||||
import LoginPage from "./LoginPage";
|
||||
import AppBar from './components/AsuraBar';
|
||||
import { Button, Container, Typography, Box, Stack, Card, CardContent, CardMedia, Paper, Grid, Icon } from "@mui/material";
|
||||
import AddCircleIcon from '@mui/icons-material/AddCircle';
|
||||
|
@ -56,6 +56,34 @@ function TournamentListItem(props) {
|
|||
</Box>;
|
||||
}
|
||||
}
|
||||
|
||||
function Countdown() {
|
||||
const [remainingTime, setremainingTime] = React.useState(Math.abs(props.tournament.startTime - new Date()))
|
||||
React.useEffect(() => {
|
||||
const interval = setInterval(() =>
|
||||
setremainingTime(Math.abs(props.tournament.startTime - new Date()))
|
||||
, 1000);
|
||||
return () => {
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, []);
|
||||
|
||||
let remainingDays = Math.floor(remainingTime / (1000 * 60 * 60 * 24));
|
||||
let remainingHours = Math.floor(remainingTime / (1000 * 60 * 60)) - remainingDays * 24
|
||||
let remainingMins = Math.floor(remainingTime / (1000 * 60)) - (remainingDays * 24 * 60 + remainingHours * 60)
|
||||
let remainingSecs = Math.floor(remainingTime / 1000) - (remainingDays * 24 * 60 * 60 + remainingHours * 60 * 60 + remainingMins * 60)
|
||||
if (props.tournament.startTime < new Date()) {
|
||||
return (<Box>
|
||||
<Typography variant="body"> Started! </Typography>
|
||||
</Box>)
|
||||
} else {
|
||||
return(<Box>
|
||||
<Typography variant="body"> Starts in: {remainingDays} Days, {remainingHours} Hours, {remainingMins} Minutes and {remainingSecs} Seconds </Typography>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<Paper elevation={8} >
|
||||
<Card>
|
||||
|
@ -73,7 +101,7 @@ function TournamentListItem(props) {
|
|||
<Typography variant="body"> End: {props.tournament.endTime.toLocaleString()} </Typography>
|
||||
</Box>
|
||||
|
||||
<Typography variant="h5" color="text.primary" gutterBottom> Players {props.tournament.teamCount} / {props.tournament.teamLimit} </Typography>
|
||||
<Typography variant="h5" color="text.primary" gutterBottom> Players: {props.tournament.teamCount} / {props.tournament.teamLimit} </Typography>
|
||||
<Description />
|
||||
|
||||
<Box sx={{flexGrow: 1, marginTop: "20px"}}>
|
||||
|
@ -92,6 +120,8 @@ function TournamentListItem(props) {
|
|||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
|
||||
<Countdown />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Paper>
|
||||
|
@ -144,6 +174,9 @@ function Home() {
|
|||
<CreateButton />
|
||||
</Box>
|
||||
<TournamentList />
|
||||
<Typography variant="h5" color="#555555">
|
||||
Finished tournaments are moved to the <Link to="/history">history-page</Link>
|
||||
</Typography>
|
||||
</Container>
|
||||
</>
|
||||
);
|
||||
|
@ -160,10 +193,7 @@ export default function App() {
|
|||
<Route path="/tournament/:tournamentId/manage" element={<TournamentManager />} />
|
||||
<Route path="/tournament/:tournamentId/teams" element={<TournamentTeams />} />
|
||||
<Route path="/history" element={<TournamentHistory />} />
|
||||
<Route
|
||||
path="/tournament/manage/announcement"
|
||||
element={<TournamentAnnouncement />}
|
||||
/>
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
</Routes>
|
||||
</Router>
|
||||
</React.StrictMode>
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import * as React from "react";
|
||||
import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
|
||||
import AppBar from "./components/AsuraBar";
|
||||
import ErrorSnackbar from "./components/ErrorSnackbar";
|
||||
|
||||
import {Button, Textfield, Stack, InputLabel, Paper, Typography} from '@mui/material';
|
||||
|
||||
|
||||
export default function LoginPage() {
|
||||
return (
|
||||
<>
|
||||
<AppBar pageTitle="Sign in" />
|
||||
<h2>Sign in with google</h2>
|
||||
<a href={process.env.REACT_APP_LOGIN_URL}>
|
||||
<img src="/btn_google_signing_dark.png" alt="Sign in with google" />
|
||||
</a>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
import * as React from "react";
|
||||
import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
|
||||
import Appbar from './components/AsuraBar';
|
||||
|
||||
function Announcement() {
|
||||
return (
|
||||
<form>
|
||||
<label for="recipients">Recipients:</label>
|
||||
<select id="recipients">
|
||||
<option value="all">All</option>
|
||||
<option value="mail1@gmail.com">Person 1</option>
|
||||
<option value="mail2@gmail.com">Person 2</option>
|
||||
<option value="mail3@gmail.com">Person 3</option>
|
||||
</select>
|
||||
<br />
|
||||
<label for="subject">Subject:</label>
|
||||
<input type="text" id="subject"></input>
|
||||
<br />
|
||||
<input type="text" id="contents"></input>
|
||||
<Link to="/tournament/manage">
|
||||
<input type="submit"></input>
|
||||
</Link>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
export default function TournamentAnnouncement() {
|
||||
return (
|
||||
<>
|
||||
<Appbar />
|
||||
<Announcement />
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -7,6 +7,7 @@ import { Button, TextField, Stack, InputLabel, Select, Container, Slider, Paper,
|
|||
import DateTimePicker from '@mui/lab/DateTimePicker';
|
||||
import AdapterDateFns from '@mui/lab/AdapterDateFns';
|
||||
import LocalizationProvider from '@mui/lab/LocalizationProvider';
|
||||
import { setDate } from "date-fns";
|
||||
|
||||
function postTournament(showError, tournamentName, tournamentDescription, tournamentStartDate, tournamentEndDate, tournamentMaxTeams) {
|
||||
if (!tournamentName || tournamentName === "") {
|
||||
|
@ -81,8 +82,8 @@ function TournamentForm(props) {
|
|||
function submitTournament(event) {
|
||||
event.preventDefault();
|
||||
let maxTeams = Math.pow(2, maxTeamsExponent);
|
||||
let tournamentStart = new Date(startTime).valueOf() - new Date().getTimezoneOffset() * 60000;
|
||||
let tournamentEnd = new Date(endTime).valueOf() - new Date().getTimezoneOffset() * 60000;
|
||||
let tournamentStart = new Date(startTime.setSeconds(0, 0, 0)).valueOf() - new Date().getTimezoneOffset() * 60*1000;
|
||||
let tournamentEnd = new Date(endTime.setSeconds(0, 0, 0)).valueOf() - new Date().getTimezoneOffset() * 60*1000;
|
||||
postTournament(
|
||||
props.showError,
|
||||
document.getElementById("nameInput").value,
|
||||
|
|
|
@ -51,7 +51,7 @@ function shorten(description, maxLength) {
|
|||
<Typography variant="body"> End: {props.tournament.endTime.toLocaleString()} </Typography>
|
||||
</Box>
|
||||
|
||||
<Typography variant="h5" color="text.primary" gutterBottom> Players {props.tournament.teamCount} / {props.tournament.teamLimit} </Typography>
|
||||
<Typography variant="h5" color="text.primary" gutterBottom> Players: {props.tournament.teamCount} / {props.tournament.teamLimit} </Typography>
|
||||
<Description />
|
||||
|
||||
<Box sx={{flexGrow: 1, marginTop: "20px"}}>
|
||||
|
|
|
@ -5,7 +5,7 @@ import Appbar from './components/Appbar';
|
|||
function MatchHistory() {
|
||||
|
||||
return(
|
||||
`Hei`
|
||||
`Hei på deg din gamle sei`
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -178,7 +178,39 @@ function BracketViewer(props){
|
|||
})}
|
||||
</div>
|
||||
: <Box sx={{display:'flex', justifyContent:'center', alignItems:'center', position:'relative', marginTop:'5%'}}><CircularProgress size={"20vw"}/></Box>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
function RemovableBar(props) {
|
||||
const [endTime, setendTime] = React.useState(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
fetch(process.env.REACT_APP_API_URL + `/tournament/${props.tournamentId}`)
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.status !== "OK") {
|
||||
// Do your error thing
|
||||
console.error(data);
|
||||
return;
|
||||
}
|
||||
let endTime = data.data.endTime;
|
||||
setendTime(endTime);
|
||||
})
|
||||
.catch(err => showError(err));
|
||||
})
|
||||
let today = new Date()
|
||||
let yesterday = today.setDate(today.getDate() - 1)
|
||||
let isComplete = new Date(endTime) < yesterday
|
||||
if (isComplete) {
|
||||
return (null)
|
||||
} else {
|
||||
return (<TournamentBar pageTitle="View Tournament" />)
|
||||
}
|
||||
}
|
||||
|
||||
function showError(error) {
|
||||
alert("Something went wrong. \n" + error);
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
export default function TournamentOverview(props) {
|
||||
|
@ -187,7 +219,7 @@ export default function TournamentOverview(props) {
|
|||
return (
|
||||
<>
|
||||
<Appbar pageTitle="View Tournament" />
|
||||
<TournamentBar pageTitle="View Tournament" />
|
||||
<RemovableBar tournamentId={tournamentId} />
|
||||
<BracketViewer tournamentId={tournamentId} className="bracketViewer" />
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -43,15 +43,18 @@ function TeamCreator(props) {
|
|||
return (
|
||||
<Paper sx={{width: "90vw", margin: "10px auto", padding: "15px"}} component={Stack} direction="column">
|
||||
<div align="center">
|
||||
<form>
|
||||
<TextField id="teamNameInput" sx={{ width: "70%" }} label="Team Name" variant="outlined" />
|
||||
{/* <Button variant="contained" color="primary" onClick={postCreate}>Create Team</Button> */}
|
||||
<Button variant="contained" color="success" onClick={postCreate} sx={{width: "20%", marginLeft: "5px"}}>
|
||||
<Button type="submit" variant="contained" color="success" onClick={postCreate} sx={{width: "20%", marginLeft: "5px"}}>
|
||||
<Box sx={{padding: "10px"}}>
|
||||
Create Team
|
||||
</Box>
|
||||
<AddCircleIcon />
|
||||
</Button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</Paper>
|
||||
)
|
||||
}
|
||||
|
@ -92,7 +95,7 @@ function TeamList(props) {
|
|||
</b></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="primary" onClick={() => {props.setSelectedTeamId(team.id); window.scrollTo(0, document.body.scrollHeight)}} endIcon={<EditIcon />}>Edit</Button>
|
||||
<Button variant="contained" sx={{margin: "auto 5px"}} color="error" onClick={() => {deleteTeam(team.id)}} endIcon={<DeleteIcon />}>Delete</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
|
@ -146,6 +149,10 @@ function TeamEditor(props) {
|
|||
setTeam(newTeam);
|
||||
}
|
||||
|
||||
function handleFocus(event) {
|
||||
event.currentTarget.select()
|
||||
}
|
||||
|
||||
function saveTeam() {
|
||||
let formData = new FormData();
|
||||
formData.append("name", team.name);
|
||||
|
@ -172,9 +179,9 @@ function TeamEditor(props) {
|
|||
<div align="center">
|
||||
<h2><b>Edit Team:</b></h2>
|
||||
<form>
|
||||
<TextField id="teamNameInput" label="Team Name" value={team.name || ""} onChange={nameInputChanged} sx={{width: "80%"}} />
|
||||
<TextField id="newTeamNameInput" label="Team Name" value={team.name || ""} onChange={nameInputChanged} onFocus={handleFocus} sx={{width: "80%"}} />
|
||||
{/* <PlayerList players={players} setPlayers={setPlayers} /> */}
|
||||
<Button variant="contained" sx={{margin: "auto 5px"}} color="primary" onClick={saveTeam}>Save</Button>
|
||||
<Button type="submit" variant="contained" sx={{margin: "auto 5px"}} color="primary" onClick={saveTeam}>Save</Button>
|
||||
</form>
|
||||
</div>
|
||||
</Paper>
|
||||
|
|
|
@ -1,7 +1,32 @@
|
|||
import * as React from "react";
|
||||
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 } from "@mui/material"
|
||||
import { Stack, Paper, Typography, Box, Button, Grid, Snackbar, IconButton } from "@mui/material"
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
|
||||
function ClipboardButton(props) {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
function copyString() {
|
||||
navigator.clipboard.writeText(props.clipboardContent || "");
|
||||
setOpen(true);
|
||||
}
|
||||
const handleClose = (event, reason) => {
|
||||
if (reason === 'clickaway') { return }
|
||||
setOpen(false);
|
||||
};
|
||||
const closeAction = <>
|
||||
<IconButton size="small" aria-label="close" color="inherit" onClick={handleClose}>
|
||||
<CloseIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</>
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button onClick={copyString} variant="outlined" color="primary" sx={{margin: "auto 5px"}} >Copy {props.name}</Button>
|
||||
<Snackbar open={open} autoHideDuration={1500} onClose={handleClose} message={props.name + " copied to clipboard"} action={closeAction} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
function ButtonLink(props) {
|
||||
return (
|
||||
|
@ -14,10 +39,17 @@ function ButtonLink(props) {
|
|||
export default function TournamentBar(props) {
|
||||
const { tournamentId } = useParams();
|
||||
return (
|
||||
<Paper sx={{width: "90vw", margin: "10px auto"}} component={Stack} direction="row" justifyContent="center">
|
||||
<Paper sx={{width: "90vw", margin: "1.5% auto"}} component={Stack} direction="column" justifyContent="center" alignItems="center">
|
||||
<Stack direction="row" paddingTop={'0.5%'}>
|
||||
<ButtonLink targetPath="" tournamentId={tournamentId} activeTitle={props.pageTitle} title="View Tournament" />
|
||||
<ButtonLink targetPath="/manage" tournamentId={tournamentId} activeTitle={props.pageTitle} title="Edit Tournament" />
|
||||
<ButtonLink targetPath="/teams" tournamentId={tournamentId} activeTitle={props.pageTitle} title="Manage Teams" />
|
||||
</Stack>
|
||||
<Stack direction="row" paddingBottom={'0.5%'}>
|
||||
<ClipboardButton clipboardContent={"https://discord.gg/asura"} name="Discord Invite Link" />
|
||||
<ClipboardButton clipboardContent={"https://asura.feal.no/tournament/" + tournamentId} name="Tournament Link" />
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue