Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions components/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default function Avatar(props: {
>
<img
src={image}
alt={"Avatar"}
onClick={props.onClick}
></img>
</div>
Expand Down
2 changes: 1 addition & 1 deletion components/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export default function Container(props: ContainerProps) {
};

loadSelectedSeasons();
}, [selectedTeamIndex, teams]);
}, [selectedTeamIndex, teams, selectedTeam]);

let showAuthBlock = false;
if (props.requireAuthentication) {
Expand Down
5 changes: 3 additions & 2 deletions components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export default function Footer() {
<img
src="/art/4026Bench.svg"
className="w-32"
alt="4026 Bench"
></img>
<p className="text-lg">
Made with <span className="">❤️</span> by{" "}
Expand Down Expand Up @@ -181,7 +182,7 @@ export default function Footer() {
src="/statbotics.webp"
width="15"
height="25"
alt="tba"
alt="Statbotics Logo"
className="mr-6"
/>
Statbotics
Expand All @@ -195,7 +196,7 @@ export default function Footer() {
src="/FIRST.png"
width="90"
height="25"
alt="tba"
alt="FIRST Logo"
/>
</Link>
</div>
Expand Down
1 change: 1 addition & 0 deletions components/UpdateModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ function News() {
<img
src="/art/BrokenRobot.svg"
className="w-1/2"
alt="Broken Robot"
></img>
</Flex>
<h3 className="font-bold text-lg">Whats New?</h3>
Expand Down
2 changes: 1 addition & 1 deletion components/competition/PitScoutingCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default function PitScoutingCard(props: {
<div className="absolute rounded z-10 translate-y-4 flex justify-center items-center">
{report.submitted ? (
<img
alt="img"
alt={`Team ${report.teamNumber}'s robot`}
src={report.data?.image}
loading="lazy"
style={{ imageResolution: "72dpi" }}
Expand Down
23 changes: 14 additions & 9 deletions components/forms/FieldPositionSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,32 @@ const Sketch = dynamic(() => import("react-p5").then((mod) => mod.default), {
let bg: p5Types.Image;
let dropped = false;

export default function FieldPositionSelector(props: {
export default function FieldPositionSelector({
alliance,
fieldImagePrefix,
initialPos,
callback,
}: {
alliance: AllianceColor;
fieldImagePrefix: string;
initialPos: FieldPos;
callback: (key: string, value: FieldPos) => void;
}) {
const [mx, setMx, getMx] = useDynamicState(props.initialPos?.x ?? 0);
const [my, setMy, getMy] = useDynamicState(props.initialPos?.y ?? 0);
const [a, setA, getA] = useDynamicState(props.initialPos?.angle ?? 0);
const [mx, setMx, getMx] = useDynamicState(initialPos?.x ?? 0);
const [my, setMy, getMy] = useDynamicState(initialPos?.y ?? 0);
const [a, setA, getA] = useDynamicState(initialPos?.angle ?? 0);
const [ax, setAx] = useState(0);
const [ay, setAy] = useState(0);

useEffect(() => {
props.callback("AutoStart", { x: mx ?? 0, y: my ?? 0, angle: a ?? 0 });
}, [mx, my, a, ax, ay]);
callback("AutoStart", { x: mx ?? 0, y: my ?? 0, angle: a ?? 0 });
}, [mx, my, a, ax, ay, callback]);

const setup = (p5: p5Types, canvasParentRef: Element) => {
bg = p5.loadImage(
props.alliance === AllianceColor.Blue
? `/fields/${props.fieldImagePrefix}Blue.png`
: `/fields/${props.fieldImagePrefix}Red.png`,
alliance === AllianceColor.Blue
? `/fields/${fieldImagePrefix}Blue.png`
: `/fields/${fieldImagePrefix}Red.png`,
);

const ctx = p5.createCanvas(350, 300).parent(canvasParentRef);
Expand Down
8 changes: 4 additions & 4 deletions components/forms/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ export default function Form(props: FormProps) {
);
}

const sync = async () => {
const sync = useCallback(async () => {
setSyncing(true);
await api.updateReport({ data: formData }, props.report?._id!);
setSyncing(false);
};
}, [formData, props.report?._id]);

const setCallback = useCallback(
(key: any, value: boolean | string | number | object) => {
Expand All @@ -79,7 +79,7 @@ export default function Form(props: FormProps) {
return copy;
});
},
[],
[sync],
);

useCallback(() => {
Expand All @@ -91,7 +91,7 @@ export default function Form(props: FormProps) {
}

setFormData(formData);
}, [props.report?.data]);
}, [formData, setCallback]);

function elementToNode(element: FormElement<QuantData>) {
const key = element.key as string;
Expand Down
1 change: 1 addition & 0 deletions components/forms/ImageUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export default function ImageUpload(props: {
<img
src={imageUrl}
className="w-64 h-64 rounded-lg"
alt="Uploaded robot image"
></img>
)}
{uploadProgress > 0 ? (
Expand Down
115 changes: 65 additions & 50 deletions components/stats/Picklist.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DbPicklist, Report } from "@/lib/Types";

import { useDrag, useDrop } from "react-dnd";
import { ChangeEvent, useEffect, useState } from "react";
import { ChangeEvent, useCallback, useEffect, useState } from "react";
import { FaArrowDown, FaArrowUp, FaPlus } from "react-icons/fa";
import ClientApi from "@/lib/api/ClientApi";

Expand Down Expand Up @@ -225,61 +225,69 @@ export default function PicklistScreen(props: {

const teams = props.teams.map((team) => ({ number: team }));

function savePicklists(picklists: Picklist[]) {
const picklistDict = picklists.reduce<DbPicklist>(
(acc, picklist) => {
acc.picklists[picklist.name] = picklist.teams.map(
(team) => team.number,
);
return acc;
},
{
_id: props.picklist._id,
picklists: {},
},
);

api.updatePicklist(picklistDict);
}
const savePicklists = useCallback(
(picklists: Picklist[]) => {
const picklistDict = picklists.reduce<DbPicklist>(
(acc, picklist) => {
acc.picklists[picklist.name] = picklist.teams.map(
(team) => team.number,
);
return acc;
},
{
_id: props.picklist._id,
picklists: {},
},
);

api.updatePicklist(picklistDict);
},
[props.picklist._id],
);

function updatePicklist(picklist: Picklist) {
setPicklists((old) => {
const newPicklists = old.map((p) => {
if (p.index === picklist.index) {
return picklist;
} else {
return p;
}
const updatePicklist = useCallback(
(picklist: Picklist) => {
setPicklists((old) => {
const newPicklists = old.map((p) => {
if (p.index === picklist.index) {
return picklist;
} else {
return p;
}
});

savePicklists(newPicklists);
return newPicklists;
});
},
[setPicklists, savePicklists],
);

savePicklists(newPicklists);
return newPicklists;
});
}

function loadDbPicklist(picklistDict: DbPicklist) {
setPicklists(
Object.entries(picklistDict.picklists).map((picklist, index) => {
const newPicklist: Picklist = {
index,
name: picklist[0],
teams: picklist[1].map((team: number) => ({ number: team })),
update: updatePicklist,
};

for (const team of newPicklist.teams) {
team.picklistIndex = newPicklist.index;
}

return newPicklist;
}),
);
}
const loadDbPicklist = useCallback(
(picklistDict: DbPicklist) => {
setPicklists(
Object.entries(picklistDict.picklists).map((picklist, index) => {
const newPicklist: Picklist = {
index,
name: picklist[0],
teams: picklist[1].map((team: number) => ({ number: team })),
update: updatePicklist,
};

for (const team of newPicklist.teams) {
team.picklistIndex = newPicklist.index;
}

return newPicklist;
}),
);
},
[updatePicklist],
);

useEffect(() => {
if (loadingPicklists !== LoadState.NotLoaded) return;

console.log(props);
setLoadingPicklists(LoadState.Loading);
api.getPicklist(props.picklist?._id).then((picklist) => {
if (picklist) {
Expand All @@ -289,7 +297,14 @@ export default function PicklistScreen(props: {
loadDbPicklist(props.picklist);

setLoadingPicklists(LoadState.Loaded);
});
}, [
loadingPicklists,
LoadState.NotLoaded,
LoadState.Loading,
LoadState.Loaded,
props.picklist,
loadDbPicklist,
]);

const addPicklist = () => {
const newPicklist: Picklist = {
Expand Down
2 changes: 1 addition & 1 deletion components/stats/SmallGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export default function SmallGraph(props: {
);
});
}
}, [key]);
}, [key, currentTeam, datapoints, props.selectedReports, props.team]);

if (!props.selectedReports) {
return <></>;
Expand Down
44 changes: 20 additions & 24 deletions components/stats/TeamPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,26 @@ export default function TeamPage(props: {

const game = games[props.gameId];

const associateTeams = () => {
useEffect(() => {
const subjectiveReports: typeof teamSubjectiveReports = {};
props.subjectiveReports.forEach((subjectiveReport) => {
for (const teamNumber of Object.keys(subjectiveReport.robotComments)) {
if (!Object.keys(subjectiveReports).includes(teamNumber)) {
subjectiveReports[Number(teamNumber)] = [subjectiveReport];
} else {
subjectiveReports[Number(teamNumber)].push(subjectiveReport);
}
}
});
setTeamSubjectiveReports(subjectiveReports);
}, [props.subjectiveReports]);

const pointTotals = reports.map((report) => game.getAvgPoints([report]));
const avgPoints = game.getAvgPoints(reports);
const stDev = StandardDeviation(pointTotals);

useEffect(() => {
console.log("Associating teams...");
const newTeamReports: typeof teamReports = {};
reports.forEach((report) => {
if (!(report.robotNumber in newTeamReports)) {
Expand Down Expand Up @@ -179,29 +198,6 @@ export default function TeamPage(props: {
}
});
setTeamSubjectiveReports(subjectiveReports);
};

useEffect(() => {
const subjectiveReports: typeof teamSubjectiveReports = {};
props.subjectiveReports.forEach((subjectiveReport) => {
for (const teamNumber of Object.keys(subjectiveReport.robotComments)) {
if (!Object.keys(subjectiveReports).includes(teamNumber)) {
subjectiveReports[Number(teamNumber)] = [subjectiveReport];
} else {
subjectiveReports[Number(teamNumber)].push(subjectiveReport);
}
}
});
setTeamSubjectiveReports(subjectiveReports);
}, [props.subjectiveReports]);

const pointTotals = reports.map((report) => game.getAvgPoints([report]));
const avgPoints = game.getAvgPoints(reports);
const stDev = StandardDeviation(pointTotals);

useEffect(() => {
console.log("Associating teams...");
associateTeams();
}, [reports, props.pitReports, props.subjectiveReports]);

// Associate pit reports
Expand Down
15 changes: 8 additions & 7 deletions components/stats/TeamStats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ export default function TeamStats(props: {
{ matchNum: number; content: { order: number; jsx: ReactNode }[] }[] | null
>(null);

const pitReport = props.pitReport;
const badges = props.getBadges(
pitReport ?? undefined,
props.selectedReports,
false,
);

useEffect(() => {
if (!props.selectedTeam) return;
setComments(null);
Expand Down Expand Up @@ -132,6 +139,7 @@ export default function TeamStats(props: {
props.selectedReports,
props.subjectiveReports,
props.pitReport,
pitReport,
]);

if (!props.selectedTeam) {
Expand All @@ -144,13 +152,6 @@ export default function TeamStats(props: {
);
}

const pitReport = props.pitReport;
const badges = props.getBadges(
pitReport ?? undefined,
props.selectedReports,
false,
);

function getSections(
header: string,
stats: (
Expand Down
Loading
Loading