Files
gamegroup2/frontend/src/views/Home.vue
T

249 lines
5.0 KiB
Vue
Raw Normal View History

<!-- src/views/Home.vue -->
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useGroupStore } from '@/stores/group'
import { getPopularGames } from '@/api/games'
import type { Game } from '@/types'
import TeamSessionPanel from '@/components/team/TeamSessionPanel.vue'
import IdleMembersList from '@/components/team/IdleMembersList.vue'
import { ElCard, ElButton, ElEmpty } from 'element-plus'
const router = useRouter()
const groupStore = useGroupStore()
const popularGames = ref<Game[]>([])
const loading = ref(false)
onMounted(async () => {
await loadPopularGames()
})
async function loadPopularGames() {
try {
loading.value = true
popularGames.value = await getPopularGames(8)
} catch (error) {
console.error('加载热门游戏失败:', error)
} finally {
loading.value = false
}
}
function selectGroup(groupId: string) {
groupStore.setCurrentGroup(groupId)
router.push({ name: 'GroupView', params: { id: groupId } })
}
</script>
<template>
<div class="home-page">
<div class="page-content">
<!-- 左侧边栏 -->
<aside class="sidebar">
<el-card class="card">
<template #header>
<div class="card-header">
<h3>我的群组</h3>
<el-button size="small" type="primary">+ 创建</el-button>
</div>
</template>
<div v-if="groupStore.groups.length === 0" class="empty">
<el-empty description="暂无群组" :image-size="80" />
</div>
<div v-else class="group-list">
<div
v-for="group in groupStore.groups"
:key="group.id"
class="group-item"
@click="selectGroup(group.id)"
>
<div class="group-info">
<span class="group-name">{{ group.name }}</span>
<span class="group-members">{{ group.members.length }} 成员</span>
</div>
</div>
</div>
</el-card>
</aside>
<!-- 主内容区 -->
<main class="main-content">
<!-- 当前临时小组 -->
<team-session-panel />
<!-- 热门游戏 -->
<el-card class="card mt-16">
<template #header>
<h3>热门游戏</h3>
</template>
<div v-if="loading" class="loading">加载中...</div>
<div v-else class="games-grid">
<div
v-for="game in popularGames"
:key="game.id"
class="game-card"
@click="router.push({ name: 'GamesLibrary' })"
>
<img
:src="game.cover || '/game-placeholder.png'"
:alt="game.name"
class="game-cover"
/>
<div class="game-info">
<span class="game-name">{{ game.name }}</span>
<span class="game-platform">{{ game.platform }}</span>
</div>
</div>
</div>
</el-card>
</main>
<!-- 右侧边栏 -->
<aside class="sidebar">
<el-card class="card">
<template #header>
<h3>空闲成员</h3>
</template>
<idle-membersList />
</el-card>
</aside>
</div>
</div>
</template>
<style scoped>
.home-page {
width: 100%;
}
.page-content {
display: grid;
grid-template-columns: 280px 1fr 280px;
gap: 16px;
}
.sidebar {
display: flex;
flex-direction: column;
gap: 16px;
}
.main-content {
display: flex;
flex-direction: column;
}
.card {
border-radius: 12px;
}
.mt-16 {
margin-top: 16px;
}
.card-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.card-header h3 {
margin: 0;
font-size: 16px;
font-weight: 600;
}
.empty {
padding: 20px;
}
.group-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.group-item {
padding: 12px;
border-radius: 8px;
background: var(--el-fill-color-light);
cursor: pointer;
transition: background-color 0.2s;
}
.group-item:hover {
background: var(--el-fill-color);
}
.group-info {
display: flex;
flex-direction: column;
gap: 4px;
}
.group-name {
font-size: 14px;
font-weight: 500;
}
.group-members {
font-size: 12px;
color: var(--el-text-color-secondary);
}
.loading {
text-align: center;
padding: 40px;
color: var(--el-text-color-secondary);
}
.games-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 12px;
}
.game-card {
cursor: pointer;
transition: transform 0.2s;
}
.game-card:hover {
transform: translateY(-4px);
}
.game-cover {
width: 100%;
aspect-ratio: 3/4;
object-fit: cover;
border-radius: 8px;
background: var(--el-fill-color-light);
}
.game-info {
display: flex;
flex-direction: column;
gap: 4px;
margin-top: 8px;
}
.game-name {
font-size: 13px;
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.game-platform {
font-size: 11px;
color: var(--el-text-color-secondary);
}
</style>