From 130283b7f10a0bc17569d2ae06e8537094b7cafa Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 31 Oct 2024 07:26:16 -0500 Subject: [PATCH] Create /teamleaderboards page and tables --- components.d.ts | 3 + .../LeaderboardTeamBattingTable.vue | 154 ++++++++++++++++ .../LeaderboardTeamFieldingTable.vue | 103 +++++++++++ .../LeaderboardTeamPitchingTable.vue | 168 ++++++++++++++++++ src/components/TeamFieldingTable.vue | 6 +- src/router/index.ts | 5 + src/services/battingStatsService.ts | 19 ++ src/services/fieldingStatsService.ts | 19 ++ src/services/pitchingStatsService.ts | 18 ++ src/views/TeamLeaderboardView.vue | 107 +++++++++++ src/views/TransactionsView.vue | 0 11 files changed, 599 insertions(+), 3 deletions(-) create mode 100644 src/components/LeaderboardTeamBattingTable.vue create mode 100644 src/components/LeaderboardTeamFieldingTable.vue create mode 100644 src/components/LeaderboardTeamPitchingTable.vue create mode 100644 src/views/TeamLeaderboardView.vue create mode 100644 src/views/TransactionsView.vue diff --git a/components.d.ts b/components.d.ts index 09af641..3bdcdd8 100644 --- a/components.d.ts +++ b/components.d.ts @@ -18,6 +18,9 @@ declare module '@vue/runtime-core' { IconTooling: typeof import('./src/components/icons/IconTooling.vue')['default'] LastFourGamesBattingTable: typeof import('./src/components/LastFourGamesBattingTable.vue')['default'] LastFourGamesPitchingTable: typeof import('./src/components/LastFourGamesPitchingTable.vue')['default'] + LeaderboardTeamBattingTable: typeof import('./src/components/LeaderboardTeamBattingTable.vue')['default'] + LeaderboardTeamFieldingTable: typeof import('./src/components/LeaderboardTeamFieldingTable.vue')['default'] + LeaderboardTeamPitchingTable: typeof import('./src/components/LeaderboardTeamPitchingTable.vue')['default'] NavBar: typeof import('./src/components/NavBar.vue')['default'] NewsPreview: typeof import('./src/components/NewsPreview.vue')['default'] PlayerBattingSummaryTable: typeof import('./src/components/PlayerBattingSummaryTable.vue')['default'] diff --git a/src/components/LeaderboardTeamBattingTable.vue b/src/components/LeaderboardTeamBattingTable.vue new file mode 100644 index 0000000..4885dc2 --- /dev/null +++ b/src/components/LeaderboardTeamBattingTable.vue @@ -0,0 +1,154 @@ + + + diff --git a/src/components/LeaderboardTeamFieldingTable.vue b/src/components/LeaderboardTeamFieldingTable.vue new file mode 100644 index 0000000..c16313c --- /dev/null +++ b/src/components/LeaderboardTeamFieldingTable.vue @@ -0,0 +1,103 @@ + + diff --git a/src/components/LeaderboardTeamPitchingTable.vue b/src/components/LeaderboardTeamPitchingTable.vue new file mode 100644 index 0000000..64ac54d --- /dev/null +++ b/src/components/LeaderboardTeamPitchingTable.vue @@ -0,0 +1,168 @@ + + + diff --git a/src/components/TeamFieldingTable.vue b/src/components/TeamFieldingTable.vue index c0fc986..b54d663 100644 --- a/src/components/TeamFieldingTable.vue +++ b/src/components/TeamFieldingTable.vue @@ -18,7 +18,7 @@ - + {{ stat.player.name }} @@ -36,7 +36,7 @@ - + Total {{ stat.pos }} {{ stat.xCheckCount }} @@ -58,7 +58,7 @@ import { aggregateFieldingStats, fetchFieldingStatsBySeasonAndTeamId, totaledFie import { POS_MAP } from '@/services/utilities' export default { - name: "TeamFieldingTable", + name: 'TeamFieldingTable', props: { seasonNumber: { type: Number, required: true }, teamId: { type: Number, required: true }, diff --git a/src/router/index.ts b/src/router/index.ts index a689d1c..394b528 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -36,6 +36,11 @@ export const routes: RouteRecordRaw[] = [ name: 'leaderboards', component: () => import('../views/LeaderboardView.vue') }, + { + path: '/teamleaderboards', + name: 'teamleaderboards', + component: () => import('../views/TeamLeaderboardView.vue') + }, { path: '/rules', name: 'rules', diff --git a/src/services/battingStatsService.ts b/src/services/battingStatsService.ts index 91f2534..776ab18 100644 --- a/src/services/battingStatsService.ts +++ b/src/services/battingStatsService.ts @@ -123,6 +123,25 @@ export async function fetchBattingStatsBySeasonAndTeamId(seasonNumber: number, t return battingStatsResponse.stats } +// Differs from fetchBattingStatsBySeasonAndTeamId because it groups stats by team, not individual player stats on a given team +export async function fetchTeamBattingStatsBySeason(seasonNumber: number): Promise { + // different endpoint for pre-modern stats (/plays) era + if (seasonNumber < MODERN_STAT_ERA_START) { + return [] + } + + const response = await fetch(`${SITE_URL}/api/v3/plays/batting?season=${seasonNumber}&group_by=team&s_type=regular`) + + const battingStatsResponse: { + count: number + stats: BattingStat[] + } = await response.json() + + if (battingStatsResponse.count === 0) return [] + + return battingStatsResponse.stats +} + async function fetchLegacyBattingStatsBySeasonAndPlayerId(seasonNumber: number, playerId: number, isRegularSeason: boolean): Promise { const response = await fetch(`${SITE_URL}/api/v3/battingstats/totals?season=${seasonNumber}&player_id=${playerId}&s_type=${isRegularSeason ? 'regular' : 'post'}`) diff --git a/src/services/fieldingStatsService.ts b/src/services/fieldingStatsService.ts index 8320f98..7238fa6 100644 --- a/src/services/fieldingStatsService.ts +++ b/src/services/fieldingStatsService.ts @@ -89,6 +89,25 @@ export async function fetchFieldingStatsBySeasonAndTeamId(seasonNumber: number, return fieldingStatsResponse.stats.map(normalizeFieldingStat) } +export async function fetchTeamFieldingStatsBySeason(seasonNumber: number): Promise { + // different endpoint for pre-modern stats (/plays) era + if (seasonNumber < MODERN_STAT_ERA_START) { + return [] + } + + // TODO might want to make this playerpositionteam grouping (currently does not exist) + const response = await fetch(`${SITE_URL}/api/v3/plays/fielding?season=${seasonNumber}&group_by=team&s_type=regular`) + + const fieldingStatsResponse: { + count: number + stats: FieldingStatRaw[] + } = await response.json() + + if (fieldingStatsResponse.count === 0) return [] + + return fieldingStatsResponse.stats.map(normalizeFieldingStat) +} + export async function fetchFieldingStatsBySeason(seasonNumber: number, isRegularSeason: boolean): Promise { // different endpoint for pre-modern stats (/plays) era if (seasonNumber < MODERN_STAT_ERA_START) { diff --git a/src/services/pitchingStatsService.ts b/src/services/pitchingStatsService.ts index fdf90c2..83b5963 100644 --- a/src/services/pitchingStatsService.ts +++ b/src/services/pitchingStatsService.ts @@ -171,6 +171,24 @@ export async function fetchPitchingStatsBySeasonAndTeamId(seasonNumber: number, return pitchingStatsResponse.stats.map(normalizePitchingStat) } +export async function fetchTeamPitchingStatsBySeason(seasonNumber: number): Promise { + // different endpoint for pre-modern stats (/plays) era + if (seasonNumber < MODERN_STAT_ERA_START) { + return [] + } + + const response = await fetch(`${SITE_URL}/api/v3/plays/pitching?season=${seasonNumber}&group_by=team&s_type=regular`) + + const pitchingStatsResponse: { + count: number + stats: PitchingStatRaw[] + } = await response.json() + + if (pitchingStatsResponse.count === 0) return [] + + return pitchingStatsResponse.stats.map(normalizePitchingStat) +} + export async function fetchPitchingStatsBySeason(seasonNumber: number, isRegularSeason: boolean): Promise { // different endpoint for pre-modern stats (/plays) era if (seasonNumber < MODERN_STAT_ERA_START) { diff --git a/src/views/TeamLeaderboardView.vue b/src/views/TeamLeaderboardView.vue new file mode 100644 index 0000000..f3c438c --- /dev/null +++ b/src/views/TeamLeaderboardView.vue @@ -0,0 +1,107 @@ + + + + + \ No newline at end of file diff --git a/src/views/TransactionsView.vue b/src/views/TransactionsView.vue new file mode 100644 index 0000000..e69de29