mirror of
https://github.com/Team4388/ScoutingApp2022.git
synced 2026-06-08 16:28:04 -06:00
AAAAAAAAAAAAGH
This commit is contained in:
@@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"prettier.printWidth": 400,
|
|
||||||
"prettier.semi": false,
|
|
||||||
"prettier.singleQuote": true
|
|
||||||
}
|
|
||||||
|
|
||||||
Vendored
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"prettier.configPath": "${workspaceFolder}/.prettierrc.json"
|
"prettier.printWidth": 800
|
||||||
}
|
}
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,14 @@
|
|||||||
|
# This file contains important security parameters. If you modify this file
|
||||||
|
# manually, Certbot will be unable to automatically provide future security
|
||||||
|
# updates. Instead, Certbot will print and log an error message with a path to
|
||||||
|
# the up-to-date file that you will need to refer to when manually updating
|
||||||
|
# this file.
|
||||||
|
|
||||||
|
ssl_session_cache shared:le_nginx_SSL:10m;
|
||||||
|
ssl_session_timeout 1440m;
|
||||||
|
ssl_session_tickets off;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers off;
|
||||||
|
|
||||||
|
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
-----BEGIN DH PARAMETERS-----
|
||||||
|
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
|
||||||
|
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
|
||||||
|
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
|
||||||
|
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
|
||||||
|
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
|
||||||
|
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
|
||||||
|
-----END DH PARAMETERS-----
|
||||||
+28
-6
@@ -1,18 +1,32 @@
|
|||||||
version: "3"
|
version: "3"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
scouting-webserver-prod:
|
scouting-webserver-prod:
|
||||||
container_name: "scouting-webserver-production"
|
container_name: "production"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
build:
|
build:
|
||||||
context: ./webserver
|
context: ./webserver
|
||||||
dockerfile: ./Dockerfile.prod
|
dockerfile: ./Dockerfile.prod
|
||||||
expose:
|
expose:
|
||||||
- 80
|
- 8080
|
||||||
ports:
|
ports:
|
||||||
- "80:80/tcp"
|
- "8080:8080/tcp"
|
||||||
|
# - "80:80/tcp"
|
||||||
|
# - "443:443/tcp"
|
||||||
|
volumes:
|
||||||
|
- ./webserver/nginx:/etc/nginx/:ro
|
||||||
|
ssl-proxy:
|
||||||
|
image: fsouza/docker-ssl-proxy
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
environment:
|
||||||
|
- DOMAIN=10.43.88.1
|
||||||
|
- TARGET_PORT=8080
|
||||||
|
- TARGET_HOST=scouting-webserver-prod
|
||||||
|
- SSL_PORT:443
|
||||||
couchdb:
|
couchdb:
|
||||||
container_name: "scouting-couchdb"
|
container_name: "scouting-couchdb"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
@@ -33,4 +47,12 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./couchdb/db.local.ini:/opt/couchdb/etc/local.ini
|
- ./couchdb/db.local.ini:/opt/couchdb/etc/local.ini
|
||||||
- ./couchdb/data:/opt/couchdb/data
|
- ./couchdb/data:/opt/couchdb/data
|
||||||
|
couch-ssl-proxy:
|
||||||
|
image: fsouza/docker-ssl-proxy
|
||||||
|
ports:
|
||||||
|
- "5985:5985"
|
||||||
|
environment:
|
||||||
|
- DOMAIN=10.43.88.1
|
||||||
|
- TARGET_PORT=5984
|
||||||
|
- TARGET_HOST=scouting-couchdb
|
||||||
|
- SSL_PORT:5985
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
docker-compose run certonly --webroot --webroot-path /var/www/certbot/ --dry-run -d scouting.local
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
if ! [ -x "$(command -v docker-compose)" ]; then
|
||||||
|
echo 'Error: docker-compose is not installed.' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
domains=scouting.local
|
||||||
|
rsa_key_size=4096
|
||||||
|
data_path="./data/certbot"
|
||||||
|
email="" # Adding a valid address is strongly recommended
|
||||||
|
staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits
|
||||||
|
|
||||||
|
if [ -d "$data_path" ]; then
|
||||||
|
read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision
|
||||||
|
if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then
|
||||||
|
echo "### Downloading recommended TLS parameters ..."
|
||||||
|
mkdir -p "$data_path/conf"
|
||||||
|
curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf"
|
||||||
|
curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "### Creating dummy certificate for $domains ..."
|
||||||
|
path="/etc/letsencrypt/live/$domains"
|
||||||
|
mkdir -p "$data_path/conf/live/$domains"
|
||||||
|
docker-compose run --rm --entrypoint "\
|
||||||
|
openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1\
|
||||||
|
-keyout '$path/privkey.pem' \
|
||||||
|
-out '$path/fullchain.pem' \
|
||||||
|
-subj '/CN=localhost'" certbot
|
||||||
|
echo
|
||||||
|
|
||||||
|
|
||||||
|
echo "### Starting nginx ..."
|
||||||
|
docker-compose up --force-recreate -d nginx
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "### Deleting dummy certificate for $domains ..."
|
||||||
|
docker-compose run --rm --entrypoint "\
|
||||||
|
rm -Rf /etc/letsencrypt/live/$domains && \
|
||||||
|
rm -Rf /etc/letsencrypt/archive/$domains && \
|
||||||
|
rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot
|
||||||
|
echo
|
||||||
|
|
||||||
|
|
||||||
|
echo "### Requesting Let's Encrypt certificate for $domains ..."
|
||||||
|
#Join $domains to -d args
|
||||||
|
domain_args=""
|
||||||
|
for domain in "${domains[@]}"; do
|
||||||
|
domain_args="$domain_args -d $domain"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Select appropriate email arg
|
||||||
|
case "$email" in
|
||||||
|
"") email_arg="--register-unsafely-without-email" ;;
|
||||||
|
*) email_arg="--email $email" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Enable staging mode if needed
|
||||||
|
if [ $staging != "0" ]; then staging_arg="--staging"; fi
|
||||||
|
|
||||||
|
docker-compose run --rm --entrypoint "\
|
||||||
|
certbot certonly --webroot -w /var/www/certbot \
|
||||||
|
$staging_arg \
|
||||||
|
$email_arg \
|
||||||
|
$domain_args \
|
||||||
|
--rsa-key-size $rsa_key_size \
|
||||||
|
--agree-tos \
|
||||||
|
--force-renewal" certbot
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "### Reloading nginx ..."
|
||||||
|
docker-compose exec nginx nginx -s reload
|
||||||
+1
-1
@@ -1 +1 @@
|
|||||||
docker-compose -f docker-compose.prod.yml up -d --build
|
docker-compose -f docker-compose.prod.yml up -d --build
|
||||||
@@ -1,9 +1,12 @@
|
|||||||
FROM node:16-alpine as build-step
|
FROM node:16-alpine as build-step
|
||||||
RUN mkdir /app/
|
RUN mkdir /app/
|
||||||
|
RUN mkdir /app/node_modules
|
||||||
|
RUN chown -R node:node /app/node_modules
|
||||||
|
#RUN mkdir /app/node_module/.bin
|
||||||
WORKDIR /app/
|
WORKDIR /app/
|
||||||
ENV PATH /app/node_modules/.bin:$PATH
|
ENV PATH /app/node_modules/.bin:$PATH
|
||||||
RUN chown -R node:node /app/node_modules
|
COPY package.json ./
|
||||||
COPY package*.json ./
|
COPY package-lock.json ./
|
||||||
RUN npm install
|
RUN npm install
|
||||||
COPY . ./
|
COPY . ./
|
||||||
# USER node
|
# USER node
|
||||||
@@ -12,6 +15,7 @@ RUN npm run build
|
|||||||
FROM nginx:1-alpine
|
FROM nginx:1-alpine
|
||||||
COPY --from=build-step /app/build /usr/share/nginx/html
|
COPY --from=build-step /app/build /usr/share/nginx/html
|
||||||
RUN rm /etc/nginx/conf.d/default.conf
|
RUN rm /etc/nginx/conf.d/default.conf
|
||||||
COPY nginx/nginx.conf /etc/nginx/conf.d
|
# COPY nginx/nginx.conf /etc/nginx/conf.d
|
||||||
EXPOSE 80
|
EXPOSE 8080
|
||||||
|
# EXPOSE 443
|
||||||
CMD ["nginx", "-g", "daemon off;"]
|
CMD ["nginx", "-g", "daemon off;"]
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
server {
|
||||||
|
listen 8080;
|
||||||
|
listen [::]:8080;
|
||||||
|
; server_name 10.43.88.1;
|
||||||
|
; server_tokens off;
|
||||||
|
; location /.well-known/acme-challenge/{
|
||||||
|
; root /var/www/certbot;
|
||||||
|
; }
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html/;
|
||||||
|
index index.html index.htm;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
; return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
|
||||||
|
; error_page 500 502 503 504 /50x.html;
|
||||||
|
; location = /50x.html {
|
||||||
|
; root /usr/share/nginx/html;
|
||||||
|
; }
|
||||||
|
}
|
||||||
|
|
||||||
|
; server {
|
||||||
|
; listen 443 default_server ssl;
|
||||||
|
; listen [::]:443 ssl;
|
||||||
|
|
||||||
|
; server_name 10.43.88.1;
|
||||||
|
|
||||||
|
; ssl_certificate /etc/nginx/ssl/live/10.43.88.1/fullchain.pem;
|
||||||
|
; ssl_certificate_key /etc/nginx/ssl/live/10.43.88.1/privkey.pem;
|
||||||
|
; include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||||
|
; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||||
|
|
||||||
|
; location / {
|
||||||
|
; root /usr/share/nginx/html/;
|
||||||
|
; index index.html index.htm;
|
||||||
|
; try_files $uri $uri/ /index.html;
|
||||||
|
; }
|
||||||
|
; }
|
||||||
+17
-12
@@ -1,13 +1,18 @@
|
|||||||
|
events {
|
||||||
server {
|
worker_connections 4096; ## Default: 1024
|
||||||
listen 80;
|
|
||||||
location / {
|
|
||||||
root /usr/share/nginx/html/;
|
|
||||||
index index.html index.htm;
|
|
||||||
try_files $uri $uri/ /index.html;
|
|
||||||
}
|
|
||||||
error_page 500 502 503 504 /50x.html;
|
|
||||||
location = /50x.html {
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
http {
|
||||||
|
server {
|
||||||
|
listen 8080;
|
||||||
|
listen [::]:8080;
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html/;
|
||||||
|
index index.html index.htm;
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
error_page 500 502 503 504 /50x.html;
|
||||||
|
location = /50x.html {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+13
-1
@@ -19,7 +19,19 @@
|
|||||||
"react-scripts": "5.0.0",
|
"react-scripts": "5.0.0",
|
||||||
"web-vitals": "^2.1.3",
|
"web-vitals": "^2.1.3",
|
||||||
"@material-ui/core": "^4.12.3",
|
"@material-ui/core": "^4.12.3",
|
||||||
"@material-ui/icons": "^4.11.2"
|
"@material-ui/icons": "^4.11.2",
|
||||||
|
"workbox-background-sync": "^5.1.4",
|
||||||
|
"workbox-broadcast-update": "^5.1.4",
|
||||||
|
"workbox-cacheable-response": "^5.1.4",
|
||||||
|
"workbox-core": "^5.1.4",
|
||||||
|
"workbox-expiration": "^5.1.4",
|
||||||
|
"workbox-google-analytics": "^5.1.4",
|
||||||
|
"workbox-navigation-preload": "^5.1.4",
|
||||||
|
"workbox-precaching": "^5.1.4",
|
||||||
|
"workbox-range-requests": "^5.1.4",
|
||||||
|
"workbox-routing": "^5.1.4",
|
||||||
|
"workbox-strategies": "^5.1.4",
|
||||||
|
"workbox-streams": "^5.1.4"
|
||||||
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
.App {
|
.App {
|
||||||
/* height: 100%; */
|
height: 100%;
|
||||||
}
|
width: 100%;
|
||||||
|
}
|
||||||
|
|||||||
+11
-17
@@ -16,7 +16,7 @@ import NotFoundPage from "./Pages/NotFoundPage";
|
|||||||
import DashboardPage from "./Pages/DashboardPage/DashboardPage";
|
import DashboardPage from "./Pages/DashboardPage/DashboardPage";
|
||||||
import WelcomePage from "./Pages/WelcomePage";
|
import WelcomePage from "./Pages/WelcomePage";
|
||||||
import InputPage from "./Pages/InputPage";
|
import InputPage from "./Pages/InputPage";
|
||||||
import { createMuiTheme, ThemeProvider } from '@material-ui/core'
|
import { createTheme, ThemeProvider } from '@material-ui/core/styles'
|
||||||
import { Formik, Field, Form } from 'formik';
|
import { Formik, Field, Form } from 'formik';
|
||||||
import { TextField, Button, Grid, FormRow, Checkbox, Radio, FormControlLabel, FormControl, FormLabel, RadioGroup, IconButton, InputAdornment } from "@material-ui/core";
|
import { TextField, Button, Grid, FormRow, Checkbox, Radio, FormControlLabel, FormControl, FormLabel, RadioGroup, IconButton, InputAdornment } from "@material-ui/core";
|
||||||
import { AddCircleOutline, RemoveCircleOutline } from "@material-ui/icons";
|
import { AddCircleOutline, RemoveCircleOutline } from "@material-ui/icons";
|
||||||
@@ -25,8 +25,7 @@ import { ProcessedDataBucketProvider } from "./ProcessedDataBucketContext";
|
|||||||
|
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const darkTheme = createMuiTheme({
|
const darkTheme = createTheme({
|
||||||
|
|
||||||
// Theme settings
|
// Theme settings
|
||||||
palette: {
|
palette: {
|
||||||
type: "dark",
|
type: "dark",
|
||||||
@@ -35,18 +34,13 @@ function App() {
|
|||||||
fontSize: 18
|
fontSize: 18
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
const styles = {
|
|
||||||
bigbution: {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<ThemeProvider theme={darkTheme}>
|
||||||
<ThemeProvider theme={darkTheme}>
|
<ProcessedDataBucketProvider>
|
||||||
<DbProvider>
|
<DbProvider>
|
||||||
<ProcessedDataBucketProvider>
|
<Router>
|
||||||
<Router>
|
<Navigation />
|
||||||
<Navigation />
|
<div className="App">
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<WelcomePage />} />
|
<Route path="/" element={<WelcomePage />} />
|
||||||
<Route path="/Dashboard" element={<DashboardPage />} />
|
<Route path="/Dashboard" element={<DashboardPage />} />
|
||||||
@@ -54,11 +48,11 @@ function App() {
|
|||||||
<Route path="/404" element={<NotFoundPage />} />
|
<Route path="/404" element={<NotFoundPage />} />
|
||||||
<Route path="*" element={<NotFoundPage />} />
|
<Route path="*" element={<NotFoundPage />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</Router>
|
</div>
|
||||||
</ProcessedDataBucketProvider>
|
</Router>
|
||||||
</DbProvider>
|
</DbProvider>
|
||||||
</ThemeProvider>
|
</ProcessedDataBucketProvider>
|
||||||
</div>
|
</ThemeProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ export function useRemoteDb() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function DbProvider({ children }) {
|
export function DbProvider({ children }) {
|
||||||
|
const pdb = React.useContext(ProcessedDataBucketContext);
|
||||||
const [localdb, setLocaldb] = useState(new PouchDB("testdata"));
|
const [localdb, setLocaldb] = useState(new PouchDB("testdata"));
|
||||||
//used in development server
|
//used in development server
|
||||||
const [remotedb, setRemotedb] = useState(
|
const [remotedb, setRemotedb] = useState(
|
||||||
@@ -25,25 +26,16 @@ export function DbProvider({ children }) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
console.log(remotedb);
|
|
||||||
// const [remotedb, setRemotedb] = useState(new PouchDB(window.location.protocol + "//" + window.location.hostname + ":5984/kcmt2021", {skip_setup: true}))
|
|
||||||
|
|
||||||
//Login to the Remote Database
|
|
||||||
// remotedb.logIn('2021', 'Ridgebotics').then(function () {
|
|
||||||
// console.log("CouchDb Login Successful!");
|
|
||||||
// }).catch(function (err) {
|
|
||||||
// console.log("Unable to login to CouchDb!");
|
|
||||||
// console.log(err);
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
pdb.updateData(localdb);
|
||||||
localdb
|
localdb
|
||||||
.sync(remotedb, {
|
.sync(remotedb, {
|
||||||
live: true,
|
live: true,
|
||||||
retry: true,
|
retry: true,
|
||||||
})
|
})
|
||||||
.on("change", function (change) {
|
.on("change", function (change) {
|
||||||
const pdb = React.useContext(ProcessedDataBucketContext);
|
console.log('DB CHANGED');
|
||||||
console.log(pdb);
|
pdb.updateData(localdb);
|
||||||
})
|
})
|
||||||
.on("paused", function (info) { })
|
.on("paused", function (info) { })
|
||||||
.on("active", function (info) { })
|
.on("active", function (info) { })
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
.maxwidth {
|
.maxwidth {
|
||||||
display: block;
|
display: block;
|
||||||
/* margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto; */
|
margin-right: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
max-width: fit-content;
|
max-width: fit-content;
|
||||||
/* max-width: 100% */
|
/* max-width: 100% */
|
||||||
}
|
}
|
||||||
.smallfeild {
|
.smallfeild {
|
||||||
max-width: 25%;
|
max-width: 25%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
Grid,
|
Grid,
|
||||||
FormRow,
|
FormRow,
|
||||||
|
Divider,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Radio,
|
Radio,
|
||||||
FormControlLabel,
|
FormControlLabel,
|
||||||
@@ -26,9 +27,8 @@ import { AddCircleOutline, RemoveCircleOutline } from "@material-ui/icons";
|
|||||||
|
|
||||||
const InputPage = () => {
|
const InputPage = () => {
|
||||||
const localdb = useLocalDb();
|
const localdb = useLocalDb();
|
||||||
console.log(localdb);
|
|
||||||
return (
|
return (
|
||||||
<div class="maxwidth">
|
<div>
|
||||||
<br />
|
<br />
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{
|
initialValues={{
|
||||||
@@ -39,17 +39,19 @@ const InputPage = () => {
|
|||||||
team_abilities_cant: "",
|
team_abilities_cant: "",
|
||||||
fouls: "0",
|
fouls: "0",
|
||||||
fouls_tech: "0",
|
fouls_tech: "0",
|
||||||
flips: "0",
|
flipped: false,
|
||||||
red_cards: "0",
|
red_cards: "0",
|
||||||
yellow_cards: "0",
|
yellow_cards: "0",
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
taxi_auto: false,
|
||||||
upper_hub_auto: "0",
|
upper_hub_auto: "0",
|
||||||
lower_hub_auto: "0",
|
lower_hub_auto: "0",
|
||||||
upper_hub: "0",
|
upper_hub_teleop: "0",
|
||||||
lower_hub: "0",
|
lower_hub_teleop: "0",
|
||||||
climb_level: "",
|
climb_level: "",
|
||||||
alliance: "",
|
alliance: "",
|
||||||
defence: ""
|
defence: "0",
|
||||||
|
disabled: false
|
||||||
}}
|
}}
|
||||||
onSubmit={(values, { setSubmitting, resetForm }) => {
|
onSubmit={(values, { setSubmitting, resetForm }) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -82,31 +84,13 @@ const InputPage = () => {
|
|||||||
handleSubmit,
|
handleSubmit,
|
||||||
isSubmitting,
|
isSubmitting,
|
||||||
}) => (
|
}) => (
|
||||||
|
|
||||||
<Form >
|
<Form >
|
||||||
<Grid
|
<Grid container direction="row" justifyContent="center" alignItems="flex-end" spacing={3}>
|
||||||
container
|
|
||||||
direction="row"
|
|
||||||
justify="center"
|
|
||||||
alignItems="flex-start"
|
|
||||||
spacing={3}>
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
{" "}
|
<Field type="input" as={TextField} name="team_number" label="Team #" />
|
||||||
<Field
|
|
||||||
type="input"
|
|
||||||
as={TextField}
|
|
||||||
name="team_number"
|
|
||||||
label="Team #"
|
|
||||||
/>{" "}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
{" "}
|
<Field type="input" as={TextField} name="match_number" label="Match Number" />
|
||||||
<Field
|
|
||||||
type="input"
|
|
||||||
as={TextField}
|
|
||||||
name="match_number"
|
|
||||||
label="Match Number"
|
|
||||||
/>{" "}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<FormControl component="fieldset">
|
<FormControl component="fieldset">
|
||||||
@@ -114,25 +98,13 @@ const InputPage = () => {
|
|||||||
<RadioGroup aria-label="Alliance" name="alliance" row>
|
<RadioGroup aria-label="Alliance" name="alliance" row>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={
|
||||||
<Field
|
<Field as={Radio} type="radio" name="alliance" value="red" style={{ fontSize: 50 }} />
|
||||||
as={Radio}
|
|
||||||
type="radio"
|
|
||||||
name="alliance"
|
|
||||||
value="red"
|
|
||||||
style={{ fontSize: 50 }}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
label="Red"
|
label="Red"
|
||||||
|
|
||||||
/>
|
/>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={
|
||||||
<Field
|
<Field as={Radio} type="radio" name="alliance" value="blue" />
|
||||||
as={Radio}
|
|
||||||
type="radio"
|
|
||||||
name="alliance"
|
|
||||||
value="blue"
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
label="Blue"
|
label="Blue"
|
||||||
/>
|
/>
|
||||||
@@ -140,118 +112,62 @@ const InputPage = () => {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<div />
|
<div />
|
||||||
<Grid
|
<Grid container direction="row" justifyContent="center" alignItems="flex-end" spacing={3}>
|
||||||
container
|
|
||||||
direction="row"
|
|
||||||
justify="center"
|
|
||||||
alignItems="flex-start"
|
|
||||||
spacing={3}>
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Grid
|
<Grid container direction="column" justifyContent="flex-end" alignItems="center" spacing={3}>
|
||||||
container
|
|
||||||
direction="column"
|
|
||||||
justify="flex-start"
|
|
||||||
alignItems="center"
|
|
||||||
spacing={3}>
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<InputNumberField
|
<InputNumberField name="upper_hub_auto" label="Upper Hub Auto" />
|
||||||
name="upper_hub_auto"
|
|
||||||
label="Upper Hub Auto"
|
|
||||||
/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<InputNumberField
|
<InputNumberField name="lower_hub_auto" label="Lower Hub Auto" />
|
||||||
name="lower_hub_auto"
|
|
||||||
label="Lower Hub Auto"
|
|
||||||
/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
{" "}
|
<Grid container direction="column" justifyContent="flex-end" alignItems="center" spacing={3}>
|
||||||
<Grid
|
|
||||||
container
|
|
||||||
direction="column"
|
|
||||||
justify="flex-start"
|
|
||||||
alignItems="center"
|
|
||||||
spacing={3}>
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
{" "}
|
<InputNumberField name="upper_hub_teleop" label="Upper Hub Teleop" />
|
||||||
<InputNumberField name="upper_hub" label="Upper Hub" />{" "}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
{" "}
|
<InputNumberField name="lower_hub_teleop" label="Lower Hub Teleop" />
|
||||||
<InputNumberField name="lower_hub" label="Lower Hub" />{" "}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>{" "}
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<div />
|
<div />
|
||||||
<Grid
|
<Grid container direction="row" justifyContent="center" alignItems="flex-end" spacing={3}>
|
||||||
container
|
|
||||||
direction="row"
|
|
||||||
justify="center"
|
|
||||||
alignItems="flex-start"
|
|
||||||
spacing={3}>
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<FormControl component="fieldset">
|
<FormControl component="fieldset">
|
||||||
<FormLabel component="legend">Climbing</FormLabel>
|
<FormLabel component="legend">Climbing</FormLabel>
|
||||||
<RadioGroup aria-label="Climbing" name="climb_level" row>
|
<RadioGroup aria-label="Climbing" name="climb_level" row>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={
|
||||||
<Field
|
<Field as={Radio} type="radio" name="climb_level" value="0" />
|
||||||
as={Radio}
|
|
||||||
type="radio"
|
|
||||||
name="climb_level"
|
|
||||||
value="0"
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
label="None"
|
label="None"
|
||||||
/>
|
/>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={
|
||||||
<Field
|
<Field as={Radio} type="radio" name="climb_level" value="1" />
|
||||||
as={Radio}
|
|
||||||
type="radio"
|
|
||||||
name="climb_level"
|
|
||||||
value="1"
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
label="Low"
|
label="Low"
|
||||||
/>
|
/>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={
|
||||||
<Field
|
<Field as={Radio} type="radio" name="climb_level" value="2" />
|
||||||
as={Radio}
|
|
||||||
type="radio"
|
|
||||||
name="climb_level"
|
|
||||||
value="2"
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
label="Mid"
|
label="Mid"
|
||||||
/>
|
/>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={
|
||||||
<Field
|
<Field as={Radio} type="radio" name="climb_level" value="3" />
|
||||||
as={Radio}
|
|
||||||
type="radio"
|
|
||||||
name="climb_level"
|
|
||||||
value="3"
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
label="High"
|
label="High"
|
||||||
/>
|
/>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={
|
||||||
<Field
|
<Field as={Radio} type="radio" name="climb_level" value="4" />
|
||||||
as={Radio}
|
|
||||||
type="radio"
|
|
||||||
name="climb_level"
|
|
||||||
value="4"
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
label="Traversal"
|
label="Traversal"
|
||||||
/>
|
/>
|
||||||
@@ -259,168 +175,77 @@ const InputPage = () => {
|
|||||||
</FormControl>
|
</FormControl>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<div />
|
<div />
|
||||||
<Grid
|
<Grid container direction="row" justifyContent="center" alignItems="flex-end" spacing={3}>
|
||||||
container
|
|
||||||
direction="row"
|
|
||||||
justify="center"
|
|
||||||
alignItems="flex-start"
|
|
||||||
spacing={3}>
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Grid
|
<Grid container direction="column" justifyContent="flex-end" alignItems="center" spacing={3}>
|
||||||
container
|
|
||||||
direction="column"
|
|
||||||
justify="flex-start"
|
|
||||||
alignItems="center"
|
|
||||||
spacing={3}>
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<InputNumberField name="fouls" label="Fouls" />{" "}
|
<InputNumberField name="fouls" label="Fouls" />
|
||||||
</Grid>{" "}
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<InputNumberField name="fouls_tech" label="Tech Fouls" />{" "}
|
<InputNumberField name="fouls_tech" label="Tech Fouls" />
|
||||||
</Grid>{" "}
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<Grid
|
<Grid container direction="column" justifyContent="flex-end" alignItems="center" spacing={3}>
|
||||||
container
|
|
||||||
direction="column"
|
|
||||||
justify="flex-start"
|
|
||||||
alignItems="center"
|
|
||||||
spacing={3}>
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<InputNumberField name="red_cards" label="Red Cards" />{" "}
|
<InputNumberField name="red_cards" label="Red Cards" />
|
||||||
</Grid>{" "}
|
|
||||||
<Grid item>
|
|
||||||
<InputNumberField name="yellow_cards" label="Yellow Cards" />{" "}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid item>
|
<Grid item>
|
||||||
{/* <InputNumberField name="disables" label="Disables" />{" "} */}
|
<InputNumberField name="yellow_cards" label="Yellow Cards" />
|
||||||
</Grid>{" "}
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<div />
|
<div />
|
||||||
<Grid
|
<Grid container direction="row" justifyContent="center" alignItems="flex-end" spacing={3}>
|
||||||
container
|
|
||||||
direction="row"
|
|
||||||
justify="center"
|
|
||||||
alignItems="flex-start"
|
|
||||||
spacing={3}>
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
<FormControl component="fieldset">
|
<FormControl component="fieldset">
|
||||||
<FormLabel component="legend">Defense</FormLabel>
|
<FormLabel component="legend">Defense</FormLabel>
|
||||||
<RadioGroup aria-label="Defense" name="defence" row>
|
<RadioGroup aria-label="Defense" name="defence" row>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={<Field as={Radio} type="radio" name="defence" value="0" />}
|
||||||
<Field
|
label="None"
|
||||||
as={Radio}
|
|
||||||
type="radio"
|
|
||||||
name="defence"
|
|
||||||
value="0"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="N/A"
|
|
||||||
/>
|
/>
|
||||||
|
{/* <Divider orientation="vertical" flexItem middle /> */}
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={<Field as={Radio} type="radio" name="defence" value="1" />}
|
||||||
<Field
|
|
||||||
as={Radio}
|
|
||||||
type="radio"
|
|
||||||
name="defence"
|
|
||||||
value="1"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Poor"
|
label="Poor"
|
||||||
/>
|
/>
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
control={
|
control={<Field as={Radio} type="radio" name="defence" value="2" />}
|
||||||
<Field
|
|
||||||
as={Radio}
|
|
||||||
type="radio"
|
|
||||||
name="defence"
|
|
||||||
value="2"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Good"
|
label="Good"
|
||||||
/>
|
/> <FormControlLabel
|
||||||
<FormControlLabel
|
control={<Field as={Radio} type="radio" name="defence" value="3" />}
|
||||||
control={
|
|
||||||
<Field
|
|
||||||
as={Radio}
|
|
||||||
type="radio"
|
|
||||||
name="defence"
|
|
||||||
value="3"
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label="Exceptional"
|
label="Exceptional"
|
||||||
/>
|
/>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<div />
|
|
||||||
|
|
||||||
<Grid
|
|
||||||
container
|
|
||||||
direction="row"
|
|
||||||
justify="center"
|
|
||||||
alignItems="flex-start"
|
|
||||||
spacing={3}>
|
|
||||||
<Grid item>
|
<Grid item>
|
||||||
{" "}
|
<FormControlLabel
|
||||||
<Field
|
control={<Field as={Checkbox} type="checkbox" name="disabled" />}
|
||||||
type="input"
|
label="Disabled"
|
||||||
as={TextField}
|
/>
|
||||||
multiline
|
|
||||||
rows={3}
|
|
||||||
rowsMax={7}
|
|
||||||
labelWidth={60}
|
|
||||||
name="team_abilities_well"
|
|
||||||
label="What they did Well"
|
|
||||||
/>{" "}
|
|
||||||
</Grid>
|
|
||||||
<Grid item>
|
|
||||||
{" "}
|
|
||||||
<Field
|
|
||||||
type="input"
|
|
||||||
as={TextField}
|
|
||||||
multiline
|
|
||||||
rows={3}
|
|
||||||
rowsMax={7}
|
|
||||||
labelWidth={60}
|
|
||||||
name="team_abilities_struggle"
|
|
||||||
label="What they struggled with"
|
|
||||||
/>{" "}
|
|
||||||
</Grid>
|
|
||||||
<Grid item>
|
|
||||||
{" "}
|
|
||||||
<Field
|
|
||||||
type="input"
|
|
||||||
as={TextField}
|
|
||||||
multiline
|
|
||||||
rows={3}
|
|
||||||
rowsMax={7}
|
|
||||||
labelWidth={60}
|
|
||||||
name="team_abilities_cant"
|
|
||||||
label="What they can't do"
|
|
||||||
/>{" "}
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<div />
|
<div />
|
||||||
<Grid
|
<Grid container direction="row" justifyContent="center" alignItems="flex-end" spacing={3}>
|
||||||
container
|
<Grid item>
|
||||||
direction="row"
|
<Field type="input" as={TextField} multiline rows={3} name="team_abilities_well" label="What they did Well" />
|
||||||
justify="center"
|
</Grid>
|
||||||
alignItems="flex-start"
|
<Grid item>
|
||||||
spacing={3}>
|
<Field type="input" as={TextField} multiline rows={3} name="team_abilities_struggle" label="What they struggled with" />
|
||||||
|
</Grid>
|
||||||
|
<Grid item>
|
||||||
|
<Field type="input" as={TextField} multiline rows={3} name="team_abilities_cant" label="What they can't do" />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<div />
|
||||||
|
<Grid container direction="row" justifyContent="center" alignItems="flex-end" spacing={3}>
|
||||||
<Button type="submit" disabled={isSubmitting}>
|
<Button type="submit" disabled={isSubmitting}>
|
||||||
{" "}
|
Submit
|
||||||
Submit{" "}
|
|
||||||
</Button>
|
</Button>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Form>
|
</Form>
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
.welcome {
|
.welcome {
|
||||||
display: block;
|
display: block;
|
||||||
/* margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto; */
|
margin-right: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.welcome img {
|
.welcome img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import "./WelcomePage.css";
|
|||||||
import "../App.css";
|
import "../App.css";
|
||||||
const WelcomePage = () => {
|
const WelcomePage = () => {
|
||||||
return (
|
return (
|
||||||
<div class = "welcome">
|
<div className="welcome">
|
||||||
<h1>Welcome to Ridgebotics Scouting Web Application 2022</h1>
|
<h1>Welcome to Ridgebotics Scouting Web Application 2022</h1>
|
||||||
<img src = "/WelcomePageImage.webp"/>
|
<img src="/WelcomePageImage.webp" />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
export class ProcessedDataBucket {
|
export class ProcessedDataBucket {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.teamData = null;
|
this.teamData = {};
|
||||||
this.matchData = null;
|
this.matchData = {};
|
||||||
this.updateData = (db) => {
|
this.updateData = (db) => {
|
||||||
|
//reset data
|
||||||
|
this.teamData = {};
|
||||||
|
this.matchData = {};
|
||||||
|
console.log(db);
|
||||||
|
|
||||||
db.allDocs({
|
db.allDocs({
|
||||||
include_docs: true,
|
include_docs: true,
|
||||||
})
|
})
|
||||||
@@ -11,55 +16,94 @@ export class ProcessedDataBucket {
|
|||||||
result.rows.forEach((dbentry) => {
|
result.rows.forEach((dbentry) => {
|
||||||
let doc = dbentry.doc;
|
let doc = dbentry.doc;
|
||||||
console.log(doc);
|
console.log(doc);
|
||||||
//if there's no processed data on a team yet, create a default data entry
|
|
||||||
if (typeof this.teamData[doc.team_name] === "undefined") {
|
// //if there's no processed data on a team yet, create a default data entry
|
||||||
this.teamData[doc.team_name] = {
|
// if (typeof this.teamData[doc.team_number] === "undefined") {
|
||||||
team_name: doc.team_name,
|
// this.teamData[doc.team_number] = {
|
||||||
alliance: doc.alliance,
|
// team_number: doc.team_number,
|
||||||
games_played: 0,
|
// games_played: 0,
|
||||||
climbs_none: 0,
|
// data_sets: {
|
||||||
climbs_low: 0,
|
// upper_hub_auto: [],
|
||||||
climbs_mid: 0,
|
// lower_hub_auto: [],
|
||||||
climbs_high: 0,
|
// upper_hub: [],
|
||||||
climbs_transverse: 0,
|
// lower_hub: [],
|
||||||
points: 0,
|
// match_points: []
|
||||||
point_average: 0,
|
// },
|
||||||
num_disables: 0,
|
// climbs_none: 0,
|
||||||
disables_average: 0,
|
// climbs_low: 0,
|
||||||
num_flips: 0,
|
// climbs_mid: 0,
|
||||||
flips_average: 0,
|
// climbs_high: 0,
|
||||||
fouls: 0,
|
// climbs_transverse: 0,
|
||||||
fouls_average: 0,
|
// points_average: 0,
|
||||||
fouls_tech: 0,
|
// num_disables: 0,
|
||||||
fouls_tech_average: 0,
|
// num_flips: 0,
|
||||||
};
|
// fouls: 0,
|
||||||
}
|
// fouls_tech: 0,
|
||||||
let thisTeamData = this.teamData[doc.team_name];
|
// red_cards: 0,
|
||||||
console.log(thisTeamData);
|
// yellow_cards: 0
|
||||||
let new_team_data = {
|
// };
|
||||||
...thisTeamData,
|
// }
|
||||||
games_played: thisTeamData.games_played + 1,
|
|
||||||
num_climbs: thisTeamData.num_climbs + (doc.climb == true ? 1 : 0),
|
// //add this game's data to the respective team data:
|
||||||
num_disables: thisTeamData.num_disables + (doc.disabled == true ? 1 : 0),
|
// let thisTeamData = this.teamData[doc.team_number];
|
||||||
num_flips: thisTeamData.num_flips + (doc.flipped_over == true ? 1 : 0),
|
// thisTeamData.games_played++;
|
||||||
fouls: thisTeamData.fouls + parseInt(doc.fouls),
|
|
||||||
fouls_tech: thisTeamData.fouls_tech + parseInt(doc.fouls_tech),
|
// let match_points
|
||||||
inner_port: thisTeamData.inner_port + parseInt(doc.inner_port),
|
// = parseInt(doc.taxi_auto)
|
||||||
outer_port: thisTeamData.outer_port + parseInt(doc.outer_port),
|
// + parseInt(doc.upper_hub_auto) * 4
|
||||||
lower_port: thisTeamData.lower_port + parseInt(doc.lower_port),
|
// + parseInt(doc.lower_hub_auto) * 2
|
||||||
};
|
// + parseInt(doc.upper_hub_teleop) * 2
|
||||||
console.log(new_team_data);
|
// + parseInt(doc.lower_hub_teleop) * 1
|
||||||
|
// + (parseInt(doc.climb_level) == 0 ? 4 : 0)
|
||||||
|
// + (parseInt(doc.climb_level) == 1 ? 6 : 0)
|
||||||
|
// + (parseInt(doc.climb_level) == 2 ? 10 : 0)
|
||||||
|
// + (parseInt(doc.climb_level) == 3 ? 15 : 0)
|
||||||
|
// ;
|
||||||
|
|
||||||
|
// //data sets
|
||||||
|
// thisTeamData.data_sets.upper_hub_auto.push(parseInt(doc.upper_hub_auto));
|
||||||
|
// thisTeamData.data_sets.lower_hub_auto.push(parseInt(doc.lower_hub_auto));
|
||||||
|
// thisTeamData.data_sets.upper_hub.push(parseInt(doc.upper_hub));
|
||||||
|
// thisTeamData.data_sets.lower_hub.push(parseInt(doc.lower_hub));
|
||||||
|
// thisTeamData.data_sets.match_points.push(match_points);
|
||||||
|
|
||||||
|
// //climb data
|
||||||
|
// switch (parseInt(doc.climb_level)) {
|
||||||
|
// case 0:
|
||||||
|
// thisTeamData.climbs_none++;
|
||||||
|
// break;
|
||||||
|
// case 1:
|
||||||
|
// thisTeamData.climbs_low++;
|
||||||
|
// break;
|
||||||
|
// case 2:
|
||||||
|
// thisTeamData.climbs_mid++;
|
||||||
|
// break;
|
||||||
|
// case 3:
|
||||||
|
// thisTeamData.climbs_high++;
|
||||||
|
// break;
|
||||||
|
// case 4:
|
||||||
|
// thisTeamData.climbs_transverse++;
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// console.error('Invalid Climb Level (how did this even happen lol?): ' + doc.climb_level);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// //misc data
|
||||||
|
// thisTeamData.num_disables += doc.disabled ? 1 : 0;
|
||||||
|
// thisTeamData.num_flips += doc.flipped ? 1 : 0;
|
||||||
|
// thisTeamData.fouls += parseInt(doc.fouls);
|
||||||
|
// thisTeamData.fouls_tech += parseInt(doc.fouls_tech);
|
||||||
|
// thisTeamData.red_cards += parseInt(doc.red_cards);
|
||||||
|
// thisTeamData.yellow_cards += parseInt(doc.yellow_cards);
|
||||||
|
|
||||||
|
// console.log(thisTeamData);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.log("Error Fetching Docs from Database!");
|
console.log("Error while processing data!");
|
||||||
console.log(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
let datasets = [
|
|
||||||
{
|
|
||||||
data: [],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import React, { useContext, useState } from "react";
|
import React, { useContext, useState } from "react";
|
||||||
import { useLocalDb } from "./DbContext";
|
|
||||||
import { ProcessedDataBucket } from "./ProcessedDataBucket.jsx"
|
import { ProcessedDataBucket } from "./ProcessedDataBucket.jsx"
|
||||||
|
|
||||||
export const ProcessedDataBucketContext = React.createContext();
|
export const ProcessedDataBucketContext = React.createContext();
|
||||||
|
|||||||
@@ -25,16 +25,15 @@ const InputNumberField = (props) => {
|
|||||||
name={props.name}
|
name={props.name}
|
||||||
label={props.label}
|
label={props.label}
|
||||||
InputProps={{
|
InputProps={{
|
||||||
style: { fontSize: 40, "max-width": 300 },
|
style: { fontSize: 40, "maxWidth": 300 },
|
||||||
startAdornment: (
|
startAdornment: (
|
||||||
<InputAdornment position="start">
|
<InputAdornment position="start">
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setFieldValue(props.name, Math.max(parseInt(values[props.name]) - 1, 0));
|
setFieldValue(props.name, Math.max(parseInt(values[props.name]) - 1, 0));
|
||||||
}}
|
}}
|
||||||
iconStyle={{ width: '48px', height: '48px' }}
|
|
||||||
style={{ width: '96px', height: '96px', padding: '24px' }}
|
style={{ width: '96px', height: '96px', padding: '24px' }}
|
||||||
touch={true}
|
touch="true"
|
||||||
>
|
>
|
||||||
<RemoveCircleOutline style={{ fontSize: 50 }} />
|
<RemoveCircleOutline style={{ fontSize: 50 }} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
@@ -46,11 +45,8 @@ const InputNumberField = (props) => {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setFieldValue(props.name, Math.max(parseInt(values[props.name]) + 1, 0));
|
setFieldValue(props.name, Math.max(parseInt(values[props.name]) + 1, 0));
|
||||||
}}
|
}}
|
||||||
iconStyle={{ width: '100px', height: '100px' }}
|
|
||||||
style={{ width: '96px', height: '96px', padding: '0' }}
|
style={{ width: '96px', height: '96px', padding: '0' }}
|
||||||
touch={true}
|
touch="true"
|
||||||
size="large"
|
|
||||||
|
|
||||||
>
|
>
|
||||||
<AddCircleOutline style={{ fontSize: 50 }} />
|
<AddCircleOutline style={{ fontSize: 50 }} />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
.Navigation {
|
||||||
|
position: -webkit-sticky; /*for safari*/
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import React, {Component} from 'react'
|
import React, {Component} from 'react'
|
||||||
import Toolbar from './Toolbar/Toolbar'
|
import Toolbar from './Toolbar/Toolbar'
|
||||||
import SideDrawer from './Drawer/SideDrawer'
|
import SideDrawer from './Drawer/SideDrawer'
|
||||||
|
import './Navigation.css'
|
||||||
|
|
||||||
class Navigation extends Component {
|
class Navigation extends Component {
|
||||||
state = {
|
state = {
|
||||||
@@ -15,7 +16,7 @@ class Navigation extends Component {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="Navigation">
|
||||||
<Toolbar drawerClickHandler={this.drawerToggleClickHandler} />
|
<Toolbar drawerClickHandler={this.drawerToggleClickHandler} />
|
||||||
<SideDrawer show={this.state.sideDrawerOpen} drawerClickHandler={this.drawerToggleClickHandler}/>
|
<SideDrawer show={this.state.sideDrawerOpen} drawerClickHandler={this.drawerToggleClickHandler}/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,63 +1,60 @@
|
|||||||
.toolbar {
|
.toolbar {
|
||||||
position: sticky;
|
width: 100%;
|
||||||
top: 0px;
|
background: #00a65a;
|
||||||
left: 0;
|
height: 56px;
|
||||||
width: 100%;
|
|
||||||
background: #00a65a;
|
|
||||||
height: 56px
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar_navigation {
|
.toolbar_navigation {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 1rem;
|
padding: 0 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar_logo {
|
.toolbar_logo {
|
||||||
margin-left: 0.5rem;
|
margin-left: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar_logo a {
|
.toolbar_logo a {
|
||||||
color: white;
|
color: white;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 2.0rem;
|
font-size: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar_spacer {
|
.toolbar_spacer {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar_items ul {
|
.toolbar_items ul {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0 0;
|
padding: 0 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar_items li {
|
.toolbar_items li {
|
||||||
color: white;
|
color: white;
|
||||||
background-color: #00000000;
|
background-color: #00000000;
|
||||||
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
padding: 0 0.6rem;
|
padding: 0 0.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar_items a {
|
.toolbar_items a {
|
||||||
color: white;
|
color: white;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
padding-top: 0.8rem;
|
padding-top: 0.8rem;
|
||||||
padding-bottom: 0.8rem;
|
padding-bottom: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar_items a:hover,
|
.toolbar_items a:hover,
|
||||||
.toolbar_items a:active {
|
.toolbar_items a:active {
|
||||||
color: #ff3b76;
|
color: #ff3b76;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.toolbar_items {
|
.toolbar_items {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const Toolbar = props => {
|
|||||||
<header className="toolbar">
|
<header className="toolbar">
|
||||||
<nav className="toolbar_navigation">
|
<nav className="toolbar_navigation">
|
||||||
<DrawerButton click={props.drawerClickHandler} />
|
<DrawerButton click={props.drawerClickHandler} />
|
||||||
<div className = "toolbar_logo"><Link to="/">Ridgebotics Scouting</Link></div>
|
<div className = "toolbar_logo"><Link to="/">Ridgebotics Scouting ;)</Link></div>
|
||||||
<div className = "toolbar_spacer" />
|
<div className = "toolbar_spacer" />
|
||||||
<div className = "toolbar_items">
|
<div className = "toolbar_items">
|
||||||
<PagesList />
|
<PagesList />
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
body {
|
body {
|
||||||
background-color: rgb(20, 26, 24);
|
background-color: rgb(20, 26, 24);
|
||||||
color: white;
|
color: white;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
code {
|
||||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
|
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import React from "react";
|
|||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
import reportWebVitals from "./reportWebVitals";
|
import * as serviceWorkerRegistration from './serviceWorkerRegistration';
|
||||||
|
import reportWebVitals from './reportWebVitals';
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
@@ -11,6 +12,11 @@ ReactDOM.render(
|
|||||||
document.getElementById("root")
|
document.getElementById("root")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If you want your app to work offline and load faster, you can change
|
||||||
|
// unregister() to register() below. Note this comes with some pitfalls.
|
||||||
|
// Learn more about service workers: https://cra.link/PWA
|
||||||
|
serviceWorkerRegistration.register();
|
||||||
|
|
||||||
// If you want to start measuring performance in your app, pass a function
|
// If you want to start measuring performance in your app, pass a function
|
||||||
// to log results (for example: reportWebVitals(console.log))
|
// to log results (for example: reportWebVitals(console.log))
|
||||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/* eslint-disable no-restricted-globals */
|
||||||
|
|
||||||
|
// This service worker can be customized!
|
||||||
|
// See https://developers.google.com/web/tools/workbox/modules
|
||||||
|
// for the list of available Workbox modules, or add any other
|
||||||
|
// code you'd like.
|
||||||
|
// You can also remove this file if you'd prefer not to use a
|
||||||
|
// service worker, and the Workbox build step will be skipped.
|
||||||
|
|
||||||
|
import { clientsClaim } from 'workbox-core';
|
||||||
|
import { ExpirationPlugin } from 'workbox-expiration';
|
||||||
|
import { precacheAndRoute, createHandlerBoundToURL } from 'workbox-precaching';
|
||||||
|
import { registerRoute } from 'workbox-routing';
|
||||||
|
import { StaleWhileRevalidate } from 'workbox-strategies';
|
||||||
|
|
||||||
|
clientsClaim();
|
||||||
|
|
||||||
|
// Precache all of the assets generated by your build process.
|
||||||
|
// Their URLs are injected into the manifest variable below.
|
||||||
|
// This variable must be present somewhere in your service worker file,
|
||||||
|
// even if you decide not to use precaching. See https://cra.link/PWA
|
||||||
|
precacheAndRoute(self.__WB_MANIFEST);
|
||||||
|
|
||||||
|
// Set up App Shell-style routing, so that all navigation requests
|
||||||
|
// are fulfilled with your index.html shell. Learn more at
|
||||||
|
// https://developers.google.com/web/fundamentals/architecture/app-shell
|
||||||
|
const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
|
||||||
|
registerRoute(
|
||||||
|
// Return false to exempt requests from being fulfilled by index.html.
|
||||||
|
({ request, url }) => {
|
||||||
|
// If this isn't a navigation, skip.
|
||||||
|
if (request.mode !== 'navigate') {
|
||||||
|
return false;
|
||||||
|
} // If this is a URL that starts with /_, skip.
|
||||||
|
|
||||||
|
if (url.pathname.startsWith('/_')) {
|
||||||
|
return false;
|
||||||
|
} // If this looks like a URL for a resource, because it contains // a file extension, skip.
|
||||||
|
|
||||||
|
if (url.pathname.match(fileExtensionRegexp)) {
|
||||||
|
return false;
|
||||||
|
} // Return true to signal that we want to use the handler.
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
|
||||||
|
);
|
||||||
|
|
||||||
|
// An example runtime caching route for requests that aren't handled by the
|
||||||
|
// precache, in this case same-origin .png requests like those from in public/
|
||||||
|
registerRoute(
|
||||||
|
// Add in any other file extensions or routing criteria as needed.
|
||||||
|
({ url }) => url.origin === self.location.origin && url.pathname.endsWith('.png'), // Customize this strategy as needed, e.g., by changing to CacheFirst.
|
||||||
|
new StaleWhileRevalidate({
|
||||||
|
cacheName: 'images',
|
||||||
|
plugins: [
|
||||||
|
// Ensure that once this runtime cache reaches a maximum size the
|
||||||
|
// least-recently used images are removed.
|
||||||
|
new ExpirationPlugin({ maxEntries: 50 }),
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// This allows the web app to trigger skipWaiting via
|
||||||
|
// registration.waiting.postMessage({type: 'SKIP_WAITING'})
|
||||||
|
self.addEventListener('message', (event) => {
|
||||||
|
if (event.data && event.data.type === 'SKIP_WAITING') {
|
||||||
|
self.skipWaiting();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Any other custom service worker logic can go here.
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
// This optional code is used to register a service worker.
|
||||||
|
// register() is not called by default.
|
||||||
|
|
||||||
|
// This lets the app load faster on subsequent visits in production, and gives
|
||||||
|
// it offline capabilities. However, it also means that developers (and users)
|
||||||
|
// will only see deployed updates on subsequent visits to a page, after all the
|
||||||
|
// existing tabs open on the page have been closed, since previously cached
|
||||||
|
// resources are updated in the background.
|
||||||
|
|
||||||
|
// To learn more about the benefits of this model and instructions on how to
|
||||||
|
// opt-in, read https://cra.link/PWA
|
||||||
|
|
||||||
|
const isLocalhost = Boolean(
|
||||||
|
window.location.hostname === 'localhost' ||
|
||||||
|
// [::1] is the IPv6 localhost address.
|
||||||
|
window.location.hostname === '[::1]' ||
|
||||||
|
// 127.0.0.0/8 are considered localhost for IPv4.
|
||||||
|
window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)
|
||||||
|
);
|
||||||
|
|
||||||
|
export function register(config) {
|
||||||
|
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||||
|
// The URL constructor is available in all browsers that support SW.
|
||||||
|
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
|
||||||
|
if (publicUrl.origin !== window.location.origin) {
|
||||||
|
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||||
|
// from what our page is served on. This might happen if a CDN is used to
|
||||||
|
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('load', () => {
|
||||||
|
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||||
|
|
||||||
|
if (isLocalhost) {
|
||||||
|
// This is running on localhost. Let's check if a service worker still exists or not.
|
||||||
|
checkValidServiceWorker(swUrl, config);
|
||||||
|
|
||||||
|
// Add some additional logging to localhost, pointing developers to the
|
||||||
|
// service worker/PWA documentation.
|
||||||
|
navigator.serviceWorker.ready.then(() => {
|
||||||
|
console.log(
|
||||||
|
'This web app is being served cache-first by a service ' +
|
||||||
|
'worker. To learn more, visit https://cra.link/PWA'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Is not localhost. Just register service worker
|
||||||
|
registerValidSW(swUrl, config);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function registerValidSW(swUrl, config) {
|
||||||
|
navigator.serviceWorker
|
||||||
|
.register(swUrl)
|
||||||
|
.then((registration) => {
|
||||||
|
registration.onupdatefound = () => {
|
||||||
|
const installingWorker = registration.installing;
|
||||||
|
if (installingWorker == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
installingWorker.onstatechange = () => {
|
||||||
|
if (installingWorker.state === 'installed') {
|
||||||
|
if (navigator.serviceWorker.controller) {
|
||||||
|
// At this point, the updated precached content has been fetched,
|
||||||
|
// but the previous service worker will still serve the older
|
||||||
|
// content until all client tabs are closed.
|
||||||
|
console.log(
|
||||||
|
'New content is available and will be used when all ' +
|
||||||
|
'tabs for this page are closed. See https://cra.link/PWA.'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Execute callback
|
||||||
|
if (config && config.onUpdate) {
|
||||||
|
config.onUpdate(registration);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// At this point, everything has been precached.
|
||||||
|
// It's the perfect time to display a
|
||||||
|
// "Content is cached for offline use." message.
|
||||||
|
console.log('Content is cached for offline use.');
|
||||||
|
|
||||||
|
// Execute callback
|
||||||
|
if (config && config.onSuccess) {
|
||||||
|
config.onSuccess(registration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error during service worker registration:', error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkValidServiceWorker(swUrl, config) {
|
||||||
|
// Check if the service worker can be found. If it can't reload the page.
|
||||||
|
fetch(swUrl, {
|
||||||
|
headers: { 'Service-Worker': 'script' },
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
// Ensure service worker exists, and that we really are getting a JS file.
|
||||||
|
const contentType = response.headers.get('content-type');
|
||||||
|
if (
|
||||||
|
response.status === 404 ||
|
||||||
|
(contentType != null && contentType.indexOf('javascript') === -1)
|
||||||
|
) {
|
||||||
|
// No service worker found. Probably a different app. Reload the page.
|
||||||
|
navigator.serviceWorker.ready.then((registration) => {
|
||||||
|
registration.unregister().then(() => {
|
||||||
|
window.location.reload();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Service worker found. Proceed as normal.
|
||||||
|
registerValidSW(swUrl, config);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
console.log('No internet connection found. App is running in offline mode.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function unregister() {
|
||||||
|
if ('serviceWorker' in navigator) {
|
||||||
|
navigator.serviceWorker.ready
|
||||||
|
.then((registration) => {
|
||||||
|
registration.unregister();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(error.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user