sba-website/src/views/PlayerView.vue

146 lines
5.0 KiB
Vue

<template>
<div class="player-view">
<div class="centerDiv">
<!-- Heading -->
<div class="row">
<div class="col-sm">
<h1 id="player-name">{{ playerName }}{{ injuryReturnDate }}</h1>
<h2 id="player-wara">{{ player?.wara }} sWAR</h2>
</div>
<div class="col-sm-1">
<RouterLink v-if="teamAbbreviation && teamThumbnail"
:to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: teamAbbreviation } }">
<img id="thumbnail" height="125" style="float:right; vertical-align:middle; max-height:100%;"
:src="teamThumbnail">
</RouterLink>
</div>
</div>
<div class="row">
<div class="col-sm-auto">
<img style="max-height:485px; max-width: 100%;" id="team-image" :src="playerImageUrl" :alt="playerName">
<p><a id="bbref-link" target="_blank" :href="baseballReferenceUrl">Baseball Reference Page</a></p>
</div>
<div class="col-sm-auto">
<img v-if="playerCardImage1Url" style="max-height:485px; max-width: 100%;" id="card-image"
:src="playerCardImage1Url">
<img v-if="playerCardImage2Url" style="max-height:485px; max-width: 100%;" id="card-image"
:src="playerCardImage2Url">
</div>
</div>
<!-- Player Summary -->
<div class="row" id="batter-summary">
<div class="col-sm-4">
<div class="table-responsive-xl" style="max-width:20rem">
<table class="table table-sm table-striped">
<thead class="thead-dark">
<tr>
<th>Inj</th>
<th v-if="lastAppearance">Last App</th>
<th v-if="secondLastAppearance">2nd Last App</th>
</tr>
</thead>
<tbody id="batter-summary-helper">
<tr>
<td>{{ injuryRating }}</td>
<td v-if="lastAppearance">{{ lastAppearance }}</td>
<td v-if="secondLastAppearance">{{ secondLastAppearance }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import { isDiscordAuthenticated } from '@/services/authenticationService'
import { fetchLast2DecisionsByPlayerId, type Decision } from '@/services/decisionsService'
import { type Player, fetchPlayerByName } from '@/services/playersService'
export default {
name: "TeamView",
data() {
return {
player: undefined as Player | undefined,
last2Decisions: [] as Decision[]
}
},
props: {
seasonNumber: { type: Number, required: true },
playerName: { type: String, required: true }
},
computed: {
isAuthenticated(): boolean {
return isDiscordAuthenticated()
},
teamAbbreviation(): string | undefined {
return this.player?.team?.abbrev
},
teamThumbnail(): string | undefined {
return this.player?.team?.thumbnail
},
baseballReferenceUrl(): string | undefined {
if (!this.player?.bbref_id) return undefined
const firstChar = this.player.bbref_id.slice(0, 1)
return `https://www.baseball-reference.com/players/${firstChar}/${this.player.bbref_id}.shtml`
},
playerImageUrl(): string | undefined {
return this.player?.vanity_card ?? this.teamThumbnail
},
playerCardImage1Url(): string | undefined {
if (!this.isAuthenticated) return undefined
return this.player?.image
},
playerCardImage2Url(): string | undefined {
if (!this.isAuthenticated) return undefined
return this.player?.image2
},
injuryReturnDate(): string | undefined {
if (!this.player?.il_return) return undefined
return ` 🏥 (${this.player.il_return})`
},
injuryRating(): string | undefined {
return this.player?.injury_rating
},
lastAppearance(): string | undefined {
if (!this.last2Decisions?.length) return undefined
if (this.last2Decisions.length <= 0) return undefined
return this.formatDecisionToAppearance(this.last2Decisions[0])
},
secondLastAppearance(): string | undefined {
if (!this.last2Decisions?.length) return undefined
if (this.last2Decisions.length <= 1) return '-'
return this.formatDecisionToAppearance(this.last2Decisions[1])
}
},
created() {
this.fetchData()
},
watch: {
seasonNumber(newValue, oldValue) {
if (newValue !== oldValue) this.fetchData()
},
playerName(newName, oldName) {
if (newName !== oldName) this.fetchData()
}
},
methods: {
async fetchData(): Promise<void> {
this.player = await fetchPlayerByName(this.seasonNumber, this.playerName)
this.last2Decisions = await fetchLast2DecisionsByPlayerId(this.seasonNumber, this.player?.id)
},
formatDecisionToAppearance(decision: Decision): string {
return `${decision.rest_ip.toFixed(1)}IP w${decision.week}g${decision.game_num}`
}
}
}
</script>