128 lines
4.4 KiB
Vue
128 lines
4.4 KiB
Vue
<script setup lang="ts">
|
|||
|
|
import { ref, onMounted } from 'vue'
|
||
|
|
import { RouterLink } from 'vue-router'
|
||
|
|
|
||
|
|
interface Bot {
|
||
|
|
id: string
|
||
|
|
name: string
|
||
|
|
eloRating: number
|
||
|
|
tier: number
|
||
|
|
wins: number
|
||
|
|
losses: number
|
||
|
|
}
|
||
|
|
|
||
|
|
const bots = ref<Bot[]>([])
|
||
|
|
const isLoading = ref(true)
|
||
|
|
|
||
|
|
onMounted(async () => {
|
||
|
|
try {
|
||
|
|
const res = await fetch('/api/bots')
|
||
|
|
if (res.ok) {
|
||
|
|
const data = await res.json()
|
||
|
|
bots.value = data.sort((a: Bot, b: Bot) => b.eloRating - a.eloRating)
|
||
|
|
}
|
||
|
|
} catch { /* */ }
|
||
|
|
isLoading.value = false
|
||
|
|
})
|
||
|
|
|
||
|
|
const tierClass = (t: number) => `tier-${t}`
|
||
|
|
const tierName = (t: number) => ['UNRANKED', 'ROOKIE', 'RISING', 'CONTENDER', 'CHAMPION', 'LEGEND'][t] || '???'
|
||
|
|
|
||
|
|
// Generate potential matchups from top bots
|
||
|
|
const matchups = ref<{ botA: Bot; botB: Bot; hype: string }[]>([])
|
||
|
|
|
||
|
|
onMounted(() => {
|
||
|
|
setTimeout(() => {
|
||
|
|
if (bots.value.length >= 2) {
|
||
|
|
const top = bots.value.slice(0, 6)
|
||
|
|
const hypes = [
|
||
|
|
'MAIN EVENT',
|
||
|
|
'CO-MAIN EVENT',
|
||
|
|
'TITLE ELIMINATOR',
|
||
|
|
'GRUDGE MATCH',
|
||
|
|
'UNDERCARD',
|
||
|
|
'DEBUT',
|
||
|
|
]
|
||
|
|
for (let i = 0; i < Math.min(3, Math.floor(top.length / 2)); i++) {
|
||
|
|
matchups.value.push({
|
||
|
|
botA: top[i * 2],
|
||
|
|
botB: top[i * 2 + 1],
|
||
|
|
hype: hypes[i],
|
||
|
|
})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}, 500)
|
||
|
|
})
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<template>
|
||
|
|
<div class="h-[calc(100vh-4rem)] flex flex-col px-6 py-6 overflow-hidden">
|
||
|
|
<div class="max-w-4xl mx-auto w-full flex flex-col flex-1 min-h-0">
|
||
|
|
|
||
|
|
<!-- Header -->
|
||
|
|
<div class="mb-6 text-center">
|
||
|
|
<p class="font-display text-[10px] font-bold text-neon-purple tracking-[0.2em] mb-2 glow-purple">
|
||
|
|
UPCOMING
|
||
|
|
</p>
|
||
|
|
<h2 class="font-display font-black text-3xl sm:text-5xl tracking-wider">
|
||
|
|
<span class="gradient-text">FIGHT CARD</span>
|
||
|
|
</h2>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<!-- Matchups -->
|
||
|
|
<div class="flex-1 min-h-0 overflow-y-auto space-y-4">
|
||
|
|
<div
|
||
|
|
v-for="(matchup, i) in matchups"
|
||
|
|
:key="i"
|
||
|
|
class="border border-border rounded-lg bg-surface-raised/50 p-5
|
||
|
|
hover:border-neon-pink/30 transition-all"
|
||
|
|
:class="i === 0 ? 'neon-border-pink' : ''"
|
||
|
|
>
|
||
|
|
<p class="text-center font-display text-[10px] font-bold tracking-[0.2em] mb-4"
|
||
|
|
:class="i === 0 ? 'text-neon-yellow' : i === 1 ? 'text-neon-pink' : 'text-text-muted'">
|
||
|
|
{{ matchup.hype }}
|
||
|
|
</p>
|
||
|
|
|
||
|
|
<div class="flex items-center justify-between">
|
||
|
|
<div class="flex-1 text-right pr-6">
|
||
|
|
<RouterLink :to="`/bot/${matchup.botA.name}`"
|
||
|
|
class="font-display font-black text-xl sm:text-2xl tracking-wider text-text-primary
|
||
|
|
hover:text-neon-cyan transition-colors">
|
||
|
|
{{ matchup.botA.name }}
|
||
|
|
</RouterLink>
|
||
|
|
<p class="font-mono text-xs mt-1">
|
||
|
|
<span :class="tierClass(matchup.botA.tier)">{{ tierName(matchup.botA.tier) }}</span>
|
||
|
|
<span class="text-text-muted"> · {{ Math.round(matchup.botA.eloRating) }}</span>
|
||
|
|
<span class="text-text-muted"> · {{ matchup.botA.wins }}W-{{ matchup.botA.losses }}L</span>
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="flex-shrink-0">
|
||
|
|
<span class="font-display font-black text-2xl text-neon-purple glow-purple">VS</span>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="flex-1 pl-6">
|
||
|
|
<RouterLink :to="`/bot/${matchup.botB.name}`"
|
||
|
|
class="font-display font-black text-xl sm:text-2xl tracking-wider text-text-primary
|
||
|
|
hover:text-neon-cyan transition-colors">
|
||
|
|
{{ matchup.botB.name }}
|
||
|
|
</RouterLink>
|
||
|
|
<p class="font-mono text-xs mt-1">
|
||
|
|
<span :class="tierClass(matchup.botB.tier)">{{ tierName(matchup.botB.tier) }}</span>
|
||
|
|
<span class="text-text-muted"> · {{ Math.round(matchup.botB.eloRating) }}</span>
|
||
|
|
<span class="text-text-muted"> · {{ matchup.botB.wins }}W-{{ matchup.botB.losses }}L</span>
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div v-if="matchups.length === 0 && !isLoading" class="flex-1 flex items-center justify-center">
|
||
|
|
<p class="font-display text-text-muted text-sm">
|
||
|
|
Card loading... check back soon.
|
||
|
|
</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|