refactor(mobile): simplify header to single row layout

- Left: username + logout button (stacked)
- Center: page title
- Right: larger progress ring (56px)
- Remove connection status (shown in WeChat navbar)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
empty
2026-02-03 22:37:15 +08:00
parent 8ab575b14a
commit 6ccc571be2

View File

@@ -61,28 +61,23 @@ onMounted(() => {
<div class="vote-view"> <div class="vote-view">
<!-- Sticky Header Container --> <!-- Sticky Header Container -->
<div class="sticky-header"> <div class="sticky-header">
<!-- Header --> <!-- Header: 单行布局 -->
<header class="page-header"> <header class="page-header">
<!-- 第一行昵称 | 节目投票 | 连接状态 --> <!-- 左侧昵称 + 退出 -->
<div class="header-row header-row-top"> <div class="header-left">
<span class="user-name">{{ connectionStore.userName || '访客' }}</span> <span class="user-name">{{ connectionStore.userName || '访客' }}</span>
<h1 class="page-title">节目投票</h1>
<span class="status-indicator" :class="{ active: connectionStore.isConnected }">
<span class="status-dot" :class="{ pulsing: connectionStore.isConnected }"></span>
已连接 {{ connectionStore.latency }}ms
</span>
</div>
<!-- 第二行退出 | 进度环 -->
<div class="header-row header-row-bottom">
<span class="logout-btn" @click="handleLogout">退出</span> <span class="logout-btn" @click="handleLogout">退出</span>
<div class="progress-ring"> </div>
<svg viewBox="0 0 36 36" class="circular-progress"> <!-- 中间标题 -->
<path class="circle-bg" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" /> <h1 class="page-title">节目投票</h1>
<path class="circle-progress" :stroke-dasharray="`${votingStore.totalTicketCount > 0 ? (votingStore.usedTicketCount / votingStore.totalTicketCount) * 100 : 0}, 100`" <!-- 右侧进度环 -->
d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" /> <div class="progress-ring">
</svg> <svg viewBox="0 0 36 36" class="circular-progress">
<span class="progress-text">{{ votingStore.usedTicketCount }}/{{ votingStore.totalTicketCount }}</span> <path class="circle-bg" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" />
</div> <path class="circle-progress" :stroke-dasharray="`${votingStore.totalTicketCount > 0 ? (votingStore.usedTicketCount / votingStore.totalTicketCount) * 100 : 0}, 100`"
d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" />
</svg>
<span class="progress-text">{{ votingStore.usedTicketCount }}/{{ votingStore.totalTicketCount }}</span>
</div> </div>
</header> </header>
</div> </div>
@@ -127,48 +122,26 @@ onMounted(() => {
background: $color-surface-glass; background: $color-surface-glass;
backdrop-filter: $backdrop-blur; backdrop-filter: $backdrop-blur;
-webkit-backdrop-filter: $backdrop-blur; -webkit-backdrop-filter: $backdrop-blur;
padding: $spacing-md $spacing-lg; padding: $spacing-sm $spacing-md;
padding-top: calc(env(safe-area-inset-top) + #{$spacing-md}); padding-top: calc(env(safe-area-inset-top) + #{$spacing-sm});
display: flex;
flex-direction: column;
gap: 8px;
}
.header-row {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
} }
.header-row-top { .header-left {
.user-name { display: flex;
flex: 1; flex-direction: column;
text-align: left; gap: 2px;
} min-width: 60px;
.page-title {
flex: 1;
text-align: center;
}
.status-indicator {
flex: 1;
justify-content: flex-end;
}
}
.header-row-bottom {
.logout-btn {
flex: 1;
text-align: left;
}
.progress-ring {
// 保持右侧
}
} }
.page-title { .page-title {
font-size: $font-size-lg; font-size: $font-size-lg;
font-weight: bold; font-weight: bold;
color: $color-text-inverse; color: $color-text-inverse;
text-align: center;
flex: 1;
} }
.user-name { .user-name {
@@ -176,47 +149,20 @@ onMounted(() => {
color: $color-gold; color: $color-gold;
} }
.status-indicator {
display: flex;
align-items: center;
gap: 4px;
color: $color-text-secondary;
font-size: $font-size-xs;
&.active {
color: #22c55e;
}
}
.logout-btn { .logout-btn {
color: #999; color: rgba(255, 255, 255, 0.6);
font-size: $font-size-xs;
cursor: pointer; cursor: pointer;
padding: 2px 6px;
border-radius: 4px;
transition: all 0.2s;
&:active { &:active {
background: rgba(255, 255, 255, 0.1);
color: #fff; color: #fff;
} }
} }
.status-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: #666;
&.pulsing {
background: #22c55e;
animation: pulse-dot 1.5s ease-in-out infinite;
}
}
.progress-ring { .progress-ring {
position: relative; position: relative;
width: 48px; width: 56px;
height: 48px; height: 56px;
} }
.circular-progress { .circular-progress {
@@ -255,10 +201,5 @@ onMounted(() => {
flex-direction: column; flex-direction: column;
gap: $spacing-lg; gap: $spacing-lg;
} }
@keyframes pulse-dot {
0%, 100% { opacity: 1; box-shadow: 0 0 0 0 rgba(34, 197, 94, 0.4); }
50% { opacity: 0.8; box-shadow: 0 0 0 4px rgba(34, 197, 94, 0); }
}
</style> </style>