frontPanel/src/ui_kit/FloatingSupportChat/index.tsx

210 lines
6.0 KiB
TypeScript
Raw Normal View History

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}
/>
}