Season 9 update + make front page standings more generic

This commit is contained in:
Peter 2024-01-05 13:13:37 -05:00
parent ffa76ceb99
commit 5f1bdbd34f
4 changed files with 29 additions and 28 deletions

View File

@ -37,6 +37,7 @@ export interface TeamStanding {
season: number season: number
teamName: string teamName: string
teamAbbreviation: string teamAbbreviation: string
divisionName: string
divisionAbbreviation: string divisionAbbreviation: string
leagueAbbreviation: string leagueAbbreviation: string
wins: number wins: number
@ -96,6 +97,7 @@ function normalizeStanding(standing: TeamStandingRaw): TeamStanding {
season: standing.team.season, season: standing.team.season,
teamName: standing.team.sname, teamName: standing.team.sname,
teamAbbreviation: standing.team.abbrev, teamAbbreviation: standing.team.abbrev,
divisionName: standing.team.division.division_name,
divisionAbbreviation: standing.team.division.division_abbrev, divisionAbbreviation: standing.team.division.division_abbrev,
leagueAbbreviation: standing.team.division.league_abbrev, leagueAbbreviation: standing.team.division.league_abbrev,
wins: standing.wins, wins: standing.wins,

View File

@ -4,7 +4,7 @@ dayjs.extend(customParseFormat)
export const SITE_URL = 'https://sba.manticorum.com' export const SITE_URL = 'https://sba.manticorum.com'
export const CURRENT_SEASON = 8 export const CURRENT_SEASON = 9
export const MODERN_STAT_ERA_START = 8 export const MODERN_STAT_ERA_START = 8
@ -15,9 +15,9 @@ export const WEEKS_PER_SEASON = 18
export const GAMES_PER_SEASON = GAMES_PER_WEEK * WEEKS_PER_SEASON export const GAMES_PER_SEASON = GAMES_PER_WEEK * WEEKS_PER_SEASON
// TODO: Annually update this start date and holidays with two week series or get it from the DB // TODO: Annually update this start date and holidays with two week series or get it from the DB
export const SEASON_START_DATE: dayjs.Dayjs = dayjs('07-31-2023', 'MM/DD/YYYY') export const SEASON_START_DATE: dayjs.Dayjs = dayjs('01-15-2024', 'MM/DD/YYYY')
export const THANKSGIVING: dayjs.Dayjs = dayjs('11-23-2023', 'MM/DD/YYYY') export const THANKSGIVING: dayjs.Dayjs = dayjs('11-28-2024', 'MM/DD/YYYY')
export const CHRISTMAS: dayjs.Dayjs = dayjs('12-25-2023', 'MM/DD/YYYY') export const CHRISTMAS: dayjs.Dayjs = dayjs('12-25-2024', 'MM/DD/YYYY')
export const POS_MAP = { export const POS_MAP = {

View File

@ -16,14 +16,12 @@
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<h2>SBa League</h2> <h2>SBa League</h2>
<h3>International wOBA Grand Prix</h3> <template v-if="standingsByDivision.length && standingsByDivision[0].length">
<StandingsTable :teams="iwgpTeams" :is-divisional=true /> <template v-for="division in standingsByDivision" :key="division[0].divisionName">
<h3>Crabbers</h3> <h3>{{ division[0].divisionName }}</h3>
<StandingsTable :teams="balTeams" :is-divisional=true /> <StandingsTable :teams="division" :is-divisional=true />
<h3>Fun Diff</h3> </template>
<StandingsTable :teams="fdTeams" :is-divisional=true /> </template>
<h3>NL West</h3>
<StandingsTable :teams="nlwTeams" :is-divisional=true />
<h3>Wildcard</h3> <h3>Wildcard</h3>
<StandingsTable :teams="wildcardTeams" :is-divisional=false /> <StandingsTable :teams="wildcardTeams" :is-divisional=false />
</div> </div>
@ -60,11 +58,8 @@ export default {
seasonNumber: CURRENT_SEASON as number, seasonNumber: CURRENT_SEASON as number,
weekNumber: undefined as number | undefined, weekNumber: undefined as number | undefined,
teamStandings: [] as TeamStanding[], teamStandings: [] as TeamStanding[],
iwgpTeams: [] as TeamStanding[],
nlwTeams: [] as TeamStanding[],
wildcardTeams: [] as TeamStanding[], wildcardTeams: [] as TeamStanding[],
balTeams: [] as TeamStanding[], standingsByDivision: [[]] as TeamStanding[][],
fdTeams: [] as TeamStanding[],
newsPosts: [] as NewsPost[] newsPosts: [] as NewsPost[]
} }
}, },
@ -77,15 +72,18 @@ export default {
this.weekNumber = leagueInfo.week this.weekNumber = leagueInfo.week
this.teamStandings = await fetchStandings(CURRENT_SEASON) this.teamStandings = await fetchStandings(CURRENT_SEASON)
// TODO this could be made more robust to division/league structure changes by identifying the unique
// league/div abbreviations, then grouping on each into an array of arrays, then in the template above
// v-for over the structure to generate a dynamic standings page
this.iwgpTeams = this.teamStandings.filter(ts => ts.divisionAbbreviation === 'IWGP')
this.nlwTeams = this.teamStandings.filter(ts => ts.divisionAbbreviation === 'NLW')
this.balTeams = this.teamStandings.filter(ts => ts.divisionAbbreviation === 'BAL')
this.fdTeams = this.teamStandings.filter(ts => ts.divisionAbbreviation === 'FD')
this.wildcardTeams = this.teamStandings.filter(ts => ts.isWildcardTeam) this.wildcardTeams = this.teamStandings.filter(ts => ts.isWildcardTeam)
const teamStandingsByDivisionAbbreviation: { [key: string]: TeamStanding[] } = {}
this.teamStandings.forEach(ts => {
if (!teamStandingsByDivisionAbbreviation[ts.divisionAbbreviation]) {
teamStandingsByDivisionAbbreviation[ts.divisionAbbreviation] = []
}
teamStandingsByDivisionAbbreviation[ts.divisionAbbreviation].push(ts)
})
this.standingsByDivision = Object.values(teamStandingsByDivisionAbbreviation)
this.newsPosts = await getPosts() this.newsPosts = await getPosts()
}, },

