diff --git a/couchdb/data/shards/00000000-7fffffff/denver_fr.1648095983.couch b/couchdb/data/shards/00000000-7fffffff/denver_fr.1648095983.couch index 6e46507..eca5bfb 100644 Binary files a/couchdb/data/shards/00000000-7fffffff/denver_fr.1648095983.couch and b/couchdb/data/shards/00000000-7fffffff/denver_fr.1648095983.couch differ diff --git a/couchdb/data/shards/00000000-7fffffff/utah_fr.1648095988.couch b/couchdb/data/shards/00000000-7fffffff/utah_fr.1648095988.couch index f9de361..1226d50 100644 Binary files a/couchdb/data/shards/00000000-7fffffff/utah_fr.1648095988.couch and b/couchdb/data/shards/00000000-7fffffff/utah_fr.1648095988.couch differ diff --git a/couchdb/data/shards/80000000-ffffffff/denver_fr.1648095983.couch b/couchdb/data/shards/80000000-ffffffff/denver_fr.1648095983.couch index 7e482ac..7d7fef6 100644 Binary files a/couchdb/data/shards/80000000-ffffffff/denver_fr.1648095983.couch and b/couchdb/data/shards/80000000-ffffffff/denver_fr.1648095983.couch differ diff --git a/couchdb/data/shards/80000000-ffffffff/denver_practice.1648095935.couch b/couchdb/data/shards/80000000-ffffffff/denver_practice.1648095935.couch index 2252b43..7df735a 100644 Binary files a/couchdb/data/shards/80000000-ffffffff/denver_practice.1648095935.couch and b/couchdb/data/shards/80000000-ffffffff/denver_practice.1648095935.couch differ diff --git a/couchdb/data/shards/80000000-ffffffff/utah_fr.1648095988.couch b/couchdb/data/shards/80000000-ffffffff/utah_fr.1648095988.couch index 85c44d9..5129c5f 100644 Binary files a/couchdb/data/shards/80000000-ffffffff/utah_fr.1648095988.couch and b/couchdb/data/shards/80000000-ffffffff/utah_fr.1648095988.couch differ diff --git a/webserver/package.json b/webserver/package.json index 11b9a55..adc926c 100644 --- a/webserver/package.json +++ b/webserver/package.json @@ -14,11 +14,13 @@ "ag-grid-react": "^26.2.0", "formik": "^2.2.9", "pouchdb": "^7.2.2", + "delta-pouch": "^1.0.2", "react": "^17.0.2", "react-dom": "^17.0.2", "react-router": "^6.2.1", "react-router-dom": "^6.2.1", "react-scripts": "5.0.0", + "superagent": "^1.7.2", "web-vitals": "^2.1.3", "@mui/material": "^5.5.0", "@mui/icons-material": "^5.5.0", diff --git a/webserver/src/App.jsx b/webserver/src/App.jsx index 80e6d64..7018e40 100644 --- a/webserver/src/App.jsx +++ b/webserver/src/App.jsx @@ -9,7 +9,11 @@ import "./App.css"; import NotFoundPage from "./Pages/NotFoundPage"; import DashboardPage from "./Pages/DashboardPage/DashboardPage"; import WelcomePage from "./Pages/WelcomePage"; +import SchedulePage from "./Pages/SchedulePage"; import InputPage from "./Pages/InputPage"; +import TeamListPage from "./Pages/TeamListPage"; +import DevPage from "./Pages/DevPage"; +import TeamPage from "./Pages/TeamPage"; import { createTheme, ThemeProvider } from "@mui/material"; import { ProcessedDataBucketProvider } from "./ProcessedDataBucketContext"; import NotesPage from "./Pages/NotesPage"; @@ -35,8 +39,8 @@ function App() { }); return ( - - + +
@@ -45,13 +49,17 @@ function App() { } /> } /> } /> + } /> + } /> + } /> + } /> } /> } />
-
-
+ +
); } diff --git a/webserver/src/DbContext.jsx b/webserver/src/DbContext.jsx index b7beb1a..894a547 100644 --- a/webserver/src/DbContext.jsx +++ b/webserver/src/DbContext.jsx @@ -3,6 +3,8 @@ import React, { useContext, useEffect, useState, useCallback } from "react"; import { useProcessedDataBucket } from "./ProcessedDataBucketContext"; import { getProcessedDataBucket, updateProcessedDataBucket } from "./ProcessedDataBucket"; +PouchDB.plugin(require("delta-pouch")); + const LocalDbContext = React.createContext(); const RemoteDbContext = React.createContext(); @@ -16,32 +18,79 @@ export function useRemoteDb() { export function DbProvider({ children }) { // const pdbCtx = useProcessedDataBucket(); - const { processedDataBucket, setProcessedDataBucket } = useProcessedDataBucket(); + // const { setProcessedDataBucket } = useProcessedDataBucket(); // console.log(pdb); - const [localdb, setLocaldb] = useState(new PouchDB("denver_fr")); + // const [localdb, setLocaldb] = useState(null); + // const [remotedb, setRemotedb] = useState(null); + // useEffect(() => { + // // setDatabaseName("denver_fr", setLocaldb, setRemotedb, setProcessedDataBucket); + // }); + + const [localdb, setLocaldb] = useState(new PouchDB("utah_fr")); const [remotedb, setRemotedb] = useState( - new PouchDB("http://" + window.location.hostname + ":5984/denver_fr", { - skip_setup: true, + new PouchDB("http://" + window.location.hostname + ":5984/utah_fr", { + // skip_setup: true, auth: { username: "scouting", password: "Ridgebotics", }, }) ); - localdb.replicate - .from(remotedb, { + localdb + // .setMaxListeners(400) + .sync(remotedb, { + // localdb + // .sync(remotedb, { live: true, retry: true, - }) - .on("change", (change) => { - updateProcessedDataBucket(localdb, setProcessedDataBucket); }); - // useEffect(()=>{ + // const [syncHandle, setSyncHandle] = useState( + // null + // // localdb + // // // .setMaxListeners(400) + // // .sync(remotedb, { + // // // localdb + // // // .sync(remotedb, { + // // live: true, + // // retry: true, + // // }) + // // .on("complete", (info) => { + // // console.log("REPLICATION CANCELLED"); + // // console.log(info); + // // }) + // ); + // if (syncHandle != null && typeof syncHandle.cancel !== "undefined") syncHandle.cancel(); + + // localdb.on("change", (change) => { + // console.log("CHANGE"); + // updateProcessedDataBucket(localdb, setProcessedDataBucket); + // }); + + // .catch(console.log); + localdb.on("update", console.log); + + useEffect(() => { + // handle.cancel(); + console.log("SYNCSYNCSYNCSYNCSYNC"); + // updateProcessedDataBucket(localdb, setProcessedDataBucket); + // localdb + // // .setMaxListeners(400) + // .sync(remotedb, { + // // localdb + // // .sync(remotedb, { + // live: true, + // retry: true, + // }); + // .on("complete", (info) => { + // console.log("REPLICATION CANCELLED"); + // console.log(info); + // }) + }, [localdb, remotedb]); + + // localdb.replicate.to(remotedb, { + // retry: true, + // }); // updateProcessedDataBucket(localdb, setProcessedDataBucket); - // }, [setProcessedDataBucket]); - // localdb.replicate.to(remotedb, { - // retry: true, - // }); // const [localNotesdb, setLocalNotesdb] = useState(new PouchDB("denver_notes")); // const [remoteNotesdb, setRemoteNotesdb] = useState( @@ -62,7 +111,6 @@ export function DbProvider({ children }) { // // updateProcessedDataBucket(localdb, setProcessedDataBucket); // }); - // updateProcessedDataBucket(localdb, setProcessedDataBucket); // useEffect(() => { // setDatabaseName("denver_fr", setLocaldb, setRemotedb, setProcessedDataBucket); @@ -116,19 +164,18 @@ export function setDatabaseName(name, setLocaldb, setRemotedb, setProcessedDataB password: "Ridgebotics", }, }); - localdb.replicate - .from(remotedb, { - live: true, - retry: true, - }) - .on("change", (change) => { - updateProcessedDataBucket(localdb, setProcessedDataBucket); - }); - updateProcessedDataBucket(localdb, setProcessedDataBucket); - localdb.replicate.to(remotedb, { - live: true, - retry: true, - }); + localdb.sync(remotedb, { + live: true, + retry: true, + }); + // .on("change", (change) => { + // updateProcessedDataBucket(localdb, setProcessedDataBucket); + // }); + // updateProcessedDataBucket(localdb, setProcessedDataBucket); + // localdb.replicate.to(remotedb, { + // live: true, + // retry: true, + // }); setLocaldb(localdb); setRemotedb(remotedb); } diff --git a/webserver/src/Pages/DevPage.jsx b/webserver/src/Pages/DevPage.jsx new file mode 100644 index 0000000..bfec512 --- /dev/null +++ b/webserver/src/Pages/DevPage.jsx @@ -0,0 +1,107 @@ +import React, { useCallback } from "react"; +import { Formik, FastField, Form, useFormikContext } from "formik"; +import { TextField, Button, Grid, FormRow, Divider, Checkbox, Radio, FormControlLabel, FormControl, FormLabel, RadioGroup, IconButton, NotesAdornment, Box } from "@mui/material"; +import { useLocalDb, useRemoteDb } from "../DbContext"; +import { useProcessedDataBucket } from "../ProcessedDataBucketContext"; +import { getProcessedDataBucket, updateProcessedDataBucket } from "../ProcessedDataBucket"; +import Schedule from "../components/Schedule"; +import superagent from "superagent"; + +const DevPage = () => { + let { localdb, setLocaldb } = useLocalDb(); + const putScheduleDoc = useCallback( + (doc) => { + localdb.save({ + $id: "schedule", + type: "schedule", + matches: doc, + }); + }, + [localdb] + ); + const putTeamListDoc = useCallback( + (doc) => { + localdb.save({ + $id: "team_list", + type: "team_list", + teams: doc, + }); + }, + [localdb] + ); + const processScheduleData = (data) => { + data.sort((a, b) => a.predicted_time - b.predicted_time); + let ret = []; + console.log(data); + for (let match of data) { + // console.log(match); + let red = []; + let blue = []; + + for (let team_key of match.alliances.red.team_keys) { + red.push(team_key.substring(3)); + } + for (let team_key of match.alliances.blue.team_keys) { + blue.push(team_key.substring(3)); + } + + ret.push({ + match_id: match.key.split("_")[1], + // ret[match.key.split("_")[1]] = { + // ret["yo"] = { + red: red, + blue: blue, + score_breakdown: match.score_breakdown, + }); + // console.log(match); + } + // console.log(ret); + return ret; + }; + + const processTeamData = (data) => { + data.sort((a, b) => a.key > b.key); + let ret = {}; + for (let team of data) { + ret[team.team_number] = { + nickname: team.nickname, + number: team.team_number, + website: team.website, + }; + } + return ret; + }; + + const updateScheduleDoc = useCallback(() => { + //gets the matches list from the blue alliance api + superagent + .get("https://www.thebluealliance.com/api/v3" + "/event/2022code/matches") + // .get("https://www.thebluealliance.com/api/v3" + "/event/2022utwv/matches") + // .get("https://www.thebluealliance.com/api/v3" + "/event/2022cala/matches") + // .get("https://www.thebluealliance.com/api/v3" + "/events/2022/keys") + .set("X-TBA-Auth-Key", "6aXgVYCAcyy4O7FwCGLqj5ATcima5k25smssLqUuHAHTCvGtCWXX7aoM9xNWfaSm") + .end((err, res) => { + //parse the resulting json and send it to the db + putScheduleDoc(processScheduleData(JSON.parse(res.text))); + }); + superagent + .get("https://www.thebluealliance.com/api/v3" + "/event/2022utwv/teams") + .set("X-TBA-Auth-Key", "6aXgVYCAcyy4O7FwCGLqj5ATcima5k25smssLqUuHAHTCvGtCWXX7aoM9xNWfaSm") + .end((err, res) => { + //parse the resulting json and send it to the db + putTeamListDoc(processTeamData(JSON.parse(res.text))); + }); + }); + + const cleanDB = useCallback(() => { + localdb.cleanup(); + }, [localdb]); + return ( + + + + + ); +}; + +export default DevPage; diff --git a/webserver/src/Pages/InputPage.jsx b/webserver/src/Pages/InputPage.jsx index 13e1775..bb7ceb3 100644 --- a/webserver/src/Pages/InputPage.jsx +++ b/webserver/src/Pages/InputPage.jsx @@ -33,6 +33,7 @@ const InputPage = () => { .put({ // _id: new Date().toISOString(), _id: "match_" + values.match_number + "_team_" + values.team_number, + _rev: new Date().toISOString(), type: "match", ...values, }) diff --git a/webserver/src/Pages/SchedulePage.jsx b/webserver/src/Pages/SchedulePage.jsx new file mode 100644 index 0000000..e1fe2eb --- /dev/null +++ b/webserver/src/Pages/SchedulePage.jsx @@ -0,0 +1,16 @@ +import React, { useCallback } from "react"; +import { Formik, FastField, Form, useFormikContext } from "formik"; +import { TextField, Button, Grid, FormRow, Divider, Checkbox, Radio, FormControlLabel, FormControl, FormLabel, RadioGroup, IconButton, NotesAdornment, Box } from "@mui/material"; +import { useProcessedDataBucket } from "../ProcessedDataBucketContext"; +import { getProcessedDataBucket, updateProcessedDataBucket } from "../ProcessedDataBucket"; +import Schedule from "../components/Schedule"; + +const SchedulePage = () => { + return ( + + + + ); +}; + +export default SchedulePage; diff --git a/webserver/src/Pages/TeamListPage.jsx b/webserver/src/Pages/TeamListPage.jsx new file mode 100644 index 0000000..56c970f --- /dev/null +++ b/webserver/src/Pages/TeamListPage.jsx @@ -0,0 +1,60 @@ +import React, { useCallback, useState, useEffect } from "react"; +import { Formik, FastField, Form, useFormikContext } from "formik"; +import { TextField, Button, Grid, FormRow, Divider, Checkbox, Radio, FormControlLabel, FormControl, FormLabel, RadioGroup, IconButton, NotesAdornment, Box } from "@mui/material"; +import { useProcessedDataBucket } from "../ProcessedDataBucketContext"; +import { getProcessedDataBucket, updateProcessedDataBucket } from "../ProcessedDataBucket"; +import { useLocalDb } from "../DbContext"; +import { Link } from "react-router-dom"; + +const TeamListPage = () => { + let { localdb, setLocaldb } = useLocalDb(); + // let + + let panel_sx = { + display: "flex", + flexDirection: "column", + alignItems: "center", + justifyContent: "center", + bgcolor: "background.paper", + p: 2, + m: 1, + gap: 2, + maxWidth: "fit-content", + borderRadius: "10px", + boxShadow: 7, + }; + const [teamList, setTeamList] = useState(null); + + useEffect(() => { + localdb.all().then((res) => { + // console.log(res["schedule"]); + setTeamList(res["team_list"]); + }); + }, [setTeamList]); + if (teamList == null) return
; + console.log("test"); + console.log(teamList); + + const TeamNumberComponent = (props) => { + return ( + +

{props.number}

+ + ); + }; + + const teamsListComponents = Object.keys(teamList.teams).map((item, index) => { + return ( + + + + ); + }); + + return ( + + {teamsListComponents} + + ); +}; +export default TeamListPage; diff --git a/webserver/src/Pages/TeamPage.jsx b/webserver/src/Pages/TeamPage.jsx new file mode 100644 index 0000000..bca9509 --- /dev/null +++ b/webserver/src/Pages/TeamPage.jsx @@ -0,0 +1,92 @@ +import React, { useCallback, useEffect, useState } from "react"; +import { useLocalDb, useRemoteDb } from "../DbContext"; +import { Formik, FastField, Form, useFormikContext } from "formik"; +import { TextField, Button, Grid, FormRow, Divider, Checkbox, Radio, FormControlLabel, FormControl, FormLabel, RadioGroup, IconButton, NotesAdornment, Box } from "@mui/material"; +import { useProcessedDataBucket } from "../ProcessedDataBucketContext"; +import { getProcessedDataBucket, updateProcessedDataBucket } from "../ProcessedDataBucket"; +import { useLocation } from "react-router-dom"; + +const TeamPage = () => { + let { localdb, setLocaldb } = useLocalDb(); + let { remotedb } = useRemoteDb(); + const location = useLocation(); + const { team } = location.state; + console.log(team); + + let panel_sx = { + display: "flex", + flexDirection: { xs: "column", md: "row" }, + alignItems: { xs: "center", sm: "center" }, + justifyContent: { xs: "flex-start", sm: "center" }, + bgcolor: "background.paper", + p: 2, + m: 1, + gap: 2, + maxWidth: "fit-content", + borderRadius: "10px", + boxShadow: 7, + }; + + const [oldDoc, setOldDoc] = useState(null); + const onSubmit = useCallback( + // (old_doc, new_doc) => { + (values, { setSubmitting, resetForm }) => { + localdb.on("update", console.log); + localdb + .saveChanges(oldDoc, values) + .then((result) => { + alert("Saved Successfully!"); + setSubmitting(false); + }) + .then(localdb.sync(remotedb)) + .catch(console.log); + }, + [localdb, oldDoc] + ); + + useEffect(() => { + localdb.all().then((res) => { + let old_doc = { + $id: team, + weight: "", + drive_train: "", + drive_motors: "", + wheels: "", + climb_level: "", + misc_design: "", + }; + if (typeof res[team] !== "undefined") { + old_doc = { ...res[team] }; + } + setOldDoc(old_doc); + }); + }, [setOldDoc]); + + if (oldDoc == null) return null; + console.log(oldDoc); + return ( +
+ + {({ isSubmitting }) => ( +
+ + + + + + + + + + + +
+ )} +
+
+ ); +}; + +export default TeamPage; diff --git a/webserver/src/ProcessedDataBucket.jsx b/webserver/src/ProcessedDataBucket.jsx index 8942982..6a1ff46 100644 --- a/webserver/src/ProcessedDataBucket.jsx +++ b/webserver/src/ProcessedDataBucket.jsx @@ -1,87 +1,100 @@ +const processSchedule = (doc) => {}; + +const createDefaultTeamData = (doc, teamData) => { + //if there's no processed data on a team yet, create a default data entry + if (typeof teamData[doc.team_number] === "undefined") { + teamData[doc.team_number] = { + team_number: doc.team_number, + matches_played: 0, + notes: [], + data_sets: { + upper_hub_auto: [], + lower_hub_auto: [], + upper_hub_teleop: [], + lower_hub_teleop: [], + auto_points: [], + teleop_hub_points: [], + climb_points: [], + total_match_points: [], + }, + climb_counts: [0, 0, 0, 0, 0], + average_auto_points: 0, + average_teleop_hub_points: 0, + average_climb_points: 0, + average_total_match_points: 0, + num_disables: 0, + num_flips: 0, + fouls: 0, + fouls_tech: 0, + red_cards: 0, + yellow_cards: 0, + }; + } +}; + +const processMatch = (doc, thisTeamData) => { + console.log("MATCH: " + doc._id); + //add this game's data to the respective team data: + thisTeamData.matches_played++; + + let auto_points = (parseInt(doc.taxi_auto) ? 2 : 0) + parseInt(doc.upper_hub_auto) * 4 + parseInt(doc.lower_hub_auto) * 2; + let teleop_hub_points = parseInt(doc.upper_hub_teleop) * 2 + parseInt(doc.lower_hub_teleop) * 1; + let climb_points = (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); + let total_match_points = auto_points + teleop_hub_points + climb_points; + //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_teleop.push(parseInt(doc.upper_hub_teleop)); + thisTeamData.data_sets.lower_hub_teleop.push(parseInt(doc.lower_hub_teleop)); + thisTeamData.data_sets.auto_points.push(auto_points); + thisTeamData.data_sets.teleop_hub_points.push(teleop_hub_points); + thisTeamData.data_sets.climb_points.push(climb_points); + thisTeamData.data_sets.total_match_points.push(total_match_points); + + //climb data + thisTeamData.climb_counts[parseInt(doc.climb_level)]++; + + //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); + + //sum of all points in the match points data set for this team + //function for getting the sum of an array, use in reduce function of array + const sum = (accum, current) => accum + current; + thisTeamData.average_auto_points = thisTeamData.data_sets.auto_points.reduce(sum, 0) / thisTeamData.matches_played; + thisTeamData.average_teleop_hub_points = thisTeamData.data_sets.teleop_hub_points.reduce(sum, 0) / thisTeamData.matches_played; + thisTeamData.average_climb_points = thisTeamData.data_sets.climb_points.reduce(sum, 0) / thisTeamData.matches_played; + thisTeamData.average_total_match_points = thisTeamData.data_sets.total_match_points.reduce(sum, 0) / thisTeamData.matches_played; +}; + export function updateProcessedDataBucket(db, setProcessedDataBucket) { + console.log("updating pdb"); return db - .allDocs({ - include_docs: true, - }) + .all() .then((result) => { + // console.log("TESTH"); + // console.log(result); //reset data let teamData = {}; let matchData = {}; - result.rows.forEach((dbentry) => { - let doc = dbentry.doc; - - //if there's no processed data on a team yet, create a default data entry - if (typeof teamData[doc.team_number] === "undefined") { - teamData[doc.team_number] = { - team_number: doc.team_number, - matches_played: 0, - notes: [], - data_sets: { - upper_hub_auto: [], - lower_hub_auto: [], - upper_hub_teleop: [], - lower_hub_teleop: [], - auto_points: [], - teleop_hub_points: [], - climb_points: [], - total_match_points: [], - }, - climb_counts: [0, 0, 0, 0, 0], - average_auto_points: 0, - average_teleop_hub_points: 0, - average_climb_points: 0, - average_total_match_points: 0, - num_disables: 0, - num_flips: 0, - fouls: 0, - fouls_tech: 0, - red_cards: 0, - yellow_cards: 0, - }; + Object.values(result).forEach((doc) => { + // console.log(doc); + if (doc.type === "schedule") { + return; } let thisTeamData = teamData[doc.team_number]; - if (doc.type === "match") - { - console.log("MATCH: " + doc._id) - //add this game's data to the respective team data: - thisTeamData.matches_played++; - - let auto_points = (parseInt(doc.taxi_auto) ? 2 : 0) + parseInt(doc.upper_hub_auto) * 4 + parseInt(doc.lower_hub_auto) * 2; - let teleop_hub_points = parseInt(doc.upper_hub_teleop) * 2 + parseInt(doc.lower_hub_teleop) * 1; - let climb_points = (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); - let total_match_points = auto_points + teleop_hub_points + climb_points; - //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_teleop.push(parseInt(doc.upper_hub_teleop)); - thisTeamData.data_sets.lower_hub_teleop.push(parseInt(doc.lower_hub_teleop)); - thisTeamData.data_sets.auto_points.push(auto_points); - thisTeamData.data_sets.teleop_hub_points.push(teleop_hub_points); - thisTeamData.data_sets.climb_points.push(climb_points); - thisTeamData.data_sets.total_match_points.push(total_match_points); - - //climb data - thisTeamData.climb_counts[parseInt(doc.climb_level)]++; - - //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); - - //sum of all points in the match points data set for this team - //function for getting the sum of an array, use in reduce function of array - const sum = (accum, current) => accum + current; - thisTeamData.average_auto_points = thisTeamData.data_sets.auto_points.reduce(sum, 0) / thisTeamData.matches_played; - thisTeamData.average_teleop_hub_points = thisTeamData.data_sets.teleop_hub_points.reduce(sum, 0) / thisTeamData.matches_played; - thisTeamData.average_climb_points = thisTeamData.data_sets.climb_points.reduce(sum, 0) / thisTeamData.matches_played; - thisTeamData.average_total_match_points = thisTeamData.data_sets.total_match_points.reduce(sum, 0) / thisTeamData.matches_played; - } else if (doc.type === "notes") { - console.log("NOTES: " + doc._id) + if (doc.type === "match") { + createDefaultTeamData(doc, teamData); + processMatch(doc, thisTeamData); + } + if (doc.type === "notes") { + createDefaultTeamData(doc, teamData); thisTeamData.notes.push(doc.notes); } }); diff --git a/webserver/src/ProcessedDataBucketContext.jsx b/webserver/src/ProcessedDataBucketContext.jsx index 27cd43c..6650795 100644 --- a/webserver/src/ProcessedDataBucketContext.jsx +++ b/webserver/src/ProcessedDataBucketContext.jsx @@ -1,5 +1,7 @@ import React, { useContext, useState } from "react"; +import { useLocalDb } from "./DbContext.jsx"; import { ProcessedDataBucket } from "./ProcessedDataBucket.jsx"; +import { getProcessedDataBucket, updateProcessedDataBucket } from "./ProcessedDataBucket"; export const ProcessedDataBucketContext = React.createContext(); export function useProcessedDataBucket() { @@ -8,6 +10,10 @@ export function useProcessedDataBucket() { export function ProcessedDataBucketProvider({ children }) { //create the processed data bucket object + const { localdb } = useLocalDb(); const [processedDataBucket, setProcessedDataBucket] = useState(null); + localdb.on("change", (change) => { + updateProcessedDataBucket(localdb, setProcessedDataBucket); + }); return {children}; } diff --git a/webserver/src/components/DbChooser.jsx b/webserver/src/components/DbChooser.jsx index ecbe8a0..330a1ff 100644 --- a/webserver/src/components/DbChooser.jsx +++ b/webserver/src/components/DbChooser.jsx @@ -9,11 +9,11 @@ const DbChooser = (props) => { const { processedDataBucket, setProcessedDataBucket } = useProcessedDataBucket(); const [dbname, setDbName] = React.useState(localdb.name); - - const sync = useCallback(()=>{ + + const sync = useCallback(() => { localdb.sync(remotedb, { // live:true, - retry:true + retry: true, }); }, [localdb, remotedb]); @@ -25,21 +25,19 @@ const DbChooser = (props) => { }); return (
- + {/* Database - - + + */}
); }; diff --git a/webserver/src/components/Navigation/PagesList.js b/webserver/src/components/Navigation/PagesList.js index 83de8de..fb260ad 100644 --- a/webserver/src/components/Navigation/PagesList.js +++ b/webserver/src/components/Navigation/PagesList.js @@ -6,7 +6,9 @@ const PagesList = props => { ) } diff --git a/webserver/src/components/Schedule.jsx b/webserver/src/components/Schedule.jsx new file mode 100644 index 0000000..7ba0a88 --- /dev/null +++ b/webserver/src/components/Schedule.jsx @@ -0,0 +1,95 @@ +import React, { useState, useCallback, useEffect } from "react"; +import { Link } from "react-router-dom"; +import { Formik, FastField, Form, useFormikContext } from "formik"; +import { TextField, Button, Grid, FormRow, Divider, Checkbox, Radio, FormControlLabel, FormControl, FormLabel, RadioGroup, IconButton, NotesAdornment, Box } from "@mui/material"; +import { useLocalDb, useRemoteDb } from "../DbContext"; +import { useProcessedDataBucket } from "../ProcessedDataBucketContext"; + +const Schedule = (props) => { + let { localdb, setLocaldb } = useLocalDb(); + // let + + let panel_sx = { + display: "flex", + flexDirection: "row", + alignItems: { xs: "center", sm: "center" }, + justifyContent: { xs: "flex-start", sm: "center" }, + bgcolor: "background.paper", + p: 2, + m: 1, + gap: 2, + maxWidth: "fit-content", + borderRadius: "10px", + boxShadow: 7, + }; + const [schedule, setSchedule] = useState(null); + + useEffect(() => { + localdb.all().then((res) => { + // console.log(res["schedule"]); + setSchedule(res["schedule"]); + }); + }, [setSchedule]); + if (schedule == null) return
; + + const TeamNumberComponent = (props) => { + return ( + +

{props.number}

+ + ); + }; + + const scheduleList = schedule.matches.map((item, index) => { + // console.log(item); + return ( + +

{item.match_id}

+ + + + + + + {/*
  • */} + + + + + + ); + }); + return {scheduleList}; + // console.log(schedule); + + // superagent + // .get("https://www.thebluealliance.com/api/v3" + "/event/2022code/matches") + // .set("X-TBA-Auth-Key", "6aXgVYCAcyy4O7FwCGLqj5ATcima5k25smssLqUuHAHTCvGtCWXX7aoM9xNWfaSm") + // .end((err, res) => { + // console.log(JSON.parse(res.text)); + // }); + + // const { values, submitForm } = useFormikContext(); + // const { processedDataBucket, setProcessedDataBucket } = useProcessedDataBucket(); + // if (processedDataBucket == null) { + // return null; + // } + + // // console.log(values); + // if (typeof processedDataBucket.teamData[values.team_number] === "undefined") { + // return null; + // } else { + // // let notesList = processedDataBucket.teamData[values.team_number].notes; + // let notesList = processedDataBucket.teamData[values.team_number].notes; + // // let notesComponents = notesList.map((item, index)=>{ + // return notesList.map((item, index) => { + // return

    {item}

    ; + // }); + // // return ( + // // //

    {processedDataBucket.teamData[values.team_number].Name

    + // // {notesComponents} + // // ) + // } +}; + +export default Schedule;