Skip to content

Commit

Permalink
feat: add wild card standings
Browse files Browse the repository at this point in the history
  • Loading branch information
smoak committed Dec 21, 2023
1 parent 40c3932 commit 9de49ee
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 0 deletions.
5 changes: 5 additions & 0 deletions app/api/standings/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ export type Standings = {
readonly wins: number;
readonly ties: number;
readonly points: number;
readonly pointPctg: number;
readonly regulationPlusOtWinPctg: number;
readonly regulationPlusOtWins: number;
readonly regulationWinPctg: number;
readonly regulationWins: number;
readonly losses: number;
readonly otLosses: number;
};
Expand Down
5 changes: 5 additions & 0 deletions app/components/Standings/StandingsTabs/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Tab } from "@headlessui/react";
import { Conference } from "../Conference";
import { Division } from "../Division";
import { WildCard } from "../WildCard";

const tabClasses =
"my-2 border-x-0 border-t-0 border-b-2 border-transparent px-6 py-3 text-lg font-medium leading-tight hover:border-transparent hover:bg-nhl-gray-100 focus:border-transparent ui-selected:bg-black ui-selected:text-white";
Expand All @@ -11,6 +12,7 @@ export const StandingsTabs = () => {
<Tab.List>
<Tab className={tabClasses}>Division</Tab>
<Tab className={tabClasses}>Conference</Tab>
<Tab className={tabClasses}>Wild Card</Tab>
</Tab.List>
<Tab.Panels className="py-3">
<Tab.Panel id="division">
Expand All @@ -19,6 +21,9 @@ export const StandingsTabs = () => {
<Tab.Panel id="conference">
<Conference />
</Tab.Panel>
<Tab.Panel id="wild-card">
<WildCard />
</Tab.Panel>
</Tab.Panels>
</Tab.Group>
);
Expand Down
89 changes: 89 additions & 0 deletions app/components/Standings/WildCard/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { useLoaderData } from "@remix-run/react";
import type { Standings, StandingsRecord } from "~/components/types";
import { StandingsSection } from "../StandingsSection";

type DivisionSection = {
readonly division: StandingsRecord[];
readonly wildCard: StandingsRecord[];
};

const asDivisionSection = (records: StandingsRecord[]): DivisionSection => {
return {
division: records.slice(0, 3),
wildCard: records.slice(3),
};
};

const conferenceWildCard = (a: DivisionSection, b: DivisionSection) =>
[...a.wildCard, ...b.wildCard].sort(byPoints);

const regulationWinsTieBreaker = (
a: StandingsRecord,
b: StandingsRecord
): number => {
return b.regulationWins - a.regulationWins;
};

const pointsPercentageTieBreaker = (a: StandingsRecord, b: StandingsRecord) => {
const aPointsPercentage = a.pointsPercentage;
const bPointsPercentage = b.pointsPercentage;
const sortValue = bPointsPercentage - aPointsPercentage;

if (sortValue === 0) {
return regulationWinsTieBreaker(a, b);
}

return sortValue;
};

const byPoints = (a: StandingsRecord, b: StandingsRecord) => {
const sortValue = b.points - a.points;

if (sortValue === 0) {
return pointsPercentageTieBreaker(a, b);
}

return sortValue;
};

export const WildCard = () => {
const { division } = useLoaderData<Standings>();
const { atlantic, central, metropolitan, pacific } = division;
const atlanticSection = asDivisionSection(atlantic);
const metroSection = asDivisionSection(metropolitan);
const centralSection = asDivisionSection(central);
const pacificSection = asDivisionSection(pacific);
const easternWildCard = conferenceWildCard(atlanticSection, metroSection);
const westernWildCard = conferenceWildCard(centralSection, pacificSection);

return (
<div className="inline-flex w-full flex-col gap-8">
<StandingsSection
headingText="Eastern"
subheadingText="Atlantic"
standings={atlanticSection.division}
/>
<StandingsSection
subheadingText="Metropolitan"
standings={metroSection.division}
/>
<StandingsSection
subheadingText="Wild Card"
standings={easternWildCard}
/>
<StandingsSection
headingText="Western"
subheadingText="Central"
standings={centralSection.division}
/>
<StandingsSection
subheadingText="Paficic"
standings={pacificSection.division}
/>
<StandingsSection
subheadingText="Wild Card"
standings={westernWildCard}
/>
</div>
);
};
15 changes: 15 additions & 0 deletions app/components/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,11 @@ export type StandingsRecord = {
readonly teamName: string;
readonly gamesPlayed: number;
readonly wins: number;
readonly regulationWins: number;
readonly losses: number;
readonly otLosses: number;
readonly points: number;
readonly pointsPercentage: number;
readonly division: "Pacific" | "Atlantic" | "Metropolitan" | "Central";
readonly conference: "Western" | "Eastern";
};
Expand All @@ -177,6 +179,19 @@ export type Standings = {
readonly division: DivisionStandings;
};

export type WildCardStandings = {
readonly east: {
readonly atlantic: StandingsRecord[];
readonly metropolitan: StandingsRecord[];
readonly wildCard: StandingsRecord[];
};
readonly west: {
readonly central: StandingsRecord[];
readonly pacific: StandingsRecord[];
readonly wildCard: StandingsRecord[];
};
};

export type DivisionStandings = {
readonly metropolitan: StandingsRecord[];
readonly atlantic: StandingsRecord[];
Expand Down
2 changes: 2 additions & 0 deletions app/data/normalization/standings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const normalizeStanding = (s: ApiStandings): StandingsRecord => {
wins: s.wins,
conference: s.conferenceName,
division: s.divisionName,
regulationWins: s.regulationWins,
pointsPercentage: s.pointPctg,
};
};

Expand Down

1 comment on commit 9de49ee

@vercel
Copy link

@vercel vercel bot commented on 9de49ee Dec 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nhl-remix – ./

nhl-remix.vercel.app
nhl-remix-git-main-smoak.vercel.app
nhl-remix-smoak.vercel.app

Please sign in to comment.