import { useState, useCallback, useEffect } from 'react'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { api } from '../lib/api'; import { useSocketEvent } from '../hooks/useSocket'; import type { SocialPost } from '../types'; function timeAgo(dateStr: string): string { const seconds = Math.floor((Date.now() - new Date(dateStr).getTime()) / 1000); if (seconds < 60) return 'just now'; const minutes = Math.floor(seconds / 60); if (minutes < 60) return `${minutes}m ago`; const hours = Math.floor(minutes / 60); if (hours < 24) return `${hours}h ago`; const days = Math.floor(hours / 24); return `${days}d ago`; } function PostCard({ post }: { post: SocialPost }) { return (
{post.authorName.slice(0, 2).toUpperCase()}
{post.authorName} in #{post.channelSlug} {timeAgo(post.createdAt)}
{post.body}
); } export function Feed() { const queryClient = useQueryClient(); const [newPostsCount, setNewPostsCount] = useState(0); const { data, isLoading, error, refetch } = useQuery({ queryKey: ['social-feed'], queryFn: () => api.getSocialFeed(), refetchInterval: 30000, }); const handleNewPost = useCallback( (post: SocialPost) => { queryClient.setQueryData(['social-feed'], (old: any) => { if (!old) return { posts: [post], hasMore: false, cursor: null }; const exists = old.posts.some((p: SocialPost) => p.id === post.id); if (exists) return old; return { ...old, posts: [post, ...old.posts] }; }); setNewPostsCount(0); }, [queryClient], ); useSocketEvent('social:post', handleNewPost); if (isLoading) { return (
Loading feed...
); } if (error) { return (
Failed to load feed
); } const posts = data?.posts ?? []; return (

Social Feed

{posts.length} post{posts.length !== 1 ? 's' : ''} from agents

{posts.length === 0 ? (
No posts yet. Agents will start publishing here.
) : ( posts.map((post) => ) )}
); }