Compare commits

..

10 Commits

Author SHA1 Message Date
Peter
5768b9f7d2 Site to season 13 2025-11-19 14:39:41 -06:00
Peter
1cf70a9c88 Sort by game id 2025-10-29 09:08:07 -05:00
Peter
642dc6e673 Cutover to new API for local development and fix standings season issue 2025-10-21 08:43:58 -05:00
Cal Corum
16e6099fc3 Import Updates
Updating two type imports caught by build process
2025-07-17 14:30:10 -05:00
Peter
c8e70217f6 Merge branch 'main' of https://github.com/pgiro/sba 2025-07-17 14:00:28 -05:00
Peter
a13ad94558 Fix navbar 2025-07-17 14:00:25 -05:00
Cal Corum
65d7c7c8a1 Update .gitignore
Excluding local build files and Claude directory
2025-07-17 13:32:06 -05:00
Peter
1e0afd634b Add archive to standings page 2025-07-15 16:42:02 -05:00
Peter
4f939e5f08 Add ids to schedule to verify sort 2025-06-30 09:48:06 -05:00
Peter
e12e207e23 Roll site to season 12 2025-05-23 08:43:32 -05:00
23 changed files with 126 additions and 79 deletions

11
.gitignore vendored
View File

@ -26,3 +26,14 @@ coverage
*.njsproj
*.sln
*.sw?
CLAUDE.md
.claude/*
*docker*
Dockerfile*
*.py
nginx.conf
scripts/*
public/cards*
.env.prod

View File

@ -5,13 +5,13 @@
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<meta property="og:title" content="SBa Season 11" />
<meta property="og:title" content="SBa Season 13" />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://sba.manticorum.com" />
<meta property="og:image" content="https://sba.manticorum.com/sba-network.png" />
<meta property="og:description" content="The home of the Strat-o-matic Baseball Association" />
<meta name="theme-color" content="#A6CE39">
<title>SBa Season 11</title>
<title>SBa Season 13</title>
</head>
<body>

View File

@ -72,7 +72,7 @@
</template>
<script lang="ts">
import { type Game } from '@/services/apiResponseTypes'
import type { Game } from '@/services/apiResponseTypes'
import { fetchPitchingStatsForLastTwoWeeksByTeam, type PitchingStat } from '@/services/pitchingStatsService'
import { fetchPlayersByTeam, type Player } from '@/services/playersService'

View File

@ -26,7 +26,7 @@
<tr v-for="(team, index) in getSortedStandings(division.teamStandings)" :key="index">
<td>
<RouterLink
:to="{ name: 'team', params: { seasonNumber: seasonNumber(), teamAbbreviation: team.teamAbbreviation } }">
:to="{ name: 'team', params: { seasonNumber: team.season, teamAbbreviation: team.teamAbbreviation } }">
{{ team.teamName }}
</RouterLink>
</td>
@ -54,7 +54,6 @@
<script lang="ts">
import type { TeamStanding } from '@/services/standingsService'
import { CURRENT_SEASON } from '@/services/utilities'
interface DivisionStub {
name: string
@ -94,9 +93,6 @@ export default {
record(teamStanding: TeamStanding): string {
return `${teamStanding.wins}-${teamStanding.losses}`
},
seasonNumber(): number {
return CURRENT_SEASON
},
getSortedStandings(teamStandings: TeamStanding[]): TeamStanding[] {
if (!teamStandings) return []
return teamStandings.slice()

View File

@ -1,6 +1,7 @@
<template>
<nav class="navbar navbar-expand-md" style="margin-bottom: 1rem">
<RouterLink class="navbar-brand nav-link" style="padding-left: 0;" to="/">SBa Season {{ seasonNumber() }}</RouterLink>
<RouterLink class="navbar-brand nav-link" style="padding-left: 0;" to="/">SBa Season {{ seasonNumber() }}
</RouterLink>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#top-navbar-collapse"
aria-controls="top-navbar-collapse" aria-expanded="false" aria-label="Toggle navigation"
@click="setMobileNavBarState(!isMobileNavBarExpanded)">
@ -15,7 +16,8 @@
<RouterLink class="nav-link" to="/schedule">Schedule</RouterLink>
</li>
<li class="nav-item">
<RouterLink class="nav-link" to="/standings">Standings</RouterLink>
<RouterLink class="nav-link" :to="{ name: 'standings', params: { seasonNumber: seasonNumber() } }">Standings
</RouterLink>
</li>
<li class="nav-item">
<RouterLink class="nav-link" to="/leaderboards">Leaders</RouterLink>
@ -50,7 +52,8 @@
<button class="nav-link" @click="clearCookie">Clear Cookie</button>
</li>
<li v-if="isAuthenticated && userTeam" class="nav-item">
<RouterLink :to="{ name: 'team', params: { seasonNumber: seasonNumber(), teamAbbreviation: userTeam.abbrev } }">
<RouterLink
:to="{ name: 'team', params: { seasonNumber: seasonNumber(), teamAbbreviation: userTeam.abbrev } }">
<img id="thumbnail" style="max-height: 35px; vertical-align: middle;" :src=userTeam?.thumbnail>
</RouterLink>
</li>

View File

@ -68,7 +68,8 @@ export default {
return `${teamStanding.wins}-${teamStanding.losses}`
},
seasonNumber(): number {
return CURRENT_SEASON
if (!this.teams) return CURRENT_SEASON
return this.teams[0].season
}
}
}

View File

@ -27,9 +27,10 @@ export const routes: RouteRecordRaw[] = [
props: castPlayersRouteParams
},
{
path: '/standings',
path: '/standings/:seasonNumber',
name: 'standings',
component: () => import('../views/StandingsView.vue')
component: () => import('../views/StandingsView.vue'),
props: castStandingsRouteParams
},
{
path: '/leaderboards',
@ -86,6 +87,12 @@ function castPlayersRouteParams(route: { params: { playerName: string, seasonNum
}
}
function castStandingsRouteParams(route: { params: { seasonNumber: string } }) {
return {
seasonNumber: Number.isNaN(Number.parseInt(route.params.seasonNumber)) ? undefined : Number(route.params.seasonNumber)
}
}
function castScheduleRouteParams(route: { params: { seasonNumber: string, weekNumber: string } }) {
return {
seasonNumber: Number.isNaN(Number.parseInt(route.params.seasonNumber)) ? undefined : Number(route.params.seasonNumber),

View File

@ -1,6 +1,6 @@
import type { Manager, Team } from './apiResponseTypes'
import type { Player } from './playersService'
import { SITE_URL } from './utilities'
import { API_URL } from './utilities'
export interface Award {
id: number,
@ -15,7 +15,7 @@ export interface Award {
}
export async function fetchAwardsByPlayerName(playerName: string): Promise<Award[]> {
const response = await fetch(`${SITE_URL}/api/v3/awards?player_name=${playerName}&timing=off-season`)
const response = await fetch(`${API_URL}/awards?player_name=${playerName}&timing=off-season`)
const awardsResponse: {
count: number
@ -26,7 +26,7 @@ export async function fetchAwardsByPlayerName(playerName: string): Promise<Award
}
export async function fetchAwardsByManagerId(managerId: number): Promise<Award[]> {
const response = await fetch(`${SITE_URL}/api/v3/awards?manager_id=${managerId}`)
const response = await fetch(`${API_URL}/awards?manager_id=${managerId}`)
const awardsResponse: {
count: number

View File

@ -1,6 +1,6 @@
import type { Game, Team } from './apiResponseTypes'
import type { Player } from './playersService'
import { MODERN_STAT_ERA_START, SITE_URL, avg, obp, ops, slg, woba } from './utilities'
import { MODERN_STAT_ERA_START, API_URL, avg, obp, ops, slg, woba } from './utilities'
// TODO make a stats object that has properties for current regular season, current post season,
// last 4 games, historical seasons, career totals
@ -71,7 +71,7 @@ export async function fetchBattingStatsBySeason(seasonNumber: number, isRegularS
return []
}
const response = await fetch(`${SITE_URL}/api/v3/plays/batting?season=${seasonNumber}&group_by=player&limit=1000&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const response = await fetch(`${API_URL}/plays/batting?season=${seasonNumber}&group_by=player&limit=1000&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const battingStatsResponse: {
count: number
@ -89,7 +89,7 @@ export async function fetchBattingStatsBySeasonAndPlayerId(seasonNumber: number,
return await fetchLegacyBattingStatsBySeasonAndPlayerId(seasonNumber, playerId, isRegularSeason)
}
const response = await fetch(`${SITE_URL}/api/v3/plays/batting?season=${seasonNumber}&player_id=${playerId}&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const response = await fetch(`${API_URL}/plays/batting?season=${seasonNumber}&player_id=${playerId}&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const battingStatsResponse: {
count: number
@ -111,7 +111,7 @@ export async function fetchBattingStatsBySeasonAndTeamId(seasonNumber: number, t
return []
}
const response = await fetch(`${SITE_URL}/api/v3/plays/batting?season=${seasonNumber}&team_id=${teamId}&group_by=playerteam&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const response = await fetch(`${API_URL}/plays/batting?season=${seasonNumber}&team_id=${teamId}&group_by=playerteam&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const battingStatsResponse: {
count: number
@ -130,7 +130,7 @@ export async function fetchTeamBattingStatsBySeason(seasonNumber: number): Promi
return []
}
const response = await fetch(`${SITE_URL}/api/v3/plays/batting?season=${seasonNumber}&group_by=team&s_type=regular`)
const response = await fetch(`${API_URL}/plays/batting?season=${seasonNumber}&group_by=team&s_type=regular`)
const battingStatsResponse: {
count: number
@ -143,7 +143,7 @@ export async function fetchTeamBattingStatsBySeason(seasonNumber: number): Promi
}
async function fetchLegacyBattingStatsBySeasonAndPlayerId(seasonNumber: number, playerId: number, isRegularSeason: boolean): Promise<BattingStat | undefined> {
const response = await fetch(`${SITE_URL}/api/v3/battingstats/totals?season=${seasonNumber}&player_id=${playerId}&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const response = await fetch(`${API_URL}/battingstats/totals?season=${seasonNumber}&player_id=${playerId}&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const legacyBattingStatsResponse: {
count: number
@ -160,7 +160,7 @@ async function fetchLegacyBattingStatsBySeasonAndPlayerId(seasonNumber: number,
}
export async function fetchBattingStatsForLastFourGamesBySeasonAndPlayerId(seasonNumber: number, playerId: number): Promise<BattingStat[]> {
const response = await fetch(`${SITE_URL}/api/v3/plays/batting?season=${seasonNumber}&player_id=${playerId}&group_by=playergame&limit=4&s_type=regular&sort=newest`)
const response = await fetch(`${API_URL}/plays/batting?season=${seasonNumber}&player_id=${playerId}&group_by=playergame&limit=4&s_type=regular&sort=newest`)
const battingStatsResponse: {
count: number
@ -180,7 +180,7 @@ export async function fetchBattingStatsBySeries(seasonNumber: number, weekNumber
return []
}
const response = await fetch(`${SITE_URL}/api/v3/plays/batting?season=${seasonNumber}&week=${weekNumber}&team_id=${homeTeamId}&team_id=${awayTeamId}&group_by=playergame`)
const response = await fetch(`${API_URL}/plays/batting?season=${seasonNumber}&week=${weekNumber}&team_id=${homeTeamId}&team_id=${awayTeamId}&group_by=playergame`)
const battingStatsResponse: {
count: number

View File

@ -1,4 +1,4 @@
import { SITE_URL } from './utilities'
import { API_URL } from './utilities'
export interface LeagueInfo {
id: number,
@ -17,7 +17,7 @@ export interface LeagueInfo {
}
export async function fetchCurrentLeagueInfo(): Promise<LeagueInfo> {
const response = await fetch(`${SITE_URL}/api/v3/current`)
const response = await fetch(`${API_URL}/current`)
const leagueInfoResponse: LeagueInfo = await response.json()

View File

@ -1,6 +1,6 @@
import type { Game } from './apiResponseTypes'
import type { Player } from './playersService'
import { SITE_URL } from './utilities'
import { API_URL } from './utilities'
export interface Decision {
id: number,
@ -22,7 +22,7 @@ export interface Decision {
}
export async function fetchLast2DecisionsByPlayerId(seasonNumber: number, playerId: number): Promise<Decision[]> {
const response = await fetch(`${SITE_URL}/api/v3/decisions?season=${seasonNumber}&player_id=${playerId}&limit=2`)
const response = await fetch(`${API_URL}/decisions?season=${seasonNumber}&player_id=${playerId}&limit=2`)
const decisionsResponse: {
count: number

View File

@ -1,6 +1,6 @@
import type { Game, Team } from './apiResponseTypes'
import type { Player } from './playersService'
import { MODERN_STAT_ERA_START, SITE_URL, isNotUndefined } from './utilities'
import { MODERN_STAT_ERA_START, API_URL, isNotUndefined } from './utilities'
// TODO make a stats object that has properties for current regular season, current post season,
// last 4 games, historical seasons, career totals
@ -58,7 +58,7 @@ export async function fetchFieldingStatsBySeasonAndPlayerId(seasonNumber: number
return await fetchLegacyFieldingStatsBySeasonAndPlayerId(seasonNumber, playerId, isRegularSeason)
}
const response = await fetch(`${SITE_URL}/api/v3/plays/fielding?season=${seasonNumber}&player_id=${playerId}&group_by=playerposition&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const response = await fetch(`${API_URL}/plays/fielding?season=${seasonNumber}&player_id=${playerId}&group_by=playerposition&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const fieldingStatsResponse: {
count: number
@ -77,7 +77,7 @@ export async function fetchFieldingStatsBySeasonAndTeamId(seasonNumber: number,
}
// TODO might want to make this playerpositionteam grouping (currently does not exist)
const response = await fetch(`${SITE_URL}/api/v3/plays/fielding?season=${seasonNumber}&team_id=${teamId}&group_by=playerposition&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const response = await fetch(`${API_URL}/plays/fielding?season=${seasonNumber}&team_id=${teamId}&group_by=playerposition&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const fieldingStatsResponse: {
count: number
@ -96,7 +96,7 @@ export async function fetchTeamFieldingStatsBySeason(seasonNumber: number): Prom
}
// 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 response = await fetch(`${API_URL}/plays/fielding?season=${seasonNumber}&group_by=team&s_type=regular`)
const fieldingStatsResponse: {
count: number
@ -114,7 +114,7 @@ export async function fetchFieldingStatsBySeason(seasonNumber: number, isRegular
return []
}
const response = await fetch(`${SITE_URL}/api/v3/plays/fielding?season=${seasonNumber}&limit=10000&group_by=playerposition&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const response = await fetch(`${API_URL}/plays/fielding?season=${seasonNumber}&limit=10000&group_by=playerposition&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const fieldingStatsResponse: {
count: number
@ -127,7 +127,7 @@ export async function fetchFieldingStatsBySeason(seasonNumber: number, isRegular
}
async function fetchLegacyFieldingStatsBySeasonAndPlayerId(seasonNumber: number, playerId: number, isRegularSeason: boolean): Promise<FieldingStat[]> {
const response = await fetch(`${SITE_URL}/api/v3/fieldingstats/totals?season=${seasonNumber}&player_id=${playerId}&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const response = await fetch(`${API_URL}/fieldingstats/totals?season=${seasonNumber}&player_id=${playerId}&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const legacyFieldingStatsResponse: {
count: number
@ -142,7 +142,7 @@ async function fetchLegacyFieldingStatsBySeasonAndPlayerId(seasonNumber: number,
}
export async function fetchFieldingStatsForLastFourGamesBySeasonAndPlayerId(seasonNumber: number, playerId: number): Promise<FieldingStat[]> {
const response = await fetch(`${SITE_URL}/api/v3/plays/fielding?season=${seasonNumber}&player_id=${playerId}&group_by=playerpositiongame&limit=4&s_type=regular&sort=newest`)
const response = await fetch(`${API_URL}/plays/fielding?season=${seasonNumber}&player_id=${playerId}&group_by=playerpositiongame&limit=4&s_type=regular&sort=newest`)
const fieldingStatsResponse: {
count: number
@ -162,7 +162,7 @@ export async function fetchFieldingStatsBySeries(seasonNumber: number, weekNumbe
return []
}
const response = await fetch(`${SITE_URL}/api/v3/plays/fielding?season=${seasonNumber}&week=${weekNumber}&team_id=${homeTeamId}&team_id=${awayTeamId}&group_by=playerpositiongame`)
const response = await fetch(`${API_URL}/plays/fielding?season=${seasonNumber}&week=${weekNumber}&team_id=${homeTeamId}&team_id=${awayTeamId}&group_by=playerpositiongame`)
const fieldingStatsResponse: {
count: number

View File

@ -1,5 +1,5 @@
import type { Game } from './apiResponseTypes'
import { MODERN_STAT_ERA_START, SITE_URL } from './utilities'
import { MODERN_STAT_ERA_START, API_URL } from './utilities'
export async function fetchGamesBySeasonAndTeamId(seasonNumber: number, teamId: number): Promise<Game[]> {
if (seasonNumber < MODERN_STAT_ERA_START) {
@ -7,7 +7,7 @@ export async function fetchGamesBySeasonAndTeamId(seasonNumber: number, teamId:
return []
}
const response = await fetch(`${SITE_URL}/api/v3/games?season=${seasonNumber}&team1_id=${teamId}&team2_id=${teamId}&season_type=regular`)
const response = await fetch(`${API_URL}/games?season=${seasonNumber}&team1_id=${teamId}&team2_id=${teamId}&season_type=regular`)
const gamesResponse: {
count: number
@ -23,7 +23,7 @@ export async function fetchGamesBySeasonAndWeek(seasonNumber: number, weekNumber
return []
}
const response = await fetch(`${SITE_URL}/api/v3/games?season=${seasonNumber}&week=${weekNumber}`)
const response = await fetch(`${API_URL}/games?season=${seasonNumber}&week=${weekNumber}`)
const gamesResponse: {
count: number
@ -39,7 +39,7 @@ export async function fetchSingleGame(seasonNumber: number, weekNumber: number,
return undefined
}
const response = await fetch(`${SITE_URL}/api/v3/games?season=${seasonNumber}&week=${weekNumber}&game_num=${gameNumber}&team1_id=${homeTeamId}&team2_id=${awayTeamId}`)
const response = await fetch(`${API_URL}/games?season=${seasonNumber}&week=${weekNumber}&game_num=${gameNumber}&team1_id=${homeTeamId}&team2_id=${awayTeamId}`)
const gamesResponse: {
count: number

View File

@ -1,5 +1,5 @@
import type { Manager } from './apiResponseTypes'
import { SITE_URL } from './utilities'
import { API_URL } from './utilities'
export async function fetchActiveManagers(): Promise<Manager[]> {
return await fetchManagers(true)
@ -10,7 +10,7 @@ export async function fetchRetiredManagers(): Promise<Manager[]> {
}
async function fetchManagers(active: boolean): Promise<Manager[]> {
const response = await fetch(`${SITE_URL}/api/v3/managers?active=${active}&short_output=true`)
const response = await fetch(`${API_URL}/managers?active=${active}&short_output=true`)
const managersResponse: {
count: number

View File

@ -1,6 +1,6 @@
import type { Game, Team } from './apiResponseTypes'
import type { Player } from './playersService'
import { MODERN_STAT_ERA_START, SITE_URL, avg, slg, woba } from './utilities'
import { MODERN_STAT_ERA_START, API_URL, avg, slg, woba } from './utilities'
// TODO make a stats object that has properties for current regular season, current post season,
// last 4 games, historical seasons, career totals
@ -138,7 +138,7 @@ export async function fetchPitchingStatsBySeasonAndPlayerId(seasonNumber: number
return await fetchLegacyPitchingStatsBySeasonAndPlayerId(seasonNumber, playerId, isRegularSeason)
}
const response = await fetch(`${SITE_URL}/api/v3/plays/pitching?season=${seasonNumber}&player_id=${playerId}&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const response = await fetch(`${API_URL}/plays/pitching?season=${seasonNumber}&player_id=${playerId}&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const pitchingStatsResponse: {
count: number
@ -160,7 +160,7 @@ export async function fetchPitchingStatsBySeasonAndTeamId(seasonNumber: number,
return []
}
const response = await fetch(`${SITE_URL}/api/v3/plays/pitching?season=${seasonNumber}&team_id=${teamId}&group_by=playerteam&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const response = await fetch(`${API_URL}/plays/pitching?season=${seasonNumber}&team_id=${teamId}&group_by=playerteam&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const pitchingStatsResponse: {
count: number
@ -178,7 +178,7 @@ export async function fetchTeamPitchingStatsBySeason(seasonNumber: number): Prom
return []
}
const response = await fetch(`${SITE_URL}/api/v3/plays/pitching?season=${seasonNumber}&group_by=team&s_type=regular`)
const response = await fetch(`${API_URL}/plays/pitching?season=${seasonNumber}&group_by=team&s_type=regular`)
const pitchingStatsResponse: {
count: number
@ -197,7 +197,7 @@ export async function fetchPitchingStatsBySeason(seasonNumber: number, isRegular
return []
}
const response = await fetch(`${SITE_URL}/api/v3/plays/pitching?season=${seasonNumber}&group_by=player&limit=1000&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const response = await fetch(`${API_URL}/plays/pitching?season=${seasonNumber}&group_by=player&limit=1000&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const pitchingStatsResponse: {
count: number
@ -210,7 +210,7 @@ export async function fetchPitchingStatsBySeason(seasonNumber: number, isRegular
}
async function fetchLegacyPitchingStatsBySeasonAndPlayerId(seasonNumber: number, playerId: number, isRegularSeason: boolean): Promise<PitchingStat | undefined> {
const response = await fetch(`${SITE_URL}/api/v3/pitchingstats/totals?season=${seasonNumber}&player_id=${playerId}&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const response = await fetch(`${API_URL}/pitchingstats/totals?season=${seasonNumber}&player_id=${playerId}&s_type=${isRegularSeason ? 'regular' : 'post'}`)
const legacyPitchingStatsResponse: {
count: number
@ -227,7 +227,7 @@ async function fetchLegacyPitchingStatsBySeasonAndPlayerId(seasonNumber: number,
}
export async function fetchPitchingStatsForLastFourGamesBySeasonAndPlayerId(seasonNumber: number, playerId: number): Promise<PitchingStat[]> {
const response = await fetch(`${SITE_URL}/api/v3/plays/pitching?season=${seasonNumber}&player_id=${playerId}&group_by=playergame&limit=4&s_type=regular&sort=newest`)
const response = await fetch(`${API_URL}/plays/pitching?season=${seasonNumber}&player_id=${playerId}&group_by=playergame&limit=4&s_type=regular&sort=newest`)
const pitchingStatsResponse: {
count: number
@ -247,7 +247,7 @@ export async function fetchPitchingStatsForLastTwoWeeksByTeam(seasonNumber: numb
return []
}
const response = await fetch(`${SITE_URL}/api/v3/plays/pitching?season=${seasonNumber}&week_start=${weekNumber - 1}&week_end=${weekNumber}&team_id=${teamId}&group_by=playergame`)
const response = await fetch(`${API_URL}/plays/pitching?season=${seasonNumber}&week_start=${weekNumber - 1}&week_end=${weekNumber}&team_id=${teamId}&group_by=playergame`)
const pitchingStatsResponse: {
count: number
@ -263,7 +263,7 @@ export async function fetchPitchingStatsBySeries(seasonNumber: number, weekNumbe
return []
}
const response = await fetch(`${SITE_URL}/api/v3/plays/pitching?season=${seasonNumber}&week=${weekNumber}&team_id=${homeTeamId}&team_id=${awayTeamId}&group_by=playergame`)
const response = await fetch(`${API_URL}/plays/pitching?season=${seasonNumber}&week=${weekNumber}&team_id=${homeTeamId}&team_id=${awayTeamId}&group_by=playergame`)
const pitchingStatsResponse: {
count: number

View File

@ -1,5 +1,5 @@
import type { Team } from './apiResponseTypes'
import { SITE_URL } from './utilities'
import { API_URL } from './utilities'
export interface Player {
bbref_id: string
@ -30,7 +30,7 @@ export interface Player {
}
export async function fetchPlayers(seasonNumber: number): Promise<Player[]> {
const response = await fetch(`${SITE_URL}/api/v3/players?season=${seasonNumber}`)
const response = await fetch(`${API_URL}/players?season=${seasonNumber}`)
const playersResponse: {
count: number
@ -42,7 +42,7 @@ export async function fetchPlayers(seasonNumber: number): Promise<Player[]> {
// TODO should/can this use team abbrev instead of id?
export async function fetchPlayersByTeam(seasonNumber: number, teamId: number): Promise<Player[]> {
const response = await fetch(`${SITE_URL}/api/v3/players?season=${seasonNumber}&team_id=${teamId}`)
const response = await fetch(`${API_URL}/players?season=${seasonNumber}&team_id=${teamId}`)
const playersResponse: {
count: number
@ -53,7 +53,7 @@ export async function fetchPlayersByTeam(seasonNumber: number, teamId: number):
}
export async function fetchPlayerByName(seasonNumber: number, playerName: string): Promise<Player | undefined> {
const response = await fetch(`${SITE_URL}/api/v3/players?season=${seasonNumber}&name=${playerName}`)
const response = await fetch(`${API_URL}/players?season=${seasonNumber}&name=${playerName}`)
const playersResponse: {
count: number

View File

@ -1,5 +1,5 @@
import type { Team } from './apiResponseTypes'
import { SITE_URL } from './utilities'
import { API_URL } from './utilities'
interface TeamStandingRaw {
away_losses: number
@ -62,7 +62,7 @@ export interface TeamStanding {
}
export async function fetchStandings(seasonNumber: number): Promise<TeamStanding[]> {
const response = await fetch(`${SITE_URL}/api/v3/standings?season=${seasonNumber}`)
const response = await fetch(`${API_URL}/standings?season=${seasonNumber}`)
const standingsResponse: {
count: number
@ -74,7 +74,7 @@ export async function fetchStandings(seasonNumber: number): Promise<TeamStanding
}
export async function fetchStandingByTeam(team: Team): Promise<TeamStanding | undefined> {
const response = await fetch(`${SITE_URL}/api/v3/standings?season=${team.season}`)
const response = await fetch(`${API_URL}/standings?season=${team.season}`)
const standingsResponse: {
count: number

View File

@ -1,8 +1,8 @@
import type { Team } from './apiResponseTypes'
import { CURRENT_SEASON, SITE_URL } from './utilities'
import { CURRENT_SEASON, API_URL } from './utilities'
export async function fetchTeam(seasonNumber: number, teamAbbreviation: string): Promise<Team> {
const response = await fetch(`${SITE_URL}/api/v3/teams?season=${seasonNumber}&team_abbrev=${teamAbbreviation}`)
const response = await fetch(`${API_URL}/teams?season=${seasonNumber}&team_abbrev=${teamAbbreviation}`)
const teamResponse: {
count: number
@ -17,7 +17,7 @@ export async function fetchTeam(seasonNumber: number, teamAbbreviation: string):
}
export async function fetchTeamsByManagerId(managerId: number): Promise<Team[]> {
const response = await fetch(`${SITE_URL}/api/v3/teams?manager_id=${managerId}`)
const response = await fetch(`${API_URL}/teams?manager_id=${managerId}`)
const teamResponse: {
count: number
@ -29,7 +29,7 @@ export async function fetchTeamsByManagerId(managerId: number): Promise<Team[]>
export async function fetchActiveTeamByOwnerId(ownerId: string): Promise<Team | undefined> {
const response = await fetch(`${SITE_URL}/api/v3/teams?season=${CURRENT_SEASON}&active_only=True&owner_id=${ownerId}`)
const response = await fetch(`${API_URL}/teams?season=${CURRENT_SEASON}&active_only=True&owner_id=${ownerId}`)
const teamResponse: {
count: number
@ -45,7 +45,7 @@ export async function fetchActiveTeamByOwnerId(ownerId: string): Promise<Team |
}
export async function fetchTeamsBySeason(season: number): Promise<Team[]> {
const response = await fetch(`${SITE_URL}/api/v3/teams?season=${season}&short_output=False`)
const response = await fetch(`${API_URL}/teams?season=${season}&short_output=False`)
const teamResponse: {
count: number

View File

@ -1,6 +1,6 @@
import type { Team } from './apiResponseTypes'
import type { Player } from './playersService'
import { CURRENT_SEASON, SITE_URL } from './utilities'
import { CURRENT_SEASON, API_URL } from './utilities'
export interface Transaction {
id: number
@ -15,7 +15,7 @@ export interface Transaction {
}
export async function fetchTransactionsByTeamAndWeek(seasonNumber: number, teamAbbreviation: string, weekNumber: number): Promise<Transaction[]> {
const response = await fetch(`${SITE_URL}/api/v3/transactions?season=${seasonNumber}&team_abbrev=${teamAbbreviation}&week_start=${weekNumber}&week_end=${weekNumber}`)
const response = await fetch(`${API_URL}/transactions?season=${seasonNumber}&team_abbrev=${teamAbbreviation}&week_start=${weekNumber}&week_end=${weekNumber}`)
const transactionsResponse: {
count: number
@ -26,7 +26,7 @@ export async function fetchTransactionsByTeamAndWeek(seasonNumber: number, teamA
}
export async function fetchTransactionsByWeek(seasonNumber: number, weekNumber: number): Promise<Transaction[]> {
const response = await fetch(`${SITE_URL}/api/v3/transactions?season=${seasonNumber}&week_start=${weekNumber}&week_end=${weekNumber}`)
const response = await fetch(`${API_URL}/transactions?season=${seasonNumber}&week_start=${weekNumber}&week_end=${weekNumber}`)
const transactionsResponse: {
count: number
@ -37,7 +37,7 @@ export async function fetchTransactionsByWeek(seasonNumber: number, weekNumber:
}
export async function fetchTransactionsForCurrentSeasonByPlayerName(playerName: string): Promise<Transaction[]> {
const response = await fetch(`${SITE_URL}/api/v3/transactions?season=${CURRENT_SEASON}&player_name=${playerName}`)
const response = await fetch(`${API_URL}/transactions?season=${CURRENT_SEASON}&player_name=${playerName}`)
const transactionsResponse: {
count: number

View File

@ -4,7 +4,9 @@ dayjs.extend(customParseFormat)
export const SITE_URL = 'https://sba.manticorum.com'
export const CURRENT_SEASON = 11
export const API_URL = 'https://api.sba.manticorum.com'
export const CURRENT_SEASON = 13
export const MODERN_STAT_ERA_START = 8
@ -15,10 +17,9 @@ export const WEEKS_PER_SEASON = 18
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
export const SEASON_START_DATE: dayjs.Dayjs = dayjs('12-16-2024', 'MM/DD/YYYY')
export const THANKSGIVING: dayjs.Dayjs = dayjs('11-27-2025', 'MM/DD/YYYY')
export const CHRISTMAS: dayjs.Dayjs = dayjs('12-25-2024', 'MM/DD/YYYY')
export const SEASON_START_DATE: dayjs.Dayjs = dayjs('2025-12-15')
export const THANKSGIVING: dayjs.Dayjs = dayjs('2026-11-26')
export const CHRISTMAS: dayjs.Dayjs = dayjs('2025-12-25')
export const POS_MAP = {
'P': 1,

View File

@ -24,8 +24,9 @@
<th style="width: 3rem">Home</th>
</tr>
</thead>
<tbody id="matchup-1">
<tr v-for="game in matchup" :key="game.id">
<tbody :id="`matchup-${index}`">
<tr v-for="game in matchup.sort((g1, g2) => g1.id - g2.id)" :key="game.id"
:id="`game-id-${game.id}`">
<td>
<RouterLink
:to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: game.away_team.abbrev } }"

View File

@ -8,7 +8,7 @@
</div>
<div class="row">
<div class="col-sm-12">
<h2 id="week-num">{{ weekNumber ? `Week ${weekNumber}` : '' }}</h2>
<h2 v-if="isCurrentSeason" id="week-num">{{ weekNumber ? `Week ${weekNumber}` : '' }}</h2>
</div>
</div>
@ -37,6 +37,18 @@
<ExtendedStandingsTable :teamsByDivision="standingsByDivision" />
</div>
</div>
<h3>
Standings Archive
</h3>
<span v-for="season in currentSeason" :key="season" style="padding-right: 1ch;">
<RouterLink v-if="season != seasonNumber" :to="{ name: 'standings', params: { seasonNumber: season } }">
S{{ season }}
</RouterLink>
<template v-else>
S{{ season }}
</template>
</span>
<div style="padding-bottom: 1em;"></div>
</div>
</main>
</template>
@ -56,22 +68,37 @@ export default {
},
data() {
return {
seasonNumber: CURRENT_SEASON as number,
currentSeason: CURRENT_SEASON,
weekNumber: undefined as number | undefined,
teamStandings: [] as TeamStanding[],
wildcardTeams: [] as TeamStanding[],
standingsByDivision: [[]] as TeamStanding[][]
}
},
props: {
seasonNumber: { type: Number, default: CURRENT_SEASON }
},
created() {
this.fetchData()
},
computed: {
isCurrentSeason(): boolean {
return this.seasonNumber == CURRENT_SEASON
}
},
watch: {
seasonNumber(newValue, oldValue) {
if (newValue !== oldValue) {
this.fetchData()
}
}
},
methods: {
async fetchData(): Promise<void> {
const leagueInfo: LeagueInfo = await fetchCurrentLeagueInfo()
this.weekNumber = leagueInfo.week
this.teamStandings = await fetchStandings(CURRENT_SEASON)
this.teamStandings = await fetchStandings(this.seasonNumber)
this.wildcardTeams = this.teamStandings.filter(ts => ts.isWildcardTeam)
const teamStandingsByDivisionAbbreviation: { [key: string]: TeamStanding[] } = {}

View File

@ -106,7 +106,7 @@
</template>
<script lang="ts">
import { type Team } from '@/services/apiResponseTypes'
import type { Team } from '@/services/apiResponseTypes'
import { type LeagueInfo, fetchCurrentLeagueInfo } from '@/services/currentService'
import { fetchTransactionsByWeek, type Transaction } from '@/services/transactionsService'
import { CURRENT_SEASON } from '@/services/utilities'