diff --git a/client/components/social/FeedItemCard.tsx b/client/components/social/FeedItemCard.tsx index f86f37af..7b7ce8fc 100644 --- a/client/components/social/FeedItemCard.tsx +++ b/client/components/social/FeedItemCard.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { Card, CardContent, @@ -10,7 +10,11 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Separator } from "@/components/ui/separator"; +import { Textarea } from "@/components/ui/textarea"; import { cn } from "@/lib/utils"; +import { useAuth } from "@/contexts/AuthContext"; +import { useToast } from "@/hooks/use-toast"; +import { communityService } from "@/lib/supabase-service"; import { Heart, MessageCircle, Share2, Volume2, VolumeX } from "lucide-react"; import type { FeedItem } from "@/pages/Feed"; @@ -32,8 +36,54 @@ export function FeedItemCard({ onComment, }: FeedItemCardProps) { const [muted, setMuted] = useState(true); + const [showComments, setShowComments] = useState(false); + const [comments, setComments] = useState([]); + const [loadingComments, setLoadingComments] = useState(false); + const [commentText, setCommentText] = useState(""); + const [submittingComment, setSubmittingComment] = useState(false); + const { user } = useAuth(); + const { toast } = useToast(); const hasMedia = item.mediaType !== "none" && Boolean(item.mediaUrl); + useEffect(() => { + if (!showComments) return; + let cancelled = false; + (async () => { + setLoadingComments(true); + try { + const data = await communityService.listComments(item.id); + if (!cancelled) setComments(Array.isArray(data) ? data : []); + } finally { + if (!cancelled) setLoadingComments(false); + } + })(); + return () => { + cancelled = true; + }; + }, [showComments, item.id]); + + const submitComment = async () => { + if (!user?.id) { + toast({ description: "Please sign in to comment." }); + return; + } + const content = commentText.trim(); + if (!content) return; + setSubmittingComment(true); + try { + const created = await communityService.addComment(item.id, user.id, content); + if (created) { + setComments((prev) => [...prev, created]); + setCommentText(""); + onComment?.(item.id); + } + } catch (e) { + toast({ variant: "destructive", description: "Failed to add comment" }); + } finally { + setSubmittingComment(false); + } + }; + return ( @@ -131,7 +181,7 @@ export function FeedItemCard({ variant="ghost" size="sm" className="gap-2 pl-2 pr-3" - onClick={() => onComment(item.id)} + onClick={() => setShowComments((s) => !s)} > @@ -164,6 +214,46 @@ export function FeedItemCard({ + + {showComments && ( +
+
+ {loadingComments ? ( +

Loading comments…

+ ) : comments.length === 0 ? ( +

Be the first to comment.

+ ) : ( + comments.map((c) => ( +
+ + + + {(c.user_profiles?.full_name || c.user_profiles?.username || "U")[0]?.toUpperCase() || "U"} + + +
+
+ {c.user_profiles?.full_name || c.user_profiles?.username || "Member"} +
+
{c.content}
+
+
+ )) + )} +
+
+