From 13ccdbc2ab555fb83b3614354972669b254c033c Mon Sep 17 00:00:00 2001 From: Mathis HERRIOT <197931332+0x485254@users.noreply.github.com> Date: Thu, 29 Jan 2026 13:48:59 +0100 Subject: [PATCH] feat: introduce reporting system and two-factor authentication (2FA) - Added `ReportDialog` component for user-generated content reporting. - Integrated `ReportService` with create, update, and fetch report functionalities. - Enhanced `AuthService` with 2FA setup, enable, disable, and verification methods. - Updated types to include 2FA responses and reporting-related data. - Enhanced `ContentCard` UI to support reporting functionality. - Improved admin services to manage user reports and statuses. --- frontend/src/components/content-card.tsx | 9 ++ frontend/src/components/report-dialog.tsx | 117 ++++++++++++++++++++++ frontend/src/services/admin.service.ts | 18 ++++ frontend/src/services/auth.service.ts | 23 ++++- frontend/src/services/report.service.ts | 40 ++++++++ frontend/src/types/auth.ts | 10 +- 6 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 frontend/src/components/report-dialog.tsx create mode 100644 frontend/src/services/report.service.ts diff --git a/frontend/src/components/content-card.tsx b/frontend/src/components/content-card.tsx index c250cff..778a2ad 100644 --- a/frontend/src/components/content-card.tsx +++ b/frontend/src/components/content-card.tsx @@ -3,6 +3,7 @@ import { Edit, Eye, + Flag, Heart, MoreHorizontal, Share2, @@ -34,6 +35,7 @@ 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 { ReportDialog } from "./report-dialog"; import { UserContentEditDialog } from "./user-content-edit-dialog"; interface ContentCardProps { @@ -49,6 +51,7 @@ export function ContentCard({ content, onUpdate }: ContentCardProps) { 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/"); @@ -188,6 +191,12 @@ export function ContentCard({ content, onUpdate }: ContentCardProps) { Partager + {!isAuthor && ( + setReportDialogOpen(true)}> + + Signaler + + )} diff --git a/frontend/src/components/report-dialog.tsx b/frontend/src/components/report-dialog.tsx new file mode 100644 index 0000000..666ccb8 --- /dev/null +++ b/frontend/src/components/report-dialog.tsx @@ -0,0 +1,117 @@ +"use client"; + +import { useState } from "react"; +import { toast } from "sonner"; +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { Label } from "@/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Textarea } from "@/components/ui/textarea"; +import { ReportReason, ReportService } from "@/services/report.service"; + +interface ReportDialogProps { + contentId?: string; + tagId?: string; + open: boolean; + onOpenChange: (open: boolean) => void; +} + +export function ReportDialog({ + contentId, + tagId, + open, + onOpenChange, +}: ReportDialogProps) { + const [reason, setReason] = useState(ReportReason.INAPPROPRIATE); + const [description, setDescription] = useState(""); + const [isSubmitting, setIsSubmitting] = useState(false); + + const handleSubmit = async () => { + setIsSubmitting(true); + try { + await ReportService.create({ + contentId, + tagId, + reason, + description, + }); + toast.success("Signalement envoyé avec succès. Merci de nous aider à maintenir la communauté sûre."); + onOpenChange(false); + setDescription(""); + } catch (error) { + toast.error("Erreur lors de l'envoi du signalement."); + } finally { + setIsSubmitting(false); + } + }; + + return ( + + + + Signaler le contenu + + Pourquoi signalez-vous ce contenu ? Un modérateur examinera votre demande. + + +
+
+ + +
+
+ +