View File

@ -7,9 +7,9 @@
<!-- TODO this will be dynamic based on batting vs pitching --> <!-- TODO this will be dynamic based on batting vs pitching -->
<h2 id="stat-heading">{{ statType }} Leaderboards - Min {{ statMinimum }}</h2> <h2 id="stat-heading">{{ statType }} Leaderboards - Min {{ statMinimum }}</h2>
<!-- <label for="seasonNumber">Select Season</label> --> <!-- <label for="seasonNumber">Select Season</label> -->
<!-- <select name="seasonNumber" id="seasonNumber" v-model="seasonNumber"> <select name="seasonNumber" id="seasonNumber" v-model="seasonNumber">
<option v-for="season in seasonNumbers" :key="season" :value="season">Season {{ season }}</option> <option v-for="season in seasonNumbers" :key="season" :value="season">Season {{ season }}</option>
</select> --> </select>
<!-- TODO ADD SORT FOR ASC/DESC --> <!-- TODO ADD SORT FOR ASC/DESC -->
<select name="statType" id="statType" v-model="statType"> <select name="statType" id="statType" v-model="statType">
<option key="Batting" value="Batting">Batting</option> <option key="Batting" value="Batting">Batting</option>
@ -63,7 +63,7 @@ import { fetchFieldingStatsBySeason, type FieldingStat } from '@/services/fieldi
import { fetchPitchingStatsBySeason, type PitchingStat } from '@/services/pitchingStatsService' import { fetchPitchingStatsBySeason, type PitchingStat } from '@/services/pitchingStatsService'
import type { Player } from '@/services/playersService' import type { Player } from '@/services/playersService'
import { fetchTeamsBySeason } from '@/services/teamsService' import { fetchTeamsBySeason } from '@/services/teamsService'
import { CURRENT_SEASON, GAMES_PER_WEEK, WEEKS_PER_SEASON } from '@/services/utilities' import { CURRENT_SEASON, GAMES_PER_WEEK, MODERN_STAT_ERA_START, WEEKS_PER_SEASON } from '@/services/utilities'
interface LeaderboardTableData<T> { interface LeaderboardTableData<T> {
title: string title: string
@ -120,11 +120,12 @@ export default {
computed: { computed: {
seasonNumbers(): number[] { seasonNumbers(): number[] {
if (!this.currentSeasonNumber) return [] if (!this.currentSeasonNumber) return []
return Array.from({ length: this.currentSeasonNumber }, (_, i) => i + 1) return Array.from({ length: this.currentSeasonNumber - MODERN_STAT_ERA_START + 1 }, (_, i) => i + MODERN_STAT_ERA_START)
}, },
weekNumberForCalcs(): number { weekNumberForCalcs(): number {
if (this.seasonNumber < this.currentSeasonNumber) return WEEKS_PER_SEASON
// since stats are for regular season, do not use post season weeks to up PA/IP mins // since stats are for regular season, do not use post season weeks to up PA/IP mins
return Math.min(this.weekNumber, WEEKS_PER_SEASON) return Math.max(0, Math.min(this.weekNumber, WEEKS_PER_SEASON))
}, },
statMinimum(): string { statMinimum(): string {
if (this.statType == 'Batting') return `PA: ${this.plateAppearanceMinimum}` if (this.statType == 'Batting') return `PA: ${this.plateAppearanceMinimum}`