'use client'; import React, { useState, useEffect } from 'react'; import { useSession } from 'next-auth/react'; import { Button } from '@/components/ui/button'; import { Textarea } from '@/components/ui/textarea'; import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog'; import { formatDistanceToNow } from 'date-fns'; import { Trash2 } from 'lucide-react'; type User = { id: string; name: string | null; email: string; image: string | null; }; type CommentReply = { id: string; userId: string; commentId: string; content: string; createdAt: string; user: User; }; type Comment = { id: string; userId: string; videoId: string; content: string; createdAt: string; user: User; replies: CommentReply[]; }; interface CommentsSectionProps { videoId: string; } export function CommentsSection({ videoId }: CommentsSectionProps) { const { data: session } = useSession(); const [comments, setComments] = useState([]); const [newCommentContent, setNewCommentContent] = useState(''); const [replyingToId, setReplyingToId] = useState(null); const [replyContent, setReplyContent] = useState(''); const [isLoading, setIsLoading] = useState(true); const [isSubmitting, setIsSubmitting] = useState(false); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [deletingCommentId, setDeletingCommentId] = useState(null); const [deleteReplyDialogOpen, setDeleteReplyDialogOpen] = useState(false); const [deletingReplyId, setDeletingReplyId] = useState(null); const [deletingReplyCommentId, setDeletingReplyCommentId] = useState(null); const isAdmin = (session?.user as any)?.role === 'admin' || (session?.user as any)?.role === 'superadmin'; const handleDeleteComment = async (commentId: string) => { try { const res = await fetch(`/api/comments/${commentId}`, { method: 'DELETE', }); if (res.ok) { setComments(comments.filter((c) => c.id !== commentId)); setDeleteDialogOpen(false); setDeletingCommentId(null); } } catch (err) { console.error('Failed to delete comment:', err); } }; const handleDeleteReply = async (replyId: string, commentId: string) => { try { const res = await fetch(`/api/comments/reply/${replyId}`, { method: 'DELETE', }); if (res.ok) { setComments( comments.map((c) => c.id === commentId ? { ...c, replies: c.replies.filter((r) => r.id !== replyId), } : c ) ); setDeleteReplyDialogOpen(false); setDeletingReplyId(null); setDeletingReplyCommentId(null); } } catch (err) { console.error('Failed to delete reply:', err); } }; // Fetch comments on mount and when videoId changes useEffect(() => { const fetchComments = async () => { setIsLoading(true); try { const res = await fetch(`/api/comments?videoId=${videoId}`); if (res.ok) { const data = await res.json(); setComments(data); } } catch (err) { console.error('Failed to fetch comments:', err); } finally { setIsLoading(false); } }; fetchComments(); }, [videoId]); const handleCommentSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!session?.user || !newCommentContent.trim()) return; setIsSubmitting(true); try { const res = await fetch('/api/comments', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ videoId, content: newCommentContent }), }); if (res.ok) { const newComment = await res.json(); setComments([newComment, ...comments]); setNewCommentContent(''); } } catch (err) { console.error('Failed to post comment:', err); } finally { setIsSubmitting(false); } }; const handleReplySubmit = async (e: React.FormEvent, commentId: string) => { e.preventDefault(); if (!session?.user || !replyContent.trim()) return; setIsSubmitting(true); try { const res = await fetch(`/api/comments/${commentId}/reply`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ content: replyContent }), }); if (res.ok) { const newReply = await res.json(); setComments( comments.map((c) => c.id === commentId ? { ...c, replies: [...c.replies, newReply] } : c ) ); setReplyContent(''); setReplyingToId(null); } } catch (err) { console.error('Failed to post reply:', err); } finally { setIsSubmitting(false); } }; const getDisplayName = (user: User) => user.name || user.email.split('@')[0]; const getInitials = (user: User) => { const name = getDisplayName(user); return name .split(' ') .map((n) => n[0]) .join('') .toUpperCase(); }; if (isLoading) { return
Loading comments...
; } return (

Comments ({comments.length})

{/* Add Comment Form */} {session?.user ? (
{getInitials({ id: (session.user as any).id, name: (session.user as any).name, email: (session.user as any).email, image: (session.user as any).image, })}