update
This commit is contained in:
@@ -6,199 +6,293 @@ const FEATURES = [
|
||||
{
|
||||
to: '/toeic',
|
||||
icon: 'assignment',
|
||||
iconBg: 'bg-blue-50',
|
||||
iconColor: 'text-blue-600',
|
||||
borderColor: 'border-l-blue-600',
|
||||
title: 'Luyện đề TOEIC',
|
||||
desc: 'Kho đề thi cập nhật theo cấu trúc mới nhất. Phân tích điểm yếu chi tiết từng Part.',
|
||||
cta: 'Bắt đầu ngay',
|
||||
ctaColor: 'text-blue-600',
|
||||
title: 'Luyện đề',
|
||||
accent: 'TOEIC',
|
||||
desc: 'Kho đề thi cập nhật theo cấu trúc mới nhất. Phân tích điểm yếu từng Part.',
|
||||
stat: '350+ câu hỏi',
|
||||
},
|
||||
{
|
||||
to: '/writing',
|
||||
icon: 'auto_fix_high',
|
||||
iconBg: 'bg-green-50',
|
||||
iconColor: 'text-green-600',
|
||||
borderColor: 'border-l-green-600',
|
||||
title: 'AI Chấm Writing',
|
||||
desc: 'Phản hồi tức thì về ngữ pháp, từ vựng, cấu trúc và bài viết mẫu từ AI.',
|
||||
cta: 'Thử ngay',
|
||||
ctaColor: 'text-green-600',
|
||||
title: 'AI chấm',
|
||||
accent: 'Writing',
|
||||
desc: 'Phản hồi tức thì về ngữ pháp, từ vựng, cấu trúc và bài viết mẫu.',
|
||||
stat: '3 lượt / ngày',
|
||||
},
|
||||
{
|
||||
to: '/flash-card',
|
||||
icon: 'menu_book',
|
||||
iconBg: 'bg-amber-50',
|
||||
iconColor: 'text-amber-600',
|
||||
borderColor: 'border-l-amber-600',
|
||||
title: 'Từ vựng thông minh',
|
||||
desc: '720 từ TOEIC theo 6 chủ đề. Flashcard với hiệu ứng lật 3D.',
|
||||
cta: 'Khám phá',
|
||||
ctaColor: 'text-amber-600',
|
||||
stat: '720 từ vựng',
|
||||
title: 'Từ vựng',
|
||||
accent: 'thông minh',
|
||||
desc: 'Bộ thẻ TOEIC với spaced-repetition, lật 3D, ảnh minh hoạ.',
|
||||
stat: '18 000+ từ',
|
||||
},
|
||||
]
|
||||
|
||||
export function Home() {
|
||||
const user = useUser()
|
||||
const openModal = useAuthModalStore((s) => s.open)
|
||||
const firstName = user?.name ?? 'bạn'
|
||||
|
||||
return (
|
||||
<div className="px-6 py-8 max-w-6xl mx-auto page-enter">
|
||||
{/* Hero */}
|
||||
<section className="flex flex-col lg:flex-row gap-10 items-center mb-12">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="inline-flex items-center gap-2 bg-blue-50 text-blue-600 text-xs font-bold px-3 py-1.5 rounded-full mb-5 uppercase tracking-wider">
|
||||
<span className="material-symbols-outlined" style={{ fontSize: 14 }}>auto_awesome</span>
|
||||
AI-Powered Learning
|
||||
</div>
|
||||
<h1 className="text-4xl lg:text-5xl font-extrabold leading-tight text-slate-800 mb-4" style={{ letterSpacing: '-0.02em' }}>
|
||||
Luyện TOEIC<br />thông minh<br />
|
||||
<span className="text-blue-600 italic">cùng AI</span>
|
||||
<div className="px-6 lg:px-10 py-10 max-w-6xl mx-auto page-enter">
|
||||
{/* Page head — editorial */}
|
||||
<div className="flex flex-col lg:flex-row lg:items-end lg:justify-between gap-6 mb-10">
|
||||
<div>
|
||||
<div className="at-eyebrow mb-3">Học TOEIC cùng AI</div>
|
||||
<h1 className="at-title text-4xl lg:text-[44px]">
|
||||
Chào <i>{firstName}</i>,<br />
|
||||
hôm nay học <i>15 phút</i>?
|
||||
</h1>
|
||||
<p className="text-slate-500 text-lg leading-relaxed mb-8 max-w-md">
|
||||
Cá nhân hóa lộ trình học tập để bứt phá điểm số trong thời gian ngắn nhất. AI phân tích điểm yếu và tối ưu bài tập cho bạn.
|
||||
</p>
|
||||
<div className="flex gap-3 flex-wrap">
|
||||
<Link
|
||||
to="/toeic"
|
||||
className="bg-blue-600 text-white px-8 py-3.5 rounded-xl font-bold text-sm hover:bg-blue-700 transition-colors shadow-lg shadow-blue-600/20"
|
||||
>
|
||||
Bắt đầu ngay
|
||||
</Link>
|
||||
<Link
|
||||
to="/writing"
|
||||
className="border border-slate-200 px-8 py-3.5 rounded-xl font-bold text-sm text-slate-500 hover:bg-white hover:border-blue-600 hover:text-blue-600 transition-all"
|
||||
>
|
||||
Thử AI Writing
|
||||
</Link>
|
||||
</div>
|
||||
<div className="flex gap-6 mt-8">
|
||||
<div>
|
||||
<div className="text-2xl font-extrabold text-blue-600">350+</div>
|
||||
<div className="text-xs text-slate-400 mt-0.5">Câu hỏi TOEIC</div>
|
||||
</div>
|
||||
<div className="w-px bg-slate-200" />
|
||||
<div>
|
||||
<div className="text-2xl font-extrabold text-green-600">720</div>
|
||||
<div className="text-xs text-slate-400 mt-0.5">Từ vựng</div>
|
||||
</div>
|
||||
<div className="w-px bg-slate-200" />
|
||||
<div>
|
||||
<div className="text-2xl font-extrabold text-amber-600">AI</div>
|
||||
<div className="text-xs text-slate-400 mt-0.5">Writing Checker</div>
|
||||
</div>
|
||||
<div className="mt-4 text-sm" style={{ color: 'var(--at-mute)' }}>
|
||||
Mục tiêu <b style={{ color: 'var(--at-ink)' }}>850</b>
|
||||
<span className="mx-2 inline-block w-[3px] h-[3px] rounded-full align-middle" style={{ background: 'var(--at-mute-2)' }} />
|
||||
hiện tại <b style={{ color: 'var(--at-ink)' }}>720</b>
|
||||
<span className="mx-2 inline-block w-[3px] h-[3px] rounded-full align-middle" style={{ background: 'var(--at-mute-2)' }} />
|
||||
còn <b style={{ color: 'var(--at-brand)' }}>130 điểm</b> nữa
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex gap-2.5">
|
||||
<Link
|
||||
to="/flash-card"
|
||||
className="inline-flex items-center gap-2 px-5 py-3 rounded-xl text-[13.5px] font-semibold transition-colors"
|
||||
style={{ background: 'var(--at-surface)', border: '1px solid var(--at-line)', color: 'var(--at-ink-2)' }}
|
||||
>
|
||||
Học từ vựng
|
||||
</Link>
|
||||
<Link
|
||||
to="/toeic"
|
||||
className="inline-flex items-center gap-2 px-5 py-3 rounded-xl text-[13.5px] font-semibold transition-colors hover:opacity-90"
|
||||
style={{ background: 'var(--at-ink)', color: 'var(--at-paper)', border: '1px solid var(--at-ink)' }}
|
||||
>
|
||||
<span className="material-symbols-outlined" style={{ fontSize: 16 }}>play_arrow</span>
|
||||
Tiếp tục học
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Preview card — hidden on mobile */}
|
||||
<div className="hidden lg:block flex-shrink-0 w-80">
|
||||
<div className="bg-white rounded-2xl p-6 shadow-xl border border-slate-100">
|
||||
<div className="flex items-center justify-between mb-5">
|
||||
<div className="grid lg:grid-cols-[2fr_1fr] gap-5">
|
||||
{/* MAIN COL */}
|
||||
<div className="flex flex-col gap-5 min-w-0">
|
||||
{/* Progress hero */}
|
||||
<div className="rounded-2xl p-7 flex flex-wrap items-center gap-7" style={{ background: 'var(--at-surface)', border: '1px solid var(--at-line)' }}>
|
||||
<ProgressRing value={85} />
|
||||
<div className="flex-1 min-w-[240px]">
|
||||
<div className="at-eyebrow mb-1">Lộ trình</div>
|
||||
<div className="at-serif text-[22px] leading-[1.2] tracking-tight mb-3" style={{ color: 'var(--at-ink)' }}>
|
||||
Bạn đang đi <i style={{ color: 'var(--at-brand)', fontStyle: 'italic' }}>đúng hướng</i> — tuần này 4/7 ngày.
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-4 items-stretch">
|
||||
<Stat num="24" label="ngày còn lại" />
|
||||
<div className="w-px self-stretch" style={{ background: 'var(--at-line)' }} />
|
||||
<Stat num="+46" label="điểm tháng này" />
|
||||
<div className="w-px self-stretch" style={{ background: 'var(--at-line)' }} />
|
||||
<Stat num="68%" label="tỷ lệ đúng" color="var(--at-good)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Feature cards */}
|
||||
<div className="rounded-2xl p-6" style={{ background: 'var(--at-surface)', border: '1px solid var(--at-line)' }}>
|
||||
<div className="at-eyebrow mb-1">Khám phá</div>
|
||||
<h2 className="at-serif text-[22px] tracking-tight mb-5" style={{ color: 'var(--at-ink)', fontWeight: 500 }}>
|
||||
Tính năng <i style={{ color: 'var(--at-brand)', fontStyle: 'italic' }}>nổi bật</i>
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-3">
|
||||
{FEATURES.map((f) => (
|
||||
<Link
|
||||
key={f.to}
|
||||
to={f.to}
|
||||
className="rounded-xl p-4 transition-all hover:-translate-y-0.5"
|
||||
style={{ background: 'var(--at-paper-2)', border: '1px solid var(--at-line)' }}
|
||||
>
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<div
|
||||
className="w-9 h-9 rounded-lg grid place-items-center"
|
||||
style={{ background: 'var(--at-brand-soft)', color: 'var(--at-brand)' }}
|
||||
>
|
||||
<span className="material-symbols-outlined" style={{ fontSize: 18 }}>{f.icon}</span>
|
||||
</div>
|
||||
<span className="at-chip at-chip-brand">
|
||||
<span className="at-chip-dot" />
|
||||
{f.stat}
|
||||
</span>
|
||||
</div>
|
||||
<div className="at-serif text-[17px] leading-[1.15] tracking-tight mb-1" style={{ color: 'var(--at-ink)', fontWeight: 500 }}>
|
||||
{f.title} <i style={{ color: 'var(--at-brand)', fontStyle: 'italic' }}>{f.accent}</i>
|
||||
</div>
|
||||
<div className="text-[12.5px] leading-[1.5]" style={{ color: 'var(--at-mute)' }}>{f.desc}</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 7-day journey */}
|
||||
<div className="rounded-2xl p-6" style={{ background: 'var(--at-surface)', border: '1px solid var(--at-line)' }}>
|
||||
<div className="flex justify-between items-end mb-4">
|
||||
<div>
|
||||
<div className="font-bold text-base text-slate-800">Tiến độ tuần này</div>
|
||||
<div className="text-xs text-slate-400 mt-0.5">Bạn đang làm rất tốt!</div>
|
||||
<div className="at-eyebrow mb-1">Tuần này</div>
|
||||
<div className="at-serif text-[20px] tracking-tight" style={{ color: 'var(--at-ink)', fontWeight: 500 }}>
|
||||
Lộ trình <i style={{ color: 'var(--at-brand)', fontStyle: 'italic' }}>7 ngày</i>
|
||||
</div>
|
||||
</div>
|
||||
<div className="bg-green-50 text-green-600 text-xs font-bold px-2.5 py-1 rounded-lg">+12%</div>
|
||||
<span className="at-chip at-chip-good">
|
||||
<span className="at-chip-dot" />
|
||||
+24% so với tuần trước
|
||||
</span>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<div className="flex justify-between text-xs font-semibold mb-1.5">
|
||||
<span>Reading Score</span><span className="text-blue-600">420/495</span>
|
||||
</div>
|
||||
<div className="h-1.5 w-full rounded-full bg-slate-100">
|
||||
<div className="h-full bg-blue-600 rounded-full" style={{ width: '85%' }} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-4">
|
||||
<div className="flex justify-between text-xs font-semibold mb-1.5">
|
||||
<span>Listening Score</span><span className="text-green-600">380/495</span>
|
||||
</div>
|
||||
<div className="h-1.5 w-full rounded-full bg-slate-100">
|
||||
<div className="h-full bg-green-600 rounded-full" style={{ width: '77%' }} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-3 mt-4">
|
||||
<div className="bg-blue-50 rounded-xl p-3 border-l-4 border-blue-600">
|
||||
<span className="material-symbols-outlined text-blue-600" style={{ fontSize: 18 }}>local_fire_department</span>
|
||||
<div className="text-xl font-extrabold text-blue-600 mt-1">14</div>
|
||||
<div className="text-xs text-slate-400">Ngày Streak</div>
|
||||
</div>
|
||||
<div className="bg-green-50 rounded-xl p-3 border-l-4 border-green-600">
|
||||
<span className="material-symbols-outlined text-green-600" style={{ fontSize: 18, fontVariationSettings: "'FILL' 1" }}>star</span>
|
||||
<div className="text-xl font-extrabold text-green-600 mt-1">1,250</div>
|
||||
<div className="text-xs text-slate-400">Điểm tích lũy</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 pt-4 border-t border-slate-100 flex items-center gap-3">
|
||||
<div className="w-8 h-8 rounded-full bg-slate-100 flex items-center justify-center flex-shrink-0">
|
||||
<span className="material-symbols-outlined text-slate-400" style={{ fontSize: 16 }}>psychology</span>
|
||||
</div>
|
||||
<p className="text-xs text-slate-500">
|
||||
<span className="font-semibold">AI gợi ý:</span> Ôn thêm Part 5 — Ngữ pháp
|
||||
</p>
|
||||
<div className="grid grid-cols-7 gap-2.5">
|
||||
{['T2', 'T3', 'T4', 'T5', 'T6', 'T7', 'CN'].map((d, i) => {
|
||||
const h = [60, 85, 40, 90, 75, 0, 0][i]
|
||||
const done = h > 0
|
||||
const today = i === 4
|
||||
return (
|
||||
<div key={d} className="flex flex-col items-center gap-2">
|
||||
<div className="w-full relative overflow-hidden rounded-[10px]" style={{ height: 96, background: 'var(--at-line-2)' }}>
|
||||
<div
|
||||
className="absolute left-0 right-0 bottom-0 rounded-[10px] transition-[height] duration-500"
|
||||
style={{
|
||||
height: `${h}%`,
|
||||
background: today ? 'var(--at-brand)' : done ? 'var(--at-brand-soft)' : 'var(--at-line-2)',
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={today ? 'at-serif italic' : ''}
|
||||
style={{ fontSize: 11, color: today ? 'var(--at-brand)' : 'var(--at-mute)', fontWeight: today ? 700 : 500 }}
|
||||
>
|
||||
{d}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Feature cards */}
|
||||
<section>
|
||||
<h2 className="text-2xl font-extrabold text-slate-800 mb-1.5">Tính năng nổi bật</h2>
|
||||
<p className="text-slate-500 mb-6">Hệ sinh thái học tập toàn diện được thiết kế để tối ưu hoá điểm số.</p>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-5">
|
||||
{FEATURES.map((f) => (
|
||||
<Link
|
||||
key={f.to}
|
||||
to={f.to}
|
||||
className={`bg-white rounded-2xl p-6 border border-slate-200 border-l-4 ${f.borderColor} hover:-translate-y-1 hover:shadow-md transition-all duration-200`}
|
||||
>
|
||||
<div className={`w-12 h-12 ${f.iconBg} rounded-xl flex items-center justify-center mb-4`}>
|
||||
<span className={`material-symbols-outlined ${f.iconColor}`}>{f.icon}</span>
|
||||
{/* SIDE COL */}
|
||||
<div className="flex flex-col gap-5">
|
||||
{/* Streak card (inky) */}
|
||||
<div className="rounded-2xl p-5" style={{ background: 'var(--at-ink)', color: 'var(--at-paper)' }}>
|
||||
<div className="flex items-center justify-between mb-3.5">
|
||||
<div style={{ fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'rgba(250,248,243,0.55)', fontWeight: 600 }}>
|
||||
Streak
|
||||
</div>
|
||||
<h3 className="font-bold text-base text-slate-800 mb-2">{f.title}</h3>
|
||||
<p className="text-slate-500 text-sm leading-relaxed mb-4">{f.desc}</p>
|
||||
<div className={`flex items-center gap-1.5 text-sm font-bold ${f.ctaColor}`}>
|
||||
{f.cta}
|
||||
<span className="material-symbols-outlined" style={{ fontSize: 16 }}>arrow_forward</span>
|
||||
<div className="w-10 h-10 rounded-xl grid place-items-center" style={{ background: 'rgba(255,255,255,0.08)', color: '#FFC27A' }}>
|
||||
<span className="material-symbols-outlined" style={{ fontSize: 20, fontVariationSettings: "'FILL' 1" }}>local_fire_department</span>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA banner */}
|
||||
<section className="mt-10">
|
||||
<div className="bg-blue-600 rounded-2xl p-8 flex items-center justify-between overflow-hidden relative">
|
||||
<div className="absolute right-4 top-0 bottom-0 flex items-center opacity-10">
|
||||
<span className="material-symbols-outlined text-white" style={{ fontSize: 120 }}>emoji_events</span>
|
||||
</div>
|
||||
<div className="at-serif" style={{ fontSize: 44, fontWeight: 400, letterSpacing: '-0.03em', lineHeight: 1, marginBottom: 4 }}>
|
||||
7 <span className="italic opacity-65" style={{ fontSize: 18 }}>ngày</span>
|
||||
</div>
|
||||
<div style={{ fontSize: 12, color: 'rgba(250,248,243,0.55)', marginBottom: 14 }}>Kỷ lục: 21 ngày</div>
|
||||
<div className="flex gap-1.5">
|
||||
{['T2', 'T3', 'T4', 'T5', 'T6', 'T7', 'CN'].map((d, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="flex-1 rounded-md grid place-items-center"
|
||||
style={{
|
||||
height: 24,
|
||||
background: i < 5 ? '#C15A34' : 'rgba(255,255,255,0.08)',
|
||||
color: i < 5 ? 'white' : 'rgba(255,255,255,0.4)',
|
||||
fontSize: 9,
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
{d}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative z-10">
|
||||
<h3 className="text-2xl font-extrabold text-white mb-2">Sẵn sàng chinh phục 990 TOEIC?</h3>
|
||||
<p className="text-blue-100 mb-5">
|
||||
{user
|
||||
? `Chào ${user.name}! Tiếp tục luyện thi hôm nay.`
|
||||
: 'Đăng ký miễn phí để lưu tiến độ và luyện thi không giới hạn.'}
|
||||
</p>
|
||||
{user ? (
|
||||
<Link
|
||||
to="/toeic"
|
||||
className="inline-block bg-white text-blue-600 px-6 py-3 rounded-xl font-bold text-sm hover:bg-blue-50 transition-colors"
|
||||
>
|
||||
Luyện thi ngay
|
||||
</Link>
|
||||
) : (
|
||||
|
||||
{/* AI nudge */}
|
||||
<div className="at-pullquote">
|
||||
<div className="flex items-center gap-2 mb-2.5">
|
||||
<div className="w-6 h-6 rounded-lg grid place-items-center" style={{ background: 'var(--at-brand)', color: 'white' }}>
|
||||
<span className="material-symbols-outlined" style={{ fontSize: 14, fontVariationSettings: "'FILL' 1" }}>auto_awesome</span>
|
||||
</div>
|
||||
<div style={{ fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--at-brand-ink)', fontWeight: 700 }}>
|
||||
AI gợi ý
|
||||
</div>
|
||||
</div>
|
||||
<div className="at-pullquote-q">
|
||||
"Bạn yếu nhất <b style={{ fontWeight: 600 }}>Part 3</b> — dành 10 phút hôm nay có thể tăng <b style={{ fontWeight: 600 }}>30+ điểm</b>."
|
||||
</div>
|
||||
<div className="mt-2.5 text-[11px] opacity-70" style={{ color: 'var(--at-brand-ink)' }}>— EnglishAI Coach</div>
|
||||
</div>
|
||||
|
||||
{/* Pro tip */}
|
||||
<div className="at-tip">
|
||||
<div className="at-tip-label">Pro tip</div>
|
||||
<div className="text-[12.5px] leading-[1.55]" style={{ color: 'var(--at-ink-2)' }}>
|
||||
Học theo <b style={{ color: 'var(--at-warm)', fontWeight: 700 }}>cụm từ</b> (collocations) giúp bạn ghi nhớ nhanh hơn{' '}
|
||||
<b style={{ color: 'var(--at-warm)', fontWeight: 700 }}>40%</b> so với học từ đơn lẻ.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Guest CTA (only if not logged in) */}
|
||||
{!user && (
|
||||
<div className="rounded-2xl p-5" style={{ background: 'var(--at-surface)', border: '1px solid var(--at-line)' }}>
|
||||
<div className="at-eyebrow mb-2">Khách</div>
|
||||
<div className="at-serif text-[17px] leading-[1.2] tracking-tight mb-3" style={{ color: 'var(--at-ink)', fontWeight: 500 }}>
|
||||
Đăng ký để <i style={{ color: 'var(--at-brand)', fontStyle: 'italic' }}>lưu tiến độ</i>.
|
||||
</div>
|
||||
<button
|
||||
onClick={() => openModal('register')}
|
||||
className="bg-white text-blue-600 px-6 py-3 rounded-xl font-bold text-sm hover:bg-blue-50 transition-colors"
|
||||
className="w-full py-2.5 rounded-xl text-[13.5px] font-semibold transition-opacity hover:opacity-90"
|
||||
style={{ background: 'var(--at-ink)', color: 'var(--at-paper)' }}
|
||||
>
|
||||
Đăng ký miễn phí
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function Stat({ num, label, color }: { num: string; label: string; color?: string }) {
|
||||
return (
|
||||
<div>
|
||||
<div className="at-serif" style={{ fontSize: 26, fontWeight: 400, letterSpacing: '-0.02em', lineHeight: 1, color: color ?? 'var(--at-ink)' }}>
|
||||
{num}
|
||||
</div>
|
||||
<div style={{ fontSize: 11, color: 'var(--at-mute)', marginTop: 4 }}>{label}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function ProgressRing({ value }: { value: number }) {
|
||||
const r = 58
|
||||
const c = 2 * Math.PI * r
|
||||
const offset = c - (value / 100) * c
|
||||
return (
|
||||
<div className="relative grid place-items-center" style={{ width: 132, height: 132 }}>
|
||||
<svg width="132" height="132">
|
||||
<circle cx="66" cy="66" r={r} fill="none" stroke="var(--at-line-2)" strokeWidth="7" />
|
||||
<circle
|
||||
cx="66"
|
||||
cy="66"
|
||||
r={r}
|
||||
fill="none"
|
||||
stroke="var(--at-brand)"
|
||||
strokeWidth="7"
|
||||
strokeDasharray={c}
|
||||
strokeDashoffset={offset}
|
||||
strokeLinecap="round"
|
||||
transform="rotate(-90 66 66)"
|
||||
style={{ transition: 'stroke-dashoffset 0.6s cubic-bezier(0.2, 0.7, 0.2, 1)' }}
|
||||
/>
|
||||
</svg>
|
||||
<div className="absolute text-center">
|
||||
<div className="at-serif" style={{ fontSize: 34, fontWeight: 400, letterSpacing: '-0.025em', lineHeight: 1, color: 'var(--at-ink)' }}>
|
||||
720
|
||||
</div>
|
||||
<div style={{ fontSize: 10, color: 'var(--at-mute)', textTransform: 'uppercase', letterSpacing: '0.12em', marginTop: 4, fontWeight: 600 }}>
|
||||
/ 850
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user