diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 19862d1..0000000 --- a/.prettierrc.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "prettier.printWidth": 400, - "prettier.semi": false, - "prettier.singleQuote": true - } - \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index b492849..08c43d5 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,3 @@ { - "prettier.configPath": "${workspaceFolder}/.prettierrc.json" + "prettier.printWidth": 800 } \ No newline at end of file diff --git a/couchdb/data/shards/00000000-7fffffff/testdata.1643440069.couch b/couchdb/data/shards/00000000-7fffffff/testdata.1643440069.couch index d8cf24a..538ad22 100644 Binary files a/couchdb/data/shards/00000000-7fffffff/testdata.1643440069.couch and b/couchdb/data/shards/00000000-7fffffff/testdata.1643440069.couch differ diff --git a/couchdb/data/shards/80000000-ffffffff/testdata.1643440069.couch b/couchdb/data/shards/80000000-ffffffff/testdata.1643440069.couch index f938573..36d9644 100644 Binary files a/couchdb/data/shards/80000000-ffffffff/testdata.1643440069.couch and b/couchdb/data/shards/80000000-ffffffff/testdata.1643440069.couch differ diff --git a/data/certbot/conf/options-ssl-nginx.conf b/data/certbot/conf/options-ssl-nginx.conf new file mode 100644 index 0000000..978e6e8 --- /dev/null +++ b/data/certbot/conf/options-ssl-nginx.conf @@ -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"; diff --git a/data/certbot/conf/ssl-dhparams.pem b/data/certbot/conf/ssl-dhparams.pem new file mode 100644 index 0000000..9b182b7 --- /dev/null +++ b/data/certbot/conf/ssl-dhparams.pem @@ -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----- diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 0c18769..94bd312 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,18 +1,32 @@ version: "3" - + services: scouting-webserver-prod: - container_name: "scouting-webserver-production" + container_name: "production" restart: unless-stopped env_file: - .env - build: + build: context: ./webserver dockerfile: ./Dockerfile.prod expose: - - 80 + - 8080 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: container_name: "scouting-couchdb" restart: unless-stopped @@ -33,4 +47,12 @@ services: volumes: - ./couchdb/db.local.ini:/opt/couchdb/etc/local.ini - ./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 diff --git a/dry_run.sh b/dry_run.sh new file mode 100644 index 0000000..72560a6 --- /dev/null +++ b/dry_run.sh @@ -0,0 +1 @@ +docker-compose run certonly --webroot --webroot-path /var/www/certbot/ --dry-run -d scouting.local \ No newline at end of file diff --git a/init-letsencrypt.sh b/init-letsencrypt.sh new file mode 100644 index 0000000..dbfeebc --- /dev/null +++ b/init-letsencrypt.sh @@ -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 diff --git a/start_prod.sh b/start_prod.sh index 5f61d26..bcbebaf 100644 --- a/start_prod.sh +++ b/start_prod.sh @@ -1 +1 @@ -docker-compose -f docker-compose.prod.yml up -d --build +docker-compose -f docker-compose.prod.yml up -d --build \ No newline at end of file diff --git a/stop.sh b/stop.sh index 685cc77..356959e 100644 --- a/stop.sh +++ b/stop.sh @@ -1 +1 @@ -docker-compose down +docker-compose down --remove-orphans \ No newline at end of file diff --git a/webserver/Dockerfile.prod b/webserver/Dockerfile.prod index 4bd8e3c..d13177c 100644 --- a/webserver/Dockerfile.prod +++ b/webserver/Dockerfile.prod @@ -1,9 +1,12 @@ FROM node:16-alpine as build-step RUN mkdir /app/ +RUN mkdir /app/node_modules +RUN chown -R node:node /app/node_modules +#RUN mkdir /app/node_module/.bin WORKDIR /app/ 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 COPY . ./ # USER node @@ -12,6 +15,7 @@ RUN npm run build FROM nginx:1-alpine COPY --from=build-step /app/build /usr/share/nginx/html RUN rm /etc/nginx/conf.d/default.conf -COPY nginx/nginx.conf /etc/nginx/conf.d -EXPOSE 80 +# COPY nginx/nginx.conf /etc/nginx/conf.d +EXPOSE 8080 +# EXPOSE 443 CMD ["nginx", "-g", "daemon off;"] diff --git a/webserver/nginx/nginx copy.conf b/webserver/nginx/nginx copy.conf new file mode 100644 index 0000000..307fb99 --- /dev/null +++ b/webserver/nginx/nginx copy.conf @@ -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; +; } +; } \ No newline at end of file diff --git a/webserver/nginx/nginx.conf b/webserver/nginx/nginx.conf index 5a3ba9f..713eb15 100644 --- a/webserver/nginx/nginx.conf +++ b/webserver/nginx/nginx.conf @@ -1,13 +1,18 @@ - -server { - 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; - } +events { + worker_connections 4096; ## Default: 1024 } +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; + } + } +} \ No newline at end of file diff --git a/webserver/package.json b/webserver/package.json index 5976d8e..508f78e 100644 --- a/webserver/package.json +++ b/webserver/package.json @@ -19,7 +19,19 @@ "react-scripts": "5.0.0", "web-vitals": "^2.1.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": { diff --git a/webserver/src/App.css b/webserver/src/App.css index f805d9c..3059d89 100644 --- a/webserver/src/App.css +++ b/webserver/src/App.css @@ -1,3 +1,4 @@ .App { - /* height: 100%; */ -} \ No newline at end of file + height: 100%; + width: 100%; +} diff --git a/webserver/src/App.jsx b/webserver/src/App.jsx index 48f54e4..be319a3 100644 --- a/webserver/src/App.jsx +++ b/webserver/src/App.jsx @@ -16,7 +16,7 @@ import NotFoundPage from "./Pages/NotFoundPage"; import DashboardPage from "./Pages/DashboardPage/DashboardPage"; import WelcomePage from "./Pages/WelcomePage"; 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 { TextField, Button, Grid, FormRow, Checkbox, Radio, FormControlLabel, FormControl, FormLabel, RadioGroup, IconButton, InputAdornment } from "@material-ui/core"; import { AddCircleOutline, RemoveCircleOutline } from "@material-ui/icons"; @@ -25,8 +25,7 @@ import { ProcessedDataBucketProvider } from "./ProcessedDataBucketContext"; function App() { - const darkTheme = createMuiTheme({ - + const darkTheme = createTheme({ // Theme settings palette: { type: "dark", @@ -35,18 +34,13 @@ function App() { fontSize: 18 } }); - const styles = { - bigbution: { - - } - } return ( -
- + + - - - + + +
} /> } /> @@ -54,11 +48,11 @@ function App() { } /> } /> - - +
+
-
-
+ + ); } diff --git a/webserver/src/DbContext.jsx b/webserver/src/DbContext.jsx index 7c7a682..c351159 100644 --- a/webserver/src/DbContext.jsx +++ b/webserver/src/DbContext.jsx @@ -14,6 +14,7 @@ export function useRemoteDb() { } export function DbProvider({ children }) { + const pdb = React.useContext(ProcessedDataBucketContext); const [localdb, setLocaldb] = useState(new PouchDB("testdata")); //used in development server 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 .sync(remotedb, { live: true, retry: true, }) .on("change", function (change) { - const pdb = React.useContext(ProcessedDataBucketContext); - console.log(pdb); + console.log('DB CHANGED'); + pdb.updateData(localdb); }) .on("paused", function (info) { }) .on("active", function (info) { }) diff --git a/webserver/src/Pages/InputPage.css b/webserver/src/Pages/InputPage.css index e687414..cd3ccbe 100644 --- a/webserver/src/Pages/InputPage.css +++ b/webserver/src/Pages/InputPage.css @@ -1,13 +1,13 @@ .maxwidth { - display: block; - /* margin-left: auto; - margin-right: auto; */ - width: 100%; - text-align: center; - margin: auto; - max-width: fit-content; - /* max-width: 100% */ + display: block; + margin-left: auto; + margin-right: auto; + width: 100%; + text-align: center; + margin: auto; + max-width: fit-content; + /* max-width: 100% */ } .smallfeild { - max-width: 25%; -} \ No newline at end of file + max-width: 25%; +} diff --git a/webserver/src/Pages/InputPage.jsx b/webserver/src/Pages/InputPage.jsx index 1051fa8..f33d962 100644 --- a/webserver/src/Pages/InputPage.jsx +++ b/webserver/src/Pages/InputPage.jsx @@ -13,6 +13,7 @@ import { Button, Grid, FormRow, + Divider, Checkbox, Radio, FormControlLabel, @@ -26,9 +27,8 @@ import { AddCircleOutline, RemoveCircleOutline } from "@material-ui/icons"; const InputPage = () => { const localdb = useLocalDb(); - console.log(localdb); return ( -
+

{ team_abilities_cant: "", fouls: "0", fouls_tech: "0", - flips: "0", + flipped: false, red_cards: "0", yellow_cards: "0", disabled: false, + taxi_auto: false, upper_hub_auto: "0", lower_hub_auto: "0", - upper_hub: "0", - lower_hub: "0", + upper_hub_teleop: "0", + lower_hub_teleop: "0", climb_level: "", alliance: "", - defence: "" + defence: "0", + disabled: false }} onSubmit={(values, { setSubmitting, resetForm }) => { setTimeout(() => { @@ -82,31 +84,13 @@ const InputPage = () => { handleSubmit, isSubmitting, }) => ( -
- + - {" "} - {" "} + - {" "} - {" "} + @@ -114,25 +98,13 @@ const InputPage = () => { + } label="Red" - /> + } label="Blue" /> @@ -140,118 +112,62 @@ const InputPage = () => { -
- + - + - + - + - {" "} - + - {" "} - {" "} + - {" "} - {" "} + - {" "} + -
- + Climbing + } label="None" /> + } label="Low" /> + } label="Mid" /> + } label="High" /> + } label="Traversal" /> @@ -259,168 +175,77 @@ const InputPage = () => { -
- + - + - {" "} - {" "} + + - {" "} - {" "} + + - + - {" "} - {" "} - - {" "} + - {/* {" "} */} - {" "} + + -
- + Defense - } - label="N/A" + control={} + label="None" /> + {/* */} - } + control={} label="Poor" /> - } + control={} label="Good" - /> - - } + /> } label="Exceptional" /> - - -
- - - {" "} - {" "} - - - {" "} - {" "} - - - {" "} - {" "} + } + label="Disabled" + /> -
- + + + + + + + + + + + +
+ diff --git a/webserver/src/Pages/WelcomePage.css b/webserver/src/Pages/WelcomePage.css index e2cbb0a..46b8e2d 100644 --- a/webserver/src/Pages/WelcomePage.css +++ b/webserver/src/Pages/WelcomePage.css @@ -1,12 +1,12 @@ .welcome { - display: block; - /* margin-left: auto; - margin-right: auto; */ - width: 100%; - text-align: center; - margin: auto; + display: block; + margin-left: auto; + margin-right: auto; + width: 100%; + text-align: center; + margin: auto; } .welcome img { max-width: 100%; -} \ No newline at end of file +} diff --git a/webserver/src/Pages/WelcomePage.jsx b/webserver/src/Pages/WelcomePage.jsx index dacee5a..ed13f66 100644 --- a/webserver/src/Pages/WelcomePage.jsx +++ b/webserver/src/Pages/WelcomePage.jsx @@ -3,9 +3,9 @@ import "./WelcomePage.css"; import "../App.css"; const WelcomePage = () => { return ( -
+

Welcome to Ridgebotics Scouting Web Application 2022

- +
) } diff --git a/webserver/src/ProcessedDataBucket.jsx b/webserver/src/ProcessedDataBucket.jsx index e80226b..9396d51 100644 --- a/webserver/src/ProcessedDataBucket.jsx +++ b/webserver/src/ProcessedDataBucket.jsx @@ -1,8 +1,13 @@ export class ProcessedDataBucket { constructor() { - this.teamData = null; - this.matchData = null; + this.teamData = {}; + this.matchData = {}; this.updateData = (db) => { + //reset data + this.teamData = {}; + this.matchData = {}; + console.log(db); + db.allDocs({ include_docs: true, }) @@ -11,55 +16,94 @@ export class ProcessedDataBucket { result.rows.forEach((dbentry) => { let doc = dbentry.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") { - this.teamData[doc.team_name] = { - team_name: doc.team_name, - alliance: doc.alliance, - games_played: 0, - climbs_none: 0, - climbs_low: 0, - climbs_mid: 0, - climbs_high: 0, - climbs_transverse: 0, - points: 0, - point_average: 0, - num_disables: 0, - disables_average: 0, - num_flips: 0, - flips_average: 0, - fouls: 0, - fouls_average: 0, - fouls_tech: 0, - fouls_tech_average: 0, - }; - } - let thisTeamData = this.teamData[doc.team_name]; - console.log(thisTeamData); - let new_team_data = { - ...thisTeamData, - games_played: thisTeamData.games_played + 1, - num_climbs: thisTeamData.num_climbs + (doc.climb == true ? 1 : 0), - num_disables: thisTeamData.num_disables + (doc.disabled == true ? 1 : 0), - num_flips: thisTeamData.num_flips + (doc.flipped_over == true ? 1 : 0), - fouls: thisTeamData.fouls + parseInt(doc.fouls), - fouls_tech: thisTeamData.fouls_tech + parseInt(doc.fouls_tech), - inner_port: thisTeamData.inner_port + parseInt(doc.inner_port), - outer_port: thisTeamData.outer_port + parseInt(doc.outer_port), - lower_port: thisTeamData.lower_port + parseInt(doc.lower_port), - }; - console.log(new_team_data); + + // //if there's no processed data on a team yet, create a default data entry + // if (typeof this.teamData[doc.team_number] === "undefined") { + // this.teamData[doc.team_number] = { + // team_number: doc.team_number, + // games_played: 0, + // data_sets: { + // upper_hub_auto: [], + // lower_hub_auto: [], + // upper_hub: [], + // lower_hub: [], + // match_points: [] + // }, + // climbs_none: 0, + // climbs_low: 0, + // climbs_mid: 0, + // climbs_high: 0, + // climbs_transverse: 0, + // points_average: 0, + // num_disables: 0, + // num_flips: 0, + // fouls: 0, + // fouls_tech: 0, + // red_cards: 0, + // yellow_cards: 0 + // }; + // } + + // //add this game's data to the respective team data: + // let thisTeamData = this.teamData[doc.team_number]; + // thisTeamData.games_played++; + + // let match_points + // = parseInt(doc.taxi_auto) + // + parseInt(doc.upper_hub_auto) * 4 + // + parseInt(doc.lower_hub_auto) * 2 + // + parseInt(doc.upper_hub_teleop) * 2 + // + 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) => { - console.log("Error Fetching Docs from Database!"); - console.log(err); + console.log("Error while processing data!"); + console.error(err); }); - let datasets = [ - { - data: [], - }, - ]; }; } } \ No newline at end of file diff --git a/webserver/src/ProcessedDataBucketContext.jsx b/webserver/src/ProcessedDataBucketContext.jsx index 5505607..8fcc327 100644 --- a/webserver/src/ProcessedDataBucketContext.jsx +++ b/webserver/src/ProcessedDataBucketContext.jsx @@ -1,5 +1,4 @@ import React, { useContext, useState } from "react"; -import { useLocalDb } from "./DbContext"; import { ProcessedDataBucket } from "./ProcessedDataBucket.jsx" export const ProcessedDataBucketContext = React.createContext(); diff --git a/webserver/src/components/InputNumberField.jsx b/webserver/src/components/InputNumberField.jsx index 09171d8..9136b48 100644 --- a/webserver/src/components/InputNumberField.jsx +++ b/webserver/src/components/InputNumberField.jsx @@ -25,16 +25,15 @@ const InputNumberField = (props) => { name={props.name} label={props.label} InputProps={{ - style: { fontSize: 40, "max-width": 300 }, + style: { fontSize: 40, "maxWidth": 300 }, startAdornment: ( { setFieldValue(props.name, Math.max(parseInt(values[props.name]) - 1, 0)); }} - iconStyle={{ width: '48px', height: '48px' }} style={{ width: '96px', height: '96px', padding: '24px' }} - touch={true} + touch="true" > @@ -46,11 +45,8 @@ const InputNumberField = (props) => { onClick={() => { setFieldValue(props.name, Math.max(parseInt(values[props.name]) + 1, 0)); }} - iconStyle={{ width: '100px', height: '100px' }} style={{ width: '96px', height: '96px', padding: '0' }} - touch={true} - size="large" - + touch="true" > diff --git a/webserver/src/components/Navigation/Navigation.css b/webserver/src/components/Navigation/Navigation.css new file mode 100644 index 0000000..86545cd --- /dev/null +++ b/webserver/src/components/Navigation/Navigation.css @@ -0,0 +1,8 @@ +.Navigation { + position: -webkit-sticky; /*for safari*/ + position: sticky; + top: 0; + left: 0; + width: 100%; + z-index: 1; +} diff --git a/webserver/src/components/Navigation/Navigation.js b/webserver/src/components/Navigation/Navigation.js index fdefe6a..c3481c6 100644 --- a/webserver/src/components/Navigation/Navigation.js +++ b/webserver/src/components/Navigation/Navigation.js @@ -1,6 +1,7 @@ import React, {Component} from 'react' import Toolbar from './Toolbar/Toolbar' import SideDrawer from './Drawer/SideDrawer' +import './Navigation.css' class Navigation extends Component { state = { @@ -15,7 +16,7 @@ class Navigation extends Component { render() { return ( -
+
diff --git a/webserver/src/components/Navigation/Toolbar/Toolbar.css b/webserver/src/components/Navigation/Toolbar/Toolbar.css index 9f7af80..ecb3097 100644 --- a/webserver/src/components/Navigation/Toolbar/Toolbar.css +++ b/webserver/src/components/Navigation/Toolbar/Toolbar.css @@ -1,63 +1,60 @@ .toolbar { - position: sticky; - top: 0px; - left: 0; - width: 100%; - background: #00a65a; - height: 56px + width: 100%; + background: #00a65a; + height: 56px; } .toolbar_navigation { - display: flex; - height: 100%; - align-items: center; - padding: 0 1rem; + display: flex; + height: 100%; + align-items: center; + padding: 0 1rem; } .toolbar_logo { - margin-left: 0.5rem; + margin-left: 0.5rem; } .toolbar_logo a { - color: white; - text-decoration: none; - font-size: 2.0rem; + color: white; + text-decoration: none; + font-size: 2rem; } .toolbar_spacer { - flex: 1; + flex: 1; } .toolbar_items ul { - list-style: none; - margin: 0; - padding: 0 0; - display: flex; + list-style: none; + margin: 0; + padding: 0 0; + display: flex; } .toolbar_items li { - color: white; - background-color: #00000000; - - text-decoration: none; - font-size: 1.5rem; - padding: 0 0.6rem; + color: white; + background-color: #00000000; + + text-decoration: none; + font-size: 1.5rem; + padding: 0 0.6rem; } .toolbar_items a { - color: white; - text-decoration: none; - padding-top: 0.8rem; - padding-bottom: 0.8rem; + color: white; + text-decoration: none; + padding-top: 0.8rem; + padding-bottom: 0.8rem; } .toolbar_items a:hover, .toolbar_items a:active { - color: #ff3b76; + color: #ff3b76; } @media (max-width: 768px) { - .toolbar_items { - display: none; - } -} \ No newline at end of file + .toolbar_items { + display: none; + } +} diff --git a/webserver/src/components/Navigation/Toolbar/Toolbar.js b/webserver/src/components/Navigation/Toolbar/Toolbar.js index 95e74c1..1a9b950 100644 --- a/webserver/src/components/Navigation/Toolbar/Toolbar.js +++ b/webserver/src/components/Navigation/Toolbar/Toolbar.js @@ -10,7 +10,7 @@ const Toolbar = props => {