sba-website/src/components/NavBar.vue

347 lines
11 KiB
Vue

<template>
<nav class="navbar navbar-expand-sm" style="margin-bottom: 1rem" id="navbar">
<RouterLink class="navbar-brand nav-link" to="/">SBa Season {{ seasonNumber() }}</RouterLink>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#top-navbar-collapse"
aria-controls="top-navbar-collapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="top-navbar-collapse">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<RouterLink class="nav-link" to="/schedule">Schedule</RouterLink>
</li>
<li class="nav-item">
<RouterLink class="nav-link" to="/standings">Standings</RouterLink>
</li>
<li class="nav-item">
<RouterLink class="nav-link"
:to="{ name: 'team', params: { seasonNumber: seasonNumber(), teamAbbreviation: 'FA' } }">Free Agents
</RouterLink>
</li>
<li class="nav-item">
<a class="nav-link" href="/rules">Rules Ref</a>
</li>
<li class="nav-item">
<a class="nav-link" target="_blank" href="https://sbanews.manticorum.com/">News</a>
</li>
<li class="nav-item">
<button v-if="!isAuthenticated" id="login" class="nav-link" @click="authenticate">Login with Discord</button>
</li>
<li v-if="false" class="nav-item">
<!-- make the above true if you want to clear cookies for testing -->
<button class="nav-link" @click="clearCookie">Clear Cookie</button>
</li>
<li v-if="isAuthenticated && userTeam" class="nav-item">
<RouterLink :to="{ name: 'team', params: { seasonNumber: seasonNumber(), teamAbbreviation: userTeam.abbrev } }">
<img id="thumbnail" style="max-height: 35px; float:right; vertical-align:middle" :src=userTeam?.thumbnail>
</RouterLink>
</li>
</ul>
<form class="form-inline" @submit.stop.prevent="searchPlayers">
<input type="text" name="name" placeholder="Player Search" list="player-names" v-model="searchPlayerName">
<datalist id="player-names">
<option v-for=" name in sortedPlayerNames " :value="name">{{ name }}</option>
</datalist>
</form>
<!-- <ul class="navbar-nav navbar-right">
<li class="nav-item">
<div class="custom-control custom-switch">
<input type="checkbox" class="custom-control-input" id="darkSwitch" />
<label class="custom-control-label" for="darkSwitch">Dark Mode</label>
</div>
<script src="/static/dark-mode-switch.js"></script>
</li>
</ul> -->
</div>
</nav>
<!-- <nav class="container">
<RouterLink to="/">SBa Season {{ seasonNumber }}</RouterLink>
<RouterLink to="/schedule">Schedule</RouterLink>
<RouterLink to="/standings">Standings</RouterLink>
<RouterLink to="/stats">Stats & Leaders</RouterLink>
<RouterLink to="/teams">Teams</RouterLink>
<RouterLink to="/transactions">Transactions</RouterLink>
<RouterLink to="/history">History</RouterLink>
<RouterLink to="/rules">Rules Ref</RouterLink>
<RouterLink to="/news">News</RouterLink>
</nav> -->
</template>
<script lang="ts">
import { RouterLink } from 'vue-router'
import type { MenuOption } from 'naive-ui'
import { fetchPlayers, type Player } from '@/services/playersService'
import { CURRENT_SEASON } from '@/services/utilities'
import type { Team } from '@/services/apiResponseTypes'
import { fetchActiveTeamByOwnerId } from '@/services/teamsService'
import { authenticate, clearCookie, completeAuthentication, getOwnerId, isDiscordAuthenticated, parseCookie } from '@/services/authenticationService'
export default {
name: 'NavBar',
data() {
return {
isAuthenticated: false as Boolean,
userTeam: undefined as Team | undefined,
players: [] as Player[],
searchPlayerName: undefined
}
},
created() {
this.populatePlayerNames()
this.completeAuthentication()
this.fetchUserTeam()
},
computed: {
menuOptions(): MenuOption[] {
return [
{
label: 'Schedule',
key: 'Schedule'
},
{
label: 'Standings',
key: 'Standings',
},
{
label: 'Stats & Leaders',
key: 'Stats & Leaders',
children: [
{
label: 'Season Leaders',
key: 'Season Leaders',
children: [
{
label: 'Batting Leaders',
key: 'Batting Leaders'
},
{
label: 'Pitching Leaders',
key: 'Pitching Leaders'
},
{
label: 'Fielding Leaders',
key: 'Fielding Leaders'
}
]
},
{
label: 'Team Stats',
key: 'Team Stats',
children: [
{
label: 'Team Batting',
key: 'Team Batting'
},
{
label: 'Team Pitching',
key: 'Team Pitching'
},
{
label: 'Team Fielding',
key: 'Team Fielding'
}
]
},
{
label: 'Single-Game Records',
key: 'Single-Game Records',
children: [
{
label: 'Single-Game Batting',
key: 'Single-Game Batting'
},
{
label: 'Single-Game Pitching',
key: 'Single-Game Pitching'
},
{
label: 'Single-Game Fielding',
key: 'Single-Game Fielding'
}
]
},
{
label: 'Single-Season Stats',
key: 'Single-Season Stats',
children: [
{
label: 'Single-Season Batting',
key: 'Single-Season Batting'
},
{
label: 'Single-Season Pitching',
key: 'Single-Season Pitching'
},
{
label: 'Single-Season Fielding',
key: 'Single-Season Fielding'
}
]
},
{
label: 'Career Leaders',
key: 'Career Leaders',
children: [
{
label: 'Career Batting',
key: 'Career Batting'
},
{
label: 'Career Pitching',
key: 'Career Pitching'
},
{
label: 'Career Fielding',
key: 'Career Fielding'
}
]
}]
},
{
label: 'Teams',
key: 'Teams',
children: [
{
label: 'AL East',
key: 'AL East',
children: [
{ label: 'Gators', key: 'Gators' },
{ label: 'Honeybees', keys: 'Honeybees' },
{ label: 'Kaiju', key: 'Kaiju' },
{ label: 'Phantoms', key: 'Phantoms' }
]
},
{
label: 'AL West',
key: 'AL West',
children: [
{ label: 'Cyclones', key: 'Cyclones' },
{ label: 'Mussels', keys: 'Mussels' },
{ label: 'Whale Sharks', key: 'Whale Sharks' },
{ label: 'Wu Xia', key: 'Wu Xia' }
]
},
{
label: 'NL East',
key: 'NL East',
children: [
{ label: 'Drillers', key: 'Drillers' },
{ label: 'Macho Men', keys: 'Macho Men' },
{ label: 'Shoebills', key: 'Shoebills' },
{ label: 'Zephyr', key: 'Zephyr' }
]
},
{
label: 'NL West',
key: 'NL West',
children: [
{ label: 'Angels', key: 'Angels' },
{ label: 'Black Bears', keys: 'Black Bears' },
{ label: 'Bovines', key: 'Bovines' },
{ label: 'Snow Geese', key: 'Snow Geese' }
]
}
]
},
{
label: 'Transactions',
key: 'Transactions',
children: [
{ label: 'Free Agents', key: 'Free Agents' },
{ label: 'Transactions', key: 'Transactions' }
]
},
{
label: 'History',
key: 'History',
children: [
{ label: 'Awards', key: 'Awards' },
{
label: 'Managers',
key: 'Managers',
// TODO figure out a way to pull active/retired into children here
children: [{ label: 'Active', key: 'Active' }, { label: 'Retired', key: 'Retired' }]
},
{
label: 'Season Recaps',
key: 'Season Recaps',
children: [
{ label: 'Season 4', key: 'Season 4' },
{ label: 'Season 3', key: 'Season 3' },
{ label: 'Season 2', key: 'Season 2' },
{ label: 'Season 1', key: 'Season 1' },
]
}
]
},
{ label: 'Rules Ref', key: 'Rules Ref' },
{ label: 'News', key: 'News' }
]
},
sortedPlayerNames(): string[] {
return this.players.sort((p1, p2) => p2.wara - p1.wara).map(p => p.name)
},
ownerId(): string | undefined {
return getOwnerId()
}
},
methods: {
async getPlayers(): Promise<Player[]> {
return await fetchPlayers(this.seasonNumber())
},
async populatePlayerNames(): Promise<void> {
this.players = await this.getPlayers()
},
searchPlayers(): void {
this.$router.push({ path: `/players/${this.seasonNumber()}/${this.searchPlayerName}` })
},
authenticate(): void {
authenticate()
},
async completeAuthentication(): Promise<void> {
if (await isDiscordAuthenticated() || this.isAuthenticated) {
this.isAuthenticated = true
return
}
completeAuthentication()
},
async fetchUserTeam(): Promise<void> {
if (!this.ownerId) return
this.userTeam = await fetchActiveTeamByOwnerId(this.ownerId)
},
seasonNumber(): number {
return CURRENT_SEASON
},
clearCookie(): void {
clearCookie()
}
}
}
</script>
<style>
.nav {
margin: 0%;
display: flex;
justify-content: flex-start;
gap: 8px;
}
.navbar {
background-color: #a6ce39;
}
.navbar-brand {
display: inline-block;
padding-top: 0.32421875rem;
padding-bottom: 0.32421875rem;
margin-right: 1rem;
font-size: 1.171875rem;
line-height: inherit;
white-space: nowrap;
}
</style>