307 lines
6.9 KiB
Vue
307 lines
6.9 KiB
Vue
<template>
|
|
<div class="build-of-day">
|
|
<h2>Build of the Day</h2>
|
|
|
|
<p v-if="loading" class="loading">Loading...</p>
|
|
<p v-if="error" class="error">Failed to load: {{ error }}</p>
|
|
|
|
<div v-if="build" class="result">
|
|
<div class="date-badge">{{ formattedDate }}</div>
|
|
|
|
<div class="hero-section">
|
|
<h3>Hero</h3>
|
|
<div class="hero">{{ build.hero.name }}</div>
|
|
<div class="hero-badge">{{ build.hero.primary }}</div>
|
|
</div>
|
|
|
|
<div class="build-section">
|
|
<h3>Items</h3>
|
|
<ul>
|
|
<li v-for="it in build.items" :key="it.id">{{ it.name }}</li>
|
|
</ul>
|
|
|
|
<h3>Skill Build</h3>
|
|
<div class="skill-build">
|
|
<div v-for="level in skillLevels" :key="level" class="skill-level">
|
|
<span class="level-num">{{ level }}</span>
|
|
<span class="skill-key" :class="getSkillClass(build.skillBuild[String(level)])">
|
|
{{ formatSkill(build.skillBuild[String(level)]) }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="build.aspect">
|
|
<h3>Aspect</h3>
|
|
<div class="aspect">{{ build.aspect }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, onMounted } from 'vue'
|
|
import { storeToRefs } from 'pinia'
|
|
import { useRandomDataStore } from '@/stores/randomData'
|
|
|
|
const randomDataStore = useRandomDataStore()
|
|
const { buildOfDay: build, buildOfDayLoading: loading, buildOfDayError: error } = storeToRefs(randomDataStore)
|
|
|
|
const skillLevels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 25]
|
|
|
|
const formattedDate = computed(() => {
|
|
if (!build.value?.date) return ''
|
|
const d = new Date(build.value.date)
|
|
return d.toLocaleDateString('ru-RU', {
|
|
day: 'numeric',
|
|
month: 'long',
|
|
year: 'numeric'
|
|
})
|
|
})
|
|
|
|
function formatSkill(skill: string | undefined): string {
|
|
if (!skill) return '-'
|
|
const map: Record<string, string> = {
|
|
q: 'Q',
|
|
w: 'W',
|
|
e: 'E',
|
|
r: 'R',
|
|
left_talent: 'L',
|
|
right_talent: 'R'
|
|
}
|
|
return map[skill] ?? skill
|
|
}
|
|
|
|
function getSkillClass(skill: string | undefined): string {
|
|
if (!skill) return ''
|
|
if (skill === 'r') return 'skill-ult'
|
|
if (skill === 'left_talent' || skill === 'right_talent') return 'skill-talent'
|
|
return 'skill-basic'
|
|
}
|
|
|
|
onMounted(() => {
|
|
randomDataStore.fetchBuildOfDay()
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
:root {
|
|
--dota-red: #b63a2b;
|
|
--dota-red-glow: rgba(182, 58, 43, 0.45);
|
|
--dota-gold: #c8a86a;
|
|
--dota-gold-glow: rgba(200, 168, 106, 0.3);
|
|
--dota-blue: #4fc3f7;
|
|
--dota-blue-glow: rgba(79, 195, 247, 0.35);
|
|
--panel: rgba(10, 14, 20, 0.6);
|
|
}
|
|
|
|
/* MAIN BLOCK -------------------------------------------------- */
|
|
.build-of-day {
|
|
padding: 26px;
|
|
border-radius: 16px;
|
|
background: linear-gradient(180deg, rgba(20, 25, 40, 0.9), rgba(8, 10, 16, 0.92)),
|
|
radial-gradient(120% 120% at 0% 0%, rgba(255, 255, 255, 0.05), transparent);
|
|
color: #e6f0fa;
|
|
|
|
border: 1px solid rgba(255, 255, 255, 0.06);
|
|
box-shadow:
|
|
0 0 18px rgba(0, 0, 0, 0.6),
|
|
0 0 32px rgba(0, 0, 0, 0.4),
|
|
inset 0 0 20px rgba(255, 255, 255, 0.02);
|
|
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* Decorative glow line */
|
|
.build-of-day::before {
|
|
content: "";
|
|
position: absolute;
|
|
inset: 0;
|
|
background: radial-gradient(circle at top left,
|
|
rgba(255, 255, 255, 0.10),
|
|
transparent 50%);
|
|
pointer-events: none;
|
|
}
|
|
|
|
/* TITLE -------------------------------------------------- */
|
|
.build-of-day > h2 {
|
|
text-align: center;
|
|
font-weight: 800;
|
|
font-size: 1.7rem;
|
|
letter-spacing: 1px;
|
|
margin-bottom: 18px;
|
|
text-shadow: 0 0 6px var(--dota-red-glow);
|
|
color: var(--dota-gold);
|
|
}
|
|
|
|
.loading {
|
|
text-align: center;
|
|
color: var(--dota-blue);
|
|
}
|
|
|
|
.error {
|
|
color: #f87171;
|
|
text-align: center;
|
|
}
|
|
|
|
/* DATE BADGE -------------------------------------------------- */
|
|
.date-badge {
|
|
text-align: center;
|
|
font-size: 1.1rem;
|
|
font-weight: 600;
|
|
color: var(--dota-gold);
|
|
margin-bottom: 18px;
|
|
padding: 10px 20px;
|
|
background: rgba(200, 168, 106, 0.1);
|
|
border: 1px solid rgba(200, 168, 106, 0.3);
|
|
border-radius: 999px;
|
|
display: inline-block;
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* RESULT PANEL -------------------------------------------------- */
|
|
.result {
|
|
margin-top: 12px;
|
|
background: linear-gradient(180deg, rgba(15, 17, 23, 0.9), rgba(6, 8, 13, 0.9));
|
|
padding: 18px;
|
|
border-radius: 14px;
|
|
|
|
border: 1px solid rgba(255, 255, 255, 0.06);
|
|
box-shadow: inset 0 0 18px rgba(0, 0, 0, 0.45);
|
|
}
|
|
|
|
.hero-section {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
/* HERO -------------------------------------------------- */
|
|
.hero {
|
|
font-weight: 900;
|
|
font-size: 1.25rem;
|
|
margin-bottom: 8px;
|
|
color: var(--dota-blue);
|
|
text-shadow: 0 0 6px var(--dota-blue-glow);
|
|
}
|
|
|
|
.hero-badge {
|
|
display: inline-block;
|
|
padding: 8px 14px;
|
|
border-radius: 999px;
|
|
|
|
background: linear-gradient(90deg,
|
|
rgba(255, 255, 255, 0.07),
|
|
rgba(255, 255, 255, 0.02));
|
|
|
|
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
color: var(--dota-gold);
|
|
font-weight: 600;
|
|
}
|
|
|
|
/* ITEMS -------------------------------------------------- */
|
|
.result ul {
|
|
list-style: none;
|
|
padding: 0;
|
|
margin: 10px 0;
|
|
display: flex;
|
|
gap: 10px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.result li {
|
|
background: rgba(255, 255, 255, 0.04);
|
|
padding: 8px 12px;
|
|
border-radius: 999px;
|
|
color: #f2f7ff;
|
|
|
|
font-weight: 600;
|
|
border: 1px solid rgba(255, 255, 255, 0.06);
|
|
|
|
box-shadow:
|
|
inset 0 -2px 0 rgba(0, 0, 0, 0.3),
|
|
0 0 10px rgba(40, 150, 255, 0.15);
|
|
|
|
transition: 0.15s ease;
|
|
}
|
|
|
|
.result li:hover {
|
|
background: rgba(255, 255, 255, 0.09);
|
|
box-shadow:
|
|
inset 0 -3px 0 rgba(0, 0, 0, 0.4),
|
|
0 0 14px rgba(40, 150, 255, 0.22);
|
|
}
|
|
|
|
/* SKILL + ASPECT -------------------------------------------------- */
|
|
h3 {
|
|
margin: 8px 0;
|
|
font-size: 1.1rem;
|
|
font-weight: 700;
|
|
color: var(--dota-gold);
|
|
text-shadow: 0 0 4px var(--dota-gold-glow);
|
|
}
|
|
|
|
.aspect {
|
|
background: rgba(255, 255, 255, 0.04);
|
|
padding: 8px 14px;
|
|
border-radius: 10px;
|
|
color: #f2f7ff;
|
|
font-weight: 600;
|
|
border: 1px solid rgba(255, 255, 255, 0.06);
|
|
display: inline-block;
|
|
}
|
|
|
|
/* SKILL BUILD -------------------------------------------------- */
|
|
.skill-build {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
margin: 10px 0;
|
|
}
|
|
|
|
.skill-level {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
min-width: 32px;
|
|
}
|
|
|
|
.level-num {
|
|
font-size: 0.7rem;
|
|
color: rgba(255, 255, 255, 0.5);
|
|
margin-bottom: 2px;
|
|
}
|
|
|
|
.skill-key {
|
|
background: rgba(255, 255, 255, 0.08);
|
|
padding: 6px 10px;
|
|
border-radius: 6px;
|
|
font-weight: 700;
|
|
font-size: 0.9rem;
|
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
.skill-basic {
|
|
color: #8bc34a;
|
|
}
|
|
|
|
.skill-ult {
|
|
color: #ffd54f;
|
|
background: rgba(255, 213, 79, 0.15);
|
|
border-color: rgba(255, 213, 79, 0.3);
|
|
}
|
|
|
|
.skill-talent {
|
|
color: #4fc3f7;
|
|
background: rgba(79, 195, 247, 0.15);
|
|
border-color: rgba(79, 195, 247, 0.3);
|
|
}
|
|
|
|
/* MOBILE -------------------------------------------------- */
|
|
@media (max-width: 720px) {
|
|
.build-of-day {
|
|
padding: 18px;
|
|
}
|
|
}
|
|
</style>
|