sba-website/src/components/TeamScheduleTable.vue

230 lines
9.3 KiB
Vue

<template>
<div v-if="schedule.length" class="team-schedule-table">
<div class="row">
<div class="col-sm-12">
<h3>Season Schedule</h3>
</div>
<!-- First Half -->
<div class="col-sm-6">
<div class="table-responsive-xl">
<table class="table table-sm table-striped" id="schedule-first">
<thead class="thead-dark">
<tr id="schedule-first-header">
<th style="width: 4rem">Week</th>
<th style="width: 8rem">Away</th>
<th style="width: 2rem"></th>
<th style="width: 8rem">Home</th>
<th style="width: 8rem">Game 1</th>
<th style="width: 8rem">Game 2</th>
<th style="width: 8rem">Game 3</th>
<th style="width: 8rem">Game 4</th>
</tr>
</thead>
<tbody>
<tr v-for="row in firstHalfRows" :key="row.week">
<td>{{ row.week }}</td>
<td>
<RouterLink
:to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: row.awayTeam.abbrev } }">
{{ row.awayTeam.sname }}
</RouterLink>
</td>
<td>@</td>
<td>
<RouterLink
:to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: row.homeTeam.abbrev } }">
{{ row.homeTeam.sname }}
</RouterLink>
</td>
<td>
<RouterLink v-if="isPlayed(row.game1)"
:to="{ name: 'games', params: { seasonNumber: seasonNumber, weekNumber: row.week, gameNumber: row.game1!.game_num, team1Abbreviation: row.awayTeam.abbrev, team2Abbreviation: row.homeTeam.abbrev } }">
{{ makeGameScore(row.game1) }}
</RouterLink>
<template v-else>-</template>
</td>
<td>
<RouterLink v-if="isPlayed(row.game2)"
:to="{ name: 'games', params: { seasonNumber: seasonNumber, weekNumber: row.week, gameNumber: row.game2!.game_num, team1Abbreviation: row.awayTeam.abbrev, team2Abbreviation: row.homeTeam.abbrev } }">
{{ makeGameScore(row.game2) }}
</RouterLink>
<template v-else>-</template>
</td>
<td>
<RouterLink v-if="isPlayed(row.game3)"
:to="{ name: 'games', params: { seasonNumber: seasonNumber, weekNumber: row.week, gameNumber: row.game3!.game_num, team1Abbreviation: row.awayTeam.abbrev, team2Abbreviation: row.homeTeam.abbrev } }">
{{ makeGameScore(row.game3) }}
</RouterLink>
<template v-else>-</template>
</td>
<td>
<RouterLink v-if="isPlayed(row.game4)"
:to="{ name: 'games', params: { seasonNumber: seasonNumber, weekNumber: row.week, gameNumber: row.game4!.game_num, team1Abbreviation: row.awayTeam.abbrev, team2Abbreviation: row.homeTeam.abbrev } }">
{{ makeGameScore(row.game4) }}
</RouterLink>
<template v-else>-</template>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Second Half -->
<div class="col-sm-6">
<div class="table-responsive-xl">
<table class="table table-sm table-striped" id="schedule-second">
<thead class="thead-dark">
<tr id="schedule-second-header">
<th style="width: 4rem">Week</th>
<th style="width: 8rem">Away</th>
<th style="width: 2rem"></th>
<th style="width: 8rem">Home</th>
<th style="width: 8rem">Game 1</th>
<th style="width: 8rem">Game 2</th>
<th style="width: 8rem">Game 3</th>
<th style="width: 8rem">Game 4</th>
</tr>
</thead>
<tbody>
<tr v-for="row in secondHalfRows" :key="row.week">
<td>{{ row.week }}</td>
<td>
<RouterLink
:to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: row.awayTeam.abbrev } }">
{{ row.awayTeam.sname }}
</RouterLink>
</td>
<td>@</td>
<td>
<RouterLink
:to="{ name: 'team', params: { seasonNumber: seasonNumber, teamAbbreviation: row.homeTeam.abbrev } }">
{{ row.homeTeam.sname }}
</RouterLink>
</td>
<td>
<RouterLink v-if="isPlayed(row.game1)"
:to="{ name: 'games', params: { seasonNumber: seasonNumber, weekNumber: row.week, gameNumber: row.game1!.game_num, team1Abbreviation: row.awayTeam.abbrev, team2Abbreviation: row.homeTeam.abbrev } }">
{{ makeGameScore(row.game1) }}
</RouterLink>
<template v-else>-</template>
</td>
<td>
<RouterLink v-if="isPlayed(row.game2)"
:to="{ name: 'games', params: { seasonNumber: seasonNumber, weekNumber: row.week, gameNumber: row.game2!.game_num, team1Abbreviation: row.awayTeam.abbrev, team2Abbreviation: row.homeTeam.abbrev } }">
{{ makeGameScore(row.game2) }}
</RouterLink>
<template v-else>-</template>
</td>
<td>
<RouterLink v-if="isPlayed(row.game3)"
:to="{ name: 'games', params: { seasonNumber: seasonNumber, weekNumber: row.week, gameNumber: row.game3!.game_num, team1Abbreviation: row.awayTeam.abbrev, team2Abbreviation: row.homeTeam.abbrev } }">
{{ makeGameScore(row.game3) }}
</RouterLink>
<template v-else>-</template>
</td>
<td>
<RouterLink v-if="isPlayed(row.game4)"
:to="{ name: 'games', params: { seasonNumber: seasonNumber, weekNumber: row.week, gameNumber: row.game4!.game_num, team1Abbreviation: row.awayTeam.abbrev, team2Abbreviation: row.homeTeam.abbrev } }">
{{ makeGameScore(row.game4) }}
</RouterLink>
<template v-else>-</template>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import type { Game, Team } from '@/services/apiResponseTypes'
import { fetchGamesBySeasonAndTeamId } from '@/services/gameService'
import { GAMES_PER_SEASON } from '@/services/utilities'
interface ScheduleRow {
week: number
awayTeam: Team
homeTeam: Team
game1: Game | undefined
game2: Game | undefined
game3: Game | undefined
game4: Game | undefined
}
export default {
name: 'TeamScheduleTable',
data() {
return {
schedule: [] as Game[]
}
},
props: {
seasonNumber: { type: Number, required: true },
teamId: { type: Number, required: true }
},
computed: {
midSeasonWeekNumber(): number {
const gamesPerWeek = 4
return (GAMES_PER_SEASON / gamesPerWeek) / 2
},
firstHalfRows(): ScheduleRow[] {
const games = this.schedule.filter(g => g.week <= this.midSeasonWeekNumber)
return this.makeScheduleRowsFromGames(games)
},
secondHalfRows(): ScheduleRow[] {
const games = this.schedule.filter(g => g.week > this.midSeasonWeekNumber)
return this.makeScheduleRowsFromGames(games)
}
},
created() {
this.fetchData()
},
watch: {
teamId(newValue, oldValue) {
if (newValue !== oldValue)
this.fetchData()
}
},
methods: {
makeScheduleRowsFromGames(games: Game[]): ScheduleRow[] {
const gamesByWeekAndHomeTeam = this.groupByWeekAndHomeTeam(games)
return Object.values(gamesByWeekAndHomeTeam).sort((games1, games2) => games1[0].id - games2[0].id).map(games => {
return {
week: games[0].week,
awayTeam: games[0].away_team,
homeTeam: games[0].home_team,
game1: games.find(g => g.game_num === 1),
game2: games.find(g => g.game_num === 2),
game3: games.find(g => g.game_num === 3),
game4: games.find(g => g.game_num === 4)
}
})
},
groupByWeekAndHomeTeam(games: Game[]): { [key: string]: Game[] } {
return games.reduce((storage, game) => {
const key = `${game.week}-${game.home_team.abbrev}`
if (storage[key]) {
storage[key].push(game)
} else {
storage[key] = [game]
}
return storage
}, {} as { [key: string]: Game[] })
},
isPlayed(game: Game | undefined) {
return !!game && (game.away_score || game.home_score)
},
makeGameScore(game: Game | undefined): string {
if (!game || (!game.away_score && !game.home_score)) return '-'
return `${game.away_team.abbrev} ${game.away_score}-${game.home_score} ${game.home_team.abbrev}`
},
async fetchData(): Promise<void> {
this.schedule = await fetchGamesBySeasonAndTeamId(this.seasonNumber, this.teamId)
}
}
}
</script>