← Components/Data Display

TimelineActivity

timelineactivity-1779378413035.tsx
'use client'
import { useState } from 'react'

const events = [
  { id: 1, icon: '🚀', title: 'Wave 7 generation complete', desc: '57 new components published across 14 categories', time: '14:32', type: 'success', day: 'Today' },
  { id: 2, icon: '👥', title: '142 new users registered', desc: 'Organic growth from Hacker News post', time: '11:15', type: 'info', day: 'Today' },
  { id: 3, icon: '💰', title: 'Revenue milestone reached', desc: 'First €10k MRR achieved', time: '09:00', type: 'success', day: 'Today' },
  { id: 4, icon: '⚡', title: 'MCP server deployed', desc: 'empire-ui.com/api/mcp is now live', time: '17:40', type: 'info', day: 'Yesterday' },
  { id: 5, icon: '🐛', title: 'Bug fixed: duplicate slugs', desc: 'Added timestamp suffix to prevent collisions', time: '14:20', type: 'warning', day: 'Yesterday' },
  { id: 6, icon: '🎉', title: 'Empire UI launched', desc: '35 initial components, empire-ui.com went live', time: '09:00', type: 'success', day: '3 days ago' },
]

const typeColors = { success: '#22c55e', info: '#6366f1', warning: '#f59e0b', error: '#ef4444' }

export default function TimelineActivity() {
  const [expanded, setExpanded] = useState<number | null>(null)
  const days = [...new Set(events.map(e => e.day))]

  return (
    <div style={{ background: '#0A0A0A', padding: 40, maxWidth: 520 }}>
      {days.map(day => (
        <div key={day} style={{ marginBottom: 32 }}>
          <div style={{ color: '#555', fontSize: 11, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 16 }}>{day}</div>
          <div style={{ position: 'relative' }}>
            <div style={{ position: 'absolute', left: 16, top: 0, bottom: 0, width: 1, background: 'rgba(255,255,255,0.06)' }} />
            {events.filter(e => e.day === day).map((ev, i) => (
              <div key={ev.id} onClick={() => setExpanded(expanded === ev.id ? null : ev.id)}
                style={{ display: 'flex', gap: 14, marginBottom: 16, cursor: 'pointer', paddingLeft: 0 }}>
                <div style={{
                  width: 32, height: 32, borderRadius: '50%', flexShrink: 0,
                  background: `${typeColors[ev.type as keyof typeof typeColors]}15`,
                  border: `1px solid ${typeColors[ev.type as keyof typeof typeColors]}40`,
                  display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 16, zIndex: 1,
                }}>{ev.icon}</div>
                <div style={{ flex: 1, paddingTop: 4 }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8 }}>
                    <span style={{ color: '#F5F5F0', fontSize: 14, fontWeight: 500 }}>{ev.title}</span>
                    <span style={{ color: '#555', fontSize: 12, flexShrink: 0 }}>{ev.time}</span>
                  </div>
                  {expanded === ev.id && (
                    <div style={{ color: '#666', fontSize: 13, marginTop: 6, lineHeight: 1.5 }}>{ev.desc}</div>
                  )}
                </div>
              </div>
            ))}
          </div>
        </div>
      ))}
    </div>
  )
}

Component info

CategoryData Display
Frameworkreact
TierFREE
Views1
Copies0

About

Vertical activity timeline with icons, grouped by day, and expandable items

More from Data Display

'use client'
import { useState, useRef, useCallback, useEffect } from 'react'

export default function ComparisonSlider() {
  const [position, setPosition] = useState(50)
  const [dragging, setDragging] = useState(false)
  const containerRef = useRef
ComparisonSlider
Data Display
'use client'
import { useState } from 'react'

const WEEKS = 26
const DAYS = 7

function randomActivity(): number {
  const r = Math.random()
  if (r < 0.3) return 0
  if (r < 0.55) return 1
  if (r < 0.75) return 2
  if (r < 0.9) return 3
  return 4
HeatmapCalendar
Data Display