Files
openclaw-backups/archive/inactive-skills/agent-voice/app/components/comments/CommentList.tsx

101 lines
2.3 KiB
TypeScript

'use client';
import { useState, useEffect } from 'react';
import Comment from './Comment';
interface CommentListProps {
postId: string;
}
interface CommentData {
id: string;
content: string;
authorName: string;
authorSlug?: string;
isAgent: boolean;
createdAt: string;
upvotes: number;
downvotes: number;
}
export default function CommentList({ postId }: CommentListProps) {
const [comments, setComments] = useState<CommentData[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState('');
const fetchComments = async () => {
try {
setIsLoading(true);
const response = await fetch(`/api/posts/${postId}/comments-web`);
if (!response.ok) {
throw new Error('Failed to fetch comments');
}
const data = await response.json();
setComments(data.comments);
setError('');
} catch (err) {
console.error('Error fetching comments:', err);
setError('Failed to load comments');
} finally {
setIsLoading(false);
}
};
useEffect(() => {
fetchComments();
}, [postId]);
// Expose refresh function via custom event
useEffect(() => {
const handleRefresh = () => {
fetchComments();
};
window.addEventListener(`refresh-comments-${postId}`, handleRefresh);
return () => {
window.removeEventListener(`refresh-comments-${postId}`, handleRefresh);
};
}, [postId]);
if (isLoading) {
return (
<div className="text-center py-8">
<div className="inline-block w-8 h-8 border-4 border-slate-600 border-t-blue-500 rounded-full animate-spin"></div>
<p className="mt-4 text-slate-400">Loading comments...</p>
</div>
);
}
if (error) {
return (
<div className="text-center py-8 text-red-400">
<p>{error}</p>
<button
onClick={fetchComments}
className="mt-4 text-blue-400 hover:text-blue-300 underline"
>
Try again
</button>
</div>
);
}
if (comments.length === 0) {
return (
<div className="text-center py-8 text-slate-400">
<p>No comments yet. Be the first to share your thoughts!</p>
</div>
);
}
return (
<div className="space-y-6">
{comments.map((comment) => (
<Comment key={comment.id} comment={comment} />
))}
</div>
);
}