Skip to content

Commit

Permalink
Merge pull request #207 from Decatur-Robotics/ftc-team-creation
Browse files Browse the repository at this point in the history
  • Loading branch information
renatodellosso authored Jun 27, 2024
2 parents 2621d5c + b59ceee commit 4f9fac4
Show file tree
Hide file tree
Showing 9 changed files with 251 additions and 131 deletions.
2 changes: 1 addition & 1 deletion components/TeamCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export default function TeamCard(props: { team: Team | undefined }) {
className="w-full bg-base-300 border-4 border-base-300 transition ease-in hover:border-primary"
>
<h1 className="font-semibold max-sm:text-sm">
Team <span className="text-accent">{team?.number}</span> -{" "}
{team?.league} Team <span className="text-accent">{team?.number}</span> -{" "}
<span className="text-primary">{team?.users.length}</span> members
</h1>
</Card>
Expand Down
6 changes: 5 additions & 1 deletion enviroment.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ declare global {
GITHUB_SECRET: string;
GITHUB_ID: string;

MONGO_DB_URI: string;
MONGODB_URI: string;
DB: string;

TBA_URL: string;
TBA_KEY: string;

TOA_URL: string;
TOA_KEY: string;
TOA_APP_ID: string;

API_URL: string;
API_KEY: string;

Expand Down
14 changes: 12 additions & 2 deletions lib/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ import Auth, { AuthenticationOptions } from "./Auth";
import { Statbotics } from "./Statbotics";
import { SerializeDatabaseObject } from "./UrlResolver";

import { QuantData } from "./Types";
import { QuantData, League } from './Types';
import { xpToLevel } from "./Xp";
import { games } from "./games";
import { GameId } from "./client/GameId";
import { TheOrangeAlliance } from "./TheOrangeAlliance";

export namespace API {
export const GearboxHeader = "gearbox-auth";
Expand Down Expand Up @@ -299,7 +300,10 @@ export namespace API {
// {
// number
// }
return res.status(200).send(await tba.getTeamAutofillData(data.number));
return res.status(200).send(data.league === League.FTC
? await TheOrangeAlliance.getTeam(data.number)
: await tba.getTeamAutofillData(data.number)
);
},

competitionAutofill: async (req, res, { tba, data }) => {
Expand Down Expand Up @@ -338,6 +342,7 @@ export namespace API {
await GenerateSlug(Collections.Teams, data.name),
data?.tbaId,
data.number,
data.league,
[data.creator],
[data.creator],
[data.creator]
Expand Down Expand Up @@ -1024,6 +1029,11 @@ export namespace API {
});

return res.status(200).send({ result: "success" });
},

getFtcTeamAutofillData: async (req, res, { tba, data }: RouteContents<{ teamNumber: number }>) => {
const team = await TheOrangeAlliance.getTeam(data.teamNumber);
return res.status(200).send(team);
}
};
}
46 changes: 46 additions & 0 deletions lib/TheOrangeAlliance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { League, Team } from "./Types";

async function request(suburl: string): Promise<any> {
var res = await fetch(process.env.TOA_URL + suburl, {
method: "GET",
headers: {
"X-Application-Origin": process.env.TOA_APP_ID,
"X-TOA-Key": process.env.TOA_KEY,
},
});

return res.json();
}

export namespace TheOrangeAlliance {
export type SimpleTeam = {
/** Appears to be the same as team_number */
team_key: string;
region_key: string;
league_key: string;
team_number: number;
team_name_short: string;
team_name_long: string;
robot_name: string;
last_active: string;
city: string;
state_prov: string;
zip_code: number;
country: string;
rookie_year: number;
website: string;
}

export async function getTeam(teamNumber: number): Promise<Team | undefined> {
const teams = await request(`/team/${teamNumber}`) as SimpleTeam[];

if (teams.length === 0)
return undefined;

const team = teams[0];
if (!team?.team_number || !team?.team_name_short)
return undefined;

return new Team(team.team_name_short, team.team_name_long, team.robot_name, team.team_number, League.FTC);
}
}
3 changes: 3 additions & 0 deletions lib/Types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export class Team {
slug: string | undefined;
tbaId: string | undefined;
number: number;
league: League = League.FRC;

owners: string[];
users: string[];
Expand All @@ -86,6 +87,7 @@ export class Team {
slug: string | undefined,
tbaId: string | undefined,
number: number,
league: League = League.FRC,
owners: string[] = [],
users: string[] = [],
scouters: string[] = [],
Expand All @@ -98,6 +100,7 @@ export class Team {
this.slug = slug;
this.tbaId = tbaId;
this.number = number;
this.league = league;
this.owners = owners;
this.users = users;
this.scouters = scouters;
Expand Down
28 changes: 23 additions & 5 deletions lib/client/ClientAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ import {
Pitreport,
DbPicklist,
SubjectiveReport,
League,
} from "../Types";
import { GameId } from "./GameId";
import { TheOrangeAlliance } from "../TheOrangeAlliance";

export enum ClientRequestMethod {
POST = "POST",
Expand Down Expand Up @@ -71,10 +73,20 @@ export default class ClientAPI {
});
}

async findTeamByNumber(n: number | undefined): Promise<Team> {
async findTeamByNumberAndLeague(n: number, league: League): Promise<Team> {
const query = league === League.FRC
? {
number: n,
$or: [
{ league: league },
{ tbaId: { $exists: true } }
]
}
: { number: n, league: league };

return await this.request("/find", {
collection: "Teams",
query: { number: n },
query,
});
}

Expand Down Expand Up @@ -117,8 +129,8 @@ export default class ClientAPI {
return await this.request("/findAll", { collection: "Teams" });
}

async getTeamAutofillData(teamNumber: number | undefined): Promise<Team> {
return await this.request("/teamAutofill", { number: teamNumber });
async getTeamAutofillData(teamNumber: number | undefined, league: League = League.FRC): Promise<Team> {
return await this.request("/teamAutofill", { number: teamNumber, league });
}

async getCompetitionAutofillData(tbaId: string): Promise<Competition> {
Expand Down Expand Up @@ -152,13 +164,15 @@ export default class ClientAPI {
name: string,
number: number,
creator: string | undefined,
tbaId: undefined | string
tbaId: undefined | string,
league: League
): Promise<Team> {
return await this.request("/createTeam", {
name: name,
number: number,
creator: creator,
tbaId: tbaId,
league: league,
});
}

Expand Down Expand Up @@ -446,4 +460,8 @@ export default class ClientAPI {
return await this.request("/updateCompNameAndTbaId", { compId, name, tbaId });
}

async getFtcTeamAutofillData(teamNumber: number): Promise<Team> {
return await this.request("/getFtcTeamAutofillData", { teamNumber });
}

}
10 changes: 3 additions & 7 deletions pages/[teamSlug]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { GetServerSideProps } from "next";
import { useEffect, useState } from "react";

import ClientAPI from "@/lib/client/ClientAPI";
import { Competition, Season, Team, User } from "@/lib/Types";
import { Competition, League, Season, Team, User } from "@/lib/Types";
import Container from "@/components/Container";
import { useCurrentSession } from "@/lib/client/useCurrentSession";
import Link from "next/link";
Expand Down Expand Up @@ -399,7 +399,7 @@ export default function TeamIndex(props: TeamPageProps) {
const { session, status } = useCurrentSession();
const team = props.team;

const isFrc = team?.tbaId?.startsWith("frc");
const isFrc = team?.tbaId || team?.league === League.FRC;

const [page, setPage] = useState(0);

Expand Down Expand Up @@ -427,11 +427,7 @@ export default function TeamIndex(props: TeamPageProps) {

<div className="divider"></div>
<Flex mode="row" className="space-x-4">
{isFrc ? (
<div className="badge badge-secondary md:badge-lg">FRC</div>
) : (
<></>
)}
<div className="badge badge-secondary md:badge-lg">{isFrc ? "FRC" : "FTC"}</div>
<Link
href={`https://www.thebluealliance.com/team/${team?.number}`}
rel="noopener noreferrer"
Expand Down
63 changes: 46 additions & 17 deletions pages/createTeam.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Team } from "@/lib/Types";
import { League, Team } from "@/lib/Types";
import { useEffect, useState } from "react";

import { useCurrentSession } from "@/lib/client/useCurrentSession";
Expand All @@ -9,6 +9,7 @@ import Card from "@/components/Card";
import Flex from "@/components/Flex";
import Loading from "@/components/Loading";
import TeamCard from "@/components/TeamCard";
import { TheOrangeAlliance } from "@/lib/TheOrangeAlliance";

const api = new ClientAPI("gearboxiscool");

Expand All @@ -17,6 +18,7 @@ export default function CreateTeam() {

const [teamNumber, setTeamNumber] = useState<string>();
const [autoData, setAutoData] = useState<Team>();
const [ftcAutoData, setFtcAutoData] = useState<Team>();
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");

Expand All @@ -26,31 +28,51 @@ export default function CreateTeam() {
}

setLoading(true);

setAutoData(undefined);
let data = await api.getTeamAutofillData(Number(teamNumber));
if (data?.name) {
setAutoData(data);
}
setFtcAutoData(undefined);

api.getTeamAutofillData(Number(teamNumber)).then((data) => {
if (data?.name) {
setAutoData(data);
}
});

api.getFtcTeamAutofillData(Number(teamNumber)).then((data) => {
console.log(data);
if (data?.name) {
setFtcAutoData(data);
}
});

setLoading(false);
};

const createTeam = async () => {
const createTeam = async (league: League) => {
if (!autoData || !session?.user) {
return;
}

if (
Object.keys(await api.findTeamByNumber(Number(teamNumber))).length > 0
await api.findTeamByNumberAndLeague(Number(teamNumber), league)
) {
setError("This Team Already Exists");
return;
}

const data = league === League.FRC ? autoData : ftcAutoData;

if (!data) {
setError("No Team Found");
return;
}

let newTeam = await api.createTeam(
autoData.name,
autoData.number,
data.name,
data.number,
session.user._id,
autoData.tbaId
data.tbaId,
league
);

const win: Window = window;
Expand Down Expand Up @@ -78,25 +100,32 @@ export default function CreateTeam() {
<input
className="input input-bordered md:w-1/2"
placeholder="Team Number"
maxLength={4}
maxLength={5}
minLength={1}
value={teamNumber}
onChange={(e) => {
setTeamNumber(e.target.value);
}}
></input>
{teamNumber ? (
{teamNumber && (
<div className="md:w-1/2 h-48 mt-10">
{loading ? (
<Loading></Loading>
<Loading />
) : (
<div onClick={createTeam}>
<TeamCard team={autoData}></TeamCard>
<div className="flex flex-row space-x-2">
{ autoData?.name &&
<div onClick={() => createTeam(League.FRC)}>
<TeamCard team={autoData} />
</div>
}
{ ftcAutoData?.name &&
<div onClick={() => createTeam(League.FTC)}>
<TeamCard team={ftcAutoData} />
</div>
}
</div>
)}
</div>
) : (
<></>
)}
</Card>
</Flex>
Expand Down
Loading

0 comments on commit 4f9fac4

Please sign in to comment.