diff --git a/apps/scouting/frontend/src/App.tsx b/apps/scouting/frontend/src/App.tsx index 7ab9ff9..59ae0d0 100644 --- a/apps/scouting/frontend/src/App.tsx +++ b/apps/scouting/frontend/src/App.tsx @@ -4,16 +4,18 @@ import { ScoutMatch } from "./scouter/pages/ScoutMatch"; import { Route, Routes } from "react-router-dom"; import { ScoutedMatches } from "./scouter/pages/ScoutedMatches"; import { TeamTab } from "./strategy/components/TeamTab"; +import { MatchForecast } from "./strategy/components/forecast/MatchForecast"; import { GeneralDataTable } from "./strategy/GeneralDataTable"; import { CompareTwo } from "./strategy/CompareTwo"; const App: FC = () => { return ( + } /> } /> } /> } /> - } /> + } /> } /> ); diff --git a/apps/scouting/frontend/src/strategy/components/forecast/CenterStat.tsx b/apps/scouting/frontend/src/strategy/components/forecast/CenterStat.tsx new file mode 100644 index 0000000..d8c24ac --- /dev/null +++ b/apps/scouting/frontend/src/strategy/components/forecast/CenterStat.tsx @@ -0,0 +1,40 @@ +// בס"ד + +import type { FC } from "react"; + +interface CenterStatProps { + label: string; + red: number; + blue: number; +} + +const DECIMAL_DIGIT_AMOUNT = 0; + +export const CenterStat: FC = ({ + label, + red, + blue, +}) => ( +
+ {/* Red Value */} +
+ + {red.toFixed(DECIMAL_DIGIT_AMOUNT)} + +
+ + {/* Center Label Pill */} +
+ + {label} + +
+ + {/* Blue Value */} +
+ + {blue.toFixed(DECIMAL_DIGIT_AMOUNT)} + +
+
+); diff --git a/apps/scouting/frontend/src/strategy/components/forecast/MatchForecast.tsx b/apps/scouting/frontend/src/strategy/components/forecast/MatchForecast.tsx new file mode 100644 index 0000000..a7eee5d --- /dev/null +++ b/apps/scouting/frontend/src/strategy/components/forecast/MatchForecast.tsx @@ -0,0 +1,136 @@ +// בס"ד +import { useEffect, useState, type FC } from "react"; +import type { Forecast } from "@repo/scouting_types"; +import { CenterStat } from "./CenterStat"; +import { StatRow } from "./StatRow"; + +interface Alliances { + redAlliance: [number, number, number]; + blueAlliance: [number, number, number]; +} + +const querifyAlliances = (alliances: Alliances) => { + const params = new URLSearchParams(); + alliances.redAlliance.forEach((team) => { + params.append("redAlliance", team.toString()); + }); + alliances.blueAlliance.forEach((team) => { + params.append("blueAlliance", team.toString()); + }); + return params; +}; + +export const MatchForecast: FC = () => { + const [forecast, setForecast] = useState(); + const [alliances, _setAlliances] = useState(); + + const updateForecast = async () => { + if (!alliances) { + return; + } + + const query = querifyAlliances(alliances); + try { + const response = await fetch(`/api/v1/forecast?${query.toString()}`); + if (!response.ok) { + const errorText = await response.text(); + throw new Error(`Bad Response: ${errorText}`); + } + const fetchedForecast: Forecast = await response.json(); + setForecast(fetchedForecast); + } catch (error: unknown) { + alert(error); + } + }; + useEffect(() => { + void updateForecast(); + }, [alliances]); + + const redData = forecast?.allianceData.redAlliance; + const blueData = forecast?.allianceData.blueAlliance; + + return ( +
+
+
+ + {alliances?.redAlliance.join(", ")} + +
+
+
+ Prediction +
+ VS +
+
+ + {alliances?.blueAlliance.join(", ")} + +
+
+ + {/* Stats Grid */} + {redData && blueData && ( +
+ {/* Fuel Section */} + + + {/* Detailed Breakdown */} +
+
+
+

+ Details +

+
+
+ +
+
+
+
+ Auto +
+
+
+ + + +
+
+
+ Tele +
+
+
+ + + +
+
+
+ )} +
+ ); +}; diff --git a/apps/scouting/frontend/src/strategy/components/forecast/StatRow.tsx b/apps/scouting/frontend/src/strategy/components/forecast/StatRow.tsx new file mode 100644 index 0000000..674c035 --- /dev/null +++ b/apps/scouting/frontend/src/strategy/components/forecast/StatRow.tsx @@ -0,0 +1,33 @@ +// בס"ד + +import type { FC } from "react"; + +interface StatRowProps { + red: number; + blue: number; +} + +export const StatRow: FC = ({ red, blue }) => { + const isRedLeading = red > blue; + return ( +
+
+
+ {red} +
+
+ {`${isRedLeading ? "Red" : "Blue"} Wins`} +
+
+ {blue} +
+
+
+ ); +};