laobinghu 30f2115877 feat: dark mode adaptation for main pages
Add dark mode CSS variable overrides to index, events, teams, results, and scoreboard pages for consistent theme switching
2026-03-22 16:03:39 +08:00

235 lines
6.0 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="home-container">
<el-card class="welcome-card slide-down-enter">
<h1>欢迎使用运动会记分板系统</h1>
<p>本系统用于管理运动会的比赛项目队伍和成绩</p>
</el-card>
<el-row :gutter="20" class="stats-row">
<el-col :xs="12" :sm="12" :md="6" :lg="6">
<el-card class="stat-card bounce-enter" :class="staggerClass(0)">
<div class="stat-content">
<el-icon class="stat-icon" color="#409eff"><Trophy /></el-icon>
<div>
<div class="stat-value">{{ stats.events }}</div>
<div class="stat-label">比赛项目</div>
</div>
</div>
</el-card>
</el-col>
<el-col :xs="12" :sm="12" :md="6" :lg="6">
<el-card class="stat-card bounce-enter" :class="staggerClass(1)">
<div class="stat-content">
<el-icon class="stat-icon" color="#67c23a"><UserFilled /></el-icon>
<div>
<div class="stat-value">{{ stats.teams }}</div>
<div class="stat-label">参赛队伍</div>
</div>
</div>
</el-card>
</el-col>
<el-col :xs="12" :sm="12" :md="6" :lg="6">
<el-card class="stat-card bounce-enter" :class="staggerClass(2)">
<div class="stat-content">
<el-icon class="stat-icon" color="#e6a23c"><Edit /></el-icon>
<div>
<div class="stat-value">{{ stats.results }}</div>
<div class="stat-label">成绩记录</div>
</div>
</div>
</el-card>
</el-col>
<el-col :xs="12" :sm="12" :md="6" :lg="6">
<el-card class="stat-card bounce-enter" :class="staggerClass(3)">
<div class="stat-content">
<el-icon class="stat-icon" color="#f56c6c"><DataLine /></el-icon>
<div>
<div class="stat-value">{{ stats.categories }}</div>
<div class="stat-label">比赛类别</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :xs="24" :sm="24" :md="12" :lg="12">
<el-card class="slide-left-enter">
<template #header>
<span>快速操作</span>
</template>
<div class="quick-actions">
<el-row :gutter="10">
<el-col :span="12">
<el-button type="primary" class="action-btn zoom-enter" @click="navigateTo('/events')">管理比赛项目</el-button>
</el-col>
<el-col :span="12">
<el-button type="success" class="action-btn zoom-enter" :class="staggerClass(1)" @click="navigateTo('/teams')">管理队伍</el-button>
</el-col>
<el-col :span="12">
<el-button type="warning" class="action-btn zoom-enter" :class="staggerClass(2)" @click="navigateTo('/results')">录入成绩</el-button>
</el-col>
<el-col :span="12">
<el-button type="info" class="action-btn zoom-enter" :class="staggerClass(3)" @click="navigateTo('/scoreboard')">查看记分板</el-button>
</el-col>
</el-row>
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="24" :md="12" :lg="12">
<el-card class="slide-right-enter">
<template #header>
<span>系统说明</span>
</template>
<ul class="system-info">
<li v-for="(item, index) in systemInfo" :key="index" class="fade-enter" :class="staggerClass(index)">
{{ item }}
</li>
</ul>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script setup lang="ts">
import { Trophy, UserFilled, Edit, DataLine } from '@element-plus/icons-vue'
import { fetchEvents, fetchTeams, fetchResults } from '~/modules/scoreboard/api'
import { computed } from 'vue'
const stats = ref({
events: 0,
teams: 0,
results: 0,
categories: 3
})
// System info list
const systemInfo = computed(() => [
'田赛:跳高、跳远、掷铅球',
'径赛100m、200m、400m、4×100m、4×400m、20×50m',
'团体赛:旱地龙舟、跳长绳、折返跑',
'组别:教师组、航空班组、体育班组、文化班甲组、文化班乙组'
])
// Staggered animation helper
const staggerClass = (index: number) => {
const classes = [
'stagger-1',
'stagger-2',
'stagger-3',
'stagger-4',
'stagger-5'
]
return classes[index] || ''
}
onMounted(async () => {
try {
const [eventsRes, teamsRes, resultsRes] = await Promise.all([
fetchEvents(),
fetchTeams(),
fetchResults()
])
stats.value.events = eventsRes?.length || 0
stats.value.teams = teamsRes?.length || 0
stats.value.results = resultsRes?.length || 0
} catch (error) {
console.error('Failed to load stats:', error)
}
})
</script>
<style scoped>
.home-container {
max-width: 1200px;
margin: 0 auto;
}
.welcome-card {
margin-bottom: 20px;
text-align: center;
}
.welcome-card h1 {
color: var(--header-text);
margin-bottom: 10px;
}
.welcome-card p {
color: var(--footer-text);
font-size: 16px;
}
.stats-row {
margin-bottom: 20px;
}
.stat-card {
text-align: center;
}
.stat-content {
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
}
.stat-icon {
font-size: 40px;
}
.stat-value {
font-size: 32px;
font-weight: bold;
color: var(--header-text);
}
.stat-label {
font-size: 14px;
color: var(--footer-text);
margin-top: 5px;
}
.quick-actions {
display: block;
}
.quick-actions .action-btn {
width: 100%;
margin-bottom: 10px;
}
.system-info {
list-style: none;
padding: 0;
margin: 0;
}
.system-info li {
padding: 8px 0;
border-bottom: 1px solid var(--header-border);
color: var(--header-text);
}
.system-info li:last-child {
border-bottom: none;
}
@media (max-width: 900px) {
.stat-value {
font-size: 24px;
}
.stat-icon {
font-size: 28px;
}
.stats-row :deep(.el-col) {
margin-bottom: 12px;
}
}
</style>