import { Avatar, Badge } from '@/components/ui'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card'; const formatDistanceToNow = (date: Date, t?: (key: string) => string): string => { const now = new Date(); const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000); if (diffInSeconds < 60) return t?.('time.justNow') || 'just now'; if (diffInSeconds < 3600) return ( t?.('time.minutesAgo', { count: Math.floor(diffInSeconds / 60) }) || `${Math.floor(diffInSeconds / 60)} minutes ago` ); if (diffInSeconds < 86400) return ( t?.('time.hoursAgo', { count: Math.floor(diffInSeconds / 3600) }) || `${Math.floor(diffInSeconds / 3600)} hours ago` ); if (diffInSeconds < 604800) return ( t?.('time.daysAgo', { count: Math.floor(diffInSeconds / 86400) }) || `${Math.floor(diffInSeconds / 86400)} days ago` ); if (diffInSeconds < 2592000) return ( t?.('time.weeksAgo', { count: Math.floor(diffInSeconds / 604800) }) || `${Math.floor(diffInSeconds / 604800)} weeks ago` ); if (diffInSeconds < 31536000) return ( t?.('time.monthsAgo', { count: Math.floor(diffInSeconds / 2592000) }) || `${Math.floor(diffInSeconds / 2592000)} months ago` ); return ( t?.('time.yearsAgo', { count: Math.floor(diffInSeconds / 31536000) }) || `${Math.floor(diffInSeconds / 31536000)} years ago` ); }; export interface ActivityItem { id: string; type: 'create' | 'update' | 'delete' | 'verify' | 'login' | 'other'; user?: { name: string; avatar?: string; email?: string; }; action: string; target?: string; timestamp: Date; metadata?: Record; } export interface ActivityFeedProps { activities: ActivityItem[]; isLoading?: boolean; emptyMessage?: string; className?: string; onLoadMore?: () => void; hasMore?: boolean; t?: (key: string) => string; } const typeColors = { create: 'success', update: 'primary', delete: 'destructive', verify: 'success', login: 'info', other: 'default', } as const; const typeIcons = { create: '➕', update: '✏️', delete: '🗑️', verify: '✓', login: '🔐', other: '•', }; /** * Activity feed component for displaying system activities */ export const ActivityFeed = ({ activities, isLoading = false, emptyMessage = 'No activities', className, onLoadMore, hasMore = false, t, }: ActivityFeedProps) => { if (isLoading && activities.length === 0) { return ( {t?.('activityFeed.recentActivity') || 'Recent Activity'}
{Array.from({ length: 5 }).map((_, i) => (
))}
); } if (activities.length === 0) { return ( {t?.('activityFeed.recentActivity') || 'Recent Activity'}

{emptyMessage}

); } return ( {t?.('activityFeed.recentActivity') || 'Recent Activity'}
{activities.map((activity) => (
{activity.user ? ( ) : (
{typeIcons[activity.type]}
)}
{activity.user && ( {activity.user.name} )} {activity.action} {activity.target && ( {activity.target} )} {activity.type}

{formatDistanceToNow(activity.timestamp, t)}

))}
{hasMore && onLoadMore && (
)}
); };