diff --git a/backend/src/controllers/postController.ts b/backend/src/controllers/postController.ts
index 353866c..9e41908 100644
--- a/backend/src/controllers/postController.ts
+++ b/backend/src/controllers/postController.ts
@@ -220,6 +220,7 @@ const fetchSinglePost = asyncHandler(async (req: Request, res: Response) => {
},
User: {
select: {
+ user_id: true,
username: true,
pic: true,
},
@@ -231,6 +232,7 @@ const fetchSinglePost = asyncHandler(async (req: Request, res: Response) => {
user_id: true,
User: {
select: {
+ user_id: true,
username: true,
pic: true,
},
@@ -260,17 +262,31 @@ const deletePost = asyncHandler(async (req: Request, res: Response) => {
},
where: { post_id: postId },
});
+
// @ts-ignore
const user_id = req.user.user_id;
if (!post) {
return res.status(404).json({ message: "Post not found" });
}
+
if (post.User.user_id !== user_id) {
return res.status(401).json({ message: "Unauthorized" });
}
+ await prisma.$transaction(async (prisma) => {
+ await prisma.comment.deleteMany({
+ where: { post_id: postId },
+ });
+ await prisma.like.deleteMany({
+ where: { post_id: postId },
+ });
- return res.status(200).json({ message: "Post deleted" });
+ await prisma.post.delete({
+ where: { post_id: postId },
+ });
+ });
+
+ return res.status(200).json({ message: "Post and comments deleted" });
});
// @ts-ignore
@@ -374,6 +390,10 @@ const deleteComment = asyncHandler(async (req: Request, res: Response) => {
return res.status(401).json({ message: "Unauthorized" });
}
+ await prisma.comment.delete({
+ where: { comment_id: commentId },
+ });
+
return res.status(200).json({ message: "Comment deleted" });
});
diff --git a/frontend/src/components/DeleteConfirmation.jsx b/frontend/src/components/DeleteConfirmation.jsx
new file mode 100644
index 0000000..9b596e9
--- /dev/null
+++ b/frontend/src/components/DeleteConfirmation.jsx
@@ -0,0 +1,36 @@
+import React from "react";
+import {
+ Modal,
+ ModalOverlay,
+ ModalContent,
+ ModalHeader,
+ ModalBody,
+ ModalFooter,
+ Button,
+ Text,
+} from "@chakra-ui/react";
+
+const DeleteConfirmation = ({ isOpen, onClose, onConfirm, message }) => {
+ return (
+
+
+
+ {" "}
+ Confirm Deletion
+
+ {message}
+
+
+
+
+
+
+
+ );
+};
+
+export default DeleteConfirmation;
diff --git a/frontend/src/components/SinglePost.jsx b/frontend/src/components/SinglePost.jsx
index a00f890..1b504dd 100644
--- a/frontend/src/components/SinglePost.jsx
+++ b/frontend/src/components/SinglePost.jsx
@@ -1,5 +1,6 @@
import React, { useEffect, useState } from "react";
import { GrLike } from "react-icons/gr";
+import { useNavigate } from "react-router-dom";
import { AiFillLike } from "react-icons/ai";
import { useParams, Navigate } from "react-router-dom";
import {
@@ -13,12 +14,15 @@ import {
Center,
VStack,
useToast,
+ Icon,
} from "@chakra-ui/react";
import { gsap } from "gsap";
import axios from "axios";
import CreateComment from "./CreateComment";
import { useUser } from "../hook/useUser";
import { InfinitySpin } from "react-loader-spinner";
+import DeleteConfirmation from "./DeleteConfirmation";
+import { FaTrash } from "react-icons/fa";
const SinglePost = () => {
const { id } = useParams();
@@ -26,11 +30,15 @@ const SinglePost = () => {
const [loading, setLoading] = useState(true);
const [postLiked, setPostLiked] = useState(false);
const { userDetails, loadingUser } = useUser();
+ const [isDeletePostOpen, setIsDeletePostOpen] = useState(false);
+ const [isDeleteCommentOpen, setIsDeleteCommentOpen] = useState(false);
+ const [commentToDelete, setCommentToDelete] = useState(null);
// Refs for the animations
const likeButtonRef = React.useRef(null);
const likeFloodRef = React.useRef(null);
const toast = useToast();
+ const navigate = useNavigate();
useEffect(() => {
const fetchPost = async () => {
@@ -43,6 +51,7 @@ const SinglePost = () => {
} catch (err) {
setLoading(false);
alert("Error fetching post");
+ console.error("Error fetching post:", err);
}
};
@@ -163,6 +172,47 @@ const SinglePost = () => {
);
+ const handleDeleteComment = async (comment) => {
+ try {
+ await axios.post(
+ "/api/post/deletecomment",
+ { commentId: comment.comment_id },
+ { withCredentials: true }
+ );
+ setPost((prevPost) => ({
+ ...prevPost,
+ Comments: prevPost.Comments.filter(
+ (c) => c.comment_id !== comment.comment_id
+ ),
+ }));
+ setIsDeleteCommentOpen(false);
+ } catch (error) {
+ console.error("Error deleting comment:", error);
+ }
+ };
+
+ const handleDeletePost = async () => {
+ try {
+ setLoading(true);
+ await axios.post(
+ "/api/post/deletepost",
+ { postId: post.post_id },
+ { withCredentials: true }
+ );
+ setIsDeletePostOpen(false);
+ setLoading(false);
+ toast({
+ title: "Post deleted successfully",
+ status: "success",
+ duration: 5000,
+ isClosable: true,
+ });
+ navigate("/posts");
+ } catch (error) {
+ console.error("Error deleting post:", error);
+ }
+ };
+
return (
{
{post.likes} {post.likes === 1 ? "like" : "likes"}
-
+
+ {post.User.user_id === userDetails.user_id && (
+
+ )}
+
+ setIsDeletePostOpen(false)}
+ onConfirm={handleDeletePost}
+ message="Are you sure you want to delete this post?"
+ />
{
-
- {/* Displaying Comments */}
{post.Comments.length > 0 ? (
post.Comments.map((comment) => (
{
{comment.User.username}
-
+
{comment.content}
+ {comment.User.user_id === userDetails.user_id && (
+
+
+ setIsDeleteCommentOpen(false)}
+ onConfirm={() => handleDeleteComment(commentToDelete)}
+ message="Are you sure you want to delete this comment?"
+ />
+
+ )}
))
) : (