diff --git a/src/pages/dashboard/Content/Support/Chat/Chat.tsx b/src/pages/dashboard/Content/Support/Chat/Chat.tsx index 3d8ad17..2b78757 100644 --- a/src/pages/dashboard/Content/Support/Chat/Chat.tsx +++ b/src/pages/dashboard/Content/Support/Chat/Chat.tsx @@ -9,205 +9,217 @@ import { GetMessagesRequest, TicketMessage } from "@root/model/ticket"; import { getTicketMessages, sendTicketMessage, subscribeToTicketMessages } from "@root/api/tickets"; import { enqueueSnackbar } from "notistack"; import { useTicketStore } from "@root/stores/tickets"; - +import { authStore } from "@root/stores/auth"; export default function Chat() { - const theme = useTheme(); - const upMd = useMediaQuery(theme.breakpoints.up("md")); - const tickets = useTicketStore(state => state.tickets); - const messages = useMessageStore(state => state.messages); - const [messageField, setMessageField] = useState(""); - const ticketId = useParams().ticketId; - const chatBoxRef = useRef(null); + const theme = useTheme(); + const upMd = useMediaQuery(theme.breakpoints.up("md")); + const tickets = useTicketStore((state) => state.tickets); + const messages = useMessageStore((state) => state.messages); + const { token } = authStore(); + const [messageField, setMessageField] = useState(""); + const ticketId = useParams().ticketId; + const chatBoxRef = useRef(null); - const ticket = tickets.find(ticket => ticket.id === ticketId); + const ticket = tickets.find((ticket) => ticket.id === ticketId); - useEffect(function scrollOnNewMessage() { - scrollToBottom(); - }, [messages]); + useEffect( + function scrollOnNewMessage() { + scrollToBottom(); + }, + [messages] + ); - useEffect(function fetchTicketMessages() { - if (!ticketId) return; + useEffect( + function fetchTicketMessages() { + if (!ticketId) return; - const getTicketsBody: GetMessagesRequest = { - amt: 100, // TODO use pagination - page: 0, - ticket: ticketId, - }; - const controller = new AbortController(); + const getTicketsBody: GetMessagesRequest = { + amt: 100, // TODO use pagination + page: 0, + ticket: ticketId, + }; + const controller = new AbortController(); - getTicketMessages({ - body: getTicketsBody, - signal: controller.signal, - }).then(result => { - console.log("GetMessagesResponse", result); - setMessages(result); - }).catch(error => { - console.log("Error fetching tickets", error); - enqueueSnackbar(error.message); + getTicketMessages({ + body: getTicketsBody, + signal: controller.signal, + }) + .then((result) => { + console.log("GetMessagesResponse", result); + setMessages(result); + }) + .catch((error) => { + console.log("Error fetching tickets", error); + enqueueSnackbar(error.message); }); - return () => { - controller.abort(); - clearMessages(); - }; - }, [ticketId]); + return () => { + controller.abort(); + clearMessages(); + }; + }, + [ticketId] + ); - useEffect(function subscribeToMessages() { - if (!ticketId) return; + useEffect( + function subscribeToMessages() { + if (!ticketId) return; - const token = localStorage.getItem("AT"); - if (!token) return; + if (!token) return; - const unsubscribe = subscribeToTicketMessages({ - ticketId, - accessToken: token, - onMessage(event) { - try { - const newMessage = JSON.parse(event.data) as TicketMessage; - console.log("SSE: parsed newMessage:", newMessage); - addOrUpdateMessages([newMessage]); - } catch (error) { - console.log("SSE: couldn't parse:", event.data); - console.log("Error parsing message SSE", error); - } - }, - onError(event) { - console.log("SSE Error:", event); - }, - }); + const unsubscribe = subscribeToTicketMessages({ + ticketId, + accessToken: token, + onMessage(event) { + try { + const newMessage = JSON.parse(event.data) as TicketMessage; + console.log("SSE: parsed newMessage:", newMessage); + addOrUpdateMessages([newMessage]); + } catch (error) { + console.log("SSE: couldn't parse:", event.data); + console.log("Error parsing message SSE", error); + } + }, + onError(event) { + console.log("SSE Error:", event); + }, + }); - return () => { - unsubscribe(); - }; - }, [ticketId]); + return () => { + unsubscribe(); + }; + }, + [ticketId] + ); - function scrollToBottom() { - if (!chatBoxRef.current) return; + function scrollToBottom() { + if (!chatBoxRef.current) return; - chatBoxRef.current.scroll({ - left: 0, - top: chatBoxRef.current.scrollHeight, - behavior: "smooth", - }); + chatBoxRef.current.scroll({ + left: 0, + top: chatBoxRef.current.scrollHeight, + behavior: "smooth", + }); + } + + function handleSendMessage() { + if (!ticket || !messageField) return; + + sendTicketMessage({ + body: { + files: [], + lang: "ru", + message: messageField, + ticket: ticket.id, + }, + }); + setMessageField(""); + } + + function handleAddAttachment() {} + + function handleTextfieldKeyPress(e: KeyboardEvent) { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); + handleSendMessage(); } + } - function handleSendMessage() { - if (!ticket || !messageField) return; + const sortedMessages = messages.sort(sortMessagesByTime); - sendTicketMessage({ - body: { - files: [], - lang: "ru", - message: messageField, - ticket: ticket.id, - } - }); - setMessageField(""); - } - - function handleAddAttachment() { - - } - - function handleTextfieldKeyPress(e: KeyboardEvent) { - if (e.key === "Enter" && !e.shiftKey) { - e.preventDefault(); - handleSendMessage(); - } - } - - const sortedMessages = messages.sort(sortMessagesByTime); - - return ( - - {ticket ? - <> - {ticket.title} - - {sortedMessages.map(message => - - )} - - setMessageField(e.target.value)} - onKeyPress={handleTextfieldKeyPress} - id="message-input" - placeholder="Написать сообщение" - fullWidth - multiline - maxRows={8} - InputProps={{ - style: { - backgroundColor: theme.palette.content.main, - color: theme.palette.secondary.main, - }, - endAdornment: ( - - - - - - - - - ) - }} - InputLabelProps={{ - style: { - color: theme.palette.secondary.main, - } - }} - /> - - : - Выберите тикет} - - ); + return ( + + {ticket ? ( + <> + {ticket.title} + + {sortedMessages.map((message) => ( + + ))} + + setMessageField(e.target.value)} + onKeyPress={handleTextfieldKeyPress} + id="message-input" + placeholder="Написать сообщение" + fullWidth + multiline + maxRows={8} + InputProps={{ + style: { + backgroundColor: theme.palette.content.main, + color: theme.palette.secondary.main, + }, + endAdornment: ( + + + + + + + + + ), + }} + InputLabelProps={{ + style: { + color: theme.palette.secondary.main, + }, + }} + /> + + ) : ( + Выберите тикет + )} + + ); } function sortMessagesByTime(message1: TicketMessage, message2: TicketMessage) { - const date1 = new Date(message1.created_at).getTime(); - const date2 = new Date(message2.created_at).getTime(); - return date1 - date2; -} \ No newline at end of file + const date1 = new Date(message1.created_at).getTime(); + const date2 = new Date(message2.created_at).getTime(); + return date1 - date2; +}