118 lines
2.7 KiB
Vue
118 lines
2.7 KiB
Vue
<template>
|
|
<view class="dashboard-container" :style="{ background: pageBg }">
|
|
<DashboardHeader
|
|
:active-tab="activeTab"
|
|
@update:active-tab="handleTabChange"
|
|
/>
|
|
|
|
<!-- Tab 1: 水晶相关 -->
|
|
<view v-if="activeTab === 'crystal'" class="dashboard-content">
|
|
<CrystalOverview
|
|
:data="data.today"
|
|
:loading="loading.today"
|
|
:error="error.today"
|
|
@retry="refresh('today')"
|
|
/>
|
|
<IncomeCurve
|
|
:points="data.curve?.points || []"
|
|
:loading="loading.curve"
|
|
:error="error.curve"
|
|
@retry="refresh('curve')"
|
|
/>
|
|
<ExhibitionCenter
|
|
:data="data.exhibition"
|
|
:loading="loading.exhibition"
|
|
:error="error.exhibition"
|
|
@retry="refresh('exhibition')"
|
|
/>
|
|
</view>
|
|
|
|
<!-- Tab 2: 赛季总览(占位) -->
|
|
<view v-else class="dashboard-content">
|
|
<view class="season-placeholder">
|
|
<text class="placeholder-icon">🏆</text>
|
|
<text class="placeholder-title">赛季总览 · 即将上线</text>
|
|
<text class="placeholder-sub">历史赛季数据正在筹备中</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, onUnmounted } from 'vue'
|
|
import DashboardHeader from './components/DashboardHeader.vue'
|
|
import CrystalOverview from './components/CrystalOverview.vue'
|
|
import IncomeCurve from './components/IncomeCurve.vue'
|
|
import ExhibitionCenter from './components/ExhibitionCenter.vue'
|
|
import { useDashboardData } from '@/composables/useDashboardData'
|
|
|
|
const pageBg = 'linear-gradient(153deg, #FF9597 0%, #80DFFF 33%, #B8B8B8 74%, #D9D9D9 100%)'
|
|
|
|
const activeTab = ref('crystal')
|
|
const starId = ref(uni.getStorageSync('star_id') || null)
|
|
|
|
const { loading, error, data, refresh, isReady, dispose } = useDashboardData({
|
|
starId: starId.value,
|
|
})
|
|
|
|
function handleTabChange(tab) {
|
|
activeTab.value = tab
|
|
}
|
|
|
|
onUnmounted(() => {
|
|
dispose()
|
|
})
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.dashboard-container {
|
|
min-height: 100vh;
|
|
padding: 0;
|
|
}
|
|
|
|
.dashboard-content {
|
|
padding: 24rpx 32rpx 80rpx;
|
|
}
|
|
|
|
.placeholder-section {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
border-radius: 22rpx;
|
|
padding: 80rpx 32rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.placeholder-text {
|
|
color: rgba(255, 255, 255, 0.6);
|
|
font-size: 28rpx;
|
|
}
|
|
|
|
.season-placeholder {
|
|
background: rgba(255, 255, 255, 0.15);
|
|
backdrop-filter: blur(10px);
|
|
border-radius: 22rpx;
|
|
padding: 120rpx 32rpx;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
}
|
|
|
|
.placeholder-icon {
|
|
font-size: 96rpx;
|
|
margin-bottom: 24rpx;
|
|
}
|
|
|
|
.placeholder-title {
|
|
color: #ffffff;
|
|
font-size: 36rpx;
|
|
font-weight: 700;
|
|
margin-bottom: 16rpx;
|
|
}
|
|
|
|
.placeholder-sub {
|
|
color: rgba(255, 255, 255, 0.7);
|
|
font-size: 26rpx;
|
|
}
|
|
</style>
|