mirror of
https://github.com/vkaelin/LeagueStats.git
synced 2026-03-25 12:57:28 +00:00
refactor: start the new summoner page design
This commit is contained in:
parent
f48bfc92ec
commit
d97accce23
16 changed files with 233 additions and 133 deletions
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div id="app" class="font-sans bg-gray-200 antialiased min-h-screen">
|
||||
<div id="app" class="font-sans bg-blue-900 antialiased min-h-screen">
|
||||
|
||||
<NotificationsContainer />
|
||||
<router-view />
|
||||
|
|
|
|||
|
|
@ -1,56 +1,20 @@
|
|||
@import url('https://fonts.googleapis.com/css?family=Lato:300,400,700,900');
|
||||
|
||||
.transition-all {
|
||||
transition-property: all;
|
||||
button:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.transition-fastest {
|
||||
transition-duration: 50ms;
|
||||
.vertical-center {
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.transition-faster {
|
||||
transition-duration: 100ms;
|
||||
.horizontal-center {
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.transition-fast {
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.transition-medium {
|
||||
transition-duration: 200ms;
|
||||
}
|
||||
|
||||
.ease-out-quad {
|
||||
transition-timing-function: cubic-bezier(.25, .46, .45, .94);
|
||||
}
|
||||
|
||||
.ease-in-quad {
|
||||
transition-timing-function: cubic-bezier(.55, .085, .68, .53);
|
||||
}
|
||||
|
||||
.scale-70 {
|
||||
transform: scale(.7);
|
||||
}
|
||||
|
||||
.scale-100 {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: opacity 2s;
|
||||
}
|
||||
|
||||
.fade-enter, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.slide-fade-enter-active,
|
||||
.slide-fade-leave-active {
|
||||
transition: all 0.4s;
|
||||
}
|
||||
|
||||
.slide-fade-enter,
|
||||
.slide-fade-leave-to {
|
||||
transform: translateX(400px);
|
||||
opacity: 0;
|
||||
.bg-gradient {
|
||||
background: linear-gradient(180deg, #2C5282 0%, rgba(44, 82, 130, 0) 100%);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
button:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.vertical-center {
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.horizontal-center {
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.input {
|
||||
border: 4px solid rgba(129, 230, 217, .7);
|
||||
background: rgba(40, 94, 97, .35);
|
||||
}
|
||||
|
||||
.input:focus,
|
||||
.btn:hover {
|
||||
background: rgba(40, 94, 97, .75);
|
||||
border-color: rgba(129, 230, 217, .9);
|
||||
}
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
@import 'tailwind.css';
|
||||
@import 'base.css';
|
||||
@import 'form.css';
|
||||
@import 'transition.css';
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@tailwind utilities;
|
||||
|
|
|
|||
54
client/src/assets/css/transition.css
Normal file
54
client/src/assets/css/transition.css
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
.transition-all {
|
||||
transition-property: all;
|
||||
}
|
||||
|
||||
.transition-fastest {
|
||||
transition-duration: 50ms;
|
||||
}
|
||||
|
||||
.transition-faster {
|
||||
transition-duration: 100ms;
|
||||
}
|
||||
|
||||
.transition-fast {
|
||||
transition-duration: 150ms;
|
||||
}
|
||||
|
||||
.transition-medium {
|
||||
transition-duration: 200ms;
|
||||
}
|
||||
|
||||
.ease-out-quad {
|
||||
transition-timing-function: cubic-bezier(.25, .46, .45, .94);
|
||||
}
|
||||
|
||||
.ease-in-quad {
|
||||
transition-timing-function: cubic-bezier(.55, .085, .68, .53);
|
||||
}
|
||||
|
||||
.scale-70 {
|
||||
transform: scale(.7);
|
||||
}
|
||||
|
||||
.scale-100 {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.fade-enter-active, .fade-leave-active {
|
||||
transition: opacity 2s;
|
||||
}
|
||||
|
||||
.fade-enter, .fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.slide-fade-enter-active,
|
||||
.slide-fade-leave-active {
|
||||
transition: all 0.4s;
|
||||
}
|
||||
|
||||
.slide-fade-enter,
|
||||
.slide-fade-leave-to {
|
||||
transform: translateX(400px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 672 KiB After Width: | Height: | Size: 672 KiB |
|
|
@ -26,6 +26,11 @@ export default {
|
|||
required: false,
|
||||
default: 'cover'
|
||||
},
|
||||
moreBackgrounds: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: ''
|
||||
},
|
||||
transitionName: {
|
||||
type: String,
|
||||
required: false,
|
||||
|
|
@ -43,7 +48,7 @@ export default {
|
|||
computed: {
|
||||
computedStyle () {
|
||||
if (this.imageState === 'loaded') {
|
||||
return 'background-image: url(' + this.asyncImage.src + '); background-size: ' + this.backgroundSize
|
||||
return `background-image: ${this.moreBackgrounds} url(${this.asyncImage.src}); background-size: ${this.backgroundSize}`
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<li class="match bg-white shadow text-sm md:text-base" :class="data.result ? 'win' : 'lose'">
|
||||
<li class="match mt-4 bg-white shadow text-sm md:text-base" :class="data.result ? 'win' : 'lose'">
|
||||
<div class="match-container">
|
||||
<!-- Responsive -->
|
||||
<div
|
||||
|
|
@ -91,7 +91,6 @@ export default {
|
|||
<style scoped>
|
||||
.match {
|
||||
border-bottom: 1px solid #dae1e7;
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
.match .flex-container {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="inline-block bg-blue-800 rounded-lg p-3">
|
||||
<div class="inline-block bg-gradient rounded-lg p-3">
|
||||
<h4 class="font-bold text-base text-white text-left">Recent Activity</h4>
|
||||
<div class="flex">
|
||||
<span class="ml-12 text-blue-200 font-semibold text-xs">{{ gridDays[0].month }}</span>
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
<template>
|
||||
<form @submit.prevent="formSubmit" class="flex text-teal-100 text-lg w-full">
|
||||
<form @submit.prevent="formSubmit" :class="formClasses" class="flex text-teal-100 text-lg w-full">
|
||||
<div v-if="dropdown" @click="dropdown = false" class="fixed z-20 inset-0"></div>
|
||||
<div class="relative w-full">
|
||||
<input
|
||||
v-model="summoner"
|
||||
type="text"
|
||||
autofocus
|
||||
class="input w-full px-2 py-4 rounded-lg outline-none pl-8 pr-16 font-bold"
|
||||
:class="[elementClasses, inputClasses]"
|
||||
class="input w-full px-2 rounded-lg outline-none pl-8 pr-16 font-bold"
|
||||
/>
|
||||
<div class="absolute right-0 z-30 vertical-center flex items-center h-full mr-2">
|
||||
<div
|
||||
|
|
@ -49,7 +50,11 @@
|
|||
</transition>
|
||||
</div>
|
||||
|
||||
<button class="input btn w-20 rounded-lg ml-2 relative" type="submit">
|
||||
<button
|
||||
:class="[elementClasses, btnClasses]"
|
||||
class="input btn rounded-lg ml-2 relative"
|
||||
type="submit"
|
||||
>
|
||||
<v-icon name="search" class="absolute vertical-center horizontal-center"></v-icon>
|
||||
</button>
|
||||
</form>
|
||||
|
|
@ -57,6 +62,12 @@
|
|||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
size: {
|
||||
type: String,
|
||||
default: 'xl'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
summoner: '',
|
||||
|
|
@ -77,6 +88,31 @@ export default {
|
|||
selectedRegion: 'EUW'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
btnClasses() {
|
||||
return {
|
||||
'w-12': this.size === 'small',
|
||||
'w-20': this.size === 'xl'
|
||||
}
|
||||
},
|
||||
elementClasses() {
|
||||
return {
|
||||
'border-2': this.size === 'small',
|
||||
'border-4': this.size === 'xl'
|
||||
}
|
||||
},
|
||||
formClasses() {
|
||||
return {
|
||||
'max-w-lg': this.size === 'small',
|
||||
}
|
||||
},
|
||||
inputClasses() {
|
||||
return {
|
||||
'py-2': this.size === 'small',
|
||||
'py-4': this.size === 'xl'
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
classRegions(index) {
|
||||
return {
|
||||
|
|
@ -103,4 +139,15 @@ export default {
|
|||
.offsetIcon {
|
||||
left: 4px;
|
||||
}
|
||||
|
||||
.input {
|
||||
border-color: rgba(129, 230, 217, .7);
|
||||
background: rgba(40, 94, 97, .35);
|
||||
}
|
||||
|
||||
.input:focus,
|
||||
.btn:hover {
|
||||
background: rgba(40, 94, 97, .75);
|
||||
border-color: rgba(129, 230, 217, .9);
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -17,11 +17,12 @@ export function createSummonerData(RiotData, championsInfos) {
|
|||
|
||||
const soloQ = soloQStats ? {} : null
|
||||
if (soloQ) {
|
||||
soloQ.rank = soloQStats.rank
|
||||
soloQ.rank = `${soloQStats.tier} ${soloQStats.rank}`
|
||||
soloQ.rankImgLink = getRankImg(soloQStats)
|
||||
soloQ.wins = soloQStats.wins
|
||||
soloQ.losses = soloQStats.losses
|
||||
soloQ.winrate = (soloQ.wins * 100 / (soloQ.wins + soloQ.losses)).toFixed(1) + '%'
|
||||
soloQ.lp = soloQStats.leaguePoints
|
||||
}
|
||||
|
||||
const matchesInfos = []
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div class="bg-blue-900">
|
||||
<LazyBackground
|
||||
:image-source="require('@/assets/bg-homepage-1.jpg')"
|
||||
:image-source="require('@/assets/img/bg-homepage-1.jpg')"
|
||||
image-class="absolute inset-0"
|
||||
transition-name="fade"
|
||||
></LazyBackground>
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
</div>
|
||||
|
||||
<div class="relative flex flex-col items-center w-full max-w-lg">
|
||||
<img class="absolute logo" src="@/assets/Logo.svg" alt="logo" />
|
||||
<img class="absolute logo" src="@/assets/img/Logo.svg" alt="logo" />
|
||||
<SearchForm @formSubmit="redirect" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,75 +1,128 @@
|
|||
<template>
|
||||
<div>
|
||||
<header class="search mb-4 bg-teal-900 text-teal-100">
|
||||
<div class="container mx-auto flex justify-between py-8">
|
||||
<router-link
|
||||
to="/"
|
||||
class="flex items-center text-lg text-teal-100 mr-8 hover:text-teal-200"
|
||||
>Home</router-link>
|
||||
<div class="bg-blue-900">
|
||||
<LazyBackground
|
||||
:image-source="require('@/assets/img/bg-homepage-1.jpg')"
|
||||
image-class="fixed w-full h-200 z-0"
|
||||
more-backgrounds="linear-gradient(180deg, rgba(42, 67, 101, 0) 0%, #2A4365 50%),"
|
||||
transition-name="fade"
|
||||
></LazyBackground>
|
||||
|
||||
<SearchForm @formSubmit="redirect" />
|
||||
</div>
|
||||
</header>
|
||||
<div class="relative z-10">
|
||||
<header class="mb-4 text-teal-100">
|
||||
<div class="container mx-auto flex justify-between items-center">
|
||||
<router-link to="/">
|
||||
<img class="w-56" src="@/assets/img/Logo.svg" alt="LeagueStats logo" />
|
||||
</router-link>
|
||||
|
||||
<template v-if="summonerFound">
|
||||
<div class="container mx-auto pb-16">
|
||||
<div class="mt-4 mx-auto p-4 text-center bg-blue-100 border border-gray-300 rounded-lg">
|
||||
<div
|
||||
class="mx-auto w-16 h-16 bg-gray-300"
|
||||
:style="{background: `url(https://ddragon.leagueoflegends.com/cdn/${this.$patch}/img/profileicon/${summonerInfos.profileIconId}.png) center/cover`}"
|
||||
></div>
|
||||
<h1>{{ summonerInfos.name }}</h1>
|
||||
<h3>{{ summonerInfos.level }}</h3>
|
||||
<SearchForm @formSubmit="redirect" size="small" />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div v-if="summonerInfos.soloQ">
|
||||
<h3>{{ summonerInfos.rank }}</h3>
|
||||
<div
|
||||
class="mx-auto w-16 h-16 bg-gray-300"
|
||||
:style="{background: `url(${summonerInfos.soloQ.rankImgLink}) center/cover`}"
|
||||
></div>
|
||||
<h3>{{ `${summonerInfos.soloQ.wins} wins / ${summonerInfos.soloQ.losses} losses` }}</h3>
|
||||
<span>Winrate: {{ summonerInfos.soloQ.winrate }}</span>
|
||||
<template v-if="summonerFound">
|
||||
<div class="container mx-auto text-white pb-12">
|
||||
<div class="flex justify-between xl:px-12">
|
||||
<div>
|
||||
<h1 class="text-4xl font-extrabold uppercase">
|
||||
<span class="text-5xl">{{ summonerInfos.name[0] }}</span>
|
||||
<span>{{ summonerInfos.name.substring(1) }}</span>
|
||||
</h1>
|
||||
<div class="flex">
|
||||
<div>
|
||||
<div
|
||||
class="relative w-24 h-24 rounded-full bg-blue-1000 border-2 border-teal-400"
|
||||
:style="{background: getSummonerIcon}"
|
||||
>
|
||||
<div
|
||||
class="absolute left-0 bottom-0 w-8 h-8 flex items-center justify-center bg-blue-900 rounded-full text-xs text-teal-500 font-extrabold border-2 border-teal-400"
|
||||
>{{ summonerInfos.level }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="summonerInfos.soloQ" class="ml-6 leading-none">
|
||||
<div class="text-lg font-extrabold">Solo/Duo</div>
|
||||
<div
|
||||
class="text-teal-500 text-4xl uppercase font-extrabold"
|
||||
>{{ summonerInfos.soloQ.rank }}</div>
|
||||
<div class="mt-4 flex items-start bg-gradient px-4 py-3 rounded-lg">
|
||||
<div class="flex items-center">
|
||||
<div
|
||||
class="w-20 h-20 bg-blue-1000"
|
||||
:style="{background: `url(${summonerInfos.soloQ.rankImgLink}) center/cover`}"
|
||||
></div>
|
||||
<div class="ml-2 text-xl font-extrabold">{{ summonerInfos.soloQ.lp }} LP</div>
|
||||
</div>
|
||||
<div class="ml-10 mt-2 font-extrabold uppercase leading-none">
|
||||
<div class="text-teal-500 text-base">Record</div>
|
||||
<div class="flex">
|
||||
<div class="mt-2 text-sm leading-tight text-right">
|
||||
<div>{{ summonerInfos.soloQ.wins }}</div>
|
||||
<div>{{ summonerInfos.soloQ.losses }}</div>
|
||||
</div>
|
||||
<div class="ml-2 mt-2 text-sm leading-tight">
|
||||
<div class="text-teal-500">Wins</div>
|
||||
<div class="text-red-300">Losses</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-10 mt-2 font-extrabold">
|
||||
<div class="text-teal-500 text-base uppercase">Winrate</div>
|
||||
<div class="mt-2 text-xl leading-tight">{{ summonerInfos.soloQ.winrate }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<RecentActivity :matches="summonerInfos.allMatches" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<RecentActivity :matches="summonerInfos.allMatches" />
|
||||
|
||||
<ul>
|
||||
<Match
|
||||
v-for="(match, index) in summonerInfos.matches"
|
||||
:key="index"
|
||||
:data="summonerInfos.matches[index]"
|
||||
/>
|
||||
</ul>
|
||||
<div class="mt-12 text-center">
|
||||
<ul class="text-gray-900">
|
||||
<Match
|
||||
v-for="(match, index) in summonerInfos.matches"
|
||||
:key="index"
|
||||
:data="summonerInfos.matches[index]"
|
||||
/>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="summonerLoading">
|
||||
<div
|
||||
class="flex items-center justify-center bg-white max-w-xs mx-auto p-5 rounded-lg shadow-xl"
|
||||
>
|
||||
<dot-loader :loading="summonerLoading" />
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="summonerNotFound">
|
||||
<p>Player can't be found.</p>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template v-else-if="summonerLoading">
|
||||
<div
|
||||
class="flex items-center justify-center bg-white max-w-xs mx-auto p-5 rounded-lg shadow-xl"
|
||||
>
|
||||
<dot-loader :loading="summonerLoading" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else-if="summonerNotFound">
|
||||
<p>Player can't be found.</p>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapActions, mapGetters } from 'vuex'
|
||||
import LazyBackground from '@/components/LazyBackgroundImage.vue'
|
||||
import RecentActivity from '@/components/RecentActivity.vue'
|
||||
import Match from '@/components/Match.vue'
|
||||
import SearchForm from '@/components/SearchForm.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LazyBackground,
|
||||
Match,
|
||||
RecentActivity,
|
||||
SearchForm
|
||||
},
|
||||
|
||||
computed: {
|
||||
getSummonerIcon() {
|
||||
return `url(https://ddragon.leagueoflegends.com/cdn/${this.$patch}/img/profileicon/${this.summonerInfos.profileIconId}.png) center/cover`
|
||||
},
|
||||
summoner() {
|
||||
return this.$route.params.name
|
||||
},
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ module.exports = {
|
|||
700: '#2b6cb0',
|
||||
800: '#2c5282',
|
||||
900: '#2a4365',
|
||||
1000: '#17314f'
|
||||
},
|
||||
indigo: {
|
||||
100: '#ebf4ff',
|
||||
|
|
@ -280,6 +281,7 @@ module.exports = {
|
|||
...theme('spacing'),
|
||||
full: '100%',
|
||||
screen: '100vh',
|
||||
'200': '50rem'
|
||||
}),
|
||||
minWidth: {
|
||||
'0': '0',
|
||||
|
|
|
|||
Loading…
Reference in a new issue