mirror of
https://github.com/vkaelin/LeagueStats.git
synced 2026-03-25 12:57:28 +00:00
feat: add switch button to toggle stats in match details
This commit is contained in:
parent
7587190861
commit
57e2fad45d
10 changed files with 204 additions and 96 deletions
|
|
@ -9,6 +9,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions } from 'vuex'
|
||||
import NotificationsContainer from '@/components/NotificationsContainer.vue'
|
||||
import SVGContainer from '@/components/SVGContainer.vue'
|
||||
|
||||
|
|
@ -17,5 +18,13 @@ export default {
|
|||
NotificationsContainer,
|
||||
SVGContainer
|
||||
},
|
||||
|
||||
created() {
|
||||
this.updatePercent()
|
||||
},
|
||||
|
||||
methods: {
|
||||
...mapActions('settings', ['updatePercent']),
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
@import 'tailwind.css';
|
||||
@import 'base.css';
|
||||
@import 'transition.css';
|
||||
@import 'match.css';
|
||||
|
|
|
|||
23
client/src/assets/css/match.css
Normal file
23
client/src/assets/css/match.css
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
.Win {
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
rgba(1, 97, 28, 0.3) 0%,
|
||||
rgba(44, 82, 130, 0) 45%
|
||||
);
|
||||
}
|
||||
|
||||
.Fail {
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
rgba(140, 0, 0, 0.3) 0%,
|
||||
rgba(44, 82, 130, 0) 45%
|
||||
);
|
||||
}
|
||||
|
||||
.Remake {
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
rgba(233, 169, 75, 0.3) 0%,
|
||||
rgba(44, 82, 130, 0) 45%
|
||||
);
|
||||
}
|
||||
|
|
@ -3,8 +3,9 @@
|
|||
<div v-if="data.status === 'loaded' && detailsOpen" class="bg-blue-800 rounded-b-lg">
|
||||
<DetailedMatchTeam :data="allyTeam" :all-players="[...allyTeam.players, ...enemyTeam.players]" />
|
||||
|
||||
<div class="px-3 py-2 flex justify-between">
|
||||
<div class="px-3 py-2 flex justify-between items-start">
|
||||
<DetailedMatchGlobalStats :team="allyTeam" :ally-team="true" />
|
||||
<SwitchToggle class="mt-2"></SwitchToggle>
|
||||
<DetailedMatchGlobalStats :team="enemyTeam" :ally-team="false" />
|
||||
</div>
|
||||
|
||||
|
|
@ -20,10 +21,13 @@
|
|||
import { mapGetters } from 'vuex'
|
||||
import DetailedMatchGlobalStats from '@/components/Match/DetailedMatchGlobalStats.vue'
|
||||
import DetailedMatchTeam from '@/components/Match/DetailedMatchTeam.vue'
|
||||
import SwitchToggle from '@/components/SwitchToggle.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DetailedMatchGlobalStats,
|
||||
DetailedMatchTeam
|
||||
DetailedMatchTeam,
|
||||
SwitchToggle,
|
||||
},
|
||||
props: {
|
||||
data: {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<table :class="{'rounded-b-lg overflow-hidden': !allyTeam}" class="w-full table-auto">
|
||||
<table :class="{'rounded-b-lg overflow-hidden': !allyTeam}" class="w-full table-fixed">
|
||||
<thead class="leading-none">
|
||||
<tr :class="`heading-${data.result}`" class="heading text-blue-200 font-semibold">
|
||||
<th class="py-5 border-r border-blue-700">
|
||||
<tr :class="`heading-${data.result}`" class="heading-detailed text-blue-200 font-semibold">
|
||||
<th class="w-players py-5 border-r border-blue-700">
|
||||
<div class="flex justify-between">
|
||||
<span
|
||||
:class="allyTeam ? 'text-teal-400' : 'text-red-400'"
|
||||
|
|
@ -20,31 +20,31 @@
|
|||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<th class="px-2 py-5 text-sm">K</th>
|
||||
<th class="px-2 py-5 text-sm">D</th>
|
||||
<th class="px-2 py-5 text-sm">A</th>
|
||||
<th class="px-2 py-5 text-sm">cs/m</th>
|
||||
<th class="px-2 py-5 text-sm">vs/m</th>
|
||||
<th class="px-2 py-5 text-sm">gold</th>
|
||||
<th class="px-2 py-5 text-sm">
|
||||
<th class="w-kda px-2 py-5 text-sm">K</th>
|
||||
<th class="w-kda px-2 py-5 text-sm">D</th>
|
||||
<th class="w-kda px-2 py-5 text-sm">A</th>
|
||||
<th class="w-minions px-2 py-5 text-sm">{{ statsFormat === 'stats' ? 'cs' : 'cs/m' }}</th>
|
||||
<th class="w-vision px-2 py-5 text-sm">{{ statsFormat === 'stats' ? 'vs' : 'vs/m' }}</th>
|
||||
<th class="w-gold-dmg-kp px-2 py-5 text-sm">gold</th>
|
||||
<th class="w-gold-dmg-kp px-2 py-5 text-sm">
|
||||
dmg
|
||||
<br />champ
|
||||
</th>
|
||||
<th class="px-2 py-5 text-sm">
|
||||
<th class="w-gold-dmg-kp px-2 py-5 text-sm">
|
||||
dmg
|
||||
<br />obj
|
||||
</th>
|
||||
<th class="px-2 py-5 text-sm">
|
||||
<th class="w-gold-dmg-kp px-2 py-5 text-sm">
|
||||
dmg
|
||||
<br />taken
|
||||
</th>
|
||||
<th class="px-2 py-5 text-sm">kp</th>
|
||||
<th class="w-gold-dmg-kp px-2 py-5 text-sm">kp</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody :class="[{'border-b border-blue-700': allyTeam}, data.result]" class="leading-none">
|
||||
<tr v-for="(player, index) in data.players" :key="player.name + index">
|
||||
<td class="py-2 border-r border-blue-700">
|
||||
<div class="px-2 flex justify-between">
|
||||
<div class="px-1 flex justify-between">
|
||||
<div class="flex">
|
||||
<div class="flex items-center">
|
||||
<div
|
||||
|
|
@ -55,7 +55,7 @@
|
|||
</div>
|
||||
<div
|
||||
:style="{backgroundImage: `url('https://ddragon.leagueoflegends.com/cdn/${version}/img/champion/${player.champion.id}.png')`}"
|
||||
class="ml-3 relative w-8 h-8 bg-cover bg-center bg-blue-1000 rounded-full"
|
||||
class="ml-2 relative w-8 h-8 bg-cover bg-center bg-blue-1000 rounded-full"
|
||||
>
|
||||
<div
|
||||
:class="allyTeam ? 'bg-teal-500 text-teal-100' : 'bg-red-500 text-red-100'"
|
||||
|
|
@ -98,12 +98,12 @@
|
|||
<div class="text-xs text-teal-500">{{ player.champion.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div v-if="false" class="ml-2">
|
||||
<div class="flex items-center">
|
||||
<div v-show="false" class="ml-1">
|
||||
<svg class="w-6 h-6">
|
||||
<use xlink:href="#rank-silver" />
|
||||
</svg>
|
||||
<div class="text-blue-200 text-xs">S2</div>
|
||||
<div class="-mt-1 text-blue-200 text-xs">S2</div>
|
||||
</div>
|
||||
<MatchItems :items="player.items" :one-row="true" />
|
||||
</div>
|
||||
|
|
@ -124,27 +124,27 @@
|
|||
<td
|
||||
class="p-2 text-white text-sm"
|
||||
:style="bgColor(player, '140, 101, 182', 'minions')"
|
||||
>{{ player.percentStats.minions }}</td>
|
||||
>{{ player[statsFormat].minions }}</td>
|
||||
<td
|
||||
class="p-2 text-white text-sm"
|
||||
:style="bgColor(player, '55, 118, 179', 'vision')"
|
||||
>{{ player.percentStats.vision }}</td>
|
||||
>{{ player[statsFormat].vision }}</td>
|
||||
<td
|
||||
class="p-2 text-white text-sm"
|
||||
:style="bgColor(player, '146, 100, 79', 'gold')"
|
||||
>{{ player.stats.gold }}</td>
|
||||
>{{ player[statsFormat].gold }}</td>
|
||||
<td
|
||||
:style="bgColor(player, '156, 71, 109', 'dmgChamp')"
|
||||
class="p-2 text-white text-sm"
|
||||
>{{ player.stats.dmgChamp }}</td>
|
||||
>{{ player[statsFormat].dmgChamp }}</td>
|
||||
<td
|
||||
:style="bgColor(player, '156, 71, 109', 'dmgObj')"
|
||||
class="p-2 text-white text-sm text-red"
|
||||
>{{ player.stats.dmgObj }}</td>
|
||||
>{{ player[statsFormat].dmgObj }}</td>
|
||||
<td
|
||||
:style="bgColor(player, '146, 145, 106', 'dmgTaken')"
|
||||
class="p-2 text-white text-sm"
|
||||
>{{ player.stats.dmgTaken }}</td>
|
||||
>{{ player[statsFormat].dmgTaken }}</td>
|
||||
<td
|
||||
:style="bgColor(player, '71, 132, 116', 'kp')"
|
||||
class="p-2 text-white text-sm"
|
||||
|
|
@ -155,7 +155,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { mapGetters, mapState } from 'vuex'
|
||||
import MatchItems from '@/components/Match/MatchItems'
|
||||
|
||||
export default {
|
||||
|
|
@ -176,12 +176,18 @@ export default {
|
|||
|
||||
data() {
|
||||
return {
|
||||
allyTeam: this.data.players.some(p => p.name.toLowerCase() === this.$route.params.name.toLowerCase())
|
||||
allyTeam: this.data.players.some(p => p.name.toLowerCase().replace(/ /g, '') === this.$route.params.name.toLowerCase().replace(/ /g, ''))
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
statsFormat() {
|
||||
return this.percentSettings === 'true' ? 'percentStats' : 'stats'
|
||||
},
|
||||
...mapGetters('ddragon', ['version']),
|
||||
...mapState({
|
||||
percentSettings: state => state.settings.percent
|
||||
}),
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
|
@ -203,7 +209,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
.heading {
|
||||
.heading-detailed {
|
||||
box-shadow: #2b6cb0 0px -1px inset;
|
||||
}
|
||||
|
||||
|
|
@ -234,41 +240,27 @@ export default {
|
|||
linear-gradient(#2a4365 0%, #2b4c77 55%, #235a93 100%);
|
||||
}
|
||||
|
||||
.team::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.Win {
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
rgba(1, 97, 28, 0.3) 0%,
|
||||
rgba(44, 82, 130, 0) 45%
|
||||
);
|
||||
}
|
||||
|
||||
.Fail {
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
rgba(140, 0, 0, 0.3) 0%,
|
||||
rgba(44, 82, 130, 0) 45%
|
||||
);
|
||||
}
|
||||
|
||||
.Remake {
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
rgba(233, 169, 75, 0.3) 0%,
|
||||
rgba(44, 82, 130, 0) 45%
|
||||
);
|
||||
}
|
||||
|
||||
.level-position {
|
||||
left: -5px;
|
||||
}
|
||||
|
||||
.w-players {
|
||||
width: 392px;
|
||||
}
|
||||
|
||||
.w-kda {
|
||||
width: 36px;
|
||||
}
|
||||
|
||||
.w-minions {
|
||||
width: 45px;
|
||||
}
|
||||
|
||||
.w-vision {
|
||||
width: 45px;
|
||||
}
|
||||
|
||||
.w-gold-dmg-kp {
|
||||
width: 58px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<Ripple
|
||||
@click.native="displayDetails"
|
||||
color="rgba(43, 108, 176, 0.7)"
|
||||
:class="[matchResultClass, showDetails ? 'rounded-t-lg' : 'rounded-lg']"
|
||||
:class="[data.result, showDetails ? 'rounded-t-lg' : 'rounded-lg']"
|
||||
class="match relative mt-4 bg-blue-800 text-white text-base cursor-pointer hover:shadow-xl"
|
||||
>
|
||||
<div class="relative flex flex-wrap px-5 py-3">
|
||||
|
|
@ -161,13 +161,6 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
matchResultClass() {
|
||||
return {
|
||||
'win': this.data.result === 'Win',
|
||||
'loss': this.data.result === 'Fail',
|
||||
'remake': this.data.result === 'Remake',
|
||||
}
|
||||
},
|
||||
...mapState({
|
||||
roles: state => state.roles
|
||||
}),
|
||||
|
|
@ -199,30 +192,6 @@ export default {
|
|||
transition-timing-function: cubic-bezier(0, 1, 0.5, 1);
|
||||
}
|
||||
|
||||
.loss {
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
rgba(140, 0, 0, 0.3) 0%,
|
||||
rgba(44, 82, 130, 0) 45%
|
||||
);
|
||||
}
|
||||
|
||||
.remake {
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
rgba(233, 169, 75, 0.3) 0%,
|
||||
rgba(44, 82, 130, 0) 45%
|
||||
);
|
||||
}
|
||||
|
||||
.win {
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
rgba(1, 97, 28, 0.3) 0%,
|
||||
rgba(44, 82, 130, 0) 45%
|
||||
);
|
||||
}
|
||||
|
||||
.game-status {
|
||||
top: 50%;
|
||||
left: 6px;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div :class="oneRow ? 'ml-2 items-center' : 'items-2-rows flex-wrap'" class="flex">
|
||||
<div :class="oneRow ? 'ml-1 items-center' : 'items-2-rows flex-wrap'" class="flex">
|
||||
<Dropdown v-for="(item, index) in items" :key="index">
|
||||
<template v-slot:trigger>
|
||||
<div
|
||||
|
|
|
|||
86
client/src/components/SwitchToggle.vue
Normal file
86
client/src/components/SwitchToggle.vue
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
<template>
|
||||
<div class="switch relative z-10 text-teal-400 text-sm select-none">
|
||||
<input
|
||||
v-model="selected"
|
||||
id="toggle-on"
|
||||
class="toggle toggle-left hidden"
|
||||
name="toggle"
|
||||
value="true"
|
||||
type="radio"
|
||||
/>
|
||||
<label
|
||||
:class="{'selected-label': selected === 'true'}"
|
||||
for="toggle-on"
|
||||
class="inline-block py-1 rounded-l-full border-t-2 border-r border-b-2 border-l-2 border-teal-500 cursor-pointer"
|
||||
>%</label>
|
||||
<input
|
||||
v-model="selected"
|
||||
id="toggle-off"
|
||||
class="toggle toggle-right hidden"
|
||||
name="toggle"
|
||||
value="false"
|
||||
type="radio"
|
||||
/>
|
||||
<label
|
||||
:class="{'selected-label': selected === 'false'}"
|
||||
for="toggle-off"
|
||||
class="inline-block py-1 rounded-r-full border-t-2 border-r-2 border-b-2 border-l border-teal-500 cursor-pointer"
|
||||
>Total</label>
|
||||
<div
|
||||
:class="selected === 'true' ? 'left-checked' : 'right-checked'"
|
||||
class="selector absolute w-1/2 inset-0 bg-teal-500"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
selected: {
|
||||
get() {
|
||||
return this.percentSettings
|
||||
},
|
||||
set(value) {
|
||||
this.updatePercent(value)
|
||||
}
|
||||
},
|
||||
...mapState({
|
||||
percentSettings: state => state.settings.percent
|
||||
}),
|
||||
},
|
||||
|
||||
methods: {
|
||||
...mapActions('settings', ['updatePercent']),
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.switch label {
|
||||
min-width: 50px;
|
||||
}
|
||||
|
||||
.selected-label {
|
||||
cursor: default;
|
||||
color: #fff;
|
||||
transition: color 200ms;
|
||||
}
|
||||
|
||||
.selector {
|
||||
z-index: -1;
|
||||
transition: left 200ms cubic-bezier(0.77, 0, 0.175, 1),
|
||||
border-radius 200ms cubic-bezier(0.77, 0, 0.175, 1);
|
||||
}
|
||||
|
||||
.left-checked {
|
||||
left: 0;
|
||||
border-radius: 999px 0 0 999px;
|
||||
}
|
||||
|
||||
.right-checked {
|
||||
left: 50%;
|
||||
border-radius: 0 999px 999px 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -3,6 +3,7 @@ import Vuex from 'vuex'
|
|||
import * as ddragon from '@/store/modules/ddragon'
|
||||
import * as detailedMatch from '@/store/modules/detailedMatch'
|
||||
import * as notification from '@/store/modules/notification'
|
||||
import * as settings from '@/store/modules/settings'
|
||||
import * as summoner from '@/store/modules/summoner'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
|
@ -14,6 +15,7 @@ export default new Vuex.Store({
|
|||
ddragon,
|
||||
detailedMatch,
|
||||
notification,
|
||||
settings,
|
||||
summoner
|
||||
},
|
||||
state: {
|
||||
|
|
|
|||
22
client/src/store/modules/settings.js
Normal file
22
client/src/store/modules/settings.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
export const namespaced = true
|
||||
|
||||
export const state = {
|
||||
percent: 'true'
|
||||
}
|
||||
|
||||
export const mutations = {
|
||||
UPDATE_PERCENT(state, percent) {
|
||||
state.percent = percent
|
||||
}
|
||||
}
|
||||
|
||||
export const actions = {
|
||||
async updatePercent({ commit }, percent) {
|
||||
if (!percent) {
|
||||
percent = localStorage.getItem('settings-percent') || 'true'
|
||||
} else {
|
||||
localStorage.setItem('settings-percent', percent)
|
||||
}
|
||||
commit('UPDATE_PERCENT', percent)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue