Collaborative session 24/03/2022

Co-authored-by: Felix Albrigtsen <felixalbrigtsen@gmail.com>
This commit is contained in:
Kristoffer Juelsenn 2022-03-24 22:29:49 +01:00
parent bcf912c18c
commit 2205d07585
18 changed files with 679 additions and 177 deletions

1
src/client/.env Normal file
View File

@ -0,0 +1 @@
REACT_APP_BACKEND_URL="http://demiurgen.pvv.ntnu.no:3000"

View File

@ -15,6 +15,7 @@
"@mui/styled-engine-sc": "^5.5.2",
"bootstrap": "^5.1.3",
"iarn": "0.0.0",
"less": "^4.1.2",
"react": "^17.0.2",
"react-bootstrap": "^2.2.1",
"react-custom-alert": "^0.1.2",
@ -5713,6 +5714,17 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"node_modules/copy-anything": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz",
"integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
"dependencies": {
"is-what": "^3.14.1"
},
"funding": {
"url": "https://github.com/sponsors/mesqueeb"
}
},
"node_modules/core-js": {
"version": "3.21.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.1.tgz",
@ -6579,14 +6591,6 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/dotenv": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
"engines": {
"node": ">=10"
}
},
"node_modules/dotenv-expand": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
@ -6673,6 +6677,18 @@
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/errno": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
"integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
"optional": true,
"dependencies": {
"prr": "~1.0.1"
},
"bin": {
"errno": "cli.js"
}
},
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@ -8643,6 +8659,18 @@
"node": ">= 4"
}
},
"node_modules/image-size": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
"integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
"optional": true,
"bin": {
"image-size": "bin/image-size.js"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/immer": {
"version": "9.0.12",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.12.tgz",
@ -9068,6 +9096,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-what": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
"integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA=="
},
"node_modules/is-wsl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
@ -11077,6 +11110,67 @@
"language-subtag-registry": "~0.3.2"
}
},
"node_modules/less": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/less/-/less-4.1.2.tgz",
"integrity": "sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA==",
"dependencies": {
"copy-anything": "^2.0.1",
"parse-node-version": "^1.0.1",
"tslib": "^2.3.0"
},
"bin": {
"lessc": "bin/lessc"
},
"engines": {
"node": ">=6"
},
"optionalDependencies": {
"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",
"source-map": "~0.6.0"
}
},
"node_modules/less/node_modules/make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
"optional": true,
"dependencies": {
"pify": "^4.0.1",
"semver": "^5.6.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/less/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"optional": true,
"bin": {
"semver": "bin/semver"
}
},
"node_modules/less/node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"optional": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/less/node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@ -11485,6 +11579,32 @@
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
},
"node_modules/needle": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz",
"integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==",
"optional": true,
"dependencies": {
"debug": "^3.2.6",
"iconv-lite": "^0.4.4",
"sax": "^1.2.4"
},
"bin": {
"needle": "bin/needle"
},
"engines": {
"node": ">= 4.4.x"
}
},
"node_modules/needle/node_modules/debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"optional": true,
"dependencies": {
"ms": "^2.1.1"
}
},
"node_modules/negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@ -11900,6 +12020,14 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/parse-node-version": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
"integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
"engines": {
"node": ">= 0.10"
}
},
"node_modules/parse5": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
@ -11990,6 +12118,15 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
"optional": true,
"engines": {
"node": ">=6"
}
},
"node_modules/pirates": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
@ -13366,6 +13503,12 @@
"node": ">= 0.10"
}
},
"node_modules/prr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
"integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
"optional": true
},
"node_modules/psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
@ -13788,6 +13931,14 @@
}
}
},
"node_modules/react-scripts/node_modules/dotenv": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==",
"engines": {
"node": ">=10"
}
},
"node_modules/react-transition-group": {
"version": "4.4.2",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz",
@ -20643,6 +20794,14 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"copy-anything": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz",
"integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
"requires": {
"is-what": "^3.14.1"
}
},
"core-js": {
"version": "3.21.1",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.1.tgz",
@ -21276,11 +21435,6 @@
}
}
},
"dotenv": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q=="
},
"dotenv-expand": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
@ -21343,6 +21497,15 @@
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="
},
"errno": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
"integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
"optional": true,
"requires": {
"prr": "~1.0.1"
}
},
"error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@ -22772,6 +22935,12 @@
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
"integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ=="
},
"image-size": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
"integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
"optional": true
},
"immer": {
"version": "9.0.12",
"resolved": "https://registry.npmjs.org/immer/-/immer-9.0.12.tgz",
@ -23046,6 +23215,11 @@
"call-bind": "^1.0.2"
}
},
"is-what": {
"version": "3.14.1",
"resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz",
"integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA=="
},
"is-wsl": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
@ -24511,6 +24685,52 @@
"language-subtag-registry": "~0.3.2"
}
},
"less": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/less/-/less-4.1.2.tgz",
"integrity": "sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA==",
"requires": {
"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"
},
"dependencies": {
"make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
"integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
"optional": true,
"requires": {
"pify": "^4.0.1",
"semver": "^5.6.0"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"optional": true
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"optional": true
},
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
}
}
},
"leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@ -24820,6 +25040,28 @@
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
},
"needle": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/needle/-/needle-2.9.1.tgz",
"integrity": "sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==",
"optional": true,
"requires": {
"debug": "^3.2.6",
"iconv-lite": "^0.4.4",
"sax": "^1.2.4"
},
"dependencies": {
"debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"optional": true,
"requires": {
"ms": "^2.1.1"
}
}
}
},
"negotiator": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
@ -25116,6 +25358,11 @@
"lines-and-columns": "^1.1.6"
}
},
"parse-node-version": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
"integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA=="
},
"parse5": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
@ -25187,6 +25434,12 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
},
"pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
"optional": true
},
"pirates": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz",
@ -26068,6 +26321,12 @@
}
}
},
"prr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
"integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
"optional": true
},
"psl": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
@ -26374,6 +26633,13 @@
"webpack-dev-server": "^4.6.0",
"webpack-manifest-plugin": "^4.0.2",
"workbox-webpack-plugin": "^6.4.1"
},
"dependencies": {
"dotenv": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q=="
}
}
},
"react-transition-group": {

View File

@ -12,6 +12,7 @@
"@mui/styled-engine-sc": "^5.5.2",
"bootstrap": "^5.1.3",
"iarn": "0.0.0",
"less": "^4.1.2",
"react": "^17.0.2",
"react-bootstrap": "^2.2.1",
"react-custom-alert": "^0.1.2",

View File

@ -1,4 +1,5 @@
import * as React from "react";
import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
import { AppBar, Typography, Toolbar, CssBaseline, Button, Box, IconButton } from "@mui/material"
import Menu from '@mui/icons-material/Menu'
import HomeImage from "./homeimage";
@ -8,14 +9,17 @@ export default function Appbar() {
<>
<CssBaseline />
<Box sx={{ flexGrow: 1 }}>
<AppBar position="static">
<AppBar position="static" color="primary">
<Toolbar>
<HomeImage />
<Typography variant="h6" component="div" sx={{
flexGrow: 1,
marginLeft: '2vw'
}}>
<Link to="/" style={{ textDecoration:'none', color:'white'}}>
Asura Tournaments
</Link>
</Typography>
<IconButton
size="large"
@ -33,4 +37,3 @@ export default function Appbar() {
</>
);
}

View File

@ -1,12 +0,0 @@
import React from "react";
import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
import Button from "@mui/material/Button";
export default function ManageButton(props) {
return (
<Link to={`/tournament/${props.tournamentId}/manage`} style={{textDecoration:'none'}}>
<Button className="ManageButton" variant="contained" color="primary">Manage Tournament</Button>
</Link>
);
}

View File

@ -1,13 +0,0 @@
import React from "react";
import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
import Button from '@mui/material/Button'
export default function OverviewButton(props) {
return (
<Link to="/tournament" style={{textDecoration:'none'}}>
<Button className="OverviewButton">
View Tournament
</Button>
</Link>
);
}

View File

@ -5,7 +5,7 @@ import Button from "@mui/material/Button";
export default function SaveButton(props) {
return (
<Link to="/" style={{textDecoration:'none'}}>
<Link to="/">
<Button variant="outlined" color="primary">Save and Exit</Button>
</Link>
);

View File

@ -10,44 +10,61 @@ const theme = createTheme({
// },
pewterblue: {
main: '#8fbcbb',
contrastText: '#fff',
},
darkskyblue: {
main: '#88c0d0'
main: '#88c0d0',
contrastText: '#fff',
},
darkpastelblue:{
main: '#81a1c1'
main: '#81a1c1',
contrastText: '#fff',
},
rackley: {
main: '#5e81ac'
main: '#3270a6',
contrastText: '#fff',
},
gainsboro:{
main: '#d8dee9'
main: '#d8dee9',
contrastText: '#fff',
},
brightgrey: {
main: '#e5e9f0',
light: '#e5e9f0'
contrastText: '#fff',
},
lightslategray: {
main: '#79869c'
main: '#79869c',
contrastText: '#fff',
},
cadetblue: {
main: '#a0aaba'
main: '#a0aaba',
contrastText: '#fff',
},
red: {
main: '#bf616a',
contrastText: '#fff',
},
copper: {
main: '#d08770',
contrastText: '#fff',
},
gold: {
main: '#ebcb8b',
contrastText: '#fff',
},
green: {
main: '#a3be8c',
contrastText: '#fff',
},
grape: {
main: '#b48ead',
main: '#b76bbf',
contrastText: '#fff',
},
background: {
default: '#f0f2f2',
}
// contrastThreshold: 5,
// tonalOffset: 0.2,
},
});

View File

@ -0,0 +1,86 @@
/* https://codepen.io/semibran/pen/VjmPJd */
html {
font-size: 1rem; }
.bracket {
display: inline-block;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
white-space: nowrap;
background: #f0f2f2 !important;
}
.bracket .round {
display: inline-block;
vertical-align: middle; }
.bracket .round .winners > div {
display: inline-block;
vertical-align: middle; }
.bracket .round .winners > div.matchups .matchup:last-child {
margin-bottom: 0 !important; }
.bracket .round .winners > div.matchups .matchup .participants {
border-radius: 0.25rem;
overflow: hidden; }
.bracket .round .winners > div.matchups .matchup .participants .participant {
box-sizing: border-box;
color: #858585;
border-left: 0.25rem solid #858585;
background: white;
width: 14rem;
height: 3rem;
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.12); }
.bracket .round .winners > div.matchups .matchup .participants .participant.winner {
color: #60c645;
border-color: #60c645; }
.bracket .round .winners > div.matchups .matchup .participants .participant.loser {
color: #dc563f;
border-color: #dc563f; }
.bracket .round .winners > div.matchups .matchup .participants .participant:not(:last-child) {
border-bottom: thin solid #f0f2f2; }
.bracket .round .winners > div.matchups .matchup .participants .participant span {
margin: 0 1.25rem;
line-height: 3;
font-size: 1rem;
font-family: "Roboto Slab"; }
.bracket .round .winners > div.connector.filled .line, .bracket .round .winners > div.connector.filled.bottom .merger:after, .bracket .round .winners > div.connector.filled.top .merger:before {
border-color: #60c645; }
.bracket .round .winners > div.connector .line, .bracket .round .winners > div.connector .merger {
box-sizing: border-box;
width: 2rem;
display: inline-block;
vertical-align: top; }
.bracket .round .winners > div.connector .line {
border-bottom: thin solid #c0c0c8;
height: 4rem; }
.bracket .round .winners > div.connector .merger {
position: relative;
height: 8rem; }
.bracket .round .winners > div.connector .merger:before, .bracket .round .winners > div.connector .merger:after {
content: "";
display: block;
box-sizing: border-box;
width: 100%;
height: 50%;
border: 0 solid;
border-color: #c0c0c8; }
.bracket .round .winners > div.connector .merger:before {
border-right-width: thin;
border-top-width: thin; }
.bracket .round .winners > div.connector .merger:after {
border-right-width: thin;
border-bottom-width: thin; }
.bracket .round.quarterfinals .winners:not(:last-child) {
margin-bottom: 2rem; }
.bracket .round.quarterfinals .winners .matchups .matchup:not(:last-child) {
margin-bottom: 2rem; }
.bracket .round.semifinals .winners .matchups .matchup:not(:last-child) {
margin-bottom: 10rem; }
.bracket .round.semifinals .winners .connector .merger {
height: 16rem; }
.bracket .round.semifinals .winners .connector .line {
height: 8rem; }
.bracket .round.finals .winners .connector .merger {
height: 3rem; }
.bracket .round.finals .winners .connector .line {
height: 1.5rem; }

View File

@ -0,0 +1,84 @@
import './tournamentBracket.css';
//
export default function TournamentBracket(props) {
return <>
<section class="round quarterfinals">
<div class="winners">
<div class="matchups">
<div class="matchup">
<div class="participants">
<div class="participant winner"><span>Uno</span></div>
<div class="participant"><span>Ocho</span></div>
</div>
</div>
<div class="matchup">
<div class="participants">
<div class="participant"><span>Dos</span></div>
<div class="participant winner"><span>Siete</span></div>
</div>
</div>
</div>
<div class="connector">
<div class="merger"></div>
<div class="line"></div>
</div>
</div>
<div class="winners">
<div class="matchups">
<div class="matchup">
<div class="participants">
<div class="participant"><span>Treis</span></div>
<div class="participant winner"><span>Seis</span></div>
</div>
</div>
<div class="matchup">
<div class="participants">
<div class="participant"><span>Cuatro</span></div>
<div class="participant winner"><span>Cinco</span></div>
</div>
</div>
</div>
<div class="connector">
<div class="merger"></div>
<div class="line"></div>
</div>
</div>
</section>
<section class="round semifinals">
<div class="winners">
<div class="matchups">
<div class="matchup">
<div class="participants">
<div class="participant winner"><span>Uno</span></div>
<div class="participant"><span>Dos</span></div>
</div>
</div>
<div class="matchup">
<div class="participants">
<div class="participant winner"><span>Seis</span></div>
<div class="participant"><span>Cinco</span></div>
</div>
</div>
</div>
<div class="connector">
<div class="merger"></div>
<div class="line"></div>
</div>
</div>
</section>
<section class="round finals">
<div class="winners">
<div class="matchups">
<div class="matchup">
<div class="participants">
<div class="participant winner"><span>Uno</span></div>
<div class="participant"><span>Seis</span></div>
</div>
</div>
</div>
</div>
</section>
</>
}

View File

@ -54,7 +54,7 @@ function submitTournament(event) {
formData.append("teamLimit", tournamentMaxTeams);
let body = new URLSearchParams(formData);
fetch("http://10.24.1.213:3000/api/tournament/create", {
fetch(process.env.REACT_APP_BACKEND_URL + "/api/tournament/create", {
method: "POST",
body: body
})

View File

@ -1,6 +1,5 @@
import * as React from "react";
import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
import ManageButton from "./components/managebutton";
import CreateTournament from "./createtournament.js";
import TournamentOverview from "./tournamentoverview.js";
import TournamentManager from "./managetournament.js";
@ -8,15 +7,13 @@ import TournamentAnnouncement from "./tournamentannouncement";
import TournamentMatches from "./tournamentmatches";
import TeamEditor from "./teameditor";
import Appbar from './components/appbar';
import { Button, Container, Typography, Grid, Box } from "@mui/material";
import { Card, CardActions,CardACtionsArea, CardContent, CardHeader, CardMedia, Collapse, Paper } from "@mui/material";
import AddCircleIcon from '@mui/icons-material/AddCircle';
import { maxWidth, palette } from "@mui/system";
function CreateButton(props) {
return (
<Link to="/create" style={{ textDecoration: "none" }}>
<Link to="/create">
<Button variant="contained" color="success" style={{ margin: '2.5% 0 0 0'}}>
<Box sx={{
marginRight: '2%',
@ -29,16 +26,6 @@ function CreateButton(props) {
);
}
function OverviewButton(props) {
return (
<Link to="/tournament" style={{ textDecoration: "none" }}>
<Button variant="contained" color="success">
View Tournament
</Button>
</Link>
);
}
function TournamentListItem(props) {
return (
<Container maxWidth="lg" align="start" sx={{
@ -53,36 +40,29 @@ function TournamentListItem(props) {
image="https://source.unsplash.com/random"
/>
<CardContent>
<Typography variant="h3" component="div" align="center">
{props.tournament.name}
</Typography>
<Typography variant="h5" color="text.primary">
{props.tournament.description}
</Typography>
<Typography variant="body2" color="text.secondary">
Start: {props.tournament.startTime.toLocaleString()}
</Typography>
<Typography variant="body2" color="text.secondary">
End: {props.tournament.endTime.toLocaleString()}
</Typography>
<Typography variant="h5" color="text.primary" gutterBottom>
Players todo / {props.tournament.teamLimit}
</Typography>
<Typography variant="h3" component="div" align="center">{props.tournament.name} </Typography>
<Typography variant="h5" color="text.primary">{props.tournament.description}</Typography>
<Typography variant="body2" color="text.secondary"> Start: {props.tournament.startTime.toLocaleString()} </Typography>
<Typography variant="body2" color="text.secondary"> End: {props.tournament.endTime.toLocaleString()} </Typography>
<Typography variant="h5" color="text.primary" gutterBottom> Players todo / {props.tournament.teamLimit} </Typography>
<Box sx={{
margin: 'auto',
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
}} component="span">
<Box sx={{
margin: '0 2% 0 2'
}}>
<ManageButton tournamentId={props.tournament.id}/>
<Box sx={{margin: '0 2% 0 2'}}>
<Link to={`/tournament/${props.tournament.id}/manage`}>
<Button className="ManageButton" variant="contained" color="primary">Manage Tournament</Button>
</Link>
</Box>
<Box sx={{
margin: '0 2% 0 2%'
}}>
<OverviewButton />
<Box sx={{margin: '0 2% 0 2%'}}>
<Link to={`/tournament/${props.tournament.id}`} >
<Button variant="contained" color="success">
View Tournament
</Button>
</Link>
</Box>
</Box>
</CardContent>
@ -97,7 +77,7 @@ function TournamentList() {
let [tournamentList, setTournamentList] = React.useState([]);
React.useEffect(() => {
fetch("http://10.24.1.213:3000/api/tournament/getTournaments")
fetch(process.env.REACT_APP_BACKEND_URL + "/api/tournament/getTournaments")
.then(res => res.json())
.then(data => {
@ -167,9 +147,9 @@ export default function App() {
<Routes>
<Route path="/" element={<Home />} />
<Route path="/create" element={<CreateTournament />} />
<Route path="/tournament/" element={<TournamentOverview />} />
<Route path="/tournament/:id/manage" element={<TournamentManager />} />
<Route path="/tournament/teams" element={<TeamEditor />} />
<Route path="/tournament/:tournamentId" element={<TournamentOverview />} />
<Route path="/tournament/:tournamentId/manage" element={<TournamentManager />} />
<Route path="/tournament/:tournamentId/teams" element={<TeamEditor />} />
<Route path="/tournament/matches" element={<TournamentMatches />} />
<Route
path="/tournament/manage/announcement"

View File

@ -10,7 +10,7 @@ body {
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: #eeeeee;
background-color: #f0f2f2;
}
code {
@ -23,9 +23,13 @@ code {
width: 60px;
border-radius: 50%;
/* border: 5px dotted salmon; */
border: 3px solid darkslateblue;
border: 3px solid #1ab35a;
background-color: white;
margin: 5px;
margin-bottom: 0;
/* margin: 50% calc(2vw + 50%) 50% 50%; */
}
a {
text-decoration: none;
}

View File

@ -8,11 +8,11 @@ import { useParams } from 'react-router-dom'
import { Button, TextField, MenuItem, InputLabel, Select, Container, Slider } from '@mui/material'
function ManageTournament(props) {
const { id } = useParams()
const { tournamentId } = useParams()
let [tournamentInfo, setTournamentInfo] = React.useState([]);
React.useEffect(() => {
fetch(`http://10.24.1.213:3000/api/tournament/${id}`)
fetch(process.env.BACKEND_URL + `/api/tournament/${tournamentId}`)
.then(res => res.json())
.then(data => {

View File

@ -1,15 +1,7 @@
import * as React from "react";
import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
import { BrowserRouter as Router, Link, Route, Routes, useParams } from "react-router-dom";
import Appbar from "./components/appbar";
import {
Button,
TextField,
MenuItem,
InputLabel,
Select,
Container,
Slider,
} from "@mui/material";
import { Button, TextField, MenuItem, InputLabel, Select, Container, Slider} from "@mui/material";
function TeamChanger() {
return (
@ -41,7 +33,7 @@ var teams = {
"team 3": ["ola", "ole", "ost"],
"team 4": ["christine", "kristine", "kristhine"],
};
function TeamList() {
function TeamList(props) {
const [teamInput, setteamInput] = React.useState("");
const [membersInput, setmembersInput] = React.useState("");
React.useEffect(() => {
@ -49,6 +41,7 @@ function TeamList() {
document.getElementById("membersInput").value = membersInput;
});
return (
<>
<div>
Registered teams:
<ul>
@ -58,19 +51,13 @@ function TeamList() {
onClick={() => {
setteamInput(team);
setmembersInput(players);
}}
>
}}>
{team}
</button>
</li>
))}
</ul>
</div>
);
}
function TeamRemover() {
return (
</div>,
<div>
Remove team:{" "}
<select>
@ -80,16 +67,25 @@ function TeamRemover() {
</select>
<button>Remove</button>
</div>
<Link to={`/`}>
{/* Link to {props.tournament.id} when teams can be fetched */}
<button>Save and Exit</button>
</Link>
</>
);
}
function Save_Button() {
return (
<Link to="/tournament">
<button>Save and Exit</button>
</Link>
);
}
// function TeamRemover() {
// return (
// 'lol'
// );
// }
// function Save_Button() {
// return (
// 'lol'
// );
// }
export default function TeamEditor() {
return (
@ -97,8 +93,8 @@ export default function TeamEditor() {
<Appbar />
<TeamChanger />
<TeamList />
<TeamRemover />
<Save_Button />
{/* <TeamRemover />
<Save_Button /> */}
</>
);
}

View File

@ -1,56 +1,139 @@
import * as React from "react";
import { BrowserRouter as Router, Link, Route, Routes } from "react-router-dom";
import ManageButton from "./components/managebutton";
import Appbar from './components/appbar';
import { useParams } from 'react-router-dom'
import { Button } from "@mui/material";
import TournamentBracket from "./components/tournamentBracket";
// Test data
// {"status":"OK","data":
// [
// {"id":1,
// "tournamentId":1,
// "parentMatchId":null,
// "team1Id":null,
// "team2Id":null,
// "winnerId":null}
function TournamentTier(props) {
let roundTypes = ["finals", "semifinals", "quarterfinals", "eighthfinals"];
let connector;
if (props.tier != 0) {
connector = <div className="connector">
<div className="merger"></div>
<div className="line"></div>
</div>;
}
function RenderBrackets(params) {
let teams = 16;
let groups = Math.log2(teams);
// Number of matches, python equivalent: sum([2**groupNumber for groupNumber in range(groups)])
let matches = [...Array(groups).keys()].map(num => Math.pow(2, num)).reduce((a, b) => a + b);
return (
<>
{new Array(groups).map((group, i) => {
return (
<div>Group {i}</div>
);
return <section className={`round ${roundTypes[props.tier]}`}><div className="winners">
<div className="matchups">
{props.matches.map((match, i) => {
return <Match teams={props.teams} match={match} key={i} />
})}
</>
);
</div>
{connector}
</div>
</section>
}
function OverviewButtons(params) {
return (
<>
<div id="touOverview"></div>
<Link to="/tournament/teams">
<button id="manageTeams">Manage Teams </button>
</Link>
{/* <Link to="/tournament/matches">
<button id="touMatches">Tournament Matches</button>
</Link> */}
</>
);
function Match(props) {
let team1;
let team2;
if (props.match.team1Id != null) {
team1 = <div className='participant'><span>{props.match.team1Id}</span></div>;
} else {
team1 = <div className='participant'><span>TBA</span></div>;
}
if (props.match.team2Id != null) {
team2 = <div className='participant'><span>{props.match.team2Id}</span></div>;
} else {
team2 = <div className='participant'><span>TBA</span></div>;
}
return <div className="matchup">
<div className="participants">
{/* <div class="participant winner"><span>{if (props.match.team1Id) { props.match.team1Id} else { "TBA" }}</span></div>
<div class="participant"><span>{props.match.team2Id}</span></div> */}
{team1}
{team2}
</div>
</div>;
}
function BracketViewer(props) {
const [tournament, setTournament] = React.useState(null);
const [matches, setMatches] = React.useState([]);
const [teams, setTeams] = React.useState([]);
React.useEffect(() => {
fetch(process.env.REACT_APP_BACKEND_URL + `/api/tournament/${props.tournamentId}`)
.then(res => res.json())
.then(data => {
if (data.status != "OK") {
// Do your error thing
console.error(data);
return;
}
let tournament = data.data;
setTournament(tournament);
})
.catch((err) => console.log(err.message));
fetch(process.env.REACT_APP_BACKEND_URL + `/api/tournament/${props.tournamentId}/getMatches`)
.then(res => res.json())
.then(data => {
if (data.status != "OK") {
// Do your error thing
console.error(data);
return;
}
let matches = data.data;
let tiers = matches.reduce((tiers, match) => {
if (tiers[match.tier] == undefined) {
tiers[match.tier] = [];
}
tiers[match.tier].push(match);
return tiers;
}, {});
tiers = Object.values(tiers);
tiers = tiers.reverse();
setMatches(tiers);
})
.catch((err) => console.log(err.message));
fetch(process.env.REACT_APP_BACKEND_URL + `/api/tournament/${props.tournamentId}/getTeams`)
.then(res => res.json())
.then(data=>{
if(data.status != "OK"){
console.error(data)
return;
}
let teams = data.data;
setTeams(teams);
})
.catch((err) => console.log(err.message));
}, []);
return <div className="bracket">
{matches.map(tier => {
let tierNum = tier[0].tier;
return <TournamentTier key={tierNum} tier={tierNum} matches={tier} teams={teams} />
})}
</div>;
}
export default function TournamentOverview(props) {
// Use-effect hook here
const { tournamentId } = useParams();
return (
<>
<Appbar />
<ManageButton />
<RenderBrackets />
<OverviewButtons />
<Link to={`/tournament/${tournamentId}/manage`}>
<Button className="ManageButton" variant="contained" color="rackley">Manage Tournament</Button>
</Link>
<Link to={`/tournament/${tournamentId}/teams`}>
<Button className="OverviewButton" variant="contained" color="grape">
Manage Teams
</Button>
</Link>
<BracketViewer tournamentId={tournamentId} className="bracketViewer" />
</>
);
}

6
src/package-lock.json generated Normal file
View File

@ -0,0 +1,6 @@
{
"name": "src",
"lockfileVersion": 2,
"requires": true,
"packages": {}
}