'use client'; import { useEffect, useState } from 'react'; import { ScrollArea } from '@/components/ui/scroll-area'; import { Badge } from '@/components/ui/badge'; import { Loader2 } from 'lucide-react'; interface ActivityEntry { id: string; actor: string; action: string; entityType: string; entityId: string; changes?: Record | null; createdAt: string; } const actionLabels: Record = { created: 'created', updated: 'updated', deleted: 'deleted', completed: 'completed', uncompleted: 'reverted', bulk_updated: 'bulk updated', dependency_added: 'added dependency to', dependency_removed: 'removed dependency from', tag_added: 'added tag to', tag_removed: 'removed tag from', }; export function TaskActivityFeed({ domainId }: { domainId: string }) { const [activities, setActivities] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { if (!domainId) return; fetch(`/api/domains/${domainId}/activity?entity_type=task&limit=10`) .then((res) => { if (!res.ok) throw new Error('Failed to load activity'); return res.json(); }) .then((data) => { setActivities(data.items || []); }) .catch((err) => { console.error('Failed to load activity feed:', err); }) .finally(() => setLoading(false)); }, [domainId]); if (loading) { return (
); } if (activities.length === 0) { return (

No recent activity

); } return (
{activities.map((entry) => (
{actionLabels[entry.action] || entry.action}

{entry.actor} {' '} {actionLabels[entry.action] || entry.action} {' '} {entry.changes && typeof entry.changes === 'object' && 'title' in entry.changes ? `"${entry.changes.title}"` : entry.entityId.slice(0, 8)}

{new Date(entry.createdAt).toLocaleString()}

))}
); }