Manager tables and record

This commit is contained in:
Peter 2024-01-04 21:07:13 -05:00
parent 01567e3aee
commit ffa76ceb99
5 changed files with 162 additions and 100 deletions

View File

@ -37,7 +37,7 @@ import { CURRENT_SEASON } from '@/services/utilities'
export default {
name: "StandingsTable",
name: 'StandingsTable',
props: {
teams: {
type: Array<TeamStanding>,

View File

@ -24,3 +24,14 @@ export async function fetchAwardsByPlayerName(playerName: string): Promise<Award
return awardsResponse.awards
}
export async function fetchAwardsByManagerId(managerId: number): Promise<Award[]> {
const response = await fetch(`${SITE_URL}/api/v3/awards?manager_id=${managerId}`)
const awardsResponse: {
count: number
awards: Award[]
} = await response.json()
return awardsResponse.awards
}

View File

@ -34,6 +34,7 @@ interface TeamStandingRaw {
}
export interface TeamStanding {
season: number
teamName: string
teamAbbreviation: string
divisionAbbreviation: string
@ -63,6 +64,26 @@ export async function fetchStandings(seasonNumber: number): Promise<TeamStanding
return standings.map(normalizeStanding)
}
export async function fetchStandingByTeam(team: Team): Promise<TeamStanding | undefined> {
const response = await fetch(`${SITE_URL}/api/v3/standings?season=${team.season}`)
const standingsResponse: {
count: number
standings: TeamStandingRaw[]
} = await response.json()
const standings: TeamStandingRaw[] = standingsResponse.standings
const teamStanding: TeamStandingRaw | undefined = standings.find(ts => ts.team.sname === team.sname)
if (!teamStanding) {
// throw new Error('standingsService.fetchStandingByTeam - Expected one team standing, found none')
console.warn('standingsService.fetchStandingByTeam - Expected one team standing, found none')
return undefined
}
return normalizeStanding(teamStanding)
}
function normalizeStanding(standing: TeamStandingRaw): TeamStanding {
const totalGamesPlayed = standing.wins + standing.losses
// round win percentage to 3 decimal places
@ -72,6 +93,7 @@ function normalizeStanding(standing: TeamStandingRaw): TeamStanding {
const isWildcardTeam = standing.wc_gb !== null || standing.wc_e_num !== null
return {
season: standing.team.season,
teamName: standing.team.sname,
teamAbbreviation: standing.team.abbrev,
divisionAbbreviation: standing.team.division.division_abbrev,

View File

@ -16,6 +16,18 @@ export async function fetchTeam(seasonNumber: number, teamAbbreviation: string):
return teamResponse.teams[0]
}
export async function fetchTeamsByManagerId(managerId: number): Promise<Team[]> {
const response = await fetch(`${SITE_URL}/api/v3/teams?manager_id=${managerId}`)
const teamResponse: {
count: number
teams: Team[]
} = await response.json()
return teamResponse.teams
}
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}`)

View File

@ -32,16 +32,9 @@
<h1 id="manager-name">{{ managerName }}</h1>
</div>
<div>🚧 Coming Soon 🚧</div>
</div>
<!-- <div class="col-sm-12">
<h3 id="manager-record">Career Record: 294-218</h3>
</div>
<div class="col-sm-12">
<p id="manager-headline"></p>
</div>
<div class="col-sm-12" v-if="managerModel">
<!-- <h3 id="manager-record">Manager Record: {{ managerModel.managerWins }}-{{ managerModel.managerLosses }}</h3> -->
<h3 id="manager-record">Career Record: {{ managerModel.teamWins }}-{{ managerModel.teamLosses }}</h3>
</div>
<div class="row">
@ -55,38 +48,19 @@
<th>Team</th>
<th>Record</th>
</tr>
<tr>
<td>7</td>
<td><a href="/teams?abbrev=TK&amp;season=7">Tokyo Kaiju</a></td>
<td id="season-7-record">47-41</td>
</tr>
<tr>
<td>6</td>
<td><a href="/teams?abbrev=TK&amp;season=6">Tokyo Kaiju</a></td>
<td id="season-6-record">51-37</td>
</tr>
<tr>
<td>5</td>
<td><a href="/teams?abbrev=TK&amp;season=5">Tokyo Kaiju</a></td>
<td id="season-5-record">55-33</td>
</tr>
<tr>
<td>4</td>
<td><a href="/teams?abbrev=TK&amp;season=4">Tokyo Kaiju</a></td>
<td id="season-4-record">55-33</td>
</tr>
<tr>
<td>3</td>
<td><a href="/teams?abbrev=TK&amp;season=3">Tokyo Kaiju</a></td>
<td id="season-3-record">49-39</td>
</tr>
<tr>
<td>2</td>
<td><a href="/teams?abbrev=TK&amp;season=2">Tokyo Kaiju</a></td>
<td id="season-2-record">37-35</td>
</tr>
</thead>
<tbody id="manager-teams"></tbody>
<tbody>
<tr v-for="row in teamsManagedRows" :key="row.season">
<td>{{ row.season }}</td>
<td>
<RouterLink
:to="{ name: 'team', params: { seasonNumber: row.season, teamAbbreviation: row.teamAbbreviation } }">
{{ row.teamName }}
</RouterLink>
</td>
<td>{{ row.record }}</td>
</tr>
</tbody>
</table>
</div>
</div>
@ -99,61 +73,92 @@
<tr>
<th>Season</th>
<th>Award</th>
<th>Extras</th>
</tr>
<tr>
<td>3</td>
<td>AL Wildcard</td>
<td><a href="/teams?abbrev=TK&amp;season=3">Tokyo Kaiju</a></td>
</tr>
<tr>
<td>2</td>
<td>Most Hated Ballpark</td>
<td><a href="/teams?abbrev=TK&amp;season=2">Tokyo Kaiju</a></td>
</tr>
<tr>
<td>2</td>
<td>American League Pennant</td>
<td><a href="/teams?abbrev=TK&amp;season=2">Tokyo Kaiju</a></td>
</tr>
<tr>
<td>2</td>
<td>AL East Leader</td>
<td><a href="/teams?abbrev=TK&amp;season=2">Tokyo Kaiju</a></td>
<th>Team</th>
</tr>
</thead>
<tbody id="manager-awards"></tbody>
<tbody>
<tr v-for="award in managerAwards.slice().sort((a1, a2) => a2.season - a1.season)" :key="award.id">
<td>{{ award.season }}</td>
<td>{{ award.name }}</td>
<td>
<RouterLink
:to="{ name: 'team', params: { seasonNumber: award.season, teamAbbreviation: award.team!.abbrev } }">
{{ award.team!.sname }}
</RouterLink>
</td>
</tr>
</tbody>
</table>
</div>
</div> -->
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import type { Manager } from '@/services/apiResponseTypes'
import type { Manager, Team } from '@/services/apiResponseTypes'
import type { Award } from '@/services/awardsService'
import { fetchActiveManagers, fetchRetiredManagers } from '@/services/managerService'
import { fetchTeamsByManagerId } from '@/services/teamsService'
import { fetchAwardsByManagerId } from '@/services/awardsService'
import { fetchStandingByTeam, type TeamStanding } from '@/services/standingsService'
import { isNotUndefined } from '@/services/utilities'
interface ManagerModel {
managerWins: number
managerLosses: number
teamWins: number
teamLosses: number
}
export default {
name: 'ManagerView',
data() {
return {
activeManagers: [] as Manager[],
retiredManagers: [] as Manager[]
retiredManagers: [] as Manager[],
managerTeams: [] as Team[],
managerTeamStandings: [] as TeamStanding[],
managerAwards: [] as Award[]
}
},
props: {
managerName: { type: String, default: undefined },
},
computed: {
zippedManagers(): { active: Manager | undefined, retired: Manager | undefined }[] {
return this.activeManagers.map((mgr, idx) => {
selectedManager(): Manager | undefined {
if (!this.managerName) return undefined
return this.activeManagers.find(manager => manager.name === this.managerName) ?? this.retiredManagers.find(manager => manager.name === this.managerName)
},
managerModel(): ManagerModel | undefined {
if (!this.selectedManager) return undefined
return this.managerTeamStandings.reduce((acc, val) => {
return {
active: mgr,
retired: idx < this.retiredManagers.length ? this.retiredManagers[idx] : undefined
managerWins: acc.managerWins + val.wins,
managerLosses: acc.managerLosses + val.losses,
teamWins: acc.managerWins + val.wins,
teamLosses: acc.managerLosses + val.losses
}
}, {
managerWins: 0,
managerLosses: 0,
teamWins: 0,
teamLosses: 0
}
)
},
teamsManagedRows(): { season: number, teamName: string, teamAbbreviation: string, record: string }[] {
return this.managerTeams
.map(team => {
const standing = this.managerTeamStandings.find(ts => ts.season === team.season)
const record = `${standing?.wins ?? 0}-${standing?.losses ?? 0}`
return { season: team.season, teamName: team.sname, teamAbbreviation: team.abbrev, record }
})
.sort((r1, r2) => r2.season - r1.season)
}
},
created() {
@ -162,13 +167,25 @@ export default {
watch: {
managerName(newValue, oldValue) {
if (newValue !== oldValue)
this.fetchData()
this.fetchManagerData()
}
},
methods: {
async fetchData(): Promise<void> {
this.activeManagers = await fetchActiveManagers()
this.retiredManagers = await fetchRetiredManagers()
await this.fetchManagerData()
},
async fetchManagerData(): Promise<void> {
// need to fetch manager/team wins/losses and awards
// fetch all teams managed, then surface managerModel as a computed instead of data
if (!this.selectedManager) return
this.managerTeams = await fetchTeamsByManagerId(this.selectedManager.id)
this.managerTeamStandings = (await Promise.all(this.managerTeams.flatMap(team =>
fetchStandingByTeam(team)
))).filter(isNotUndefined)
this.managerAwards = await fetchAwardsByManagerId(this.selectedManager.id)
}
}
}