178 lines
3.8 KiB
Vue
178 lines
3.8 KiB
Vue
<template>
|
|
<div class="container">
|
|
<h1>Vinlottis highscore</h1>
|
|
|
|
<div class="filter flex el-spacing">
|
|
<input type="text" v-model="filterInput" placeholder="Filtrer på navn" />
|
|
<button v-if="filterInput" @click="resetFilter" class="vin-button auto-height margin-left-sm">
|
|
Reset
|
|
</button>
|
|
</div>
|
|
|
|
<p class="highscore-header margin-bottom-md"><b>Plassering.</b> Navn - Antall vinn</p>
|
|
|
|
<ol v-if="highscore.length > 0" class="highscore-list">
|
|
<li v-for="person in filteredResults" @click="selectWinner(person)" @keydown.enter="selectWinner(person)" tabindex="0">
|
|
<b>{{ person.rank }}.</b> {{ person.name }} - {{ person.wins.length }}
|
|
</li>
|
|
</ol>
|
|
|
|
<div class="center desktop-only">
|
|
👈 Se dine vin(n), trykk på navnet ditt
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
|
|
import { highscoreStatistics } from "@/api";
|
|
import { humanReadableDate, daysAgo } from "@/utils";
|
|
import Wine from "@/ui/Wine";
|
|
|
|
export default {
|
|
components: { Wine },
|
|
data() {
|
|
return {
|
|
highscore: [],
|
|
filterInput: ''
|
|
}
|
|
},
|
|
async mounted() {
|
|
let response = await highscoreStatistics();
|
|
response.sort((a, b) => {
|
|
return a.wins.length > b.wins.length ? -1 : 1;
|
|
});
|
|
response = response.filter(
|
|
person => person.name != null && person.name != ""
|
|
);
|
|
this.highscore = this.generateScoreBoard(response);
|
|
},
|
|
computed: {
|
|
filteredResults() {
|
|
let highscore = this.highscore;
|
|
let val = this.filterInput;
|
|
|
|
if (val.length) {
|
|
val = val.toLowerCase()
|
|
const nameIncludesString = (person) => person.name.toLowerCase().includes(val);
|
|
highscore = highscore.filter(nameIncludesString)
|
|
}
|
|
|
|
return highscore
|
|
}
|
|
},
|
|
methods: {
|
|
generateScoreBoard(highscore=this.highscore) {
|
|
let place = 0;
|
|
let highestWinCount = -1;
|
|
|
|
return highscore.map(win => {
|
|
const wins = win.wins.length
|
|
if (wins != highestWinCount) {
|
|
place += 1
|
|
highestWinCount = wins
|
|
}
|
|
|
|
const placeString = place.toString().padStart(2, "0");
|
|
win.rank = placeString;
|
|
return win
|
|
})
|
|
},
|
|
resetFilter() {
|
|
this.filterInput = '';
|
|
document.getElementsByTagName('input')[0].focus();
|
|
},
|
|
selectWinner(winner) {
|
|
const path = "/highscore/" + encodeURIComponent(winner.name)
|
|
this.$router.push(path);
|
|
},
|
|
humanReadableDate: humanReadableDate,
|
|
daysAgo: daysAgo
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
@import "@/styles/media-queries.scss";
|
|
@import "@/styles/variables.scss";
|
|
$elementSpacing: 3.5rem;
|
|
|
|
.el-spacing {
|
|
margin-bottom: $elementSpacing;
|
|
}
|
|
|
|
.container {
|
|
width: 90vw;
|
|
margin: 3rem auto;
|
|
max-width: 1200px;
|
|
margin-bottom: 0;
|
|
padding-bottom: 3rem;
|
|
|
|
@include desktop {
|
|
width: 80vw;
|
|
}
|
|
}
|
|
|
|
h1 {
|
|
font-size: 3rem;
|
|
font-family: "knowit";
|
|
color: $matte-text-color;
|
|
font-weight: normal;
|
|
}
|
|
|
|
.filter input {
|
|
font-size: 1rem;
|
|
width: 100%;
|
|
border-color: black;
|
|
border-width: 1.5px;
|
|
padding: 0.75rem 1rem;
|
|
|
|
@include desktop {
|
|
width: 30%;
|
|
}
|
|
}
|
|
|
|
.highscore-header {
|
|
margin-bottom: 2rem;
|
|
font-size: 1.3rem;
|
|
color: $matte-text-color;
|
|
}
|
|
|
|
.highscore-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
padding-left: 0;
|
|
|
|
li {
|
|
width: fit-content;
|
|
display: inline-block;
|
|
margin-bottom: calc(1rem - 2px);
|
|
font-size: 1.25rem;
|
|
color: $matte-text-color;
|
|
cursor: pointer;
|
|
|
|
border-bottom: 2px solid transparent;
|
|
&:hover, &:focus {
|
|
border-color: $link-color;
|
|
}
|
|
}
|
|
}
|
|
|
|
.center {
|
|
position: absolute;
|
|
top: 40%;
|
|
right: 10vw;
|
|
max-width: 50vw;
|
|
|
|
font-size: 2.5rem;
|
|
background-color: $primary;
|
|
padding: 1rem 1rem;
|
|
border-radius: 8px;
|
|
font-style: italic;
|
|
|
|
@include widescreen {
|
|
right: 20vw;
|
|
}
|
|
}
|
|
</style>
|