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={{ backgrounMetricCard
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 circleDashOffsetProgressRing
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