← Components/Dashboard & App UI

ActivityFeed

activityfeed-1779379195563.tsx
'use client'
import { useState, useEffect } from 'react'

type EventType = 'component_added' | 'user_signup' | 'purchase' | 'api_call' | 'review'

const EVENTS: { id: number; type: EventType; user: string; detail: string; time: number; color: string; icon: string }[] = [
  { id: 1, type: 'purchase', user: 'Sarah C.', detail: 'Upgraded to Pro plan', time: Date.now() - 60000, color: '#C9A84C', icon: '💳' },
  { id: 2, type: 'component_added', user: 'system', detail: 'DataTable published', time: Date.now() - 180000, color: '#6366f1', icon: '⬡' },
  { id: 3, type: 'user_signup', user: 'Marcus W.', detail: 'New user registered', time: Date.now() - 420000, color: '#22c55e', icon: '👤' },
  { id: 4, type: 'api_call', user: 'Claude Code', detail: '847 MCP requests (last hour)', time: Date.now() - 900000, color: '#f59e0b', icon: '⚡' },
  { id: 5, type: 'review', user: 'Priya P.', detail: 'Left 5-star review', time: Date.now() - 1800000, color: '#ec4899', icon: '★' },
  { id: 6, type: 'purchase', user: 'Alex K.', detail: 'Lifetime access purchased', time: Date.now() - 3600000, color: '#C9A84C', icon: '💳' },
  { id: 7, type: 'component_added', user: 'system', detail: 'LineChart published', time: Date.now() - 7200000, color: '#6366f1', icon: '⬡' },
  { id: 8, type: 'user_signup', user: 'Jordan L.', detail: 'New user registered', time: Date.now() - 10800000, color: '#22c55e', icon: '👤' },
]

function timeAgo(ms: number): string {
  const s = Math.floor((Date.now() - ms) / 1000)
  if (s < 60) return `${s}s ago`
  if (s < 3600) return `${Math.floor(s / 60)}m ago`
  if (s < 86400) return `${Math.floor(s / 3600)}h ago`
  return `${Math.floor(s / 86400)}d ago`
}

export default function ActivityFeed() {
  const [filter, setFilter] = useState<EventType | 'all'>('all')
  const [, tick] = useState(0)

  useEffect(() => {
    const t = setInterval(() => tick(n => n + 1), 30000)
    return () => clearInterval(t)
  }, [])

  const filtered = filter === 'all' ? EVENTS : EVENTS.filter(e => e.type === filter)

  const FILTERS: { key: EventType | 'all'; label: string }[] = [
    { key: 'all', label: 'All' }, { key: 'purchase', label: 'Sales' },
    { key: 'user_signup', label: 'Signups' }, { key: 'component_added', label: 'Components' },
    { key: 'api_call', label: 'API' },
  ]

  return (
    <div style={{ background: '#0D0D0D', border: '1px solid rgba(255,255,255,0.06)', borderRadius: 16, overflow: 'hidden', width: '100%' }}>
      <div style={{ padding: '16px 20px', borderBottom: '1px solid rgba(255,255,255,0.06)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <div style={{ color: '#F5F5F0', fontSize: 15, fontWeight: 600 }}>Activity</div>
        <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: '#22c55e', boxShadow: '0 0 6px #22c55e', display: 'inline-block', animation: 'pulse 2s infinite' }} />
          <span style={{ color: 'rgba(255,255,255,0.4)', fontSize: 12 }}>Live</span>
        </div>
      </div>

      <div style={{ display: 'flex', gap: 4, padding: '10px 20px', borderBottom: '1px solid rgba(255,255,255,0.04)', overflowX: 'auto' }}>
        {FILTERS.map(f => (
          <button key={f.key} onClick={() => setFilter(f.key)} style={{ background: filter === f.key ? 'rgba(201,168,76,0.12)' : 'rgba(255,255,255,0.04)', border: '1px solid', borderColor: filter === f.key ? 'rgba(201,168,76,0.25)' : 'rgba(255,255,255,0.06)', color: filter === f.key ? '#C9A84C' : 'rgba(255,255,255,0.4)', borderRadius: 6, padding: '4px 10px', cursor: 'pointer', fontSize: 11, whiteSpace: 'nowrap' }}>{f.label}</button>
        ))}
      </div>

      <div style={{ padding: '8px 0', maxHeight: 320, overflowY: 'auto' }}>
        {filtered.map((ev, i) => (
          <div key={ev.id} style={{ display: 'flex', alignItems: 'flex-start', gap: 12, padding: '10px 20px', borderBottom: i < filtered.length - 1 ? '1px solid rgba(255,255,255,0.03)' : 'none' }}>
            <div style={{ width: 32, height: 32, borderRadius: '50%', background: ev.color + '18', border: `1px solid ${ev.color}30`, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 14, flexShrink: 0 }}>{ev.icon}</div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ color: '#F5F5F0', fontSize: 13 }}><span style={{ fontWeight: 600 }}>{ev.user}</span> {ev.detail}</div>
              <div style={{ color: 'rgba(255,255,255,0.3)', fontSize: 11, marginTop: 2 }}>{timeAgo(ev.time)}</div>
            </div>
          </div>
        ))}
      </div>
      <style>{`@keyframes pulse { 0%,100% { opacity:1 } 50% { opacity:0.4 } }`}</style>
    </div>
  )
}

Component info

CategoryDashboard & App UI
Frameworkreact
TierFREE
Views0
Copies0

About

Real-time activity feed with event types, user avatars, timestamps, and filtered views

More from Dashboard & App UI

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

const METRICS = [
  { label: 'Monthly Revenue', value: 48320, prev: 41200, prefix: '$', suffix: '', color: '#C9A84C', data: [22,28,24,32,28,38,35,42,40,48] },
  { label: 'Active Users'
KPICards
Dashboard & App UI
import React from 'react';

interface MetricCardProps {
  value: number;
  trend: 'up' | 'down';
  sparklineData: number[];
}

const MetricCard: React.FC<MetricCardProps> = ({ value, trend, sparklineData }) => {
  return (
    <div style={{ backgroun
MetricCard
Dashboard & App UI
import React from 'react';
import './ProgressRing.css';
interface ProgressRingProps {
  percentage: number;
}
const ProgressRing: React.FC<ProgressRingProps> = ({ percentage }) => {
  const circleDashArray = 2 * Math.PI * 50;
  const circleDashOffset
ProgressRing
Dashboard & App UI
'use client';

import React from 'react';

interface KPIWidgetProps {
  metric: number;
  label: string;
  target: number;
  progress: number;
  sparklineData: number[];
  periodComparison: string;
}

const KPIWidget: React.FC<KPIWidgetProps> = ({
  
KPIWidget
Dashboard & App UI