From 54b3353a0bdd2dfef50ec69ecb42bc81230481f4 Mon Sep 17 00:00:00 2001 From: Aquaticholic Date: Wed, 2 Feb 2022 05:37:10 +0000 Subject: [PATCH] AAAAAAAAAAAAGH --- .prettierrc.json | 6 - .vscode/settings.json | 2 +- .../testdata.1643440069.couch | Bin 221386 -> 659658 bytes .../testdata.1643440069.couch | Bin 135373 -> 422093 bytes data/certbot/conf/options-ssl-nginx.conf | 14 + data/certbot/conf/ssl-dhparams.pem | 8 + docker-compose.prod.yml | 34 +- dry_run.sh | 1 + init-letsencrypt.sh | 80 +++++ start_prod.sh | 2 +- stop.sh | 2 +- webserver/Dockerfile.prod | 12 +- webserver/nginx/nginx copy.conf | 42 +++ webserver/nginx/nginx.conf | 29 +- webserver/package.json | 14 +- webserver/src/App.css | 5 +- webserver/src/App.jsx | 28 +- webserver/src/DbContext.jsx | 16 +- webserver/src/Pages/InputPage.css | 20 +- webserver/src/Pages/InputPage.jsx | 301 ++++-------------- webserver/src/Pages/WelcomePage.css | 14 +- webserver/src/Pages/WelcomePage.jsx | 4 +- webserver/src/ProcessedDataBucket.jsx | 138 +++++--- webserver/src/ProcessedDataBucketContext.jsx | 1 - webserver/src/components/InputNumberField.jsx | 10 +- .../src/components/Navigation/Navigation.css | 8 + .../src/components/Navigation/Navigation.js | 3 +- .../components/Navigation/Toolbar/Toolbar.css | 65 ++-- .../components/Navigation/Toolbar/Toolbar.js | 2 +- webserver/src/index.css | 17 +- webserver/src/index.js | 8 +- webserver/src/service-worker.js | 72 +++++ webserver/src/serviceWorkerRegistration.js | 137 ++++++++ 33 files changed, 675 insertions(+), 420 deletions(-) delete mode 100644 .prettierrc.json create mode 100644 data/certbot/conf/options-ssl-nginx.conf create mode 100644 data/certbot/conf/ssl-dhparams.pem create mode 100644 dry_run.sh create mode 100644 init-letsencrypt.sh create mode 100644 webserver/nginx/nginx copy.conf create mode 100644 webserver/src/components/Navigation/Navigation.css create mode 100644 webserver/src/service-worker.js create mode 100644 webserver/src/serviceWorkerRegistration.js 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 d8cf24a136908c9ffefddccd9322a08e759241f3..538ad22a078c988225fbaf7f9311c0af0401ed1e 100644 GIT binary patch literal 659658 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 + 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 => {