diff --git a/package-lock.json b/package-lock.json index 5c35d07..5831e0e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "react-hot-toast": "^2.4.1", "react-icons": "^4.8.0", "react-markdown": "^9.0.0", - "react-router-dom": "^6.14.2", + "react-router-dom": "^6.21.1", "react-scripts": "5.0.1", "react-simplemde-editor": "^5.2.0", "simplemde": "^1.11.2", @@ -3616,11 +3616,11 @@ } }, "node_modules/@remix-run/router": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.7.2.tgz", - "integrity": "sha512-7Lcn7IqGMV+vizMPoEl5F0XDshcdDYtMI6uJLQdQz5CfZAwy3vvGKYSUk789qndt5dEC4HfSjviSYlSoHGL2+A==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.1.tgz", + "integrity": "sha512-Qg4DMQsfPNAs88rb2xkdk03N3bjK4jgX5fR24eHCTR9q6PrhZQZ4UJBPzCHJkIpTRN1UKxx2DzjZmnC+7Lj0Ow==", "engines": { - "node": ">=14" + "node": ">=14.0.0" } }, "node_modules/@rollup/plugin-babel": { @@ -15475,29 +15475,29 @@ } }, "node_modules/react-router": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.14.2.tgz", - "integrity": "sha512-09Zss2dE2z+T1D03IheqAFtK4UzQyX8nFPWx6jkwdYzGLXd5ie06A6ezS2fO6zJfEb/SpG6UocN2O1hfD+2urQ==", + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.21.1.tgz", + "integrity": "sha512-W0l13YlMTm1YrpVIOpjCADJqEUpz1vm+CMo47RuFX4Ftegwm6KOYsL5G3eiE52jnJpKvzm6uB/vTKTPKM8dmkA==", "dependencies": { - "@remix-run/router": "1.7.2" + "@remix-run/router": "1.14.1" }, "engines": { - "node": ">=14" + "node": ">=14.0.0" }, "peerDependencies": { "react": ">=16.8" } }, "node_modules/react-router-dom": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.14.2.tgz", - "integrity": "sha512-5pWX0jdKR48XFZBuJqHosX3AAHjRAzygouMTyimnBPOLdY3WjzUSKhus2FVMihUFWzeLebDgr4r8UeQFAct7Bg==", + "version": "6.21.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.21.1.tgz", + "integrity": "sha512-QCNrtjtDPwHDO+AO21MJd7yIcr41UetYt5jzaB9Y1UYaPTCnVuJq6S748g1dE11OQlCFIQg+RtAA1SEZIyiBeA==", "dependencies": { - "@remix-run/router": "1.7.2", - "react-router": "6.14.2" + "@remix-run/router": "1.14.1", + "react-router": "6.21.1" }, "engines": { - "node": ">=14" + "node": ">=14.0.0" }, "peerDependencies": { "react": ">=16.8", diff --git a/package.json b/package.json index 8904574..1c8cf0e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "react-hot-toast": "^2.4.1", "react-icons": "^4.8.0", "react-markdown": "^9.0.0", - "react-router-dom": "^6.14.2", + "react-router-dom": "^6.21.1", "react-scripts": "5.0.1", "react-simplemde-editor": "^5.2.0", "simplemde": "^1.11.2", diff --git a/src/App.js b/src/App.js index 0dae341..886134e 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,4 @@ -import { HomePage, PostForm, NotFoundPage } from "./pages/index"; +import { HomePage, PostForm, NotFoundPage, SubscriptionPage } from "./pages/index"; import { Routes, Route } from "react-router-dom"; import { PostProvider } from "./context/postContext"; import { Toaster } from "react-hot-toast"; @@ -10,6 +10,7 @@ import Navbar from "./components/Navbar/Navbar"; import ContactForm from "./pages/Contact"; import { DefaultCarousel } from "./components/Carousel/Carousel"; import UserList from "./pages/Users"; +import { PostDetailsCard } from "./components/PostDetailsCard"; function App() { return ( @@ -23,11 +24,12 @@ function App() { } /> } /> } /> - + } /> + } /> {/* Private routes */} }> } /> - } /> + } /> } /> } /> diff --git a/src/components/Comments.jsx b/src/components/Comments.jsx new file mode 100644 index 0000000..b848635 --- /dev/null +++ b/src/components/Comments.jsx @@ -0,0 +1,128 @@ +import React from "react"; +import moment from "moment"; +import axios from "axios"; +import toast from "react-hot-toast"; +import Cookies from "js-cookie"; +import { useState } from "react"; + +export const Comment = ({ comment, onDelete, onEdit }) => { + const [isEditing, setIsEditing] = useState(false); + const [editedText, setEditedText] = useState(comment.text); + + const handleDeleteComment = async () => { + try { + await axios.delete( + `http://localhost:4000/api/posts/${comment._id}/comments/`, + { + withCredentials: true, + } + ); + + onDelete(comment._id); + + toast.success("Comment successfully deleted."); + } catch (error) { + toast.error("Error deleting the comment", error); + } + }; + + const handleEditComment = async () => { + try { + const response = await axios.put( + `http://localhost:4000/api/posts/${comment._id}/comments/`, + { text: editedText }, + { + withCredentials: true, + } + ); + + if (onEdit) { + onEdit(response.data); + } + + toast.success("Comment successfully edited."); + setIsEditing(false); + } catch (error) { + toast.error("Error editing the comment", error); + } + }; + + const canEditAndDelete = + comment?.commentator?.trim() === Cookies.get("username")?.trim(); + + return ( +
+
+ + {comment.commentator} + + + -{moment(comment.createdAt).format("DD/MM/YYYY")} + + {canEditAndDelete && ( + <> + {isEditing ? ( + <> + + + + ) : ( + <> + + + + )} + + )} + + +
+ {isEditing ? ( +