210 lines
6.0 KiB
TypeScript
210 lines
6.0 KiB
TypeScript
|
import { TicketMessage, makeRequest, useSSESubscription, useTicketMessages, useTicketsFetcher } from "@frontend/kitui";
|
||
|
import FloatingSupportChat from "./FloatingSupportChat"
|
||
|
import { useUserStore } from "@root/user";
|
||
|
import { useCallback, useEffect, useState } from "react";
|
||
|
import { sendTicketMessage, shownMessage } from "../../api/ticket";
|
||
|
import { useSSETab } from "../../utils/hooks/useSSETab";
|
||
|
import {
|
||
|
addOrUpdateUnauthMessages,
|
||
|
useTicketStore,
|
||
|
setUnauthIsPreventAutoscroll,
|
||
|
setUnauthTicketMessageFetchState,
|
||
|
cleanAuthTicketData,
|
||
|
setTicketData,
|
||
|
} from "@root/ticket";
|
||
|
import { enqueueSnackbar } from "notistack";
|
||
|
import { getMessageFromFetchError } from "@utils/backendMessageHandler";
|
||
|
import { createTicket } from "@frontend/kitui";
|
||
|
import { setIsMessageSending } from "@root/ticket";
|
||
|
|
||
|
export default () => {
|
||
|
const user = useUserStore((state) => state.user?._id);
|
||
|
const ticket = useTicketStore(state => state[user ? "authData" : "unauthData"]);
|
||
|
|
||
|
const { isActiveSSETab, updateSSEValue } = useSSETab<TicketMessage[]>(
|
||
|
"ticket",
|
||
|
addOrUpdateUnauthMessages,
|
||
|
);
|
||
|
|
||
|
|
||
|
const [isChatOpened, setIsChatOpened] = useState<boolean>(false);
|
||
|
const handleChatClickOpen = () => {
|
||
|
setIsChatOpened(true);
|
||
|
};
|
||
|
const handleChatClickClose = () => {
|
||
|
setIsChatOpened(false);
|
||
|
};
|
||
|
const handleChatClickSwitch = () => {
|
||
|
setIsChatOpened(state => !state);
|
||
|
};
|
||
|
useTicketsFetcher({
|
||
|
url: process.env.REACT_APP_DOMAIN + "/heruvym/getTickets",
|
||
|
ticketsPerPage: 10,
|
||
|
ticketApiPage: 0,
|
||
|
onSuccess: (result) => {
|
||
|
if (result.data) {
|
||
|
setTicketData({
|
||
|
ticketId: result.data[0].id,
|
||
|
sessionId: result.data[0].sess,
|
||
|
|
||
|
});
|
||
|
}
|
||
|
},
|
||
|
onError: (error: Error) => {
|
||
|
const message = getMessageFromFetchError(error);
|
||
|
if (message) enqueueSnackbar(message);
|
||
|
},
|
||
|
onFetchStateChange: () => { },
|
||
|
enabled: Boolean(user)
|
||
|
});
|
||
|
|
||
|
useTicketMessages({
|
||
|
url: process.env.REACT_APP_DOMAIN + "/heruvym/getMessages",
|
||
|
isUnauth: true,
|
||
|
ticketId: ticket.sessionData?.ticketId,
|
||
|
messagesPerPage: ticket.messagesPerPage,
|
||
|
messageApiPage: ticket.apiPage,
|
||
|
onSuccess: useCallback((messages) => {
|
||
|
console.log("получены сообщения", messages)
|
||
|
addOrUpdateUnauthMessages(messages);
|
||
|
}, []),
|
||
|
onError: useCallback((error: Error) => {
|
||
|
const message = getMessageFromFetchError(error);
|
||
|
if (message) enqueueSnackbar(message);
|
||
|
}, []),
|
||
|
onFetchStateChange: setUnauthTicketMessageFetchState,
|
||
|
});
|
||
|
|
||
|
useSSESubscription<TicketMessage>({
|
||
|
enabled: isActiveSSETab && Boolean(ticket.sessionData?.sessionId),
|
||
|
url:
|
||
|
process.env.REACT_APP_DOMAIN +
|
||
|
`/heruvym/ticket?ticket=${ticket.sessionData?.ticketId}&s=${ticket.sessionData?.sessionId}`,
|
||
|
onNewData: (ticketMessages) => {
|
||
|
console.log("вывалилось: ", ticketMessages)
|
||
|
updateSSEValue(ticketMessages);
|
||
|
addOrUpdateUnauthMessages(ticketMessages);
|
||
|
},
|
||
|
onDisconnect: useCallback(() => {
|
||
|
setUnauthIsPreventAutoscroll(false);
|
||
|
}, []),
|
||
|
marker: "ticket",
|
||
|
});
|
||
|
|
||
|
useEffect(() => {
|
||
|
cleanAuthTicketData()
|
||
|
}, [user])
|
||
|
|
||
|
useEffect(() => {
|
||
|
if (isChatOpened) {
|
||
|
const newMessages = ticket.messages.filter(({ shown }) => shown?.me !== 1);
|
||
|
|
||
|
newMessages.map(async ({ id }) => {
|
||
|
await shownMessage(id);
|
||
|
});
|
||
|
}
|
||
|
}, [isChatOpened, ticket.messages]);
|
||
|
|
||
|
|
||
|
const sendMessage = async (messageField: string) => {
|
||
|
if (!messageField || ticket.isMessageSending) return false;
|
||
|
|
||
|
let successful = false
|
||
|
setIsMessageSending(true);
|
||
|
if (!ticket.sessionData?.ticketId) {
|
||
|
try {
|
||
|
const data = await createTicket({
|
||
|
url: process.env.REACT_APP_DOMAIN + "/heruvym/create",
|
||
|
body: {
|
||
|
Title: "Unauth title",
|
||
|
Message: messageField,
|
||
|
},
|
||
|
useToken: Boolean(user),
|
||
|
})
|
||
|
successful = true
|
||
|
setTicketData({
|
||
|
ticketId: data.Ticket,
|
||
|
sessionId: data.sess,
|
||
|
});
|
||
|
} catch (error: any) {
|
||
|
successful = false
|
||
|
const errorMessage = getMessageFromFetchError(error);
|
||
|
if (errorMessage) enqueueSnackbar(errorMessage);
|
||
|
}
|
||
|
setIsMessageSending(false);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
const [_, sendTicketMessageError] = await sendTicketMessage(
|
||
|
ticket.sessionData?.ticketId,
|
||
|
messageField,
|
||
|
);
|
||
|
successful = true
|
||
|
|
||
|
if (sendTicketMessageError) {
|
||
|
successful = false
|
||
|
enqueueSnackbar(sendTicketMessageError);
|
||
|
}
|
||
|
setIsMessageSending(false);
|
||
|
}
|
||
|
|
||
|
return successful
|
||
|
}
|
||
|
const sendFile = async (file: File) => {
|
||
|
if (file === undefined) return true
|
||
|
|
||
|
let data
|
||
|
if (!ticket.sessionData?.ticketId) {
|
||
|
try {
|
||
|
data = await createTicket({
|
||
|
url: process.env.REACT_APP_DOMAIN + "/heruvym/create",
|
||
|
body: {
|
||
|
Title: "Unauth title",
|
||
|
Message: "",
|
||
|
},
|
||
|
useToken: Boolean(user),
|
||
|
})
|
||
|
setTicketData({
|
||
|
ticketId: data.Ticket,
|
||
|
sessionId: data.sess,
|
||
|
});
|
||
|
} catch (error: any) {
|
||
|
const errorMessage = getMessageFromFetchError(error);
|
||
|
if (errorMessage) enqueueSnackbar(errorMessage);
|
||
|
}
|
||
|
setIsMessageSending(false);
|
||
|
|
||
|
}
|
||
|
|
||
|
const ticketId = ticket.sessionData?.ticketId || data?.Ticket
|
||
|
if (ticketId !== undefined) {
|
||
|
|
||
|
try {
|
||
|
const body = new FormData
|
||
|
|
||
|
body.append(file.name, file)
|
||
|
body.append("ticket", ticketId)
|
||
|
await makeRequest({
|
||
|
url: process.env.REACT_APP_DOMAIN + "/heruvym/sendFiles",
|
||
|
body: body,
|
||
|
method: "POST",
|
||
|
});
|
||
|
|
||
|
} catch (error: any) {
|
||
|
const errorMessage = getMessageFromFetchError(error);
|
||
|
if (errorMessage) enqueueSnackbar(errorMessage);
|
||
|
}
|
||
|
return true
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
return <FloatingSupportChat
|
||
|
isChatOpened={isChatOpened}
|
||
|
handleChatClickOpen={handleChatClickOpen}
|
||
|
handleChatClickClose={handleChatClickClose}
|
||
|
handleChatClickSwitch={handleChatClickSwitch}
|
||
|
sendMessage={sendMessage}
|
||
|
sendFile={sendFile}
|
||
|
/>
|
||
|
}
|