diff --git a/backend/src/controllers/TicketController.js b/backend/src/controllers/TicketController.js index 1025412..25b9a3f 100644 --- a/backend/src/controllers/TicketController.js +++ b/backend/src/controllers/TicketController.js @@ -120,3 +120,23 @@ exports.update = async (req, res) => { res.status(200).json(ticket); }; + +exports.delete = async (req, res) => { + const io = getIO(); + const { ticketId } = req.params; + + const ticket = await Ticket.findByPk(ticketId); + + if (!ticket) { + return res.status(400).json({ error: "No ticket found with this ID" }); + } + + await ticket.destroy(); + + io.to("notification").emit("ticket", { + action: "delete", + ticketId: ticket.id, + }); + + res.status(200).json({ message: "ticket deleted" }); +}; diff --git a/backend/src/routes/tickets.js b/backend/src/routes/tickets.js index ba500e5..5bf490f 100644 --- a/backend/src/routes/tickets.js +++ b/backend/src/routes/tickets.js @@ -11,4 +11,6 @@ routes.post("/tickets", isAuth, TicketController.store); routes.put("/tickets/:ticketId", isAuth, TicketController.update); +routes.delete("/tickets/:ticketId", isAuth, TicketController.delete); + module.exports = routes; diff --git a/frontend/src/components/MessagesList/TicketOptionsMenu.js b/frontend/src/components/MessagesList/TicketOptionsMenu.js new file mode 100644 index 0000000..f5f777a --- /dev/null +++ b/frontend/src/components/MessagesList/TicketOptionsMenu.js @@ -0,0 +1,73 @@ +import React, { useState } from "react"; + +import { useHistory } from "react-router-dom"; +import { toast } from "react-toastify"; + +import MenuItem from "@material-ui/core/MenuItem"; +import Menu from "@material-ui/core/Menu"; + +import api from "../../services/api"; +import ConfirmationModal from "../ConfirmationModal"; + +const TicketOptionsMenu = ({ ticket, menuOpen, handleClose, anchorEl }) => { + const history = useHistory(); + + const [confirmationOpen, setConfirmationOpen] = useState(false); + + const handleDeleteTicket = async () => { + try { + await api.delete(`/tickets/${ticket.id}`); + toast.success("Ticket deletado com sucesso."); + history.push("/chat"); + } catch (err) { + toast.error("Erro ao deletar o ticket"); + } + + console.log("deleted"); + handleClose(); + }; + + const handleTransferTicket = e => { + console.log("transfered"); + handleClose(); + }; + + const handleOpenConfirmationModal = e => { + setConfirmationOpen(true); + handleClose(); + }; + + console.log(ticket); + return ( + <> + + Deletar + Transferir + + + Atenção, todas as mensagens relacionadas a este ticket serão apagadas. + + + ); +}; + +export default TicketOptionsMenu; diff --git a/frontend/src/components/MessagesList/index.js b/frontend/src/components/MessagesList/index.js index 8c6c49f..07d403e 100644 --- a/frontend/src/components/MessagesList/index.js +++ b/frontend/src/components/MessagesList/index.js @@ -20,12 +20,15 @@ import Button from "@material-ui/core/Button"; import Paper from "@material-ui/core/Paper"; import { green } from "@material-ui/core/colors"; import Skeleton from "@material-ui/lab/Skeleton"; +import IconButton from "@material-ui/core/IconButton"; +import MoreVertIcon from "@material-ui/icons/MoreVert"; import api from "../../services/api"; import ContactDrawer from "../ContactDrawer"; import whatsBackground from "../../assets/wa-background.png"; import LinkifyWithTargetBlank from "../LinkifyWithTargetBlank"; import MessageInput from "../MessageInput/"; +import TicketOptionsMenu from "./TicketOptionsMenu"; const drawerWidth = 320; @@ -65,7 +68,7 @@ const useStyles = makeStyles(theme => ({ messagesHeader: { display: "flex", - cursor: "pointer", + // cursor: "pointer", backgroundColor: "#eee", flex: "none", borderBottom: "1px solid rgba(0, 0, 0, 0.12)", @@ -233,6 +236,9 @@ const MessagesList = () => { const [drawerOpen, setDrawerOpen] = useState(false); const lastMessageRef = useRef(); + const [anchorEl, setAnchorEl] = useState(null); + const moreMenuOpen = Boolean(anchorEl); + useEffect(() => { setMessagesList([]); }, [searchParam]); @@ -366,9 +372,15 @@ const MessagesList = () => { } }; + const handleOpenTicketOptionsMenu = e => { + setAnchorEl(e.currentTarget); + }; + + const handleCloseTicketOptionsMenu = e => { + setAnchorEl(null); + }; + const handleUpdateTicketStatus = async (e, status, userId) => { - e.preventDefault(); - e.stopPropagation(); try { await api.put(`/tickets/${ticketId}`, { status: status, @@ -380,6 +392,14 @@ const MessagesList = () => { history.push("/chat"); }; + const handleDrawerOpen = () => { + setDrawerOpen(true); + }; + + const handleDrawerClose = () => { + setDrawerOpen(false); + }; + const renderMessageAck = message => { if (message.ack === 0) { return ; @@ -480,13 +500,6 @@ const MessagesList = () => { } }; - const handleDrawerOpen = () => { - setDrawerOpen(true); - }; - const handleDrawerClose = () => { - setDrawerOpen(false); - }; - return (
{ [classes.mainWrapperShift]: drawerOpen, })} > - + { )} + + + +
)} diff --git a/frontend/src/components/TicketsList/index.js b/frontend/src/components/TicketsList/index.js index 888d1d6..86bd68c 100644 --- a/frontend/src/components/TicketsList/index.js +++ b/frontend/src/components/TicketsList/index.js @@ -251,11 +251,14 @@ const TicketsList = () => { socket.on("ticket", data => { if (data.action === "updateUnread") { - resetUnreadMessages(data.ticketId); + resetUnreadMessages(data); } if (data.action === "updateStatus" || data.action === "create") { updateTickets(data); } + if (data.action === "delete") { + deleteTicket(data); + } }); socket.on("appMessage", data => { @@ -277,57 +280,64 @@ const TicketsList = () => { }; }, [ticketId, userId]); - const updateUnreadMessagesCount = data => { + const updateUnreadMessagesCount = ({ message, ticket }) => { setTickets(prevState => { - const ticketIndex = prevState.findIndex( - ticket => ticket.id === data.message.ticketId - ); + const ticketIndex = prevState.findIndex(t => t.id === message.ticketId); if (ticketIndex !== -1) { let aux = [...prevState]; - if (!data.message.fromMe) { + if (!message.fromMe) { aux[ticketIndex].unreadMessages++; } - aux[ticketIndex].lastMessage = data.message.body; - aux[ticketIndex].status = data.ticket.status; + aux[ticketIndex].lastMessage = message.body; + aux[ticketIndex].status = ticket.status; aux.unshift(aux.splice(ticketIndex, 1)[0]); return aux; } else { - return [data.ticket, ...prevState]; + return [ticket, ...prevState]; } }); }; - const updateTickets = data => { + const updateTickets = ({ ticket }) => { setTickets(prevState => { - const ticketIndex = prevState.findIndex( - ticket => ticket.id === data.ticket.id - ); + const ticketIndex = prevState.findIndex(t => t.id === ticket.id); if (ticketIndex === -1) { - return [data.ticket, ...prevState]; + return [ticket, ...prevState]; } else { let aux = [...prevState]; - aux[ticketIndex] = data.ticket; + aux[ticketIndex] = ticket; return aux; } }); }; - const showDesktopNotification = data => { + const deleteTicket = ({ ticketId }) => { + setTickets(prevState => { + const ticketIndex = prevState.findIndex(ticket => ticket.id === ticketId); + + if (ticketIndex === -1) { + return prevState; + } else { + let aux = [...prevState]; + aux.splice(ticketIndex, 1); + return aux; + } + }); + }; + + const showDesktopNotification = ({ message, contact, ticket }) => { const options = { - body: `${data.message.body} - ${format(new Date(), "HH:mm")}`, - icon: data.contact.profilePicUrl, - tag: data.ticket.id, + body: `${message.body} - ${format(new Date(), "HH:mm")}`, + icon: contact.profilePicUrl, + tag: ticket.id, }; - let notification = new Notification( - `Mensagem de ${data.contact.name}`, - options - ); + let notification = new Notification(`Mensagem de ${contact.name}`, options); notification.onclick = function (event) { event.preventDefault(); // - window.open(`/chat/${data.ticket.id}`, "_self"); + window.open(`/chat/${ticket.id}`, "_self"); }; document.addEventListener("visibilitychange", () => { @@ -339,7 +349,7 @@ const TicketsList = () => { document.getElementById("sound").play(); }; - const resetUnreadMessages = ticketId => { + const resetUnreadMessages = ({ ticketId }) => { setTickets(prevState => { const ticketIndex = prevState.findIndex( ticket => ticket.id === +ticketId