build's a bitch

This commit is contained in:
iamBadgers
2024-09-02 22:17:46 -07:00
parent 903117696e
commit 36f5d6b396
8 changed files with 134 additions and 64 deletions

View File

@@ -3,6 +3,6 @@
"semi": false, "semi": false,
"tabWidth": 2, "tabWidth": 2,
"singleQuote": true, "singleQuote": true,
"printWidth": 100, "printWidth": 80,
"trailingComma": "none" "trailingComma": "none"
} }

View File

@@ -18,6 +18,7 @@ const gameListRoute = {
} }
const gameDetailsRoute = { const gameDetailsRoute = {
name: 'game',
path: '/games/:gameId', path: '/games/:gameId',
component: GameDetails component: GameDetails
} }
@@ -28,6 +29,7 @@ const characterListRoute = {
} }
const characterDetailsRoute = { const characterDetailsRoute = {
name: 'character',
path: '/characters/:characterId', path: '/characters/:characterId',
component: CharacterDetails component: CharacterDetails
} }

View File

@@ -5,17 +5,21 @@
<h2>Player: {{ character.playerName }}</h2> <h2>Player: {{ character.playerName }}</h2>
<div>Total Game EB: {{ earnedEB }} --- Total Game IP: {{ earnedIP }}</div> <div>Total Game EB: {{ earnedEB }} --- Total Game IP: {{ earnedIP }}</div>
<div> <div>
Games Played: {{ gamesPlayedCount }} --- Games Applied: {{ gamesAppliedCount }} -- Pick Rate: Games Played: {{ gamesPlayedCount }} --- Games Applied:
{{ pickRate.toFixed(2) }}% {{ gamesAppliedCount }} -- Pick Rate: {{ pickRate.toFixed(2) }}%
</div> </div>
<div>Last Game: {{ lastPlayedPostDate }}</div> <div>Last Game: {{ lastPlayedPostDate }}</div>
<div class="d-flex flex-row"> <div class="d-flex flex-row">
<div class="flex-column game-list"> <div class="flex-column game-list">
<h3 class="game-list-title">{{ (games.played || []).length }} Games Played</h3> <h3 class="game-list-title">
{{ (games.played || []).length }} Games Played
</h3>
<GameTable :gameList="games.played"></GameTable> <GameTable :gameList="games.played"></GameTable>
</div> </div>
<div class="flex-column game-list"> <div class="flex-column game-list">
<h3 class="game-list-title">{{ (games.applied || []).length }} Games Applied</h3> <h3 class="game-list-title">
{{ (games.applied || []).length }} Games Applied
</h3>
<game-table :gameList="games.applied"></game-table> <game-table :gameList="games.applied"></game-table>
</div> </div>
</div> </div>
@@ -65,8 +69,12 @@ const pickRate = ref(0)
const lastPlayedPostDate = ref() const lastPlayedPostDate = ref()
async function loadCharacterDetails() { async function loadCharacterDetails() {
const characterResponse = await axios.get(`/api/character/${characterId.value}`) const characterResponse = await axios.get(
const gameDetails = await axios.post(`/api/character/${characterId.value}/gameHistory`) `/api/character/${characterId.value}`
)
const gameDetails = await axios.post(
`/api/character/${characterId.value}/gameHistory`
)
character.value = characterResponse.data character.value = characterResponse.data
games.value = { games.value = {
@@ -86,7 +94,10 @@ function calculateDerivedEarnings(gamesPlayedList: Game[]) {
earnedIP.value = runningEarnedIp earnedIP.value = runningEarnedIp
} }
function calculateDerivedGameStats(gamesPlayedList: Game[], gamesAppliedList: Game[]) { function calculateDerivedGameStats(
gamesPlayedList: Game[],
gamesAppliedList: Game[]
) {
gamesPlayedCount.value = gamesPlayedList.length gamesPlayedCount.value = gamesPlayedList.length
gamesAppliedCount.value = gamesAppliedList.length gamesAppliedCount.value = gamesAppliedList.length
pickRate.value = (gamesPlayedList.length / gamesAppliedList.length) * 100 pickRate.value = (gamesPlayedList.length / gamesAppliedList.length) * 100
@@ -96,7 +107,9 @@ function calculateDerivedLastPlayedPostDate(gamesPlayedList: Game[]) {
if (gamesPlayedList.length === 0) { if (gamesPlayedList.length === 0) {
lastPlayedPostDate.value = 'N/A' lastPlayedPostDate.value = 'N/A'
} else { } else {
lastPlayedPostDate.value = new Date(gamesPlayedList[gamesPlayedList.length - 1].postdate * 1000) lastPlayedPostDate.value = new Date(
gamesPlayedList[gamesPlayedList.length - 1].postdate * 1000
)
.toISOString() .toISOString()
.split('T')[0] .split('T')[0]
} }

View File

@@ -16,10 +16,16 @@
@update:options="loadData" @update:options="loadData"
> >
<template v-slot:item.id="{ item }"> <template v-slot:item.id="{ item }">
<a v-bind:href="`/#/characters/${item.id}`">{{ item.id }}</a> <router-link
:to="{ name: 'character', params: { characterId: item.id } }"
>{{ item.id }}</router-link
>
</template> </template>
<template v-slot:item.characterName="{ item }"> <template v-slot:item.characterName="{ item }">
<a v-bind:href="`/#/characters/${item.id}`">{{ item.characterName }}</a> <router-link
:to="{ name: 'character', params: { characterId: item.id } }"
>{{ item.characterName }}</router-link
>
</template> </template>
<template v-slot:item.creationDate="{ item }"> <template v-slot:item.creationDate="{ item }">
{{ new Date(item.creationDate * 1000).toISOString().split('T')[0] }} {{ new Date(item.creationDate * 1000).toISOString().split('T')[0] }}
@@ -37,11 +43,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { Character } from '../types' import { Character } from '../types'
import { onBeforeMount, ref, watch } from 'vue' import { onBeforeMount, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter, LocationQueryValue } from 'vue-router'
import { VDataTable } from 'vuetify/components' import { VDataTable } from 'vuetify/components'
import axios from 'axios' import axios from 'axios'
type ReadonlyHeaders = VDataTable['$props']['headers'] type ReadonlyHeaders = VDataTable['$props']['headers']
type SortItems = VDataTable['sortBy']
const headers: ReadonlyHeaders = [ const headers: ReadonlyHeaders = [
{ title: 'ID', align: 'start', sortable: true, key: 'id' }, { title: 'ID', align: 'start', sortable: true, key: 'id' },
@@ -49,7 +56,12 @@ const headers: ReadonlyHeaders = [
{ title: 'Role', align: 'start', sortable: true, key: 'role' }, { title: 'Role', align: 'start', sortable: true, key: 'role' },
{ title: 'Player', align: 'start', sortable: true, key: 'playerName' }, { title: 'Player', align: 'start', sortable: true, key: 'playerName' },
{ title: 'Status', align: 'start', sortable: true, key: 'status' }, { title: 'Status', align: 'start', sortable: true, key: 'status' },
{ title: 'Creation Date', align: 'start', sortable: true, key: 'creationDate' } {
title: 'Creation Date',
align: 'start',
sortable: true,
key: 'creationDate'
}
] ]
const route = useRoute() const route = useRoute()
@@ -63,7 +75,7 @@ const count = ref(10)
const pageValue = ref(1) const pageValue = ref(1)
const filterValue = ref('') const filterValue = ref('')
const sortValue = ref([]) const sortValue = ref<SortItems>([])
async function loadData({ page, itemsPerPage, sortBy }: any) { async function loadData({ page, itemsPerPage, sortBy }: any) {
let sortString = 'id asc' let sortString = 'id asc'
@@ -92,25 +104,29 @@ async function loadData({ page, itemsPerPage, sortBy }: any) {
} }
async function reloadData() { async function reloadData() {
loadData({ loadData({
page: pageValue.value, page: pageValue.value,
itemsPerPage: 10, itemsPerPage: 10,
sortBy: sortValue.value sortBy: sortValue.value
}) })
} }
function buildSortFromQuery(query: string | LocationQueryValue[]): SortItems {
if (typeof route.query.sort === 'string') {
const key = route.query.sort.split(' ')[0]
const order = route.query.sort.split(' ')[1] === 'asc' ? 'asc' : 'desc'
return [{ key, order }]
}
return []
}
watch(route, (newRoute, oldRoute) => { watch(route, (newRoute, oldRoute) => {
if (newRoute.query.page) { if (newRoute.query.page) {
pageValue.value = Number(newRoute.query.page) pageValue.value = Number(newRoute.query.page)
} }
if (newRoute.query.sort) { if (newRoute.query.sort) {
sortValue.value = [ sortValue.value = buildSortFromQuery(newRoute.query.sort)
{
key: newRoute.query.sort.split(' ')[0],
order: newRoute.query.sort.split(' ')[1]
}
]
} }
if (newRoute.query.filter) { if (newRoute.query.filter) {
@@ -124,7 +140,11 @@ watch(filterValue, (newFilter: string, oldFilter: string) => {
debounce = setTimeout(() => { debounce = setTimeout(() => {
router.replace({ query: { page: route.query.page, filter: newFilter } }) router.replace({ query: { page: route.query.page, filter: newFilter } })
}, 500) }, 500)
loadData({ page: pageValue.value, itemsPerPage: resultePerPage.value, sortBy: [] }) loadData({
page: pageValue.value,
itemsPerPage: resultePerPage.value,
sortBy: []
})
}) })
onBeforeMount(async () => { onBeforeMount(async () => {
@@ -133,19 +153,14 @@ onBeforeMount(async () => {
pageValue.value = 1 pageValue.value = 1
} else { } else {
pageValue.value = Number(route.query.page) pageValue.value = Number(route.query.page)
count.value = route.query.page * 10 count.value = Number(route.query.page) * 10
} }
// Initialize Sort // Initialize Sort
if (!route.query.sort) { if (!route.query.sort) {
sortValue.value = [] sortValue.value = []
} else { } else {
sortValue.value = [ sortValue.value = buildSortFromQuery(route.query.sort)
{
key: route.query.sort.split(' ')[0],
order: route.query.sort.split(' ')[1]
}
]
} }
// Initialize Filter // Initialize Filter

View File

@@ -23,23 +23,41 @@
<div class="d-flex flex-row"> <div class="d-flex flex-row">
<div class="character-list"> <div class="character-list">
<h3>{{ picks.length }} Character Picks</h3> <h3>{{ picks.length }} Character Picks</h3>
<v-data-table-virtual :headers="pickHeaders" :items="picks" height="500px" fixed-header> <v-data-table-virtual
:headers="pickHeaders"
:items="picks"
height="500px"
fixed-header
>
<template v-slot:item.characterId="{ item }"> <template v-slot:item.characterId="{ item }">
<a v-bind:href="`/#/characters/${item.characterId}`">{{ item.characterId }}</a> <a v-bind:href="`/#/characters/${item.characterId}`">{{
item.characterId
}}</a>
</template> </template>
<template v-slot:item.characterName="{ item }"> <template v-slot:item.characterName="{ item }">
<a v-bind:href="`/#/characters/${item.characterId}`">{{ item.characterName }}</a> <a v-bind:href="`/#/characters/${item.characterId}`">{{
item.characterName
}}</a>
</template> </template>
</v-data-table-virtual> </v-data-table-virtual>
</div> </div>
<div class="character-list"> <div class="character-list">
<h3>{{ apps.length }} Character Apps</h3> <h3>{{ apps.length }} Character Apps</h3>
<v-data-table-virtual :headers="appHeaders" :items="apps" height="500px" fixed-header> <v-data-table-virtual
:headers="appHeaders"
:items="apps"
height="500px"
fixed-header
>
<template v-slot:item.characterId="{ item }"> <template v-slot:item.characterId="{ item }">
<a v-bind:href="`/#/characters/${item.characterId}`">{{ item.characterId }}</a> <a v-bind:href="`/#/characters/${item.characterId}`">{{
item.characterId
}}</a>
</template> </template>
<template v-slot:item.characterName="{ item }"> <template v-slot:item.characterName="{ item }">
<a v-bind:href="`/#/characters/${item.characterId}`">{{ item.characterName }}</a> <a v-bind:href="`/#/characters/${item.characterId}`">{{
item.characterName
}}</a>
</template> </template>
</v-data-table-virtual> </v-data-table-virtual>
</div> </div>

View File

@@ -16,10 +16,14 @@
@update:options="loadData" @update:options="loadData"
> >
<template v-slot:item.id="{ item }"> <template v-slot:item.id="{ item }">
<a v-bind:href="`/#/games/${item.id}`">{{ item.id }}</a> <router-link :to="{ name: 'game', params: { gameId: item.id } }">{{
item.id
}}</router-link>
</template> </template>
<template v-slot:item.title="{ item }"> <template v-slot:item.title="{ item }">
<a v-bind:href="`/#/games/${item.id}`">{{ item.title }}</a> <router-link :to="{ name: 'game', params: { gameId: item.id } }">{{
item.title
}}</router-link>
</template> </template>
<template v-slot:item.postdate="{ item }"> <template v-slot:item.postdate="{ item }">
{{ new Date(item.postdate * 1000).toISOString().split('T')[0] }} {{ new Date(item.postdate * 1000).toISOString().split('T')[0] }}
@@ -27,7 +31,10 @@
<template #bottom></template> <template #bottom></template>
</v-data-table-server> </v-data-table-server>
<v-pagination v-model:model-value="pageValue" :length="pageCount"></v-pagination> <v-pagination
v-model:model-value="pageValue"
:length="pageCount"
></v-pagination>
</template> </template>
<style> <style>
@@ -43,11 +50,12 @@
import { Game } from '../types' import { Game } from '../types'
import GameTable from './GameTable.vue' import GameTable from './GameTable.vue'
import { onBeforeMount, watch, ref } from 'vue' import { onBeforeMount, watch, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRoute, useRouter, LocationQueryValue } from 'vue-router'
import axios from 'axios' import axios from 'axios'
// import { VDataTable } from 'vuetify/components' import { VDataTable } from 'vuetify/components'
type ReadonlyHeaders = VDataTable['$props']['headers'] type ReadonlyHeaders = VDataTable['$props']['headers']
type SortItems = VDataTable['sortBy']
const headers: ReadonlyHeaders = [ const headers: ReadonlyHeaders = [
{ title: 'ID', align: 'start', sortable: true, key: 'id' }, { title: 'ID', align: 'start', sortable: true, key: 'id' },
@@ -67,7 +75,7 @@ const count = ref(0)
const pageValue = ref(1) const pageValue = ref(1)
const filterValue = ref('') const filterValue = ref('')
const sortValue = ref([]) const sortValue = ref<SortItems>([])
async function loadData({ page, itemsPerPage, sortBy }: any) { async function loadData({ page, itemsPerPage, sortBy }: any) {
let sortString = 'id asc' let sortString = 'id asc'
@@ -103,19 +111,22 @@ async function reloadData() {
}) })
} }
function buildSortFromQuery(query: string | LocationQueryValue[]): SortItems {
if (typeof route.query.sort === 'string') {
const key = route.query.sort.split(' ')[0]
const order = route.query.sort.split(' ')[1] === 'asc' ? 'asc' : 'desc'
return [{ key, order }]
}
return []
}
watch(route, (newRoute, oldRoute) => { watch(route, (newRoute, oldRoute) => {
console.log('route')
if (newRoute.query.page) { if (newRoute.query.page) {
pageValue.value = Number(newRoute.query.page) pageValue.value = Number(newRoute.query.page)
} }
if (newRoute.query.sort) { if (newRoute.query.sort) {
sortValue.value = [ sortValue.value = buildSortFromQuery(newRoute.query.sort)
{
key: newRoute.query.sort.split(' ')[0],
order: newRoute.query.sort.split(' ')[1]
}
]
} }
if (newRoute.query.filter) { if (newRoute.query.filter) {
@@ -137,19 +148,14 @@ onBeforeMount(async () => {
pageValue.value = 1 pageValue.value = 1
} else { } else {
pageValue.value = Number(route.query.page) pageValue.value = Number(route.query.page)
count.value = route.query.page * 10 count.value = Number(route.query.page) * 10
} }
// Initialize Sort // Initialize Sort
if (!route.query.sort) { if (!route.query.sort) {
sortValue.value = [] sortValue.value = []
} else { } else {
sortValue.value = [ sortValue.value = buildSortFromQuery(route.query.sort)
{
key: route.query.sort.split(' ')[0],
order: route.query.sort.split(' ')[1]
}
]
} }
// Initialize Filter // Initialize Filter

View File

@@ -1,5 +1,10 @@
<template> <template>
<v-data-table-virtual :headers="headers" :items="gameList" height="500px" fixed-header> <v-data-table-virtual
:headers="headers"
:items="gameList"
height="500px"
fixed-header
>
<template v-slot:item.id="{ item }"> <template v-slot:item.id="{ item }">
<a v-bind:href="`/#/games/${item.id}`">{{ item.id }}</a> <a v-bind:href="`/#/games/${item.id}`">{{ item.id }}</a>
</template> </template>

View File

@@ -1,6 +1,11 @@
<template> <template>
<div class="d-flex flex-column"> <div class="d-flex flex-column">
<v-select class="date-selector" v-model="dateSelect" variant="underlined" :items="dateItems"> <v-select
class="date-selector"
v-model="dateSelect"
variant="underlined"
:items="dateItems"
>
</v-select> </v-select>
<div class="stat-bar d-flex flex-row justify-space-around"> <div class="stat-bar d-flex flex-row justify-space-around">
<div class="d-flex flex-column"> <div class="d-flex flex-column">
@@ -18,13 +23,15 @@
<div class="d-flex flex-column"> <div class="d-flex flex-column">
<v-label class="title">Total / Average EB</v-label> <v-label class="title">Total / Average EB</v-label>
<v-label <v-label
>{{ Math.floor(gameStats.TotalEB) }} / {{ Math.floor(gameStats.AverageEB) }}</v-label >{{ Math.floor(gameStats.TotalEB) }} /
{{ Math.floor(gameStats.AverageEB) }}</v-label
> >
</div> </div>
<div class="d-flex flex-column"> <div class="d-flex flex-column">
<v-label class="title">Total / Average IP</v-label> <v-label class="title">Total / Average IP</v-label>
<v-label <v-label
>{{ Math.floor(gameStats.TotalIP) }} / {{ Math.floor(gameStats.AverageIP) }}</v-label >{{ Math.floor(gameStats.TotalIP) }} /
{{ Math.floor(gameStats.AverageIP) }}</v-label
> >
</div> </div>
</div> </div>
@@ -49,7 +56,9 @@
</td> </td>
<td class="text-left">{{ roleStat.apps }}</td> <td class="text-left">{{ roleStat.apps }}</td>
<td class="text-left">{{ roleStat.picks }}</td> <td class="text-left">{{ roleStat.picks }}</td>
<td class="text-left">{{ Math.floor((roleStat.picks / roleStat.apps) * 100) }}%</td> <td class="text-left">
{{ Math.floor((roleStat.picks / roleStat.apps) * 100) }}%
</td>
<td class="text-left"> <td class="text-left">
{{ Math.floor((roleStat.picks / gameStats.Complete) * 100) }}% {{ Math.floor((roleStat.picks / gameStats.Complete) * 100) }}%
</td> </td>
@@ -229,7 +238,9 @@ function updateChart(stats: RoleStats, tag: ChartType) {
{ {
label: 'Game Type', label: 'Game Type',
data: [ data: [
gameStats.value.Complete - gameStats.value.Events - gameStats.value.Fixes, gameStats.value.Complete -
gameStats.value.Events -
gameStats.value.Fixes,
gameStats.value.Postponed, gameStats.value.Postponed,
gameStats.value.Pending, gameStats.value.Pending,
gameStats.value.Events, gameStats.value.Events,