← Components/Timeline

ProductTimeline

producttimeline-1779379195677.tsx
'use client'
import { useState } from 'react'

const PHASES = [
  { phase: 'Phase 0', label: 'MVP Launch', date: 'May 2026', status: 'done', color: '#22c55e', items: ['Public website (empire-ui.com)', '60+ components published', 'MCP server live', 'Admin panel with CRUD', 'Waitlist system'] },
  { phase: 'Phase 1', label: 'User Auth & Pro Gating', date: 'June 2026', status: 'active', color: '#C9A84C', items: ['User registration & login', 'API key generation', 'Pro plan gating', 'Account dashboard', 'Usage analytics'] },
  { phase: 'Phase 2', label: 'Payments & Monetization', date: 'July 2026', status: 'upcoming', color: '#6366f1', items: ['Stripe integration', 'Pro & Lifetime plans', 'Team billing', 'Invoice generation', 'Usage metering'] },
  { phase: 'Phase 3', label: 'Search & Discovery', date: 'August 2026', status: 'planned', color: '#64748b', items: ['pgvector semantic search', 'AI-powered recommendations', 'Category refinement', 'Component preview sandbox', 'Collections & bookmarks'] },
  { phase: 'Phase 4', label: 'Scale to 1000+', date: 'Q4 2026', status: 'planned', color: '#64748b', items: ['Automated generation pipeline', 'Framework variants (Vue, Svelte)', 'Component playground', 'npm package distribution', 'Enterprise tier'] },
]

const STATUS_LABELS = { done: 'Complete', active: 'In Progress', upcoming: 'Upcoming', planned: 'Planned' }

export default function ProductTimeline() {
  const [expanded, setExpanded] = useState<string | null>('Phase 1')

  return (
    <div style={{ padding: 32, background: '#0A0A0A', maxWidth: 480, margin: '0 auto' }}>
      <div style={{ color: '#F5F5F0', fontSize: 20, fontWeight: 700, marginBottom: 4 }}>Product Roadmap</div>
      <div style={{ color: 'rgba(255,255,255,0.4)', fontSize: 13, marginBottom: 32 }}>Empire UI — 2026 milestones</div>

      <div style={{ position: 'relative' }}>
        <div style={{ position: 'absolute', left: 18, top: 24, bottom: 0, width: 2, background: 'rgba(255,255,255,0.06)' }} />

        {PHASES.map(p => (
          <div key={p.phase} style={{ display: 'flex', gap: 20, marginBottom: 16, position: 'relative' }}>
            <div style={{ width: 38, flexShrink: 0, display: 'flex', justifyContent: 'center', paddingTop: 12 }}>
              <div style={{ width: 14, height: 14, borderRadius: '50%', background: p.color, border: `3px solid #0A0A0A`, boxShadow: `0 0 0 2px ${p.color}40`, zIndex: 1, transition: 'box-shadow 0.3s' }} />
            </div>
            <div style={{ flex: 1, cursor: 'pointer' }} onClick={() => setExpanded(ex => ex === p.phase ? null : p.phase)}>
              <div style={{ background: '#111', border: `1px solid ${expanded === p.phase ? p.color + '30' : 'rgba(255,255,255,0.06)'}`, borderRadius: 12, padding: '14px 18px', transition: 'border-color 0.2s' }}>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 4 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                    <span style={{ color: '#F5F5F0', fontSize: 14, fontWeight: 700 }}>{p.label}</span>
                    <span style={{ background: p.color + '18', color: p.color, border: `1px solid ${p.color}30`, padding: '1px 8px', borderRadius: 20, fontSize: 11, fontWeight: 600 }}>{STATUS_LABELS[p.status as keyof typeof STATUS_LABELS]}</span>
                  </div>
                  <span style={{ color: expanded === p.phase ? '#C9A84C' : 'rgba(255,255,255,0.25)', fontSize: 12, transition: 'color 0.2s' }}>{expanded === p.phase ? '▲' : '▼'}</span>
                </div>
                <div style={{ color: 'rgba(255,255,255,0.35)', fontSize: 12 }}>{p.phase} · {p.date}</div>

                {expanded === p.phase && (
                  <div style={{ marginTop: 14, borderTop: '1px solid rgba(255,255,255,0.06)', paddingTop: 14, display: 'flex', flexDirection: 'column', gap: 7, animation: 'fadeIn 0.2s ease' }}>
                    {p.items.map(item => (
                      <div key={item} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                        <span style={{ color: p.color, fontSize: 12 }}>{p.status === 'done' ? '✓' : '◦'}</span>
                        <span style={{ color: p.status === 'done' ? 'rgba(255,255,255,0.5)' : 'rgba(255,255,255,0.7)', fontSize: 13, textDecoration: p.status === 'done' ? 'line-through' : 'none' }}>{item}</span>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            </div>
          </div>
        ))}
      </div>
      <style>{`@keyframes fadeIn { from { opacity:0 } to { opacity:1 } }`}</style>
    </div>
  )
}

Component info

CategoryTimeline
Frameworkreact
TierFREE
Views0
Copies0

About

Vertical product roadmap timeline with phases, status badges, dates, and expandable details