← Components/Onboarding

OnboardingChecklist

onboardingchecklist-1779379195580.tsx
'use client'
import { useState } from 'react'

const STEPS = [
  { id: 'profile', title: 'Complete your profile', desc: 'Add your name and avatar to personalize your experience.', xp: 50 },
  { id: 'browse', title: 'Browse components', desc: 'Explore 100+ production-ready React components.', xp: 25 },
  { id: 'copy', title: 'Copy your first component', desc: 'Click the copy button on any component page.', xp: 50 },
  { id: 'mcp', title: 'Setup MCP in Claude Code', desc: 'Add Empire UI to your Claude configuration.', xp: 100 },
  { id: 'api', title: 'Get your API key', desc: 'Visit your account page to get your personal API key.', xp: 75 },
]

export default function OnboardingChecklist() {
  const [done, setDone] = useState<Set<string>>(new Set(['browse']))

  const total = STEPS.length
  const completed = done.size
  const pct = (completed / total) * 100
  const xpTotal = STEPS.filter(s => done.has(s.id)).reduce((a, s) => a + s.xp, 0)

  const r = 32, circ = 2 * Math.PI * r

  return (
    <div style={{ background: '#0A0A0A', padding: 32, maxWidth: 440, margin: '0 auto' }}>
      {/* Header with ring */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 20, marginBottom: 28, background: '#111', border: '1px solid rgba(255,255,255,0.06)', borderRadius: 16, padding: 20 }}>
        <svg width={80} height={80} viewBox="0 0 80 80" style={{ flexShrink: 0 }}>
          <circle cx={40} cy={40} r={r} fill="none" stroke="rgba(255,255,255,0.06)" strokeWidth={6} />
          <circle cx={40} cy={40} r={r} fill="none" stroke={completed === total ? '#22c55e' : '#C9A84C'} strokeWidth={6}
            strokeDasharray={circ} strokeDashoffset={circ * (1 - pct / 100)}
            strokeLinecap="round" transform="rotate(-90 40 40)" style={{ transition: 'stroke-dashoffset 0.5s ease' }} />
          <text x={40} y={44} textAnchor="middle" fontSize={16} fontWeight={800} fill="#F5F5F0">{completed}/{total}</text>
        </svg>
        <div>
          <div style={{ color: '#F5F5F0', fontSize: 18, fontWeight: 700, marginBottom: 4 }}>
            {completed === total ? 'šŸŽ‰ Complete!' : 'Getting started'}
          </div>
          <div style={{ color: 'rgba(255,255,255,0.4)', fontSize: 13, marginBottom: 8 }}>{Math.round(pct)}% done</div>
          <div style={{ background: 'rgba(201,168,76,0.12)', border: '1px solid rgba(201,168,76,0.2)', color: '#C9A84C', padding: '3px 10px', borderRadius: 20, fontSize: 12, fontWeight: 600, display: 'inline-block' }}>
            ⚔ {xpTotal} XP earned
          </div>
        </div>
      </div>

      <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
        {STEPS.map(step => {
          const isDone = done.has(step.id)
          return (
            <div key={step.id} onClick={() => setDone(s => { const n = new Set(s); isDone ? n.delete(step.id) : n.add(step.id); return n })}
              style={{ display: 'flex', gap: 14, padding: '14px 16px', border: '1px solid', borderColor: isDone ? 'rgba(34,197,94,0.2)' : 'rgba(255,255,255,0.06)', borderRadius: 12, cursor: 'pointer', background: isDone ? 'rgba(34,197,94,0.04)' : 'rgba(255,255,255,0.02)', transition: 'all 0.2s' }}>
              <div style={{ width: 22, height: 22, borderRadius: '50%', border: `2px solid ${isDone ? '#22c55e' : 'rgba(255,255,255,0.2)'}`, background: isDone ? '#22c55e' : 'transparent', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0, marginTop: 1, transition: 'all 0.2s' }}>
                {isDone && <span style={{ color: '#fff', fontSize: 12, fontWeight: 800 }}>āœ“</span>}
              </div>
              <div style={{ flex: 1 }}>
                <div style={{ color: isDone ? 'rgba(255,255,255,0.4)' : '#F5F5F0', fontSize: 14, fontWeight: 600, textDecoration: isDone ? 'line-through' : 'none', marginBottom: 2, transition: 'all 0.2s' }}>{step.title}</div>
                {!isDone && <div style={{ color: 'rgba(255,255,255,0.4)', fontSize: 12 }}>{step.desc}</div>}
              </div>
              <div style={{ color: '#C9A84C', fontSize: 11, fontWeight: 700, flexShrink: 0 }}>+{step.xp} XP</div>
            </div>
          )
        })}
      </div>
    </div>
  )
}

Component info

CategoryOnboarding
Frameworkreact
TierFREE
Views0
Copies0

About

Onboarding checklist with progress ring, animated checkmarks, step descriptions, and completion reward