- 22-page high-fidelity design gallery - shadcn/ui + Tailwind CSS + Vite - iPhone frame wrapper for realistic preview - Bottom tab bar component - All pages match ZhiXi app screens
231 lines
9.3 KiB
TypeScript
231 lines
9.3 KiB
TypeScript
// Page 8: Study Workbench - 学习首页/学习工作台
|
||
import { PlayIcon, CheckCircleIcon, CircleIcon, FlameIcon, CalendarIcon } from 'lucide-react';
|
||
import BottomTabBar from '../components/BottomTabBar';
|
||
|
||
const todayTasks = [
|
||
{ title: '机器学习 - 回忆测试', type: '回忆测试', mins: 10, done: true, color: '#7C6EFA' },
|
||
{ title: '高数 - 间隔复习 8 题', type: '间隔复习', mins: 15, done: true, color: '#F97316' },
|
||
{ title: '英语词汇 - 25 个待复习', type: '词汇复习', mins: 8, done: false, color: '#2DD4BF' },
|
||
{ title: '注意力机制 - 费曼解释', type: '费曼练习', mins: 12, done: false, color: '#A78BFA' },
|
||
{ title: '产品设计 - 薄弱点复习', type: '薄弱点', mins: 10, done: false, color: '#F59E0B' },
|
||
];
|
||
|
||
const weekActivity = [0.3, 0.7, 1, 0.4, 0.9, 0.6, 0.2];
|
||
const weekDays = ['一', '二', '三', '四', '五', '六', '日'];
|
||
|
||
const StudyHomePage = () => {
|
||
const done = todayTasks.filter(t => t.done).length;
|
||
const total = todayTasks.length;
|
||
const progress = (done / total) * 100;
|
||
|
||
return (
|
||
<div
|
||
data-cmp="StudyHomePage"
|
||
className="absolute inset-0 flex flex-col"
|
||
style={{
|
||
background: '#0F0F1A',
|
||
paddingTop: '44px',
|
||
}}
|
||
>
|
||
{/* Header */}
|
||
<div className="flex items-center justify-between px-5 pt-4 pb-3">
|
||
<div>
|
||
<p style={{ fontSize: '12px', color: 'rgba(240,240,255,0.4)', fontWeight: '500' }}>周四,1月16日</p>
|
||
<h1 style={{ fontSize: '20px', fontWeight: '800', color: '#F0F0FF', letterSpacing: '-0.4px' }}>学习工作台</h1>
|
||
</div>
|
||
<div className="flex items-center gap-2 px-3 py-1.5"
|
||
style={{
|
||
background: 'rgba(249,115,22,0.15)',
|
||
border: '1px solid rgba(249,115,22,0.3)',
|
||
borderRadius: '20px',
|
||
}}
|
||
>
|
||
<FlameIcon size={14} style={{ color: '#F97316' }} />
|
||
<span style={{ fontSize: '13px', fontWeight: '700', color: '#F97316' }}>14 天连续</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex-1 overflow-y-auto px-5 pb-24">
|
||
{/* Today's progress card */}
|
||
<div
|
||
className="mb-5"
|
||
style={{
|
||
borderRadius: '20px',
|
||
background: 'linear-gradient(135deg, rgba(124,110,250,0.15) 0%, rgba(45,212,191,0.08) 100%)',
|
||
border: '1px solid rgba(124,110,250,0.2)',
|
||
padding: '16px',
|
||
}}
|
||
>
|
||
<div className="flex items-center justify-between mb-4">
|
||
<div>
|
||
<p style={{ fontSize: '13px', color: 'rgba(240,240,255,0.5)', fontWeight: '500' }}>今日进度</p>
|
||
<p style={{ fontSize: '26px', fontWeight: '900', color: '#F0F0FF', letterSpacing: '-0.5px', marginTop: '2px' }}>
|
||
{done} / {total}
|
||
<span style={{ fontSize: '14px', fontWeight: '500', color: 'rgba(240,240,255,0.4)', marginLeft: '6px' }}>个任务</span>
|
||
</p>
|
||
</div>
|
||
<div
|
||
style={{
|
||
width: '64px', height: '64px',
|
||
borderRadius: '50%',
|
||
background: 'conic-gradient(#7C6EFA 0%, #7C6EFA ' + progress + '%, rgba(255,255,255,0.08) ' + progress + '%)',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
}}
|
||
>
|
||
<div
|
||
style={{
|
||
width: '48px', height: '48px',
|
||
borderRadius: '50%',
|
||
background: '#12122A',
|
||
display: 'flex',
|
||
alignItems: 'center',
|
||
justifyContent: 'center',
|
||
}}
|
||
>
|
||
<span style={{ fontSize: '14px', fontWeight: '800', color: '#7C6EFA' }}>{Math.round(progress)}%</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Progress bar */}
|
||
<div style={{ height: '6px', background: 'rgba(255,255,255,0.08)', borderRadius: '3px', overflow: 'hidden' }}>
|
||
<div
|
||
style={{
|
||
height: '100%',
|
||
width: `${progress}%`,
|
||
background: 'linear-gradient(90deg, #7C6EFA, #A78BFA)',
|
||
borderRadius: '3px',
|
||
}}
|
||
/>
|
||
</div>
|
||
|
||
{/* Stats */}
|
||
<div className="flex items-center gap-4 mt-4">
|
||
{[
|
||
{ label: '已学', value: `${done * 12} 分钟` },
|
||
{ label: '剩余', value: `${(total - done) * 11} 分钟` },
|
||
{ label: '掌握', value: '+5 点' },
|
||
].map((s, i) => (
|
||
<div key={i} className="flex flex-col">
|
||
<span style={{ fontSize: '13px', fontWeight: '700', color: '#F0F0FF' }}>{s.value}</span>
|
||
<span style={{ fontSize: '10px', color: 'rgba(240,240,255,0.4)' }}>{s.label}</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Today's tasks */}
|
||
<div className="mb-5">
|
||
<div className="flex items-center justify-between mb-3">
|
||
<h2 style={{ fontSize: '15px', fontWeight: '700', color: '#F0F0FF' }}>今日任务</h2>
|
||
<div className="flex items-center gap-1">
|
||
<CalendarIcon size={12} style={{ color: 'rgba(240,240,255,0.4)' }} />
|
||
<span style={{ fontSize: '12px', color: 'rgba(240,240,255,0.4)' }}>AI 自动排期</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex flex-col gap-2.5">
|
||
{todayTasks.map((task, i) => (
|
||
<div
|
||
key={i}
|
||
className="flex items-center gap-3 px-4 py-3"
|
||
style={{
|
||
background: task.done ? 'rgba(255,255,255,0.03)' : 'rgba(255,255,255,0.05)',
|
||
border: `1px solid ${task.done ? 'rgba(255,255,255,0.05)' : 'rgba(255,255,255,0.08)'}`,
|
||
borderRadius: '14px',
|
||
opacity: task.done ? 0.6 : 1,
|
||
}}
|
||
>
|
||
{task.done
|
||
? <CheckCircleIcon size={20} style={{ color: '#34D399', flexShrink: 0 }} />
|
||
: <CircleIcon size={20} style={{ color: 'rgba(240,240,255,0.2)', flexShrink: 0 }} />
|
||
}
|
||
<div className="flex-1 min-w-0">
|
||
<p
|
||
style={{
|
||
fontSize: '13px',
|
||
fontWeight: '600',
|
||
color: task.done ? 'rgba(240,240,255,0.4)' : '#F0F0FF',
|
||
textDecoration: task.done ? 'line-through' : 'none',
|
||
}}
|
||
>
|
||
{task.title}
|
||
</p>
|
||
<div className="flex items-center gap-2 mt-1">
|
||
<span
|
||
style={{
|
||
fontSize: '10px',
|
||
fontWeight: '600',
|
||
color: task.color,
|
||
padding: '1px 6px',
|
||
background: `${task.color}22`,
|
||
borderRadius: '20px',
|
||
}}
|
||
>
|
||
{task.type}
|
||
</span>
|
||
<span style={{ fontSize: '10px', color: 'rgba(240,240,255,0.35)' }}>约 {task.mins} 分钟</span>
|
||
</div>
|
||
</div>
|
||
{!task.done && (
|
||
<div
|
||
style={{
|
||
width: '32px', height: '32px',
|
||
borderRadius: '10px',
|
||
background: `linear-gradient(135deg, ${task.color}, ${task.color}aa)`,
|
||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||
flexShrink: 0,
|
||
}}
|
||
>
|
||
<PlayIcon size={14} style={{ color: 'white' }} />
|
||
</div>
|
||
)}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Weekly activity heatmap */}
|
||
<div>
|
||
<h2 style={{ fontSize: '15px', fontWeight: '700', color: '#F0F0FF', marginBottom: '14px' }}>本周学习活跃</h2>
|
||
<div className="flex items-end gap-2">
|
||
{weekActivity.map((val, i) => (
|
||
<div key={i} className="flex-1 flex flex-col items-center gap-2">
|
||
<div
|
||
style={{
|
||
width: '100%',
|
||
height: `${val * 60}px`,
|
||
background: i === 6 ? 'rgba(255,255,255,0.1)' : `rgba(124,110,250,${val * 0.9 + 0.1})`,
|
||
borderRadius: '6px',
|
||
minHeight: '8px',
|
||
transition: 'height 0.3s',
|
||
}}
|
||
/>
|
||
<span
|
||
style={{
|
||
fontSize: '10px',
|
||
color: i === 2 ? '#7C6EFA' : 'rgba(240,240,255,0.3)',
|
||
fontWeight: i === 2 ? '700' : '400',
|
||
}}
|
||
>
|
||
{weekDays[i]}
|
||
</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
<div className="flex items-center justify-between mt-3 px-1">
|
||
<span style={{ fontSize: '11px', color: 'rgba(240,240,255,0.3)' }}>总计 3.5 小时</span>
|
||
<span style={{ fontSize: '11px', color: 'rgba(240,240,255,0.3)' }}>日均 30 分钟</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<BottomTabBar active="study" />
|
||
</div>
|
||
);
|
||
};
|
||
|
||
export default StudyHomePage;
|