sba-website/src/views/TeamView.vue

275 lines
10 KiB
Vue

<template>
<div class="team-view centerDiv">
<div class="row">
<div class="col-sm">
<h1 id="team-record">{{ teamName }} {{ teamRecord }}</h1>
<h2 id="standings"></h2>
<h2 id="streak">Last 8: {{ lastEight }} / Streak: {{ streak }}</h2>
</div>
<div class="col-sm">
<h2 id="manager">
Manager{{ hasMultipleManagers ? 's' : '' }}:
<RouterLink v-if="manager1Name" :to="{ name: 'manager', params: { managerName: manager1Name } }">
{{ manager1Name }}
</RouterLink>
{{ hasMultipleManagers ? ' & ' : '' }}
<RouterLink v-if="hasMultipleManagers && manager2Name"
:to="{ name: 'manager', params: { managerName: manager2Name } }">
{{ manager2Name }}
</RouterLink>
</h2>
<h2 id="abbrev">Abbrev: {{ teamAbbreviation }}</h2>
</div>
<div class="col-sm-1">
<!-- TODO move thumbnail to computed and fallback on default pic? -->
<img id="thumbnail" height="125" style="float:right; vertical-align:middle" :src=team?.thumbnail>
</div>
</div>
<!-- Team Rosters -->
<div class="row">
<!-- Left Column -->
<div class="col-sm-6">
<h3 id="active-roster-count">({{ rosterCount }}/26) Active Roster ({{ swarTotal(players).toFixed(2) }})</h3>
<div class="table-responsive-xl">
<table class="table table-sm table-striped" id="table-active-roster">
<thead class="thead-dark">
<tr>
<th>Pos</th>
<th>Name</th>
<th>sWAR</th>
<th>Injury</th>
<th>Positions</th>
</tr>
</thead>
<tbody id="active-roster">
<tr v-for="player in sortedPlayers(players)">
<td>{{ player.pos_1 }}</td>
<td :title="player.il_return ? `Injured until ${player.il_return}` : ''">
{{ player.il_return ? '🏥' : '' }}
<RouterLink :to="{ name: 'player', params: { seasonNumber: seasonNumber, playerName: player.name } }">
{{ player.name }}
</RouterLink>
{{ player.il_return ? '🏥' : '' }}
</td>
<td>{{ player.wara.toFixed(2) }}</td>
<td>{{ player.injury_rating }}</td>
<td>{{ allPositions(player) }}</td>
</tr>
</tbody>
<tfoot>
<tr>
<th>Pos</th>
<th>Name</th>
<th>sWAR</th>
<th>Injury</th>
<th>Positions</th>
</tr>
</tfoot>
</table>
</div>
</div>
<!-- Right Column -->
<div v-if="!isFreeAgentTeam" class="col-sm-6">
<h3 id="minors-header">{{ minorsTeamName }} ({{ swarTotal(playersMinors).toFixed(2) }})</h3>
<div class="table-responsive-xl">
<table class="table table-sm table-striped" id="table-minors-roster">
<thead class="thead-dark">
<tr>
<th>Pos</th>
<th>Name</th>
<th>sWAR</th>
<th>Inj Return</th>
<th>Positions</th>
</tr>
</thead>
<tbody id="minors-roster">
<tr v-for="player in sortedPlayers(playersMinors)">
<td>{{ player.pos_1 }}</td>
<td>
<RouterLink :to="{ name: 'player', params: { seasonNumber: seasonNumber, playerName: player.name } }">
{{ player.name }}
</RouterLink>
</td>
<td>{{ player.wara.toFixed(2) }}</td>
<td>{{ player.il_return }}</td>
<td>{{ allPositions(player) }}</td>
</tr>
</tbody>
</table>
</div>
<h3 id="short-il-header">Injured List ({{ swarTotal(playersInjuredList).toFixed(2) }})</h3>
<div class="table-responsive-xl">
<table class="table table-sm table-striped" id="table-shortil-roster">
<thead class="thead-dark">
<tr>
<th>Pos</th>
<th>Name</th>
<th>sWAR</th>
<th>Inj Return</th>
<th>Positions</th>
</tr>
</thead>
<tbody id="short-il-roster">
<tr v-for="player in sortedPlayers(playersInjuredList)">
<td>{{ player.pos_1 }}</td>
<td>
<RouterLink :to="{ name: 'player', params: { seasonNumber: seasonNumber, playerName: player.name } }">
{{ player.name }}
</RouterLink>
</td>
<td>{{ player.wara.toFixed(2) }}</td>
<td>{{ player.il_return }}</td>
<td>{{ allPositions(player) }}</td>
</tr>
</tbody>
</table>
</div>
<h3 id="transactions-header">Week {{ transactionsWeekNumber }} Transactions ({{ transactionsWar.toFixed(2) }})
</h3>
<div class="table-responsive-xl">
<table class="table table-sm table-striped" id="table-transactions">
<thead class="thead-dark">
<tr>
<th>Week</th>
<th>Player</th>
<th>Old Team</th>
<th>New Team</th>
</tr>
</thead>
<tbody id="transactions-body"></tbody>
<tr v-for="row in transactionRows">
<td>{{ row.week }}</td>
<td>{{ row.playerName }}</td>
<td>{{ row.oldTeam }}</td>
<td>{{ row.newTeam }}</td>
</tr>
</table>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import type { Team } from '@/services/apiResponseTypes'
import { fetchCurrentLeagueInfo } from '@/services/currentService'
import { fetchPlayersByTeam, type Player } from '@/services/playersService'
import { fetchStandings, type TeamStanding } from '@/services/standingsService'
import { fetchTeam } from '@/services/teamsService'
import { fetchTransactionsByTeamAndWeek, type Transaction } from '@/services/transactionsService'
export default {
name: "TeamView",
data() {
return {
team: undefined as Team | undefined,
teamMinors: undefined as Team | undefined,
teamInjuredList: undefined as Team | undefined,
teamStanding: undefined as TeamStanding | undefined,
players: [] as Player[],
playersMinors: [] as Player[],
playersInjuredList: [] as Player[],
transactions: [] as Transaction[],
weekNumber: undefined as number | undefined
}
},
props: {
seasonNumber: { type: Number, required: true },
teamAbbreviation: { type: String, required: true },
},
computed: {
isFreeAgentTeam(): boolean {
return this.teamAbbreviation === 'FA'
},
manager1Name(): string | undefined {
return this.team?.manager1?.name
},
manager2Name(): string | undefined {
return this.team?.manager2?.name
},
hasMultipleManagers(): boolean {
return !!(this.manager1Name && this.manager2Name)
},
teamName(): string | undefined {
return this.team?.lname
},
teamRecord(): string | undefined {
if (!this.teamStanding) return undefined
return `(${this.teamStanding?.wins}-${this.teamStanding.losses})`
},
minorsTeamName(): string | undefined {
return this.teamMinors?.sname
},
lastEight(): string | undefined {
return this.teamStanding?.last8Record
},
streak(): string | undefined {
return this.teamStanding?.streak
},
rosterCount(): number {
return this.players.length
},
transactionsWeekNumber(): number | undefined {
if (this.weekNumber === undefined) return undefined
return this.weekNumber + 1
},
transactionsWar(): number {
const teamsWar = this.swarTotal(this.players)
if (!this.transactions.length) return teamsWar
const playersOut = this.transactions.filter(t => t.oldteam.abbrev === this.teamAbbreviation).map(t => t.player)
const playersIn = this.transactions.filter(t => t.newteam.abbrev === this.teamAbbreviation).map(t => t.player)
const swarOut = this.swarTotal(playersOut)
const swarIn = this.swarTotal(playersIn)
return teamsWar - swarOut + swarIn
},
transactionRows(): { week: number, playerName: string, oldTeam: string, newTeam: string }[] {
return this.transactions.map(t => {
return { week: t.week, playerName: t.player.name, oldTeam: t.oldteam.sname, newTeam: t.newteam.sname }
})
}
},
created() {
this.fetchData()
},
methods: {
async fetchData(): Promise<void> {
this.team = await fetchTeam(this.seasonNumber, this.teamAbbreviation)
if (!this.isFreeAgentTeam) {
this.teamMinors = await fetchTeam(this.seasonNumber, `${this.teamAbbreviation}MiL`)
this.teamInjuredList = await fetchTeam(this.seasonNumber, `${this.teamAbbreviation}IL`)
}
this.teamStanding = (await fetchStandings(this.seasonNumber)).find(ts => ts.teamName === this.team?.sname)
this.weekNumber = (await fetchCurrentLeagueInfo()).week
this.players = await fetchPlayersByTeam(this.seasonNumber, this.team?.id)
if (!this.isFreeAgentTeam) {
this.playersMinors = await fetchPlayersByTeam(this.seasonNumber, this.teamMinors!.id)
this.playersInjuredList = await fetchPlayersByTeam(this.seasonNumber, this.teamInjuredList!.id)
}
this.transactions = (await fetchTransactionsByTeamAndWeek(this.seasonNumber, this.teamAbbreviation, this.transactionsWeekNumber!))
},
allPositions(player: Player): string {
let positions = []
positions.push(player.pos_1, player.pos_2, player.pos_3, player.pos_4, player.pos_5, player.pos_6, player.pos_7)
return positions.join(" ")
},
swarTotal(players: Player[]): number {
return players.map(p => p.wara).reduce((prev, curr) => prev + curr, 0)
},
sortedPlayers(players: Player[]): Player[] {
return players.sort((a, b) => b.wara - a.wara)
}
}
}
</script>