"use client"; import { Edit, Eye, Flag, Heart, MoreHorizontal, Share2, Trash2, Volume2, VolumeX, } from "lucide-react"; import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/navigation"; import * as React from "react"; import { toast } from "sonner"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardFooter, CardHeader, } from "@/components/ui/card"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { useAudio } from "@/providers/audio-provider"; import { useAuth } from "@/providers/auth-provider"; import { ContentService } from "@/services/content.service"; import { FavoriteService } from "@/services/favorite.service"; import type { Content } from "@/types/content"; import { UserContentEditDialog } from "./user-content-edit-dialog"; interface ContentCardProps { content: Content; onUpdate?: () => void; } export function ContentCard({ content, onUpdate }: ContentCardProps) { const { isAuthenticated, user } = useAuth(); const { isGlobalMuted, activeVideoId, toggleGlobalMute, setActiveVideo } = useAudio(); const router = useRouter(); const [isLiked, setIsLiked] = React.useState(content.isLiked || false); const [likesCount, setLikesCount] = React.useState(content.favoritesCount); const [editDialogOpen, setEditDialogOpen] = React.useState(false); const [_reportDialogOpen, setReportDialogOpen] = React.useState(false); const isAuthor = user?.uuid === content.authorId; const isVideo = !content.mimeType.startsWith("image/"); const isThisVideoActive = activeVideoId === content.id; const isMuted = isGlobalMuted || (isVideo && !isThisVideoActive); const videoRef = React.useRef(null); React.useEffect(() => { if (videoRef.current) { if (isThisVideoActive) { const playPromise = videoRef.current.play(); if (playPromise !== undefined) { playPromise.catch((_error) => { // L'auto-lecture peut échouer si l'utilisateur n'a pas interagi avec la page // On peut tenter de mettre en sourdine pour forcer la lecture si nécessaire }); } } else { videoRef.current.pause(); } } }, [isThisVideoActive]); React.useEffect(() => { setIsLiked(content.isLiked || false); setLikesCount(content.favoritesCount); }, [content.isLiked, content.favoritesCount]); const handleLike = async (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); if (!isAuthenticated) { toast.error("Vous devez être connecté pour liker un mème"); router.push("/login"); return; } try { if (isLiked) { await FavoriteService.remove(content.id); setIsLiked(false); setLikesCount((prev) => prev - 1); } else { await FavoriteService.add(content.id); setIsLiked(true); setLikesCount((prev) => prev + 1); } } catch (_error) { toast.error("Une erreur est survenue"); } }; const handleToggleMute = (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); if (isGlobalMuted) { setActiveVideo(content.id); } else if (isThisVideoActive) { toggleGlobalMute(); } else { setActiveVideo(content.id); } }; const handleUse = async (e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); try { await ContentService.incrementUsage(content.id); toast.success("Mème prêt à être utilisé !"); } catch (_error) { toast.error("Une erreur est survenue"); } }; const handleDelete = async () => { if (!confirm("Êtes-vous sûr de vouloir supprimer ce mème ?")) return; try { await ContentService.remove(content.id); toast.success("Mème supprimé !"); if (onUpdate) { onUpdate(); } else { // Si pas de onUpdate, on est probablement sur la page de détail router.push("/"); } } catch (_error) { toast.error("Erreur lors de la suppression."); } }; return ( <> {content.author.username[0].toUpperCase()}
{content.author.username}
{isAuthor && ( <> setEditDialogOpen(true)}> Modifier Supprimer )} toast.success("Lien copié !")}> Partager {!isAuthor && ( setReportDialogOpen(true)}> Signaler )}
{content.mimeType.startsWith("image/") ? ( {content.title} ) : (
{content.views}

{likesCount} J'aime

{content.author.username} {content.title}
{content.tags.slice(0, 5).map((tag, _i) => ( #{typeof tag === "string" ? tag : tag.name} ))}

{new Date(content.createdAt).toLocaleDateString("fr-FR", { day: "numeric", month: "long", })}

onUpdate?.()} /> ); }