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) =>
)
)}
);
}