优化答题界面布局和视觉设计

主要更改:
- 头部布局优化:将返回按钮、标题、统计信息整合到一行,使用毛玻璃卡片样式
- 统计信息重构:将正确/错误次数移到头部右侧,采用紧凑的标签+数值设计
- 进度条优化:使用卡片包裹,添加毛玻璃效果,简化显示内容,只保留进度条
- 响应式优化:移动端自动调整为多行布局,平板和PC端保持横向一行显示
- 视觉统一:所有组件使用一致的毛玻璃风格和 macOS 设计语言

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
yanlongqi 2025-11-05 11:14:48 +08:00
parent c0a280132c
commit 3c97985af0
3 changed files with 150 additions and 29 deletions

View File

@ -1,8 +1,5 @@
import React from 'react' import React from 'react'
import { Progress, Space, Typography } from 'antd' import { Progress, Card } from 'antd'
import { CheckOutlined, CloseOutlined } from '@ant-design/icons'
const { Text } = Typography
interface QuestionProgressProps { interface QuestionProgressProps {
currentIndex: number currentIndex: number
@ -14,33 +11,40 @@ interface QuestionProgressProps {
const QuestionProgress: React.FC<QuestionProgressProps> = ({ const QuestionProgress: React.FC<QuestionProgressProps> = ({
currentIndex, currentIndex,
totalQuestions, totalQuestions,
correctCount,
wrongCount,
}) => { }) => {
if (totalQuestions === 0) return null if (totalQuestions === 0) return null
const percent = Math.round(((currentIndex + 1) / totalQuestions) * 100)
return ( return (
<div style={{ marginBottom: 20 }}> <Card
style={{
marginBottom: 20,
borderRadius: 16,
background: 'rgba(255, 255, 255, 0.9)',
backdropFilter: 'blur(30px) saturate(180%)',
WebkitBackdropFilter: 'blur(30px) saturate(180%)',
boxShadow: '0 2px 12px rgba(0, 0, 0, 0.05), 0 1px 4px rgba(0, 0, 0, 0.03), 0 0 0 1px rgba(0, 0, 0, 0.03)',
border: '0.5px solid rgba(0, 0, 0, 0.04)',
}}
bodyStyle={{ padding: '16px 20px' }}
>
<Progress <Progress
percent={Math.round(((currentIndex + 1) / totalQuestions) * 100)} percent={percent}
status="active" status="active"
strokeColor={{ strokeColor={{
'0%': '#108ee9', '0%': '#007aff',
'100%': '#87d068', '100%': '#52c41a',
}} }}
trailColor="rgba(0, 0, 0, 0.06)"
strokeWidth={12}
format={() => `${currentIndex + 1} / ${totalQuestions}`} format={() => `${currentIndex + 1} / ${totalQuestions}`}
style={{
fontSize: '14px',
fontWeight: 600,
}}
/> />
<div style={{ marginTop: 8, textAlign: 'center' }}> </Card>
<Space size="large">
<Text>
<CheckOutlined style={{ color: '#52c41a' }} /> {correctCount}
</Text>
<Text>
<CloseOutlined style={{ color: '#ff4d4f' }} /> {wrongCount}
</Text>
</Space>
</div>
</div>
) )
} }

View File

@ -14,12 +14,63 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 24px; margin-bottom: 20px;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(30px) saturate(180%);
-webkit-backdrop-filter: blur(30px) saturate(180%);
padding: 16px 20px;
border-radius: 16px;
box-shadow:
0 2px 12px rgba(0, 0, 0, 0.05),
0 1px 4px rgba(0, 0, 0, 0.03),
0 0 0 1px rgba(0, 0, 0, 0.03);
border: 0.5px solid rgba(0, 0, 0, 0.04);
.backButton {
color: #007aff;
font-weight: 500;
padding: 4px 12px;
&:hover {
color: #0051d5;
background: rgba(0, 122, 255, 0.08);
}
}
.title { .title {
color: #1d1d1f !important; color: #1d1d1f !important;
margin: 0 !important; margin: 0 !important;
font-weight: 700; font-weight: 700;
font-size: 18px !important;
flex: 1;
text-align: center;
}
.statsGroup {
display: flex;
gap: 16px;
align-items: center;
}
.statItem {
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
}
.statLabel {
font-size: 11px;
color: #86868b;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.statValue {
font-size: 20px;
font-weight: 700;
line-height: 1;
} }
} }
@ -75,12 +126,41 @@
} }
.header { .header {
flex-direction: column; flex-wrap: wrap;
gap: 12px; gap: 12px;
align-items: flex-start; padding: 12px 16px;
border-radius: 12px;
.backButton {
order: 1;
flex: 0 0 auto;
}
.title { .title {
font-size: 20px !important; order: 2;
flex: 1 1 100%;
text-align: center;
font-size: 16px !important;
}
.statsGroup {
order: 3;
flex: 1 1 100%;
justify-content: center;
gap: 24px;
}
.statItem {
flex-direction: row;
gap: 6px;
}
.statLabel {
font-size: 12px;
}
.statValue {
font-size: 18px;
} }
} }
@ -101,13 +181,35 @@
} }
} }
// 响应式设计 - 平板
@media (min-width: 769px) and (max-width: 1024px) {
.container {
padding: 24px;
}
.header {
.title {
font-size: 20px !important;
}
}
}
// 响应式设计 - PC端 // 响应式设计 - PC端
@media (min-width: 769px) { @media (min-width: 1025px) {
.container { .container {
padding: 32px; padding: 32px;
} }
.header { .header {
margin-bottom: 32px; margin-bottom: 24px;
padding: 18px 24px;
.title {
font-size: 22px !important;
}
.statValue {
font-size: 24px;
}
} }
} }

View File

@ -253,12 +253,27 @@ const QuestionPage: React.FC = () => {
<div className={styles.content}> <div className={styles.content}>
{/* 头部 */} {/* 头部 */}
<div className={styles.header}> <div className={styles.header}>
<Button icon={<ArrowLeftOutlined />} onClick={() => navigate("/")}> <Button
icon={<ArrowLeftOutlined />}
onClick={() => navigate("/")}
className={styles.backButton}
type="text"
>
</Button> </Button>
<Title level={3} className={styles.title}> <Title level={3} className={styles.title}>
AnKao AnKao
</Title> </Title>
<div className={styles.statsGroup}>
<div className={styles.statItem}>
<span className={styles.statLabel}></span>
<span className={styles.statValue} style={{ color: '#52c41a' }}>{correctCount}</span>
</div>
<div className={styles.statItem}>
<span className={styles.statLabel}></span>
<span className={styles.statValue} style={{ color: '#ff4d4f' }}>{wrongCount}</span>
</div>
</div>
</div> </div>
{/* 进度条 */} {/* 进度条 */}