diff --git a/client/src/components/Message.tsx b/client/src/components/Message.tsx index 483eb67..dba854d 100644 --- a/client/src/components/Message.tsx +++ b/client/src/components/Message.tsx @@ -1,6 +1,6 @@ import { FaThumbsUp } from 'react-icons/fa'; import Avatar from '@components/Avatar'; -import PopupMessage from './PopupMessage'; +import PopupMenu from './PopupMenu'; const Image = ({ image }: {image: string}) => { if (image === '' || image === null) { @@ -39,7 +39,7 @@ const Message = ({ message }: any) => {
{message.author.firstName} {message.author.lastName}
- + diff --git a/client/src/components/MessageWrapper.tsx b/client/src/components/MessageWrapper.tsx index 84155de..ec29fb1 100644 --- a/client/src/components/MessageWrapper.tsx +++ b/client/src/components/MessageWrapper.tsx @@ -1,19 +1,6 @@ import { useQuery } from "@tanstack/react-query"; -import { Cookies } from "react-cookie"; import Message from "./Message"; - -const getMessages = async () => { - const token = new Cookies().get("token"); - const response = await fetch("/api/posts", { - method: "GET", - mode: "cors", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${token}`, - }, - }); - return response.json(); -}; +import { getMessages } from "@controllers/MessageController"; const MessageWrapper = () => { const messages = useQuery(["messages"], getMessages, { diff --git a/client/src/components/NewMessage.tsx b/client/src/components/NewMessage.tsx index 474156e..288404d 100644 --- a/client/src/components/NewMessage.tsx +++ b/client/src/components/NewMessage.tsx @@ -1,36 +1,14 @@ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useState } from 'react'; -import { Cookies } from 'react-cookie'; import { FaPlus } from 'react-icons/fa'; - -const sendMessage = async (data: FormData) => { - const token = new Cookies().get('token'); - let contentType = 'application/json'; - let body: FormData | string | undefined = undefined; - - if (data.get('image')) { - contentType = 'multipart/form-data'; - body = data; - } else { - body = JSON.stringify(data); - } - const response = await fetch('/api/posts/new', { - method: 'POST', - mode: 'cors', - headers: { - Authorization: `Bearer ${token}`, - }, - body, - }); - return response.json(); -}; +import {newMessage} from '@controllers/MessageController'; const NewMessage = () => { const [message, setMessage] = useState(''); const [image, setImage] = useState(''); const queryClient = useQueryClient(); - const { mutate: send } = useMutation(sendMessage, { + const { mutate: send } = useMutation(newMessage, { onSuccess: () => { queryClient.invalidateQueries(['messages']); }, diff --git a/client/src/components/PopupMenu.tsx b/client/src/components/PopupMenu.tsx new file mode 100644 index 0000000..53ec70f --- /dev/null +++ b/client/src/components/PopupMenu.tsx @@ -0,0 +1,69 @@ +import { useEffect, useState } from 'react'; +import { FaEllipsisH } from 'react-icons/fa'; +import DeleteMessage from '@components/Popups/DeleteMessage'; +import EditMessage from '@components/Popups/EditMessage'; + +const PopupMenu = ({ message }: { message: any }) => { + const [show, setShow] = useState(false); + const [showEdit, setShowEdit] = useState(false); + const [showDelete, setShowDelete] = useState(false); + + useEffect(() => { + const handleClick = (e: any) => { + if (e.target.closest('#messageId' + message.id) === null) { + setShow(false); + } + }; + + document.addEventListener('click', handleClick); + }, [message.id]); + + return ( + <> +
+
setShow(!show)} + > + +
+
+
+
+ + +
+
+ + + + ); +}; + +export default PopupMenu; diff --git a/client/src/components/PopupMessage.tsx b/client/src/components/PopupMessage.tsx deleted file mode 100644 index 58f3186..0000000 --- a/client/src/components/PopupMessage.tsx +++ /dev/null @@ -1,151 +0,0 @@ -import { useEffect, useState } from 'react'; -import { FaEllipsisH } from 'react-icons/fa'; -import Modal from './Modal'; -import { deleteMessage } from '@controllers/MessageController'; -import { useQueryClient } from '@tanstack/react-query'; -import { toast } from 'react-toastify'; - -const DeleteModal = ({ - authorId, - messageId, - showDelete, - setShowDelete, -}: { - authorId: string; - messageId: string; - showDelete: boolean; - setShowDelete: (showDelete: boolean) => void; -}) => { - const queryClient = useQueryClient(); - - const handleDelete = async () => { - const response = await deleteMessage(messageId); - queryClient.invalidateQueries(['messages']); - setShowDelete(false); - if (response.error) { - toast.error(response.error, { - position: 'top-right', - autoClose: 5000, - hideProgressBar: false, - closeOnClick: true, - pauseOnHover: true, - draggable: true, - progress: undefined, - }); - } else { - toast.success(response.message, { - position: 'top-right', - autoClose: 5000, - hideProgressBar: false, - closeOnClick: true, - pauseOnHover: true, - draggable: true, - progress: undefined, - }); - } - setShowDelete(false); - }; - - return ( - <> - -
Voulez vous vraiment supprimer ce message ?
- - -
- - ); -}; - -const EditModal = ({ - authorId, - messageId, - showEdit, - setShowEdit, -}: { - authorId: string; - messageId: string; - showEdit: boolean; - setShowEdit: (showEdit: boolean) => void; -}) => { - return ( - -
Modifier
-
- ); -}; - -const PopupMessage = ({ message }: { message: any }) => { - const [show, setShow] = useState(false); - const [showEdit, setShowEdit] = useState(false); - const [showDelete, setShowDelete] = useState(false); - - useEffect(() => { - const handleClick = (e: any) => { - if (e.target.closest('#messageId' + message.id) === null) { - setShow(false); - } - }; - - document.addEventListener('click', handleClick); - }, [message.id]); - - return ( - <> -
-
setShow(!show)} - > - -
-
-
-
- - -
-
- - - - ); -}; - -export default PopupMessage; diff --git a/client/src/components/Popups/DeleteMessage.tsx b/client/src/components/Popups/DeleteMessage.tsx new file mode 100644 index 0000000..352a0e0 --- /dev/null +++ b/client/src/components/Popups/DeleteMessage.tsx @@ -0,0 +1,68 @@ +import { deleteMessage } from "@controllers/MessageController"; +import { useQueryClient } from "@tanstack/react-query"; +import { toast } from "react-toastify"; +import Modal from "../Modal"; + +const DeleteMessage = ({ + authorId, + messageId, + showDelete, + setShowDelete, +}: { + authorId: string; + messageId: string; + showDelete: boolean; + setShowDelete: (showDelete: boolean) => void; +}) => { + const queryClient = useQueryClient(); + + const handleDelete = async () => { + const response = await deleteMessage(messageId); + queryClient.invalidateQueries(['messages']); + setShowDelete(false); + if (response.error) { + toast.error(response.error, { + position: 'top-right', + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + }); + } else { + toast.success(response.message, { + position: 'top-right', + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + }); + } + setShowDelete(false); + }; + + return ( + <> + +
Voulez vous vraiment supprimer ce message ?
+ + +
+ + ); +}; + +export default DeleteMessage; \ No newline at end of file diff --git a/client/src/components/Popups/EditMessage.tsx b/client/src/components/Popups/EditMessage.tsx new file mode 100644 index 0000000..15526c0 --- /dev/null +++ b/client/src/components/Popups/EditMessage.tsx @@ -0,0 +1,81 @@ +import Modal from '@components/Modal'; +import { useQueryClient } from '@tanstack/react-query'; +import { useState } from 'react'; +import { FaTimes } from 'react-icons/fa'; +import { editMessage } from '@controllers/MessageController'; +import { toast } from 'react-toastify'; + +const EditMessage = ({ + message, + showEdit, + setShowEdit, +}: { + message: any; + showEdit: boolean; + setShowEdit: (showEdit: boolean) => void; +}) => { + const [messageContent, setMessageContent] = useState(message.content); + const queryClient = useQueryClient(); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + const data = new FormData(e.target as HTMLFormElement); + const response = await editMessage(message.id, data); + + if (response.error) { + toast.error(response.error, { + position: 'top-right', + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + }); + return; + } + + toast.success('Message édité avec succès!', { + position: 'top-right', + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + }); + queryClient.invalidateQueries(['messages']); + setShowEdit(false); + }; + + return ( + +
+
Modifier votre message
+ setShowEdit(!showEdit)} + /> +
+
+ setMessageContent(e.target.value)} + placeholder="Message" + className="bg-grey-dark text-white rounded-xl p-2.5 w-full placeholder-red-light" + id="content" + name="content" + /> + +
+
+ ); +}; + +export default EditMessage; diff --git a/client/src/controllers/MessageController.ts b/client/src/controllers/MessageController.ts index 1e3414e..e4f2bac 100644 --- a/client/src/controllers/MessageController.ts +++ b/client/src/controllers/MessageController.ts @@ -14,18 +14,9 @@ const getMessages = async () => { const newMessage = async (data: FormData) => { const token = new Cookies().get('token'); - let body; - if (data.get('image')) { - body = data; - } else { - body = JSON.stringify({ - content: data.get('content'), - }); - } - const response = await fetch('/api/posts/new', { method: 'POST', - body, + body: data, mode: 'cors', headers: { Authorization: `Bearer ${token}`, @@ -47,18 +38,10 @@ const deleteMessage = async (id: string) => { const editMessage = async (id: string, data: FormData) => { const token = new Cookies().get('token'); - let body; - if (data.get('image')) { - body = data; - } else { - body = JSON.stringify({ - content: data.get('content'), - }); - } - - const response = await fetch(`/api/posts/${id}`, { + const response = await fetch(`/api/posts/edit/${id}`, { method: 'PUT', - body, + body: data, + mode: 'cors', headers: { Authorization: `Bearer ${token}`, },