2023-06-06 17:59:06 +00:00
|
|
|
import React, { useState, useEffect, useContext } from "react";
|
2022-01-06 01:26:15 +00:00
|
|
|
import { useParams, useHistory } from "react-router-dom";
|
|
|
|
|
|
|
|
import { toast } from "react-toastify";
|
|
|
|
import openSocket from "socket.io-client";
|
|
|
|
import clsx from "clsx";
|
|
|
|
|
|
|
|
import { Paper, makeStyles } from "@material-ui/core";
|
|
|
|
|
|
|
|
import ContactDrawer from "../ContactDrawer";
|
|
|
|
import MessageInput from "../MessageInput/";
|
|
|
|
import TicketHeader from "../TicketHeader";
|
|
|
|
import TicketInfo from "../TicketInfo";
|
|
|
|
import TicketActionButtons from "../TicketActionButtons";
|
|
|
|
import MessagesList from "../MessagesList";
|
|
|
|
import api from "../../services/api";
|
|
|
|
import { ReplyMessageProvider } from "../../context/ReplyingMessage/ReplyingMessageContext";
|
|
|
|
import toastError from "../../errors/toastError";
|
|
|
|
|
2023-06-06 17:59:06 +00:00
|
|
|
import { AuthContext } from "../../context/Auth/AuthContext"
|
|
|
|
|
2022-01-06 01:26:15 +00:00
|
|
|
const drawerWidth = 320;
|
|
|
|
|
|
|
|
const useStyles = makeStyles((theme) => ({
|
|
|
|
root: {
|
|
|
|
display: "flex",
|
|
|
|
height: "100%",
|
|
|
|
position: "relative",
|
|
|
|
overflow: "hidden",
|
|
|
|
},
|
|
|
|
|
|
|
|
ticketInfo: {
|
|
|
|
maxWidth: "50%",
|
|
|
|
flexBasis: "50%",
|
|
|
|
[theme.breakpoints.down("sm")]: {
|
|
|
|
maxWidth: "80%",
|
|
|
|
flexBasis: "80%",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
ticketActionButtons: {
|
|
|
|
maxWidth: "50%",
|
|
|
|
flexBasis: "50%",
|
|
|
|
display: "flex",
|
|
|
|
[theme.breakpoints.down("sm")]: {
|
|
|
|
maxWidth: "100%",
|
|
|
|
flexBasis: "100%",
|
|
|
|
marginBottom: "5px",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
mainWrapper: {
|
|
|
|
flex: 1,
|
|
|
|
height: "100%",
|
|
|
|
display: "flex",
|
|
|
|
flexDirection: "column",
|
|
|
|
overflow: "hidden",
|
|
|
|
borderTopLeftRadius: 0,
|
|
|
|
borderBottomLeftRadius: 0,
|
|
|
|
borderLeft: "0",
|
|
|
|
marginRight: -drawerWidth,
|
|
|
|
transition: theme.transitions.create("margin", {
|
|
|
|
easing: theme.transitions.easing.sharp,
|
|
|
|
duration: theme.transitions.duration.leavingScreen,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
|
|
|
|
mainWrapperShift: {
|
|
|
|
borderTopRightRadius: 0,
|
|
|
|
borderBottomRightRadius: 0,
|
|
|
|
transition: theme.transitions.create("margin", {
|
|
|
|
easing: theme.transitions.easing.easeOut,
|
|
|
|
duration: theme.transitions.duration.enteringScreen,
|
|
|
|
}),
|
|
|
|
marginRight: 0,
|
|
|
|
},
|
|
|
|
}));
|
|
|
|
|
|
|
|
const Ticket = () => {
|
2023-06-06 17:59:06 +00:00
|
|
|
|
|
|
|
const { user } = useContext(AuthContext);
|
|
|
|
|
|
|
|
|
2022-01-06 01:26:15 +00:00
|
|
|
const { ticketId } = useParams();
|
|
|
|
const history = useHistory();
|
|
|
|
const classes = useStyles();
|
|
|
|
|
|
|
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
const [contact, setContact] = useState({});
|
|
|
|
const [ticket, setTicket] = useState({});
|
|
|
|
|
2023-06-06 17:59:06 +00:00
|
|
|
const [statusChatEnd, setStatusChatEnd] = useState({})
|
2022-02-28 13:51:11 +00:00
|
|
|
|
2022-01-06 01:26:15 +00:00
|
|
|
useEffect(() => {
|
|
|
|
setLoading(true);
|
|
|
|
const delayDebounceFn = setTimeout(() => {
|
2023-06-06 17:59:06 +00:00
|
|
|
const fetchTicket = async () => {
|
2022-02-28 13:51:11 +00:00
|
|
|
|
2023-06-06 17:59:06 +00:00
|
|
|
try {
|
2022-01-06 01:26:15 +00:00
|
|
|
|
2023-06-06 17:59:06 +00:00
|
|
|
let number
|
|
|
|
let msg
|
|
|
|
let contactId
|
2022-03-10 11:24:10 +00:00
|
|
|
|
2023-06-06 17:59:06 +00:00
|
|
|
if (ticketId && ticketId.includes("&&text=")) {
|
|
|
|
|
|
|
|
number = ticketId.split('&&text=')[0]
|
|
|
|
msg = ticketId.split('&&text=')[1]
|
|
|
|
|
|
|
|
msg = decodeURIComponent(msg);
|
|
|
|
|
|
|
|
|
|
|
|
console.log('NUMBER: ', number)
|
|
|
|
|
|
|
|
const { data: data0 } = await api.get("/contacts/", { params: { searchParam: number, pageNumber: "1" }, });
|
|
|
|
|
|
|
|
if (data0 && data0.contacts.length > 0) {
|
|
|
|
console.log('-----> data: ', data0.contacts[0].id)
|
|
|
|
contactId = data0.contacts[0].id
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
console.log('NO CONTACT whith this NUMBER: ', number)
|
|
|
|
|
|
|
|
const values = {
|
|
|
|
name: number,
|
|
|
|
number: number,
|
|
|
|
};
|
|
|
|
|
|
|
|
const { data: data1 } = await api.post("/contacts", values);
|
|
|
|
|
|
|
|
console.log('data1: ', data1)
|
|
|
|
|
|
|
|
contactId = data1.id
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const { data: ticket } = await api.post("/tickets", {
|
|
|
|
contactId: contactId,
|
|
|
|
userId: user.id,
|
|
|
|
status: "open",
|
|
|
|
msg
|
|
|
|
});
|
|
|
|
|
|
|
|
window.location.reload();
|
|
|
|
history.push(`/tickets/${ticket.id}`);
|
|
|
|
window.location.reload();
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
console.log('>>>>>>>>>>>>>>>>>>>>>>>>> ticketId: ', ticketId)
|
|
|
|
|
|
|
|
const { data } = await api.get("/tickets/" + ticketId);
|
|
|
|
|
|
|
|
// setContact(data.contact);
|
|
|
|
// setTicket(data);
|
|
|
|
|
|
|
|
setContact(data.contact.contact);
|
|
|
|
setTicket(data.contact);
|
|
|
|
|
|
|
|
setStatusChatEnd(data.statusChatEnd)
|
|
|
|
|
|
|
|
setLoading(false);
|
|
|
|
}
|
2022-02-28 13:51:11 +00:00
|
|
|
|
|
|
|
|
2022-01-06 01:26:15 +00:00
|
|
|
} catch (err) {
|
2023-06-08 11:16:18 +00:00
|
|
|
setLoading(false);
|
2022-01-06 01:26:15 +00:00
|
|
|
toastError(err);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
fetchTicket();
|
|
|
|
}, 500);
|
|
|
|
return () => clearTimeout(delayDebounceFn);
|
2023-06-06 17:59:06 +00:00
|
|
|
}, [ticketId, history, user.id]);
|
2022-01-06 01:26:15 +00:00
|
|
|
|
|
|
|
useEffect(() => {
|
2023-06-06 17:59:06 +00:00
|
|
|
|
|
|
|
const regex = /^[0-9\b]+$/; // Regular expression to match only numbers
|
|
|
|
if (ticketId && !ticketId.match(regex)) return
|
|
|
|
|
2022-01-06 01:26:15 +00:00
|
|
|
const socket = openSocket(process.env.REACT_APP_BACKEND_URL);
|
|
|
|
|
|
|
|
socket.on("connect", () => socket.emit("joinChatBox", ticketId));
|
|
|
|
|
|
|
|
socket.on("ticket", (data) => {
|
|
|
|
if (data.action === "update") {
|
|
|
|
setTicket(data.ticket);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (data.action === "delete") {
|
|
|
|
toast.success("Ticket deleted sucessfully.");
|
|
|
|
history.push("/tickets");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
socket.on("contact", (data) => {
|
|
|
|
if (data.action === "update") {
|
|
|
|
setContact((prevState) => {
|
|
|
|
if (prevState.id === data.contact?.id) {
|
|
|
|
return { ...prevState, ...data.contact };
|
|
|
|
}
|
|
|
|
return prevState;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
socket.disconnect();
|
|
|
|
};
|
|
|
|
}, [ticketId, history]);
|
|
|
|
|
|
|
|
const handleDrawerOpen = () => {
|
|
|
|
setDrawerOpen(true);
|
|
|
|
};
|
|
|
|
|
|
|
|
const handleDrawerClose = () => {
|
|
|
|
setDrawerOpen(false);
|
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div className={classes.root} id="drawer-container">
|
|
|
|
<Paper
|
|
|
|
variant="outlined"
|
|
|
|
elevation={0}
|
|
|
|
className={clsx(classes.mainWrapper, {
|
|
|
|
[classes.mainWrapperShift]: drawerOpen,
|
|
|
|
})}
|
|
|
|
>
|
|
|
|
<TicketHeader loading={loading}>
|
|
|
|
<div className={classes.ticketInfo}>
|
|
|
|
<TicketInfo
|
|
|
|
contact={contact}
|
|
|
|
ticket={ticket}
|
|
|
|
onClick={handleDrawerOpen}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
<div className={classes.ticketActionButtons}>
|
2023-06-06 17:59:06 +00:00
|
|
|
<TicketActionButtons ticket={ticket} statusChatEnd={statusChatEnd} />
|
2022-01-06 01:26:15 +00:00
|
|
|
</div>
|
|
|
|
</TicketHeader>
|
|
|
|
<ReplyMessageProvider>
|
|
|
|
<MessagesList
|
|
|
|
ticketId={ticketId}
|
|
|
|
isGroup={ticket.isGroup}
|
|
|
|
></MessagesList>
|
|
|
|
<MessageInput ticketStatus={ticket.status} />
|
|
|
|
</ReplyMessageProvider>
|
|
|
|
</Paper>
|
|
|
|
<ContactDrawer
|
|
|
|
open={drawerOpen}
|
|
|
|
handleDrawerClose={handleDrawerClose}
|
|
|
|
contact={contact}
|
|
|
|
loading={loading}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default Ticket;
|