优化 Dashboard 布局:实现炫酷徽章、水平滚动AI建议和玻璃拟态效果
This commit is contained in:
@@ -36,29 +36,8 @@
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 学习概览主卡片 -->
|
||||
<div class="main-overview-card">
|
||||
<div class="overview-header">
|
||||
<div class="level-progress-main">
|
||||
<div class="level-badge">
|
||||
<span class="level-text">Lv.{{ userLevel }} 学习达人</span>
|
||||
<div class="level-fire">🔥</div>
|
||||
</div>
|
||||
<div class="progress-info">
|
||||
<div class="progress-bar-main">
|
||||
<div class="progress-fill-animated" :style="{ width: userProgress.rankPercent + '%' }"></div>
|
||||
</div>
|
||||
<span class="progress-text">排名超越 {{ userProgress.rankPercent }}% 同龄用户</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overview-actions">
|
||||
<button @click="showDetailedStats" class="action-btn primary">
|
||||
📊 详细分析
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 核心统计数据 -->
|
||||
<!-- 学习概览卡(轻量化) -->
|
||||
<div class="overview-card">
|
||||
<div class="core-stats">
|
||||
<div class="stat-item">
|
||||
<div class="stat-icon">⏱️</div>
|
||||
@@ -88,20 +67,18 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 学习小目标 Widget -->
|
||||
<div class="learning-goals">
|
||||
<!-- 今日学习目标进度 -->
|
||||
<div class="goal-progress-container">
|
||||
<div class="goal-header">
|
||||
<span class="goal-icon">🌟</span>
|
||||
<span class="goal-title">今日学习目标</span>
|
||||
<span class="goal-title">今日目标</span>
|
||||
</div>
|
||||
<div class="goal-content">
|
||||
<p class="goal-text">{{ getTodayGoal() }}</p>
|
||||
<div class="goal-progress">
|
||||
<div class="goal-bar">
|
||||
<div class="goal-fill" :style="{ width: getGoalProgress() + '%' }"></div>
|
||||
</div>
|
||||
<span class="goal-percentage">{{ getGoalProgress() }}%</span>
|
||||
<p class="goal-text">{{ getTodayGoal() }}</p>
|
||||
<div class="goal-progress">
|
||||
<div class="goal-bar">
|
||||
<div class="goal-fill" :style="{ width: getGoalProgress() + '%' }"></div>
|
||||
</div>
|
||||
<span class="goal-percentage">{{ getGoalProgress() }}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -190,22 +167,29 @@
|
||||
<span v-else>⏳</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="suggestions-grid">
|
||||
<div v-for="suggestion in aiSuggestions" :key="suggestion.id" class="suggestion-card" @click="applySuggestion(suggestion)">
|
||||
<div class="suggestion-icon">{{ suggestion.icon }}</div>
|
||||
<div class="suggestion-content">
|
||||
<h4 class="suggestion-title">{{ suggestion.title }}</h4>
|
||||
<p class="suggestion-description">{{ suggestion.description }}</p>
|
||||
<div class="suggestion-meta">
|
||||
<span class="meta-item">{{ suggestion.duration }}</span>
|
||||
<span class="meta-item">{{ suggestion.difficulty }}</span>
|
||||
<!-- 水平滚动的AI建议卡片 -->
|
||||
<div class="suggestions-carousel">
|
||||
<div class="suggestions-track">
|
||||
<div v-for="suggestion in aiSuggestions" :key="suggestion.id" class="suggestion-card" @click="applySuggestion(suggestion)">
|
||||
<div class="suggestion-icon">{{ suggestion.icon }}</div>
|
||||
<div class="suggestion-content">
|
||||
<h4 class="suggestion-title">{{ suggestion.title }}</h4>
|
||||
<p class="suggestion-description">{{ suggestion.description }}</p>
|
||||
<div class="suggestion-meta">
|
||||
<span class="meta-item">{{ suggestion.duration }}</span>
|
||||
<span class="meta-item">{{ suggestion.difficulty }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="suggestion-action">
|
||||
<span class="action-arrow">→</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="suggestion-action">
|
||||
<span class="action-arrow">→</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 悬浮AI按钮 -->
|
||||
<button class="ai-more-btn" @click="showDetailedStats">
|
||||
<span>🤖</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -738,7 +722,97 @@ window.addEventListener('resize', () => {
|
||||
font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
}
|
||||
|
||||
/* 背景层 - 深浅分层护眼配色 */
|
||||
/* 布局比例调整 */
|
||||
.dashboard-container {
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 响应式优化 */
|
||||
@media (max-width: 1024px) {
|
||||
.data-cards-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.data-card.large {
|
||||
grid-column: span 1;
|
||||
}
|
||||
|
||||
.suggestions-track {
|
||||
padding-left: 10px;
|
||||
padding-right: 60px; /* 为AI按钮留出空间 */
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.dashboard-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.top-header {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.core-stats {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.stat-divider {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.overview-header {
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.ai-assistant-fab {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
|
||||
.ai-fab-icon {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.suggestions-track {
|
||||
padding-left: 10px;
|
||||
padding-right: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.section-header {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.overview-card {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.data-card {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.suggestion-card {
|
||||
min-width: 280px;
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 背景层 - 优化渐变 */
|
||||
.bg-gradient {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@@ -746,15 +820,24 @@ window.addEventListener('resize', () => {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg,
|
||||
#1e293b 0%,
|
||||
#334155 25%,
|
||||
#475569 50%,
|
||||
#334155 75%,
|
||||
#1e293b 100%
|
||||
#0f172a 0%,
|
||||
#1e293b 25%,
|
||||
#334155 50%,
|
||||
#1e293b 75%,
|
||||
#0f172a 100%
|
||||
);
|
||||
z-index: -2;
|
||||
}
|
||||
|
||||
/* 玻璃拟态通用样式 */
|
||||
.glass-effect {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.floating-orbs {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
@@ -861,9 +944,10 @@ window.addEventListener('resize', () => {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
background: rgba(30, 41, 59, 0.8);
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
border-radius: 20px;
|
||||
padding: 24px 32px;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
|
||||
@@ -992,6 +1076,39 @@ window.addEventListener('resize', () => {
|
||||
60% { transform: translateY(-5px); }
|
||||
}
|
||||
|
||||
.level-badge {
|
||||
background: linear-gradient(135deg, #00e0ff, #45ff9d);
|
||||
color: #0f172a;
|
||||
font-weight: 600;
|
||||
padding: 6px 14px;
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 0 12px rgba(0, 255, 204, 0.6);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { box-shadow: 0 0 8px rgba(0,255,204,0.5); }
|
||||
50% { box-shadow: 0 0 16px rgba(0,255,204,0.9); }
|
||||
}
|
||||
|
||||
.badge-glow {
|
||||
background: linear-gradient(135deg, #00e0ff, #45ff9d);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* 卡片玻璃拟态效果 */
|
||||
.data-card {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
backdrop-filter: blur(8px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.progress-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -1166,9 +1283,9 @@ window.addEventListener('resize', () => {
|
||||
min-width: 40px;
|
||||
}
|
||||
|
||||
/* 数据卡片区 */
|
||||
/* 数据卡片区 - 提升视觉核心地位 */
|
||||
.data-cards-section {
|
||||
margin-bottom: 32px;
|
||||
margin: 24px 0 32px;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
@@ -1183,12 +1300,15 @@ window.addEventListener('resize', () => {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
color: #ECEFF4;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.filter-select {
|
||||
background: rgba(30, 41, 59, 0.8);
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
color: #ECEFF4;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
padding: 8px 16px;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
@@ -1201,9 +1321,10 @@ window.addEventListener('resize', () => {
|
||||
}
|
||||
|
||||
.data-card {
|
||||
background: rgba(30, 41, 59, 0.6);
|
||||
backdrop-filter: blur(16px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
border-radius: 20px;
|
||||
padding: 24px;
|
||||
transition: all 0.3s ease;
|
||||
@@ -1211,7 +1332,7 @@ window.addEventListener('resize', () => {
|
||||
}
|
||||
|
||||
.data-card:hover {
|
||||
background: rgba(30, 41, 59, 0.8);
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
@@ -1220,6 +1341,137 @@ window.addEventListener('resize', () => {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
/* 优化后的学习概览卡片 */
|
||||
.overview-card {
|
||||
background: rgba(30, 41, 59, 0.6);
|
||||
backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 24px;
|
||||
padding: 24px;
|
||||
margin-bottom: 24px;
|
||||
box-shadow: 0 16px 40px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.core-stats {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.08);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.stat-item:hover {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
font-size: 28px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.stat-content {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 28px;
|
||||
font-weight: 700;
|
||||
color: #58C5A5;
|
||||
text-shadow: 0 0 15px rgba(88, 197, 165, 0.4);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-unit {
|
||||
font-size: 14px;
|
||||
color: #8892A0;
|
||||
font-weight: 500;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: #ECEFF4;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.stat-divider {
|
||||
width: 1px;
|
||||
height: 60px;
|
||||
background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.1), transparent);
|
||||
}
|
||||
|
||||
.goal-progress-container {
|
||||
background: rgba(168, 230, 207, 0.1);
|
||||
border: 1px solid rgba(168, 230, 207, 0.2);
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.goal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.goal-icon {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.goal-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #A8E6CF;
|
||||
}
|
||||
|
||||
.goal-text {
|
||||
color: #ECEFF4;
|
||||
font-size: 14px;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.goal-progress {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.goal-bar {
|
||||
flex: 1;
|
||||
height: 6px;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.goal-fill {
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, #58C5A5, #48B885);
|
||||
border-radius: 3px;
|
||||
transition: width 1s ease;
|
||||
}
|
||||
|
||||
.goal-percentage {
|
||||
color: #58C5A5;
|
||||
font-weight: 600;
|
||||
min-width: 36px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -1437,10 +1689,29 @@ window.addEventListener('resize', () => {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.suggestions-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
|
||||
.suggestions-carousel {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding: 10px 0 30px;
|
||||
}
|
||||
|
||||
.suggestions-track {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
overflow-x: auto;
|
||||
scroll-snap-type: x mandatory;
|
||||
padding-bottom: 10px;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(88, 197, 165, 0.5) transparent;
|
||||
}
|
||||
|
||||
.suggestions-track::-webkit-scrollbar {
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
.suggestions-track::-webkit-scrollbar-thumb {
|
||||
background: rgba(88, 197, 165, 0.5);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.suggestion-card {
|
||||
@@ -1449,10 +1720,12 @@ window.addEventListener('resize', () => {
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 16px;
|
||||
padding: 20px;
|
||||
min-width: 320px;
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
.suggestion-card:hover {
|
||||
@@ -1462,6 +1735,30 @@ window.addEventListener('resize', () => {
|
||||
border-color: rgba(88, 197, 165, 0.3);
|
||||
}
|
||||
|
||||
.ai-more-btn {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
bottom: 10px;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #58C5A5, #48B885);
|
||||
border: none;
|
||||
color: white;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 4px 16px rgba(88, 197, 165, 0.4);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.ai-more-btn:hover {
|
||||
transform: scale(1.1);
|
||||
box-shadow: 0 6px 20px rgba(88, 197, 165, 0.6);
|
||||
}
|
||||
|
||||
.suggestion-icon {
|
||||
font-size: 24px;
|
||||
width: 48px;
|
||||
|
||||
Reference in New Issue
Block a user