Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
989a264
Publishing Branch
BanEvading Mar 5, 2025
bcb7275
Should Fix
BanEvading Mar 5, 2025
a90dae1
1.2.9
gearbox4026 Mar 5, 2025
c3943d4
formatting
BanEvading Mar 5, 2025
99379b3
[npm]: Bump jose from 5.9.6 to 6.0.8
dependabot[bot] Mar 10, 2025
b48a3fd
1.2.17
gearbox4026 Mar 10, 2025
e97e669
Implemented Requested Changes
BanEvading Mar 11, 2025
ae36f33
Merge branch 'main' into dependabot/npm_and_yarn/jose-6.0.8
renatodellosso Mar 11, 2025
8f8bd4e
Publishing. Create variables and labels for
BanEvading Mar 11, 2025
cf7dc8d
Puhsing Changes?
BanEvading Mar 11, 2025
aad0c9e
Adding new badge pushing methods
BanEvading Mar 11, 2025
ebddb86
Removing Previous Coral Badge Pushing Methods
BanEvading Mar 11, 2025
ce12f6f
Moving Coral buttons
BanEvading Mar 11, 2025
41aa803
Sad
BanEvading Mar 11, 2025
65578a6
ARGH
BanEvading Mar 11, 2025
5c140f6
1.2.17
gearbox4026 Mar 11, 2025
323ed3c
Formatting
BanEvading Mar 11, 2025
6193203
Merge branch 'pit-scouting' of https://github.com/Decatur-Robotics/Ge…
BanEvading Mar 11, 2025
1c2551a
Removes a line that uses the removed enum. Should fix build issues.
BanEvading Mar 11, 2025
1c6d022
Merge pull request #471 from Decatur-Robotics/pit-scouting
renatodellosso Mar 11, 2025
22c92bf
Resolve Requests.
BanEvading Mar 11, 2025
1fe86b8
Merge branch 'main' into pit-scouting-add
BanEvading Mar 11, 2025
8a67679
Formatting
BanEvading Mar 11, 2025
a577991
Merge pull request #461 from Decatur-Robotics/pit-scouting-add
BanEvading Mar 11, 2025
aa20971
[npm]: Bump the npm_and_yarn group with 3 updates
dependabot[bot] Mar 11, 2025
b5983c1
1.2.18
gearbox4026 Mar 11, 2025
0c59d8e
Merge pull request #472 from Decatur-Robotics/dependabot/npm_and_yarn…
renatodellosso Mar 13, 2025
12f3e8a
Merge branch 'main' into dependabot/npm_and_yarn/jose-6.0.8
renatodellosso Mar 13, 2025
6f75825
Push Change
BanEvading Mar 13, 2025
a2aa8d0
Merge pull request #467 from Decatur-Robotics/dependabot/npm_and_yarn…
renatodellosso Mar 13, 2025
ce1c901
duper
BanEvading Mar 13, 2025
a2e1d2c
Added a bounce effect and green border to matches you are scouting
BanEvading Mar 13, 2025
59fef8a
1.2.19
gearbox4026 Mar 13, 2025
be5b45f
Merge pull request #473 from Decatur-Robotics/make-scouted-team-clearer
renatodellosso Mar 13, 2025
f14a433
Fix sign in error
renatodellosso Mar 14, 2025
e55a590
Merge branch 'main' of github.com:Decatur-Robotics/Gearbox
renatodellosso Mar 14, 2025
4c8d234
Add routes and buttons to delete comps and seasons. Needs tests
renatodellosso Mar 15, 2025
45c6bed
Start adding tests for delete utils
renatodellosso Mar 15, 2025
1376ac2
Finish tests for deletion functions
renatodellosso Mar 17, 2025
3d289be
1.2.20
gearbox4026 Mar 17, 2025
7d0470c
[npm]: Bump postcss from 8.5.1 to 8.5.3
dependabot[bot] Mar 17, 2025
0a6e3e5
[npm]: Bump eslint-config-next from 15.1.6 to 15.2.2
dependabot[bot] Mar 17, 2025
8901032
1.2.20
gearbox4026 Mar 17, 2025
0cd5bea
1.2.20
gearbox4026 Mar 17, 2025
ac29a1e
Merge pull request #475 from Decatur-Robotics/dependabot/npm_and_yarn…
renatodellosso Mar 17, 2025
01c8ab2
Merge pull request #476 from Decatur-Robotics/dependabot/npm_and_yarn…
renatodellosso Mar 17, 2025
767ccb1
Adding rounding to the pitstats page
BanEvading Mar 17, 2025
a784078
1.2.20
gearbox4026 Mar 17, 2025
47faa0b
Rounds to two sigfigs now
BanEvading Mar 17, 2025
92ef4ca
Merge branch 'limit-pitstats-sigfigs' of https://github.com/Decatur-R…
BanEvading Mar 17, 2025
aec7f80
Merge branch 'main' into limit-pitstats-sigfigs
BanEvading Mar 17, 2025
113cc00
Merge pull request #477 from Decatur-Robotics/limit-pitstats-sigfigs
BanEvading Mar 17, 2025
e62ed96
Does what it says on the tin
BanEvading Mar 17, 2025
c8417d9
Merge pull request #474 from Decatur-Robotics/deleteable-comps-and-se…
renatodellosso Mar 17, 2025
a3274b1
DID WE COOK ON THIS ONE BOIS?
BanEvading Mar 18, 2025
8996442
1.2.21
gearbox4026 Mar 18, 2025
b36c983
Merge pull request #479 from Decatur-Robotics/scouting-form-updates
BanEvading Mar 18, 2025
a550abb
Adding
BanEvading Mar 18, 2025
2e2c0f1
1.2.21
gearbox4026 Mar 18, 2025
2b25b9a
Merge branch 'main' into allow-non-pit-scout-teams-in-pitstats
BanEvading Mar 18, 2025
444de48
Submitting to authoritarianism
BanEvading Mar 18, 2025
ae3c9e5
Submitting to authoritarianism Sir
BanEvading Mar 18, 2025
b7467d2
Merge branch 'allow-non-pit-scout-teams-in-pitstats' of https://githu…
BanEvading Mar 18, 2025
934ab1f
"LiNt fiXeD"
BanEvading Mar 18, 2025
f568359
formatting
BanEvading Mar 18, 2025
9fd61ec
Merge pull request #480 from Decatur-Robotics/allow-non-pit-scout-tea…
BanEvading Mar 18, 2025
43f4680
NO MORE IMAGES!
renatodellosso Mar 20, 2025
a077745
Display sign in menu instead of "You are not signed in"
renatodellosso Mar 21, 2025
802130e
Refactor PitScoutingCard to replace image with check icon and clean u…
renatodellosso Mar 21, 2025
8b2df56
Refactor assignScoutersToCompetitionMatches to use sorted match objec…
renatodellosso Mar 21, 2025
b050083
Reduced usage of database when assigning scouters
renatodellosso Mar 21, 2025
d430fb0
add border flash animation for subjective report button when you're a…
renatodellosso Mar 21, 2025
4297fcd
Don't show flashing border on subjective reports if they have been su…
renatodellosso Mar 21, 2025
cd3313a
Fix duplicate reports in SmallGraph
renatodellosso Mar 21, 2025
9e8dc94
[npm]: Bump next from 15.1.6 to 15.2.3 in the npm_and_yarn group
dependabot[bot] Mar 21, 2025
07e3846
1.2.22
gearbox4026 Mar 21, 2025
ce4a3e0
Use a set to avoid duplicate reports in stats
renatodellosso Mar 21, 2025
6e1bb50
Use removeDuplicates to remove duplicate reports
renatodellosso Mar 21, 2025
a46fbb5
Add climb status to graphs
renatodellosso Mar 21, 2025
e4b9a03
Add climb badge
renatodellosso Mar 21, 2025
29954f8
Add report counter to stats page
renatodellosso Mar 22, 2025
3789d62
Merge branch 'main' into dependabot/npm_and_yarn/npm_and_yarn-6f406c18d0
renatodellosso Mar 22, 2025
db6f5ed
Merge pull request #483 from Decatur-Robotics/dependabot/npm_and_yarn…
renatodellosso Mar 22, 2025
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
3 changes: 2 additions & 1 deletion components/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export default function Avatar(props: {
imgHeightOverride?: string | undefined;
showLevel?: boolean | undefined;
borderThickness?: number | undefined;
animation?: string | undefined;
onClick?: () => void | undefined;
className?: string | undefined;
online?: boolean;
Expand All @@ -21,7 +22,7 @@ export default function Avatar(props: {

return (
<div
className={`avatar ${props.online && "online"} ${props.scale} ${props.className}`}
className={`avatar ${props.online && "online"} ${props.scale} ${props.className} ${props.animation}`}
>
{(props.showLevel ?? true) && (
<div className="absolute z-10 bg-base-100 rounded-tl-xl rounded-br-xl h-6 w-14 text-center text-sm font-semibold">
Expand Down
19 changes: 2 additions & 17 deletions components/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Banner, { DiscordBanner } from "./Banner";
import { stat } from "fs";
import { forceOfflineMode } from "@/lib/client/ClientUtils";
import Head from "next/head";
import SignInMenu from "./SignInMenu";

const api = new ClientApi();

Expand Down Expand Up @@ -253,23 +254,7 @@ export default function Container(props: ContainerProps) {
</div>

{showAuthBlock ? (
<div className="w-full h-full flex flex-col items-center justify-center">
<div className="card w-3/4 lg:w-1/4 bg-base-200 text-primary-content">
<div className="card-body flex items-center text-white">
<BsGearFill
size={70}
className="animate-spin-slow"
></BsGearFill>
<h2 className="card-title">Wait a minute...</h2>
<p>You need to sign in first!</p>
<div className="card-actions justify-end">
<Link href={"/signin"}>
<button className="btn btn-primary">Sign In</button>
</Link>
</div>
</div>
</div>
</div>
<SignInMenu />
) : (
<>
{props.notForMobile && !accepted && onMobile ? (
Expand Down
112 changes: 112 additions & 0 deletions components/SignInMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import Container from "@/components/Container";
import { signIn } from "next-auth/react";
import { useRouter } from "next/router";
import { useCallback, useEffect, useRef, useState } from "react";
import {
GoogleReCaptchaProvider,
useGoogleReCaptcha,
} from "react-google-recaptcha-v3";
import { FaGoogle, FaSlack } from "react-icons/fa";

const errorMessages: { [error: string]: string } = {
oauthcallback: "Failed to sign in with OAuth provider.",
callback: "A server-side error occurred during sign in.",
};

function SignInCard() {
const router = useRouter();
const emailRef = useRef<HTMLInputElement>(null);
const { executeRecaptcha } = useGoogleReCaptcha();

const [error, setError] = useState<string>(router.query.error as string);

useEffect(() => {
if (router.query.error) {
const error = (router.query.error as string).toLowerCase();
const message =
(error in errorMessages ? errorMessages[error] : error) +
" Try clearing your cookies and then signing in again.";

setError(message);
}
}, [router.query.error]);

function signInWithCallbackUrl(provider: string, options?: object) {
const callbackUrl = router.query.callbackUrl as string;

signIn(provider, { callbackUrl, ...options });
}
async function logInWithEmail() {
const email = emailRef.current?.value;

if (!email) {
setError("Email is required");
return;
}

if (!executeRecaptcha) {
setError("Recaptcha not available");
return;
}

const captchaToken = await executeRecaptcha();

signInWithCallbackUrl("email", { email, captchaToken });
}

return (
<div className="card bg-base-300 w-5/6 md:w-1/2">
<div className="card-body">
<h1 className="card-title">Sign In</h1>
{error && <p className="text-error">{error}</p>}
<p>Choose a login provider</p>
<div className="divider" />

<button
onClick={() => signInWithCallbackUrl("google")}
className="btn btn-primary w-full font-bold text-md"
>
<FaGoogle />
Login with Google
</button>

<button
onClick={() => signInWithCallbackUrl("slack")}
className="btn btn-secondary w-full font-bold text-md"
>
<FaSlack />
Login with Slack
</button>

<div className="divider" />
<div className="flex flex-col gap-2">
<p>Email Sign In</p>
<input
ref={emailRef}
className="input input-bordered w-full"
type="email"
placeholder="Email"
/>
<button
onClick={logInWithEmail}
className="btn btn-accent w-full font-bold text-md"
>
Login with Email
</button>
</div>
</div>
</div>
);
}

export default function SignInMenu() {
return (
<GoogleReCaptchaProvider
reCaptchaKey={process.env.NEXT_PUBLIC_RECAPTCHA_KEY}
>
<div className="p-12 flex flex-col items-center justify-center">
<SignInCard />
</div>
</GoogleReCaptchaProvider>
);
}
44 changes: 40 additions & 4 deletions components/competition/InsightsAndSettingsCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@ import { Competition, MatchType, Pitreport, Report, Team } from "@/lib/Types";
import Link from "next/link";
import { ChangeEvent, useState } from "react";
import { BsGearFill, BsClipboard2Check } from "react-icons/bs";
import { FaSync, FaBinoculars, FaUserCheck, FaDatabase } from "react-icons/fa";
import {
FaSync,
FaBinoculars,
FaUserCheck,
FaDatabase,
FaTrash,
} from "react-icons/fa";
import { FaUserGroup } from "react-icons/fa6";
import ClientApi from "@/lib/api/ClientApi";
import toast from "react-hot-toast";

const api = new ClientApi();

Expand Down Expand Up @@ -49,10 +56,10 @@ export default function InsightsAndSettingsCard(props: {
const [newCompName, setNewCompName] = useState(comp?.name);
const [newCompTbaId, setNewCompTbaId] = useState(comp?.tbaId);
const [exportPending, setExportPending] = useState(false);
const [teamToAdd, setTeamToAdd] = useState<number>(0);
const [teamToAdd, setTeamToAdd] = useState<number>();
const [blueAlliance, setBlueAlliance] = useState<number[]>([]);
const [redAlliance, setRedAlliance] = useState<number[]>([]);
const [matchNumber, setMatchNumber] = useState<number | undefined>(undefined);
const [matchNumber, setMatchNumber] = useState<number>();

const exportAsCsv = async () => {
setExportPending(true);
Expand Down Expand Up @@ -132,6 +139,28 @@ export default function InsightsAndSettingsCard(props: {
.finally(() => location.reload());
}

function deleteComp() {
if (!comp?._id) return;

const confirmKey = `delete-comp-${comp.slug}`;
if (
prompt(
`If you are sure you want to IRREVOCABLY delete this competition and all data associated with it, type "${confirmKey}"`,
) === confirmKey
) {
toast.promise(
api.deleteComp(comp._id).finally(() => {
window.location.href = `/${team?.slug}/${seasonSlug}`;
}),
{
loading: "Deleting competition...",
success: "Competition deleted successfully!",
error: "Error deleting competition.",
},
);
} else toast.error("Competition not deleted.");
}

return (
<div className="w-full card bg-base-200 shadow-xl">
<div className="card-body w-full">
Expand Down Expand Up @@ -391,12 +420,19 @@ export default function InsightsAndSettingsCard(props: {
</>
)}

<div className="divider"></div>
<div className="divider" />
<Link href={`/${team?.slug}/${seasonSlug}/${comp?.slug}/scouters`}>
<button className="btn btn-lg btn-primary w-full">
<FaBinoculars /> Manage Scouters
</button>
</Link>
<div className="divider" />
<button
className="btn btn-lg btn-error w-full"
onClick={deleteComp}
>
<FaTrash /> Delete Competition
</button>
</div>
) : (
<div className="w-full">
Expand Down
40 changes: 21 additions & 19 deletions components/competition/MatchScheduleCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ export default function MatchScheduleCard(props: {
<a
href={`/${team?.slug}/${seasonSlug}/${comp?.slug}/${reportId}`}
key={reportId}
className={`${color} ${mine && !submitted ? "border-6 border-purple-500" : "border-2 border-white"}
className={`${color} ${mine && !submitted ? "border-4 border-green-400 animate-bounce" : "border-2 border-white"}
${timeSinceCheckIn && timeSinceCheckIn < 10 && "avatar online"}
rounded-lg w-12 h-12 flex items-center justify-center text-white`}
>
Expand Down Expand Up @@ -227,7 +227,7 @@ export default function MatchScheduleCard(props: {
})}
</div>
</div>
<div>
<div className="flex items-center gap-1">
{match.subjectiveScouter &&
usersById[match.subjectiveScouter] ? (
<div className="flex flex-row items-center space-x-1">
Expand Down Expand Up @@ -267,30 +267,32 @@ export default function MatchScheduleCard(props: {
) : (
<div>
Subjective Scouter:{" "}
{usersById[match.subjectiveScouter ?? ""].name}{" "}
<div
className="tooltip before:w-[10rem] "
data-tip="Subjective Scouters watch the entire match and comment on what's going on"
>
<FaInfoCircle></FaInfoCircle>
</div>
{
usersById[match.subjectiveScouter ?? ""].name
}{" "}
</div>
)}
</div>
) : (
<div>
No subjective scouter assigned{" "}
<div
className="tooltip before:w-[10rem] "
data-tip="Subjective Scouters watch the entire match and comment on what's going on"
>
<FaInfoCircle></FaInfoCircle>
</div>
</div>
<div>No subjective scouter assigned </div>
)}
<div
className="tooltip before:w-[10rem] "
data-tip="Subjective Scouters watch the entire match and comment on what's going on"
>
<FaInfoCircle />
</div>
</div>
<a
className={`btn btn-primary btn-sm ${match.subjectiveScouter && usersById[match.subjectiveScouter]?.slackId && "-translate-y-1"}`}
className={`btn btn-primary btn-sm
${match.subjectiveScouter && usersById[match.subjectiveScouter]?.slackId && "-translate-y-1"}
${
session &&
!match.assignedSubjectiveScouterHasSubmitted &&
match.subjectiveScouter === session.user?._id &&
"animate-borderFlash border-4"
}
`}
href={`/${team?.slug}/${seasonSlug}/${comp?.slug}/${match._id}/subjective`}
>
Add Subjective Report (
Expand Down
17 changes: 9 additions & 8 deletions components/competition/PitScoutingCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { NotLinkedToTba } from "@/lib/client/ClientUtils";
import { Competition, Pitreport } from "@/lib/Types";
import Link from "next/link";
import { BsGearFill } from "react-icons/bs";
import { FaRobot } from "react-icons/fa";
import { FaCheck, FaRobot } from "react-icons/fa";

export default function PitScoutingCard(props: {
pitreports: Pitreport[];
Expand Down Expand Up @@ -49,13 +49,14 @@ export default function PitScoutingCard(props: {
</div>
<div className="absolute rounded z-10 translate-y-4 flex justify-center items-center">
{report.submitted ? (
<img
alt={`Team ${report.teamNumber}'s robot`}
src={report.data?.image}
loading="lazy"
style={{ imageResolution: "72dpi" }}
className="w-2/3 h-auto rounded-lg"
></img>
// <img
// alt={`Team ${report.teamNumber}'s robot`}
// src={report.data?.image}
// loading="lazy"
// style={{ imageResolution: "72dpi" }}
// className="w-2/3 h-auto rounded-lg"
// ></img>
<FaCheck size={64} />
) : (
<FaRobot size={64} />
)}
Expand Down
Loading