Add buttons to navigate through players cards from different sets
This commit is contained in:
parent
8a56977446
commit
d5252f99b7
1
components.d.ts
vendored
1
components.d.ts
vendored
@ -9,6 +9,7 @@ export {}
|
|||||||
|
|
||||||
declare module '@vue/runtime-core' {
|
declare module '@vue/runtime-core' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
|
CardImagesDisplay: typeof import('./src/components/CardImagesDisplay.vue')['default']
|
||||||
IconCommunity: typeof import('./src/components/icons/IconCommunity.vue')['default']
|
IconCommunity: typeof import('./src/components/icons/IconCommunity.vue')['default']
|
||||||
IconDocumentation: typeof import('./src/components/icons/IconDocumentation.vue')['default']
|
IconDocumentation: typeof import('./src/components/icons/IconDocumentation.vue')['default']
|
||||||
IconEcosystem: typeof import('./src/components/icons/IconEcosystem.vue')['default']
|
IconEcosystem: typeof import('./src/components/icons/IconEcosystem.vue')['default']
|
||||||
|
|||||||
125
src/components/CardImagesDisplay.vue
Normal file
125
src/components/CardImagesDisplay.vue
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
<template>
|
||||||
|
<div class="card-images-display">
|
||||||
|
<div class="col-sm-auto" style="max-width: 941px;">
|
||||||
|
<div class="row">
|
||||||
|
<img v-if="selectedCardImage1Url" style="max-height:486px; max-width: 941px;" id="card-image"
|
||||||
|
:src="selectedCardImage1Url">
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<img v-if="selectedCardImage2Url" style="max-height:486px; max-width: 941px;" id="card-image"
|
||||||
|
:src="selectedCardImage2Url">
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<!-- TODO set visibility off if there is another key with lower value -->
|
||||||
|
<div v-visible="hasPreviousCard" class="col-sm-5">
|
||||||
|
<input type="button" class="w-100" @click="decrementCurrentSeasonNumber" value="<<" />
|
||||||
|
</div>
|
||||||
|
<strong class="col-sm-2" style="text-align: center;">
|
||||||
|
{{ getSeasonStringBySeasonNumber(currentSeasonNumber) }}
|
||||||
|
</strong>
|
||||||
|
<div v-visible="hasNextCard" class="col-sm-5">
|
||||||
|
<input type="button" class="w-100" @click="incrementCurrentSeasonNumber" value=">>" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import type { Player } from '@/services/playersService'
|
||||||
|
import { CURRENT_SEASON } from '@/services/utilities'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CardImagesDisplay',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
currentSeasonNumber: this.selectedSeasonNumber
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
isAuthenticated: { type: Boolean, default: false },
|
||||||
|
selectedSeasonNumber: { type: Number, required: true },
|
||||||
|
playerSeasons: { type: Array<Player>, default: [] },
|
||||||
|
playerName: { type: String, required: true }
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
cardImage1UrlBySeasonNumber(): Map<number, string> {
|
||||||
|
return new Map(this.playerSeasons.map(ps => [ps.season, ps.image]))
|
||||||
|
},
|
||||||
|
cardImage2UrlBySeasonNumber(): Map<number, string> {
|
||||||
|
return new Map(this.playerSeasons.map(ps => [ps.season, ps.image2]))
|
||||||
|
},
|
||||||
|
selectedCardImage1Url(): string | undefined {
|
||||||
|
if (!this.cardImage1UrlBySeasonNumber.has(this.currentSeasonNumber)) return undefined
|
||||||
|
|
||||||
|
return this.cardImage1UrlBySeasonNumber.get(this.currentSeasonNumber)
|
||||||
|
},
|
||||||
|
selectedCardImage2Url(): string | undefined {
|
||||||
|
if (!this.cardImage2UrlBySeasonNumber.has(this.currentSeasonNumber)) return undefined
|
||||||
|
|
||||||
|
return this.cardImage2UrlBySeasonNumber.get(this.currentSeasonNumber)
|
||||||
|
},
|
||||||
|
hasPreviousCard(): boolean {
|
||||||
|
const currentImage = this.cardImage1UrlBySeasonNumber.get(this.currentSeasonNumber)
|
||||||
|
let season = this.currentSeasonNumber
|
||||||
|
while (season > 0) {
|
||||||
|
season--
|
||||||
|
if (this.cardImage1UrlBySeasonNumber.has(season)
|
||||||
|
&& currentImage !== this.cardImage1UrlBySeasonNumber.get(season)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
hasNextCard(): boolean {
|
||||||
|
const currentImage = this.cardImage1UrlBySeasonNumber.get(this.currentSeasonNumber)
|
||||||
|
let season = this.currentSeasonNumber
|
||||||
|
while (season <= CURRENT_SEASON) {
|
||||||
|
season++
|
||||||
|
if (this.cardImage1UrlBySeasonNumber.has(season)
|
||||||
|
&& currentImage !== this.cardImage1UrlBySeasonNumber.get(season)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
playerName(newName, oldName) {
|
||||||
|
if (newName !== oldName) {
|
||||||
|
this.currentSeasonNumber = this.selectedSeasonNumber
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getSeasonStringBySeasonNumber(season: number): string {
|
||||||
|
if (season === 1) return 'S1'
|
||||||
|
|
||||||
|
// assumes seasons will continue to be paired like S2/3, S4/5, etc.
|
||||||
|
const firstSeason = Math.trunc(season / 2) * 2
|
||||||
|
return `S${firstSeason}/${firstSeason + 1}`
|
||||||
|
},
|
||||||
|
decrementCurrentSeasonNumber(): void {
|
||||||
|
const currentImage = this.cardImage1UrlBySeasonNumber.get(this.currentSeasonNumber)
|
||||||
|
while (this.currentSeasonNumber > 0) {
|
||||||
|
this.currentSeasonNumber--
|
||||||
|
if (this.cardImage1UrlBySeasonNumber.has(this.currentSeasonNumber)
|
||||||
|
&& currentImage !== this.cardImage1UrlBySeasonNumber.get(this.currentSeasonNumber)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
incrementCurrentSeasonNumber(): void {
|
||||||
|
const currentImage = this.cardImage1UrlBySeasonNumber.get(this.currentSeasonNumber)
|
||||||
|
while (this.currentSeasonNumber <= CURRENT_SEASON) {
|
||||||
|
this.currentSeasonNumber++
|
||||||
|
if (this.cardImage1UrlBySeasonNumber.has(this.currentSeasonNumber)
|
||||||
|
&& currentImage !== this.cardImage1UrlBySeasonNumber.get(this.currentSeasonNumber)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
@ -11,6 +11,11 @@ import './assets/oldSite.css'
|
|||||||
|
|
||||||
const app = createApp(App as any)
|
const app = createApp(App as any)
|
||||||
|
|
||||||
|
app.directive('visible', function (el, binding) {
|
||||||
|
// eslint-disable-next-line no-extra-boolean-cast
|
||||||
|
el.style.visibility = !!binding?.value ? 'visible' : 'hidden'
|
||||||
|
})
|
||||||
|
|
||||||
app.use(router)
|
app.use(router)
|
||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|||||||
@ -15,6 +15,9 @@
|
|||||||
<h2 class="text-center">
|
<h2 class="text-center">
|
||||||
Season {{ seasonNumber }} - Week {{ weekNumber }} - Game {{ gameNumber }}
|
Season {{ seasonNumber }} - Week {{ weekNumber }} - Game {{ gameNumber }}
|
||||||
</h2>
|
</h2>
|
||||||
|
<h3>
|
||||||
|
<!-- TODO show pitching decisions and link to google sheet if exists -->
|
||||||
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-2">
|
<div class="col-sm-2">
|
||||||
<RouterLink v-if="homeTeamAbbreviation && homeTeamThumbnail"
|
<RouterLink v-if="homeTeamAbbreviation && homeTeamThumbnail"
|
||||||
@ -417,6 +420,9 @@ export default {
|
|||||||
&& fs.game.game_num === this.gameNumber
|
&& fs.game.game_num === this.gameNumber
|
||||||
&& fs.team.abbrev === this.awayTeamAbbreviation)
|
&& fs.team.abbrev === this.awayTeamAbbreviation)
|
||||||
.sort((a, b) => b.xCheckCount - a.xCheckCount)
|
.sort((a, b) => b.xCheckCount - a.xCheckCount)
|
||||||
|
},
|
||||||
|
sheetsUrl(): string | undefined {
|
||||||
|
return this.game?.scorecard_url
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
|||||||
@ -5,10 +5,10 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm">
|
<div class="col-sm">
|
||||||
<h1 id="player-name">{{ playerName }}{{ injuryReturnDate }}</h1>
|
<h1 id="player-name">{{ playerName }}{{ injuryReturnDate }}</h1>
|
||||||
<h2 v-if="isCurrentPlayer" id="player-wara">{{ player?.wara }} sWAR</h2>
|
<h2 id="player-wara">{{ player?.wara }} sWAR</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isCurrentPlayer" class="col-sm-1">
|
<div class="col-sm-1">
|
||||||
<RouterLink v-if="teamAbbreviation && teamThumbnail"
|
<RouterLink v-if="teamAbbreviation && teamThumbnail"
|
||||||
:to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: teamAbbreviation } }">
|
:to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: teamAbbreviation } }">
|
||||||
<img id="thumbnail" height="125" style="float:right; vertical-align:middle; max-height:100%;"
|
<img id="thumbnail" height="125" style="float:right; vertical-align:middle; max-height:100%;"
|
||||||
@ -17,22 +17,39 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="isCurrentPlayer" class="row">
|
<div class="row">
|
||||||
<div class="col-sm-auto">
|
<div class="col-sm-auto">
|
||||||
<img style="max-height:485px; max-width: 100%;" id="team-image" :src="playerImageUrl" :alt="playerName">
|
<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>
|
<p><a id="bbref-link" target="_blank" :href="baseballReferenceUrl">Baseball Reference Page</a></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-auto">
|
<CardImagesDisplay :player-seasons="playerSeasons" :player-name="playerName"
|
||||||
<img v-if="playerCardImage1Url" style="max-height:485px; max-width: 100%;" id="card-image"
|
:selected-season-number="seasonNumber" :is-authenticated="isAuthenticated" />
|
||||||
:src="playerCardImage1Url">
|
<!-- <div class="col-sm-auto">
|
||||||
<img v-if="playerCardImage2Url" style="max-height:485px; max-width: 100%;" id="card-image"
|
<div class="row">
|
||||||
:src="playerCardImage2Url">
|
<img v-if="playerCardImage1Url" style="max-height:485px; max-width: 100%;" id="card-image"
|
||||||
</div>
|
:src="playerCardImage1Url">
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<img v-if="playerCardImage2Url" style="max-height:485px; max-width: 100%;" id="card-image"
|
||||||
|
:src="playerCardImage2Url">
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div v-visible="false" class="col-sm-5">
|
||||||
|
<input type="button" class="w-100" @click="console.log('foo')" value="<<" />
|
||||||
|
</div>
|
||||||
|
<strong class="col-sm-2" style="text-align: center;">
|
||||||
|
S8/9
|
||||||
|
</strong>
|
||||||
|
<div v-visible="false" class="col-sm-5">
|
||||||
|
<input type="button" class="w-100" @click="console.log('bar')" value=">>" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Summary -->
|
<!-- Summary -->
|
||||||
<div v-if="isCurrentPlayer" class="row" id="batter-summary">
|
<div class="row" id="batter-summary">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<h3>Summary</h3>
|
<h3>Summary</h3>
|
||||||
</div>
|
</div>
|
||||||
@ -158,6 +175,7 @@ import PlayerCareerPitchingTable from '@/components/PlayerCareerPitchingTable.vu
|
|||||||
import PlayerCareerFieldingTable from '@/components/PlayerCareerFieldingTable.vue'
|
import PlayerCareerFieldingTable from '@/components/PlayerCareerFieldingTable.vue'
|
||||||
import PlayerBattingSummaryTable from '@/components/PlayerBattingSummaryTable.vue'
|
import PlayerBattingSummaryTable from '@/components/PlayerBattingSummaryTable.vue'
|
||||||
import PlayerPitchingSummaryTable from '@/components/PlayerPitchingSummaryTable.vue'
|
import PlayerPitchingSummaryTable from '@/components/PlayerPitchingSummaryTable.vue'
|
||||||
|
import CardImagesDisplay from '@/components/CardImagesDisplay.vue'
|
||||||
import { fetchPitchingStatsBySeasonAndPlayerId, fetchPitchingStatsForLastFourGamesBySeasonAndPlayerId, type PitchingStat } from '@/services/pitchingStatsService'
|
import { fetchPitchingStatsBySeasonAndPlayerId, fetchPitchingStatsForLastFourGamesBySeasonAndPlayerId, type PitchingStat } from '@/services/pitchingStatsService'
|
||||||
import { fetchFieldingStatsBySeasonAndPlayerId, fetchFieldingStatsForLastFourGamesBySeasonAndPlayerId, type FieldingStat } from '@/services/fieldingStatsService'
|
import { fetchFieldingStatsBySeasonAndPlayerId, fetchFieldingStatsForLastFourGamesBySeasonAndPlayerId, type FieldingStat } from '@/services/fieldingStatsService'
|
||||||
import { fetchTransactionsForCurrentSeasonByPlayerName, type Transaction } from '@/services/transactionsService'
|
import { fetchTransactionsForCurrentSeasonByPlayerName, type Transaction } from '@/services/transactionsService'
|
||||||
@ -169,6 +187,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
player: undefined as Player | undefined,
|
player: undefined as Player | undefined,
|
||||||
|
playerSeasons: [] as Player[],
|
||||||
last2Decisions: [] as Decision[],
|
last2Decisions: [] as Decision[],
|
||||||
// Batting stats
|
// Batting stats
|
||||||
regularSeasonBattingStats: [] as BattingStat[],
|
regularSeasonBattingStats: [] as BattingStat[],
|
||||||
@ -198,19 +217,14 @@ export default {
|
|||||||
PlayerPitchingSummaryTable,
|
PlayerPitchingSummaryTable,
|
||||||
PlayerCareerPitchingTable,
|
PlayerCareerPitchingTable,
|
||||||
LastFourGamesPitchingTable,
|
LastFourGamesPitchingTable,
|
||||||
PlayerCareerFieldingTable
|
PlayerCareerFieldingTable,
|
||||||
|
CardImagesDisplay
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
seasonNumber: { type: Number, required: true },
|
seasonNumber: { type: Number, required: true },
|
||||||
playerName: { type: String, required: true }
|
playerName: { type: String, required: true }
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
playerSeasonNumber(): number | undefined {
|
|
||||||
return this.player?.season
|
|
||||||
},
|
|
||||||
isCurrentPlayer(): boolean {
|
|
||||||
return this.seasonNumber === this.playerSeasonNumber
|
|
||||||
},
|
|
||||||
isBatter(): boolean {
|
isBatter(): boolean {
|
||||||
return !this.player?.pos_1.includes('P')
|
return !this.player?.pos_1.includes('P')
|
||||||
},
|
},
|
||||||
@ -313,13 +327,16 @@ export default {
|
|||||||
|
|
||||||
// TODO: this should change, either with an api that can take a player name for every season, a way
|
// TODO: this should change, either with an api that can take a player name for every season, a way
|
||||||
// to get multiple seasons stats at once, or a players ids across all seasons at once
|
// to get multiple seasons stats at once, or a players ids across all seasons at once
|
||||||
const playerSeasons = await Promise.all(Array.from(Array(CURRENT_SEASON), (element, index) => index + 1).map(seasonNumber => fetchPlayerByName(seasonNumber, this.player!.name)))
|
this.playerSeasons = (await Promise.all(Array.from(Array(CURRENT_SEASON), (element, index) => index + 1).map(seasonNumber => fetchPlayerByName(seasonNumber, this.player!.name)))).filter(isNotUndefined)
|
||||||
this.regularSeasonBattingStats = (await Promise.all(playerSeasons.filter(isNotUndefined).map(player => fetchBattingStatsBySeasonAndPlayerId(player!.season, player!.id, true)))).filter(isNotUndefined)
|
this.regularSeasonBattingStats = (await Promise.all(this.playerSeasons.map(player => fetchBattingStatsBySeasonAndPlayerId(player!.season, player!.id, true)))).filter(isNotUndefined)
|
||||||
this.postSeasonBattingStats = (await Promise.all(playerSeasons.filter(isNotUndefined).map(player => fetchBattingStatsBySeasonAndPlayerId(player!.season, player!.id, false)))).filter(isNotUndefined)
|
this.postSeasonBattingStats = (await Promise.all(this.playerSeasons.map(player => fetchBattingStatsBySeasonAndPlayerId(player!.season, player!.id, false)))).filter(isNotUndefined)
|
||||||
this.regularSeasonPitchingStats = (await Promise.all(playerSeasons.filter(isNotUndefined).map(player => fetchPitchingStatsBySeasonAndPlayerId(player!.season, player!.id, true)))).filter(isNotUndefined)
|
this.regularSeasonPitchingStats = (await Promise.all(this.playerSeasons.map(player => fetchPitchingStatsBySeasonAndPlayerId(player!.season, player!.id, true)))).filter(isNotUndefined)
|
||||||
this.postSeasonPitchingStats = (await Promise.all(playerSeasons.filter(isNotUndefined).map(player => fetchPitchingStatsBySeasonAndPlayerId(player!.season, player!.id, false)))).filter(isNotUndefined)
|
this.postSeasonPitchingStats = (await Promise.all(this.playerSeasons.map(player => fetchPitchingStatsBySeasonAndPlayerId(player!.season, player!.id, false)))).filter(isNotUndefined)
|
||||||
this.regularSeasonFieldingStats = (await Promise.all(playerSeasons.filter(isNotUndefined).map(player => fetchFieldingStatsBySeasonAndPlayerId(player!.season, player!.id, true)))).flatMap(stat => stat).filter(isNotUndefined)
|
this.regularSeasonFieldingStats = (await Promise.all(this.playerSeasons.map(player => fetchFieldingStatsBySeasonAndPlayerId(player!.season, player!.id, true)))).flatMap(stat => stat).filter(isNotUndefined)
|
||||||
this.postSeasonFieldingStats = (await Promise.all(playerSeasons.filter(isNotUndefined).map(player => fetchFieldingStatsBySeasonAndPlayerId(player!.season, player!.id, false)))).flatMap(stat => stat).filter(isNotUndefined)
|
this.postSeasonFieldingStats = (await Promise.all(this.playerSeasons.map(player => fetchFieldingStatsBySeasonAndPlayerId(player!.season, player!.id, false)))).flatMap(stat => stat).filter(isNotUndefined)
|
||||||
|
|
||||||
|
// const images = playerSeasons.map(ps => ps.)
|
||||||
|
// console.log(images.length, Array.from(new Set(images)).length, images, Array.from(new Set(images)))
|
||||||
|
|
||||||
this.transactions = await fetchTransactionsForCurrentSeasonByPlayerName(this.player.name)
|
this.transactions = await fetchTransactionsForCurrentSeasonByPlayerName(this.player.name)
|
||||||
this.awards = await fetchAwardsByPlayerName(this.player.name)
|
this.awards = await fetchAwardsByPlayerName(this.player.name)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user