style: 首页 Dashboard 移动端适配

- 添加响应式网格布局
- 卡片和图表移动端优化
- 添加底部 Tab 导航
- 管理入口根据用户权限显示

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-23 17:57:56 +08:00
parent fe99649f72
commit a37cf93c67

View File

@@ -3455,10 +3455,54 @@ def get_dashboard_html() -> str:
.nav a.active {
color: #667eea;
}
/* 移动端适配 */
@media (max-width: 768px) {
.nav {
display: none !important;
}
body {
padding-bottom: 80px;
}
.container {
padding: 12px;
}
header {
padding: 20px 16px;
margin-bottom: 16px;
}
header h1 {
font-size: 1.5rem;
}
.grid {
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.card {
padding: 14px;
}
.card .value {
font-size: 1.5rem;
}
.chart-container {
padding: 14px;
height: auto;
}
.chart-container canvas {
max-height: 180px;
}
.meals-list li {
flex-wrap: wrap;
gap: 10px;
gap: 4px;
}
.meal-desc {
width: 100%;
margin: 4px 0;
order: 3;
}
}
@media (max-width: 480px) {
.grid {
grid-template-columns: 1fr;
}
}
.container {
@@ -3806,6 +3850,86 @@ def get_dashboard_html() -> str:
loadTodayData();
loadWeekData();
loadWeightData();
// 检查管理员状态并显示管理入口
const user = JSON.parse(localStorage.getItem('user') || '{}');
if (user.is_admin) {
const adminLink = document.getElementById('admin-link');
if (adminLink) adminLink.style.display = 'block';
}
</script>
<!-- 移动端底部导航 -->
<nav class="mobile-nav">
<a href="/" class="mobile-nav-item active">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/>
</svg>
<span class="nav-label">首页</span>
</a>
<a href="/exercise" class="mobile-nav-item">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2"/>
</svg>
<span class="nav-label">运动</span>
</a>
<a href="/meal" class="mobile-nav-item">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M18 8h1a4 4 0 0 1 0 8h-1"/><path d="M2 8h16v9a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V8z"/><line x1="6" y1="1" x2="6" y2="4"/><line x1="10" y1="1" x2="10" y2="4"/><line x1="14" y1="1" x2="14" y2="4"/>
</svg>
<span class="nav-label">饮食</span>
</a>
<a href="/sleep" class="mobile-nav-item">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/>
</svg>
<span class="nav-label">睡眠</span>
</a>
<div class="mobile-nav-item more-trigger" onclick="toggleMoreMenu()">
<svg class="nav-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/>
</svg>
<span class="nav-label">更多</span>
</div>
</nav>
<div id="more-menu" class="more-menu hidden">
<a href="/weight" class="more-menu-item">体重</a>
<a href="/reading" class="more-menu-item">阅读</a>
<a href="/report" class="more-menu-item">报告</a>
<a href="/settings" class="more-menu-item">设置</a>
<a href="/admin" class="more-menu-item" id="admin-link" style="display:none">管理</a>
</div>
<style>
.mobile-nav {
position: fixed; bottom: 0; left: 0; right: 0; height: 64px;
background: white; border-top: 1px solid #E2E8F0;
display: none; justify-content: space-around; align-items: center; z-index: 50;
}
.mobile-nav-item {
display: flex; flex-direction: column; align-items: center; justify-content: center;
min-width: 64px; min-height: 44px; color: #64748B; text-decoration: none; cursor: pointer;
}
.mobile-nav-item.active { color: #667eea; }
.nav-icon { width: 24px; height: 24px; margin-bottom: 2px; }
.nav-label { font-size: 10px; font-weight: 500; }
.more-menu {
position: fixed; bottom: 72px; right: 16px; background: white;
border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.15); padding: 8px 0; z-index: 51;
}
.more-menu.hidden { display: none; }
.more-menu-item { display: block; padding: 12px 24px; color: #1E293B; text-decoration: none; }
.more-menu-item:hover { background: #F1F5F9; }
@media (max-width: 768px) { .mobile-nav { display: flex; } }
</style>
<script>
function toggleMoreMenu() {
document.getElementById('more-menu').classList.toggle('hidden');
}
document.addEventListener('click', function(e) {
if (!e.target.closest('.more-trigger') && !e.target.closest('.more-menu')) {
document.getElementById('more-menu').classList.add('hidden');
}
});
</script>
</body>
</html>