Files
buildpath/frontend/components/nav/SideBar.vue
T
vhaudiquet aff27b9a51
pipeline / lint-and-format (push) Successful in 3m23s
pipeline / build-and-push-images (push) Successful in 1m44s
pipeline / lint-and-publish-chart (push) Successful in 6s
feat/frontend: display patches in new format
2026-08-22 12:57:20 +02:00

201 lines
5.5 KiB
Vue

<script setup lang="ts">
import { LANE_IMAGES, lanePositionToIndex, POSITIONS_STR } from '~/utils/cdragon'
import { displayPatch } from '~/utils/helpers'
import type { LaneData } from 'match_collector'
defineProps<{
championName?: string
championLanes?: Array<LaneData>
tierlistList?: boolean
}>()
const emit = defineEmits<{
stateChange: [state: string, lane: number]
}>()
const state = ref('build')
const laneState = ref(0)
function handleStateChange(newState: string, newLane: number) {
state.value = newState
laneState.value = newLane
emit('stateChange', newState, newLane)
}
const { data: stats }: { data: Ref<{ patch: number; count: number }> } = useFetch('/api/stats', {
lazy: true, // Don't block rendering
server: false // Client-side only
})
const route = useRoute()
const selected = ref('')
if (route.path.startsWith('/tierlist/')) {
const lane = route.params.lane as string
selected.value = lane
}
</script>
<template>
<!-- To make content have a 300px margin -->
<div class="sidebar-margin" />
<div class="sidebar-container">
<Logo
font-size="2rem"
img-width="45"
style="padding-left: 10px; padding-right: 10px; margin-top: 20px"
/>
<div v-for="(lane, i) in championLanes" :key="i">
<div
style="
display: flex;
align-items: center;
margin-top: 20px;
padding-right: 10px;
overflow: hidden;
"
>
<h1 style="font-size: 1.8rem; padding-left: 15px">{{ championName }}</h1>
<NuxtImg
format="webp"
style="margin-left: 8px"
width="30"
height="30"
:src="LANE_IMAGES[lanePositionToIndex(lane.data)]"
/>
<h2
v-if="championName != null && championName != undefined && championName.length < 8"
style="margin-left: 5px; font-size: 1.4rem; font-weight: 200"
>
{{ POSITIONS_STR[lanePositionToIndex(lane.data.toLowerCase())] }}
</h2>
</div>
<h2
:class="
'sidebar-link ' + (state == 'build' && laneState == i ? 'sidebar-link-selected' : '')
"
style="margin-top: 8px; font-size: 1.5rem; padding-left: 25px"
@click="handleStateChange('build', i)"
>
Build
</h2>
<h2
:class="
'sidebar-link ' +
(state == 'alternatives' && laneState == i ? 'sidebar-link-selected' : '')
"
style="margin-top: 8px; font-size: 1.5rem; padding-left: 25px"
@click="handleStateChange('alternatives', i)"
>
Alternatives
</h2>
<h2
:class="
'sidebar-link ' + (state == 'matchups' && laneState == i ? 'sidebar-link-selected' : '')
"
style="margin-top: 8px; font-size: 1.5rem; padding-left: 25px"
@click="handleStateChange('matchups', i)"
>
Matchups
</h2>
</div>
<div v-if="tierlistList == true" style="margin-top: 20px">
<h2 style="padding-left: 15px; font-size: 1.8rem; margin-bottom: 8px">Tierlist</h2>
<NuxtLink
v-for="(pos, i) in POSITIONS"
:key="i"
style="margin-top: 5px; margin-bottom: 5px"
:to="'/tierlist/' + pos"
>
<div
:class="selected == pos ? 'sidebar-link-selected' : ''"
class="sidebar-link"
style="padding-left: 25px; display: flex; align-items: center"
>
<NuxtImg
format="webp"
width="30"
height="30"
:src="LANE_IMAGES[i]"
:alt="POSITIONS_STR[i]"
/>
<h3 style="font-size: 1.6rem; font-weight: 200; margin-left: 8px">
{{ POSITIONS_STR[i] }}
</h3>
</div>
</NuxtLink>
</div>
<div style="position: absolute; bottom: 0; margin-bottom: 10px; padding-left: 10px">
<template v-if="stats">
<h3 style="font-size: 18px; font-weight: 200">
Patch {{ displayPatch(String(stats.patch)) }}
</h3>
<h3 style="font-size: 18px; font-weight: 200">{{ stats.count }} games</h3>
</template>
<template v-else>
<h3 style="font-size: 18px; font-weight: 200; opacity: 0.5">Loading stats...</h3>
</template>
<h3 style="font-size: 18px; font-weight: 200; margin-top: 10px; margin-bottom: 10px">
Challenger only
</h3>
<h3 style="font-size: 18px; font-weight: 200; margin-top: 10px; margin-bottom: 10px">
EUW/EUNE/NA/KR
</h3>
<NuxtLink to="/about"><h3>About</h3></NuxtLink>
<h2 style="font-size: 10px; font-weight: 200; margin-top: 3px; margin-right: 10px">
BuildPath isn't endorsed by Riot Games and doesn't reflect the views or opinions of Riot
Games or anyone officially involved in producing or managing Riot Games properties. Riot
Games, and all associated properties are trademarks or registered trademarks of Riot Games,
Inc.
</h2>
</div>
</div>
</template>
<style>
.sidebar-container {
background-color: #2b2826;
width: 300px;
position: fixed;
top: 0;
left: 0;
height: 100%;
z-index: 10;
}
.sidebar-margin {
width: 300px;
flex-shrink: 0;
}
.sidebar-link {
user-select: none;
margin: 5px;
padding-top: 5px;
padding-bottom: 5px;
border-radius: 8px;
}
.sidebar-link:hover {
cursor: pointer;
background-color: var(--color-surface-darker);
}
.sidebar-link-selected {
background-color: var(--color-surface);
}
@media only screen and (max-width: 1200px) {
.sidebar-container {
display: none;
}
.sidebar-margin {
display: none;
}
}
</style>