From 9cb0b1b55b4c1a3ffb95fea900a417dfb9847590 Mon Sep 17 00:00:00 2001 From: Kristoffer Juelsen Date: Wed, 13 Apr 2022 11:11:13 +0200 Subject: [PATCH 01/11] limited max team limit --- src/client/src/TournamentCreator.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/client/src/TournamentCreator.js b/src/client/src/TournamentCreator.js index ae32d9a..b2b1cd2 100644 --- a/src/client/src/TournamentCreator.js +++ b/src/client/src/TournamentCreator.js @@ -100,8 +100,7 @@ function TournamentForm(props) { { value: 3, label: "8",}, { value: 4, label: "16",}, { value: 5, label: "32",}, - { value: 6, label: "64",}, - { value: 7, label: "128",} + { value: 6, label: "64",} ]; return ( @@ -147,7 +146,7 @@ function TournamentForm(props) { - + From 93b5946ffec0efbe6550330acb8a342608434423 Mon Sep 17 00:00:00 2001 From: Felix Albrigtsen Date: Wed, 20 Apr 2022 14:34:28 +0200 Subject: [PATCH 02/11] Timezone compensation --- src/client/src/TournamentCreator.js | 24 +++------ src/client/src/TournamentManager.js | 61 ++++++---------------- src/client/src/components/TournamentBar.js | 36 ++++++++++++- 3 files changed, 58 insertions(+), 63 deletions(-) diff --git a/src/client/src/TournamentCreator.js b/src/client/src/TournamentCreator.js index b2b1cd2..00a6a8b 100644 --- a/src/client/src/TournamentCreator.js +++ b/src/client/src/TournamentCreator.js @@ -17,11 +17,11 @@ function postTournament(showError, tournamentName, tournamentDescription, tourna showError("Tournament description cannot be empty"); return; } - if (!tournamentStartDate || tournamentStartDate === "") { + if (!tournamentStartDate || tournamentStartDate === "" || tournamentStartDate === 0) { showError("Tournament start date cannot be empty"); return; } - if (!tournamentEndDate || tournamentEndDate === "") { + if (!tournamentEndDate || tournamentEndDate === "" || tournamentEndDate === 0) { showError("Tournament end date cannot be empty"); return; } @@ -75,15 +75,14 @@ function TournamentForm(props) { setMaxTeamsExponent(event.target.value); } - const [startTime, setStartTime] = React.useState([new Date(), new Date()]); - const [endTime, setEndTime] = React.useState([new Date(), new Date()]); + const [startTime, setStartTime] = React.useState(new Date()); + const [endTime, setEndTime] = React.useState(new Date()); function submitTournament(event) { event.preventDefault(); - console.log(maxTeamsExponent) let maxTeams = Math.pow(2, maxTeamsExponent); - let tournamentStart = new Date(startTime).toUTCString(); - let tournamentEnd = new Date(endTime).toUTCString(); + let tournamentStart = new Date(startTime).valueOf() - new Date().getTimezoneOffset() * 60000; + let tournamentEnd = new Date(endTime).valueOf() - new Date().getTimezoneOffset() * 60000; postTournament( props.showError, document.getElementById("nameInput").value, @@ -92,7 +91,6 @@ function TournamentForm(props) { tournamentEnd, maxTeams ); - console.log(tournamentStart, tournamentEnd); } const marks = [ @@ -116,10 +114,7 @@ function TournamentForm(props) { { - setStartTime(newValue); - // console.log(new Date(newValue).toUTCString()); - }} + onChange={setStartTime} renderInput={(params) => } /> @@ -128,10 +123,7 @@ function TournamentForm(props) { { - setEndTime(newValue); - // console.log(new Date(newValue).toUTCString()); - }} + onChange={setEndTime} renderInput={(params) => } /> diff --git a/src/client/src/TournamentManager.js b/src/client/src/TournamentManager.js index 1196c06..0420b0f 100644 --- a/src/client/src/TournamentManager.js +++ b/src/client/src/TournamentManager.js @@ -49,14 +49,13 @@ let submitChanges = curryTournamentId => event => { return; } - tournamentStartDate = new Date(tournamentStartDate).toUTCString(); - tournamentEndDate = new Date(tournamentEndDate).toUTCString(); + tournamentStartDate = new Date(tournamentStartDate).valueOf() - new Date().getTimezoneOffset() * 60 * 1000; + tournamentEndDate = new Date(tournamentEndDate).valueOf() - new Date().getTimezoneOffset() * 60 * 1000; let formData = new FormData(); formData.append("name", tournamentName); formData.append("description", tournamentDescription); - // formData.append("image", tournamentImageFile); formData.append("startDate", tournamentStartDate); formData.append("endDate", tournamentEndDate); // formData.append("teamLimit", tournamentMaxTeams); @@ -104,8 +103,8 @@ let deleteTournament = tournamentId => event => { function ManageTournament(props) { - const [startTime, setStartTime] = React.useState([new Date(),null]); - const [endTime, setEndTime] = React.useState([new Date(),null]); + const [startTime, setStartTime] = React.useState(new Date()); + const [endTime, setEndTime] = React.useState(new Date()); React.useEffect(() => { fetch( @@ -119,11 +118,18 @@ function ManageTournament(props) { document.getElementById("editName").value = data.data.name; document.getElementById("editDesc").value = data.data.description; - setStartTime(data.data.startTime.slice(0, 16)); - setEndTime(data.data.endTime.slice(0, 16)); + // Get the time from the server, add the local timezone offset and set the input fields + let startDate = new Date(data.data.startTime.slice(0, 16)); + let endDate = new Date(data.data.endTime.slice(0, 16)); + let localTimeOffset = new Date().getTimezoneOffset() * 60*1000; // Minutes -> Milliseconds + startDate = new Date(startDate.getTime() - localTimeOffset); + endDate = new Date(endDate.getTime() - localTimeOffset); + + setStartTime(startDate); + setEndTime(endDate); }) .catch((err) => showError(err)); - }, [endTime, props.tournamentId, startTime]); + }, [props.tournamentId]); return ( <> @@ -136,10 +142,7 @@ function ManageTournament(props) { { - setStartTime(newValue); - console.log(new Date(newValue).toUTCString()); - }} + onChange={setStartTime} renderInput={(params) => } /> @@ -147,19 +150,13 @@ function ManageTournament(props) { { - setEndTime(newValue); - console.log(new Date(newValue).toUTCString()); - }} + onChange={setEndTime} renderInput={(params) => } /> - {/* - */} - @@ -175,30 +172,6 @@ function showError(error) { console.error(error); } -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 = <> - - - - - - return ( - <> - - - - ); -} - export default function TournamentManager(props) { const { tournamentId } = useParams(); @@ -221,8 +194,6 @@ export default function TournamentManager(props) { - - diff --git a/src/client/src/components/TournamentBar.js b/src/client/src/components/TournamentBar.js index 153eb2c..b196488 100644 --- a/src/client/src/components/TournamentBar.js +++ b/src/client/src/components/TournamentBar.js @@ -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 = <> + + + + + + return ( + <> + + + + ); +} function ButtonLink(props) { return ( @@ -14,10 +39,17 @@ function ButtonLink(props) { export default function TournamentBar(props) { const { tournamentId } = useParams(); return ( - + + + + + + + + ) } \ No newline at end of file From 2475495206cb4ddebe667a02085d38030e4a8a54 Mon Sep 17 00:00:00 2001 From: Felix Albrigtsen Date: Wed, 20 Apr 2022 14:37:04 +0200 Subject: [PATCH 03/11] Update dependency --- src/client/package-lock.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/client/package-lock.json b/src/client/package-lock.json index dd036ab..bf11bdc 100644 --- a/src/client/package-lock.json +++ b/src/client/package-lock.json @@ -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" }, From 4bae1b3e20316886c875f0ba17a9d7ac48368585 Mon Sep 17 00:00:00 2001 From: Felix Albrigtsen Date: Wed, 20 Apr 2022 15:19:54 +0200 Subject: [PATCH 04/11] Minor cleanup --- src/client/src/FrontPage.js | 8 +++--- src/client/src/TournamentAnnouncement.js | 34 ------------------------ 2 files changed, 3 insertions(+), 39 deletions(-) delete mode 100644 src/client/src/TournamentAnnouncement.js diff --git a/src/client/src/FrontPage.js b/src/client/src/FrontPage.js index ebe1da4..25bbe9e 100644 --- a/src/client/src/FrontPage.js +++ b/src/client/src/FrontPage.js @@ -3,7 +3,6 @@ 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 AppBar from './components/AsuraBar'; @@ -144,6 +143,9 @@ function Home() { + + Finished tournaments are moved to the history-page + ); @@ -160,10 +162,6 @@ export default function App() { } /> } /> } /> - } - /> diff --git a/src/client/src/TournamentAnnouncement.js b/src/client/src/TournamentAnnouncement.js deleted file mode 100644 index af10100..0000000 --- a/src/client/src/TournamentAnnouncement.js +++ /dev/null @@ -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 ( -
- - -
- - -
- - - - -
- ); -} - -export default function TournamentAnnouncement() { - return ( - <> - - - - ); -} From 72628e06a64fce90e649ef9b00c7633e844658a7 Mon Sep 17 00:00:00 2001 From: Kristoffer Juelsen Date: Wed, 20 Apr 2022 15:40:39 +0200 Subject: [PATCH 05/11] Added some pages --- src/client/src/AdminsOverview.js | 62 +++++++++++++++++++++++++++++ src/client/src/LoginPage.js | 8 ++++ src/client/src/TournamentManager.js | 2 +- 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 src/client/src/AdminsOverview.js create mode 100644 src/client/src/LoginPage.js diff --git a/src/client/src/AdminsOverview.js b/src/client/src/AdminsOverview.js new file mode 100644 index 0000000..5484b19 --- /dev/null +++ b/src/client/src/AdminsOverview.js @@ -0,0 +1,62 @@ +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'; +import DeleteIcon from '@mui/icons/Delete'; + +function showError(error) { + alert("Something went wrong. \n" + error); + console.error(error); +} + +function AdminCreator(props){ + function postCreate(){ + let adminEmail = document.getElementById("adminEmailInput").value; + if (!adminName) { + showError("Admin email is required"); + return; + } + + + let formData = new FormData(); + formData.append("name", teamName) + 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 ( + +
+ + {/* */} + +
+
+ ) +} + +function AdminList(props){ + const deleteAdmin = adminId => { + fetch(process.env.REACT_APP_API_URL) +} \ No newline at end of file diff --git a/src/client/src/LoginPage.js b/src/client/src/LoginPage.js new file mode 100644 index 0000000..09205fe --- /dev/null +++ b/src/client/src/LoginPage.js @@ -0,0 +1,8 @@ +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'; + + diff --git a/src/client/src/TournamentManager.js b/src/client/src/TournamentManager.js index 0420b0f..87db5eb 100644 --- a/src/client/src/TournamentManager.js +++ b/src/client/src/TournamentManager.js @@ -5,7 +5,7 @@ import AppBar from "./components/AsuraBar"; import TournamentBar from "./components/TournamentBar"; import { useParams } from "react-router-dom"; import { Button, TextField, Grid, Box, Container, Paper, Stack } from "@mui/material"; -import { Snackbar, IconButton, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"; +import { Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle } from "@mui/material"; import CloseIcon from '@mui/icons-material/Close'; import DeleteIcon from '@mui/icons-material/Delete'; import DateTimePicker from '@mui/lab/DateTimePicker'; From 21e16b09dc85296db60d1facf03fbeecc5f54f04 Mon Sep 17 00:00:00 2001 From: Felix Albrigtsen Date: Wed, 20 Apr 2022 16:00:23 +0200 Subject: [PATCH 06/11] Dev session: login + design --- src/client/.env | 3 +- src/client/public/btn_google_signing_dark.png | Bin 0 -> 8001 bytes src/client/src/AdminsOverview.js | 86 ++++++++++++++++-- src/client/src/FrontPage.js | 2 + src/client/src/LoginPage.js | 11 +++ src/client/src/TournamentMatches.js | 2 +- 6 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 src/client/public/btn_google_signing_dark.png diff --git a/src/client/.env b/src/client/.env index 02a4337..b046e98 100644 --- a/src/client/.env +++ b/src/client/.env @@ -1,2 +1,3 @@ -REACT_APP_API_URL=https://asura.feal.no/api +REACT_APP_API_URL=http://10.24.1.22:3001/api +REACT_APP_LOGIN_URL=http://localhost:3001/auth/google BROWSER=none diff --git a/src/client/public/btn_google_signing_dark.png b/src/client/public/btn_google_signing_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f27bb2433042aea5fc34e19fcf90944430ec331b GIT binary patch literal 8001 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 Jvd$@?2>`##Tzmik literal 0 HcmV?d00001 diff --git a/src/client/src/AdminsOverview.js b/src/client/src/AdminsOverview.js index 5484b19..f04db42 100644 --- a/src/client/src/AdminsOverview.js +++ b/src/client/src/AdminsOverview.js @@ -1,10 +1,12 @@ import * as React from "react"; -import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom"; -import AppBar from "./components/AsuraBar"; +import { BrowserRouter as Router, Link, Route, Routes, useParams } from "react-router-dom"; +import Appbar from "./components/AsuraBar"; import ErrorSnackbar from "./components/ErrorSnackbar"; -import {Button, Textfield, Stack, InputLabel, Paper, Typography} from '@mui/material'; -import DeleteIcon from '@mui/icons/Delete'; +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); @@ -14,14 +16,14 @@ function showError(error) { function AdminCreator(props){ function postCreate(){ let adminEmail = document.getElementById("adminEmailInput").value; - if (!adminName) { + if (!adminEmail) { showError("Admin email is required"); return; } let formData = new FormData(); - formData.append("name", teamName) + formData.append("email", adminEmail) let body = new URLSearchParams(formData) fetch(process.env.REACT_APP_API_URL + `/admins/create`, { @@ -58,5 +60,75 @@ function AdminCreator(props){ function AdminList(props){ const deleteAdmin = adminId => { - fetch(process.env.REACT_APP_API_URL) + 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( + +
+ {/* TODO: scroll denne menyen, eventuelt søkefelt */} + + + + Admin + Actions + + + + {props.admins.map((admin) => ( + + + {admin.name} + + {/* {team.members} */} + + {/* */} + + + + ))} + +
+
+
+ ) +} + +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 ( + <> + +
+ + +
+ + ); } \ No newline at end of file diff --git a/src/client/src/FrontPage.js b/src/client/src/FrontPage.js index 25bbe9e..99687b5 100644 --- a/src/client/src/FrontPage.js +++ b/src/client/src/FrontPage.js @@ -5,6 +5,7 @@ import TournamentOverview from "./TournamentOverview.js"; import TournamentManager from "./TournamentManager.js"; 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'; @@ -162,6 +163,7 @@ export default function App() { } /> } /> } /> + } /> diff --git a/src/client/src/LoginPage.js b/src/client/src/LoginPage.js index 09205fe..f723b63 100644 --- a/src/client/src/LoginPage.js +++ b/src/client/src/LoginPage.js @@ -6,3 +6,14 @@ import ErrorSnackbar from "./components/ErrorSnackbar"; import {Button, Textfield, Stack, InputLabel, Paper, Typography} from '@mui/material'; +export default function LoginPage() { + return ( + <> + +

Sign in with google

+ + Sign in with google + + + ); +} \ No newline at end of file diff --git a/src/client/src/TournamentMatches.js b/src/client/src/TournamentMatches.js index 43afb8a..44772c8 100644 --- a/src/client/src/TournamentMatches.js +++ b/src/client/src/TournamentMatches.js @@ -5,7 +5,7 @@ import Appbar from './components/Appbar'; function MatchHistory() { return( - `Hei` + `Hei på deg din gamle sei` ); } From 3f1b13cc161e4b0b931957cf8cea835bcb673fda Mon Sep 17 00:00:00 2001 From: Felix Albrigtsen Date: Wed, 20 Apr 2022 16:01:00 +0200 Subject: [PATCH 07/11] revert api url --- src/client/.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/.env b/src/client/.env index b046e98..fafeb61 100644 --- a/src/client/.env +++ b/src/client/.env @@ -1,3 +1,3 @@ -REACT_APP_API_URL=http://10.24.1.22:3001/api +REACT_APP_API_URL=https://asura.feal.no/api REACT_APP_LOGIN_URL=http://localhost:3001/auth/google BROWSER=none From a283ae90b08f5d24fef71b30d488433e2e25d3f0 Mon Sep 17 00:00:00 2001 From: Kristoffer Longva Eriksen Date: Thu, 21 Apr 2022 10:34:57 +0200 Subject: [PATCH 08/11] disabled editing of archived tournaments --- src/client/src/TournamentOverview.js | 29 +++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/client/src/TournamentOverview.js b/src/client/src/TournamentOverview.js index f89c410..ea162b4 100644 --- a/src/client/src/TournamentOverview.js +++ b/src/client/src/TournamentOverview.js @@ -176,6 +176,33 @@ function BracketViewer(props) { ); } +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 () + } +} + function showError(error) { alert("Something went wrong. \n" + error); console.error(error); @@ -187,7 +214,7 @@ export default function TournamentOverview(props) { return ( <> - + ); From 6deead1260f60d49997864b1ea84be860299110d Mon Sep 17 00:00:00 2001 From: Kristoffer Longva Eriksen Date: Thu, 21 Apr 2022 11:05:50 +0200 Subject: [PATCH 09/11] rounded seconds and milliseconds of new tournament dates to 0 --- src/client/src/TournamentCreator.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/client/src/TournamentCreator.js b/src/client/src/TournamentCreator.js index 00a6a8b..a589981 100644 --- a/src/client/src/TournamentCreator.js +++ b/src/client/src/TournamentCreator.js @@ -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, From eb8019d22ef4e730621e47b8a6535899a7338950 Mon Sep 17 00:00:00 2001 From: Kristoffer Longva Eriksen Date: Thu, 21 Apr 2022 11:52:55 +0200 Subject: [PATCH 10/11] fixed submit buttons on manage teams page, including autoscroll --- src/client/src/TournamentTeams.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/client/src/TournamentTeams.js b/src/client/src/TournamentTeams.js index e063834..3d24409 100644 --- a/src/client/src/TournamentTeams.js +++ b/src/client/src/TournamentTeams.js @@ -43,15 +43,18 @@ function TeamCreator(props) { return (
+
{/* */} - +
+
) } @@ -92,7 +95,7 @@ function TeamList(props) { {/* {team.members} */} - + @@ -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) {

Edit Team:

- + {/* */} - +
From e572d64160e590099c304712f9d36014f63b0c52 Mon Sep 17 00:00:00 2001 From: Kristoffer Longva Eriksen Date: Thu, 21 Apr 2022 13:35:06 +0200 Subject: [PATCH 11/11] Added countdown timers to tournaments --- src/client/src/FrontPage.js | 32 ++++++++++++++++++++++++++++- src/client/src/TournamentHistory.js | 2 +- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/client/src/FrontPage.js b/src/client/src/FrontPage.js index 99687b5..3cfc07d 100644 --- a/src/client/src/FrontPage.js +++ b/src/client/src/FrontPage.js @@ -56,6 +56,34 @@ function TournamentListItem(props) { ; } } + + 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 ( + Started! + ) + } else { + return( + Starts in: {remainingDays} Days, {remainingHours} Hours, {remainingMins} Minutes and {remainingSecs} Seconds + + ) + } + } + return ( @@ -73,7 +101,7 @@ function TournamentListItem(props) { End: {props.tournament.endTime.toLocaleString()} - Players {props.tournament.teamCount} / {props.tournament.teamLimit} + Players: {props.tournament.teamCount} / {props.tournament.teamLimit} @@ -92,6 +120,8 @@ function TournamentListItem(props) {
+ + diff --git a/src/client/src/TournamentHistory.js b/src/client/src/TournamentHistory.js index e874523..5845096 100644 --- a/src/client/src/TournamentHistory.js +++ b/src/client/src/TournamentHistory.js @@ -51,7 +51,7 @@ function shorten(description, maxLength) { End: {props.tournament.endTime.toLocaleString()} - Players {props.tournament.teamCount} / {props.tournament.teamLimit} + Players: {props.tournament.teamCount} / {props.tournament.teamLimit}