import { useState, useEffect } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; import { Badge } from "@/components/ui/badge"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Separator } from "@/components/ui/separator"; import { aethexToast } from "@/lib/aethex-toast"; import { MessageCircle, Send, Trash2, Loader2 } from "lucide-react"; const API_BASE = import.meta.env.VITE_API_BASE || ""; interface Comment { id: string; content: string; created_at: string; user_id: string; user_profiles?: { id: string; username?: string; full_name?: string; avatar_url?: string; }; } interface CommentsModalProps { open: boolean; onOpenChange: (open: boolean) => void; postId: string; currentUserId?: string; onCommentAdded?: () => void; } export default function CommentsModal({ open, onOpenChange, postId, currentUserId, onCommentAdded, }: CommentsModalProps) { const [comments, setComments] = useState([]); const [isLoading, setIsLoading] = useState(false); const [newComment, setNewComment] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); // Load comments when modal opens useEffect(() => { if (open) { loadComments(); } }, [open]); const loadComments = async () => { setIsLoading(true); try { const response = await fetch( `${API_BASE}/api/community/post-comments?post_id=${postId}&limit=50`, ); if (response.ok) { const data = await response.json(); setComments(data.comments || []); } else { aethexToast.error({ title: "Failed to load comments", description: "Please try again", }); } } catch (error) { console.error("Failed to load comments:", error); aethexToast.error({ title: "Failed to load comments", description: "An unexpected error occurred", }); } finally { setIsLoading(false); } }; const handleAddComment = async (e: React.FormEvent) => { e.preventDefault(); if (!currentUserId) { aethexToast.error({ title: "Not authenticated", description: "Please log in to comment", }); return; } if (newComment.trim().length === 0) { aethexToast.error({ title: "Empty comment", description: "Please write something", }); return; } setIsSubmitting(true); try { const response = await fetch(`${API_BASE}/api/community/post-comments`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ post_id: postId, user_id: currentUserId, content: newComment, }), }); if (response.ok) { const data = await response.json(); setComments((prev) => [data.comment, ...prev]); setNewComment(""); aethexToast.success({ title: "Comment added", description: "Your comment has been posted", }); onCommentAdded?.(); } else { const error = await response.json(); aethexToast.error({ title: "Failed to add comment", description: error.error || "Please try again", }); } } catch (error) { console.error("Failed to add comment:", error); aethexToast.error({ title: "Failed to add comment", description: "An unexpected error occurred", }); } finally { setIsSubmitting(false); } }; const handleDeleteComment = async (commentId: string) => { setIsSubmitting(true); try { const response = await fetch(`${API_BASE}/api/community/post-comments`, { method: "DELETE", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ comment_id: commentId, user_id: currentUserId, }), }); if (response.ok) { setComments((prev) => prev.filter((comment) => comment.id !== commentId), ); aethexToast.success({ title: "Comment deleted", description: "Your comment has been removed", }); onCommentAdded?.(); } else { const error = await response.json(); aethexToast.error({ title: "Failed to delete comment", description: error.error || "Please try again", }); } } catch (error) { console.error("Failed to delete comment:", error); aethexToast.error({ title: "Failed to delete comment", description: "An unexpected error occurred", }); } finally { setIsSubmitting(false); } }; const formatDate = (dateString: string) => { const date = new Date(dateString); const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffSecs = Math.floor(diffMs / 1000); const diffMins = Math.floor(diffSecs / 60); const diffHours = Math.floor(diffMins / 60); const diffDays = Math.floor(diffHours / 24); if (diffSecs < 60) return "just now"; if (diffMins < 60) return `${diffMins}m ago`; if (diffHours < 24) return `${diffHours}h ago`; if (diffDays < 7) return `${diffDays}d ago`; return date.toLocaleDateString("en-US", { year: "numeric", month: "short", day: "numeric", }); }; return ( Comments ({comments.length}) {isLoading ? (
) : comments.length === 0 ? (

No comments yet. Be the first to comment!

) : (
{comments.map((comment) => (
{comment.user_profiles?.avatar_url && ( {comment.user_profiles.full_name )}

{comment.user_profiles?.full_name || comment.user_profiles?.username || "Anonymous"}

{formatDate(comment.created_at)}

{comment.content}

{currentUserId === comment.user_id && ( )}
))}
)}