import { useState, useEffect } from 'react'; export default function ActivityLog({ collectionId }) { const [activities, setActivities] = useState([]); const [loading, setLoading] = useState(true); const [showAll, setShowAll] = useState(false); useEffect(() => { if (collectionId) { fetchActivities(); } }, [collectionId]); const fetchActivities = async () => { try { const response = await fetch(`/api/collections/${collectionId}/activity`); if (response.ok) { const data = await response.json(); setActivities(data); } } catch (error) { console.error('Error fetching activities:', error); } finally { setLoading(false); } }; const getActivityIcon = (action) => { switch (action) { case 'card_added': return '➕'; case 'card_removed': return '➖'; case 'card_quantity_updated': return '��'; case 'collection_updated': return '✏️'; case 'collection_deleted': return '🗑️'; case 'user_invited': return '📧'; case 'invitation_accepted': return '✅'; case 'invitation_declined': return '❌'; case 'permission_updated': return '🔐'; case 'user_removed': return '👋'; default: return '📝'; } }; const getActivityDescription = (activity) => { const { action, details } = activity; switch (action) { case 'card_added': return `added a card (qty: ${details.quantity})`; case 'card_removed': return details.reason === 'quantity_zero' ? 'removed a card by setting quantity to 0' : 'removed a card from the collection'; case 'card_quantity_updated': return details.oldQuantity ? `updated card quantity from ${details.oldQuantity} to ${details.newQuantity}` : `updated card quantity to ${details.newQuantity}`; case 'collection_updated': return 'updated collection details'; case 'collection_deleted': return 'deleted the collection'; case 'user_invited': return `invited ${details.email} as ${details.role}`; case 'invitation_accepted': return 'accepted an invitation'; case 'invitation_declined': return 'declined an invitation'; case 'permission_updated': return `updated user permissions to ${details.role}`; case 'user_removed': return 'removed a user from the collection'; default: return action.replace(/_/g, ' '); } }; const formatTimeAgo = (timestamp) => { const now = new Date(); const activityTime = new Date(timestamp); const diffMs = now - activityTime; const diffMins = Math.floor(diffMs / 60000); const diffHours = Math.floor(diffMs / 3600000); const diffDays = Math.floor(diffMs / 86400000); if (diffMins < 1) return 'just now'; if (diffMins < 60) return `${diffMins}m ago`; if (diffHours < 24) return `${diffHours}h ago`; if (diffDays < 7) return `${diffDays}d ago`; return activityTime.toLocaleDateString(); }; if (loading) { return (
); } const displayedActivities = showAll ? activities : activities.slice(0, 5); return (

Recent Activity

{activities.length > 5 && ( )}
{displayedActivities.map((activity) => (
{getActivityIcon(activity.action)}

{activity.user_email || 'System'} {' '} {getActivityDescription(activity)}

{formatTimeAgo(activity.created_at)}
{activity.details && Object.keys(activity.details).length > 0 && (
{activity.action === 'collection_updated' && activity.details.name && ( Name: "{activity.details.name}" )} {activity.action === 'user_invited' && activity.details.message && ( Message: "{activity.details.message}" )}
)}
))} {activities.length === 0 && (
📝

No activity yet. Start collaborating to see updates here!

)}
); }