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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 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}