Manager tables and record
This commit is contained in:
parent
01567e3aee
commit
ffa76ceb99
@ -37,7 +37,7 @@ import { CURRENT_SEASON } from '@/services/utilities'
|
|||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "StandingsTable",
|
name: 'StandingsTable',
|
||||||
props: {
|
props: {
|
||||||
teams: {
|
teams: {
|
||||||
type: Array<TeamStanding>,
|
type: Array<TeamStanding>,
|
||||||
|
|||||||
@ -24,3 +24,14 @@ export async function fetchAwardsByPlayerName(playerName: string): Promise<Award
|
|||||||
|
|
||||||
return awardsResponse.awards
|
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
|
||||||
|
}
|
||||||
|
|||||||
@ -34,6 +34,7 @@ interface TeamStandingRaw {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface TeamStanding {
|
export interface TeamStanding {
|
||||||
|
season: number
|
||||||
teamName: string
|
teamName: string
|
||||||
teamAbbreviation: string
|
teamAbbreviation: string
|
||||||
divisionAbbreviation: string
|
divisionAbbreviation: string
|
||||||
@ -63,6 +64,26 @@ export async function fetchStandings(seasonNumber: number): Promise<TeamStanding
|
|||||||
return standings.map(normalizeStanding)
|
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 {
|
function normalizeStanding(standing: TeamStandingRaw): TeamStanding {
|
||||||
const totalGamesPlayed = standing.wins + standing.losses
|
const totalGamesPlayed = standing.wins + standing.losses
|
||||||
// round win percentage to 3 decimal places
|
// 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
|
const isWildcardTeam = standing.wc_gb !== null || standing.wc_e_num !== null
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
season: standing.team.season,
|
||||||
teamName: standing.team.sname,
|
teamName: standing.team.sname,
|
||||||
teamAbbreviation: standing.team.abbrev,
|
teamAbbreviation: standing.team.abbrev,
|
||||||
divisionAbbreviation: standing.team.division.division_abbrev,
|
divisionAbbreviation: standing.team.division.division_abbrev,
|
||||||
|
|||||||
@ -16,6 +16,18 @@ export async function fetchTeam(seasonNumber: number, teamAbbreviation: string):
|
|||||||
return teamResponse.teams[0]
|
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> {
|
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(`${SITE_URL}/api/v3/teams?season=${CURRENT_SEASON}&active_only=True&owner_id=${ownerId}`)
|
||||||
|
|
||||||
|
|||||||
@ -32,128 +32,133 @@
|
|||||||
<h1 id="manager-name">{{ managerName }}</h1>
|
<h1 id="manager-name">{{ managerName }}</h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>🚧 Coming Soon 🚧</div>
|
<div class="col-sm-12" v-if="managerModel">
|
||||||
</div>
|
<!-- <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="col-sm-12">
|
<div class="row">
|
||||||
<h3 id="manager-record">Career Record: 294-218</h3>
|
<div class="col-sm-4">
|
||||||
</div>
|
<h3 style="text-align: center">Teams Managed</h3>
|
||||||
|
<div class="table-responsive-xl">
|
||||||
|
<table style="text-align: center" class="table table-sm table-striped" id="manager-teams-table">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Season</th>
|
||||||
|
<th>Team</th>
|
||||||
|
<th>Record</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<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>
|
||||||
|
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-5">
|
||||||
<p id="manager-headline"></p>
|
<h3 style="text-align: center">Awards Received</h3>
|
||||||
</div>
|
<div class="table-responsive-xl">
|
||||||
</div>
|
<table style="text-align: center" class="table table-sm table-striped" id="manager-awards-table">
|
||||||
|
<thead class="thead-dark">
|
||||||
<div class="row">
|
<tr>
|
||||||
<div class="col-sm-4">
|
<th>Season</th>
|
||||||
<h3 style="text-align: center">Teams Managed</h3>
|
<th>Award</th>
|
||||||
<div class="table-responsive-xl">
|
<th>Team</th>
|
||||||
<table style="text-align: center" class="table table-sm table-striped" id="manager-teams-table">
|
</tr>
|
||||||
<thead class="thead-dark">
|
</thead>
|
||||||
<tr>
|
<tbody>
|
||||||
<th>Season</th>
|
<tr v-for="award in managerAwards.slice().sort((a1, a2) => a2.season - a1.season)" :key="award.id">
|
||||||
<th>Team</th>
|
<td>{{ award.season }}</td>
|
||||||
<th>Record</th>
|
<td>{{ award.name }}</td>
|
||||||
</tr>
|
<td>
|
||||||
<tr>
|
<RouterLink
|
||||||
<td>7</td>
|
:to="{ name: 'team', params: { seasonNumber: award.season, teamAbbreviation: award.team!.abbrev } }">
|
||||||
<td><a href="/teams?abbrev=TK&season=7">Tokyo Kaiju</a></td>
|
{{ award.team!.sname }}
|
||||||
<td id="season-7-record">47-41</td>
|
</RouterLink>
|
||||||
</tr>
|
</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>6</td>
|
</tbody>
|
||||||
<td><a href="/teams?abbrev=TK&season=6">Tokyo Kaiju</a></td>
|
</table>
|
||||||
<td id="season-6-record">51-37</td>
|
</div>
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
|
||||||
<td>5</td>
|
|
||||||
<td><a href="/teams?abbrev=TK&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&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&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&season=2">Tokyo Kaiju</a></td>
|
|
||||||
<td id="season-2-record">37-35</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="manager-teams"></tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-5">
|
|
||||||
<h3 style="text-align: center">Awards Received</h3>
|
|
||||||
<div class="table-responsive-xl">
|
|
||||||
<table style="text-align: center" class="table table-sm table-striped" id="manager-awards-table">
|
|
||||||
<thead class="thead-dark">
|
|
||||||
<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&season=3">Tokyo Kaiju</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>2</td>
|
|
||||||
<td>Most Hated Ballpark</td>
|
|
||||||
<td><a href="/teams?abbrev=TK&season=2">Tokyo Kaiju</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>2</td>
|
|
||||||
<td>American League Pennant</td>
|
|
||||||
<td><a href="/teams?abbrev=TK&season=2">Tokyo Kaiju</a></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>2</td>
|
|
||||||
<td>AL East Leader</td>
|
|
||||||
<td><a href="/teams?abbrev=TK&season=2">Tokyo Kaiju</a></td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody id="manager-awards"></tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<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 { 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 {
|
export default {
|
||||||
name: 'ManagerView',
|
name: 'ManagerView',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
activeManagers: [] as Manager[],
|
activeManagers: [] as Manager[],
|
||||||
retiredManagers: [] as Manager[]
|
retiredManagers: [] as Manager[],
|
||||||
|
managerTeams: [] as Team[],
|
||||||
|
managerTeamStandings: [] as TeamStanding[],
|
||||||
|
managerAwards: [] as Award[]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
managerName: { type: String, default: undefined },
|
managerName: { type: String, default: undefined },
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
zippedManagers(): { active: Manager | undefined, retired: Manager | undefined }[] {
|
selectedManager(): Manager | undefined {
|
||||||
return this.activeManagers.map((mgr, idx) => {
|
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 {
|
return {
|
||||||
active: mgr,
|
managerWins: acc.managerWins + val.wins,
|
||||||
retired: idx < this.retiredManagers.length ? this.retiredManagers[idx] : undefined
|
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() {
|
created() {
|
||||||
@ -162,14 +167,26 @@ export default {
|
|||||||
watch: {
|
watch: {
|
||||||
managerName(newValue, oldValue) {
|
managerName(newValue, oldValue) {
|
||||||
if (newValue !== oldValue)
|
if (newValue !== oldValue)
|
||||||
this.fetchData()
|
this.fetchManagerData()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async fetchData(): Promise<void> {
|
async fetchData(): Promise<void> {
|
||||||
this.activeManagers = await fetchActiveManagers()
|
this.activeManagers = await fetchActiveManagers()
|
||||||
this.retiredManagers = await fetchRetiredManagers()
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user