import React from "react"; import openSocket from "socket.io-client"; import TicketListStyled from "./TicketsList.style"; import useTickets from "../../../../hooks/useTickets"; import TicketListItem from "../TicketsList/TicketListItem/TicketListItem"; import TicketsListSkeleton from "../TicketsListSkeleton/TicketListSkeleton"; import { i18n } from "../../../../translate/i18n"; import { AuthContext } from "../../../../context/Auth/AuthContext"; const reducer = (state, action) => { if (action.type === "LOAD_TICKETS") { const newTickets = action.payload; newTickets.forEach((ticket) => { const ticketIndex = state.findIndex((t) => t.id === ticket.id); if (ticketIndex !== -1) { state[ticketIndex] = ticket; if (ticket.unreadMessages > 0) { state.unshift(state.splice(ticketIndex, 1)[0]); } } else { state.push(ticket); } }); return [...state]; } if (action.type === "RESET_UNREAD") { const ticketId = action.payload; const ticketIndex = state.findIndex((t) => t.id === ticketId); if (ticketIndex !== -1) { state[ticketIndex].unreadMessages = 0; } return [...state]; } if (action.type === "UPDATE_TICKET") { const ticket = action.payload; const ticketIndex = state.findIndex((t) => t.id === ticket.id); if (ticketIndex !== -1) { state[ticketIndex] = ticket; } else { state.unshift(ticket); } return [...state]; } if (action.type === "UPDATE_TICKET_UNREAD_MESSAGES") { const message = action.payload.message; const ticket = action.payload.ticket; const ticketIndex = state.findIndex((t) => t.id === ticket.id); if (ticketIndex !== -1) { if (!message.fromMe) { ticket.unreadMessages += 1; } state[ticketIndex] = ticket; state.unshift(state.splice(ticketIndex, 1)[0]); } else { state.unshift(ticket); } return [...state]; } if (action.type === "UPDATE_TICKET_CONTACT") { const contact = action.payload; const ticketIndex = state.findIndex((t) => t.contactId === contact.id); if (ticketIndex !== -1) { state[ticketIndex].contact = contact; } return [...state]; } if (action.type === "DELETE_TICKET") { const ticketId = action.payload; const ticketIndex = state.findIndex((t) => t.id === ticketId); if (ticketIndex !== -1) { state.splice(ticketIndex, 1); } return [...state]; } if (action.type === "RESET") { return []; } }; const TicketsList = ({ status, searchParam, showAll, selectedQueueIds, updateCount }) => { const [pageNumber, setPageNumber] = React.useState(1); const [ticketsList, dispatch] = React.useReducer(reducer, []); const { user } = React.useContext(AuthContext); const { tickets, loading } = useTickets({ pageNumber, searchParam, status, showAll, queueIds: JSON.stringify(selectedQueueIds), }); React.useEffect(() => { dispatch({ type: "RESET" }); setPageNumber(1); }, [status, searchParam, dispatch, showAll, selectedQueueIds]); React.useEffect(() => { if (!status && !searchParam) return; dispatch({ type: "LOAD_TICKETS", payload: tickets, }); }, [tickets, searchParam]); React.useEffect(() => { const socket = openSocket(process.env.REACT_APP_BACKEND_URL); const shouldUpdateTicket = (ticket) => (!ticket.userId || ticket.userId === user?.id || showAll) && (!ticket.queueId || selectedQueueIds.indexOf(ticket.queueId) > -1); const notBelongsToUserQueues = (ticket) => ticket.queueId && selectedQueueIds.indexOf(ticket.queueId) === -1; socket.on("connect", () => { if (status) { socket.emit("joinTickets", status); } else { socket.emit("joinNotification"); } }); socket.on("ticket", (data) => { if (data.action === "updateUnread") { dispatch({ type: "RESET_UNREAD", payload: data.ticketId, }); } if (data.action === "update" && shouldUpdateTicket(data.ticket)) { dispatch({ type: "UPDATE_TICKET", payload: data.ticket, }); } if (data.action === "update" && notBelongsToUserQueues(data.ticket)) { dispatch({ type: "DELETE_TICKET", payload: data.ticket.id }); } if (data.action === "delete") { dispatch({ type: "DELETE_TICKET", payload: data.ticketId }); } }); socket.on("appMessage", (data) => { if (data.action === "create" && shouldUpdateTicket(data.ticket)) { dispatch({ type: "UPDATE_TICKET_UNREAD_MESSAGES", // payload: data.ticket, payload: data, }); } }); socket.on("contact", (data) => { if (data.action === "update") { dispatch({ type: "UPDATE_TICKET_CONTACT", payload: data.contact, }); } }); return () => { socket.disconnect(); }; }, [status, showAll, user, selectedQueueIds]); if (loading) return ; return ( {ticketsList.map((ticket) => ( ))} ); }; export default TicketsList;