2024-03-09 21:01:57 +00:00
|
|
|
import {
|
|
|
|
TicketMessage,
|
|
|
|
useSSESubscription,
|
|
|
|
useTicketMessages,
|
|
|
|
useTicketsFetcher,
|
|
|
|
} from "@frontend/kitui";
|
2024-04-16 20:20:46 +00:00
|
|
|
import makeRequest from "@api/makeRequest";
|
2024-03-09 21:01:57 +00:00
|
|
|
import FloatingSupportChat from "./FloatingSupportChat";
|
2024-03-06 11:13:28 +00:00
|
|
|
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";
|
|
|
|
|
2024-03-09 21:01:57 +00:00
|
|
|
type ModalWarningType =
|
|
|
|
| "errorType"
|
|
|
|
| "errorSize"
|
|
|
|
| "picture"
|
|
|
|
| "video"
|
|
|
|
| "audio"
|
|
|
|
| "document"
|
|
|
|
| null;
|
|
|
|
const MAX_FILE_SIZE = 419430400;
|
|
|
|
const ACCEPT_SEND_FILE_TYPES_MAP = [
|
|
|
|
".jpeg",
|
|
|
|
".jpg",
|
|
|
|
".png",
|
|
|
|
".mp4",
|
|
|
|
".doc",
|
|
|
|
".docx",
|
|
|
|
".pdf",
|
|
|
|
".txt",
|
|
|
|
".xlsx",
|
|
|
|
".csv",
|
|
|
|
] as const;
|
|
|
|
|
2024-03-06 11:13:28 +00:00
|
|
|
export default () => {
|
|
|
|
const user = useUserStore((state) => state.user?._id);
|
2024-03-09 21:01:57 +00:00
|
|
|
const ticket = useTicketStore(
|
|
|
|
(state) => state[user ? "authData" : "unauthData"],
|
|
|
|
);
|
2024-03-06 11:13:28 +00:00
|
|
|
|
|
|
|
const { isActiveSSETab, updateSSEValue } = useSSETab<TicketMessage[]>(
|
|
|
|
"ticket",
|
|
|
|
addOrUpdateUnauthMessages,
|
|
|
|
);
|
|
|
|
|
2024-03-09 21:01:57 +00:00
|
|
|
const [modalWarningType, setModalWarningType] =
|
|
|
|
useState<ModalWarningType>(null);
|
2024-03-06 11:13:28 +00:00
|
|
|
const [isChatOpened, setIsChatOpened] = useState<boolean>(false);
|
|
|
|
const handleChatClickOpen = () => {
|
|
|
|
setIsChatOpened(true);
|
|
|
|
};
|
|
|
|
const handleChatClickClose = () => {
|
|
|
|
setIsChatOpened(false);
|
|
|
|
};
|
|
|
|
const handleChatClickSwitch = () => {
|
2024-03-09 21:01:57 +00:00
|
|
|
setIsChatOpened((state) => !state);
|
2024-03-06 11:13:28 +00:00
|
|
|
};
|
|
|
|
useTicketsFetcher({
|
|
|
|
url: process.env.REACT_APP_DOMAIN + "/heruvym/getTickets",
|
|
|
|
ticketsPerPage: 10,
|
|
|
|
ticketApiPage: 0,
|
|
|
|
onSuccess: (result) => {
|
2024-03-11 16:02:47 +00:00
|
|
|
if (result.data?.length) {
|
|
|
|
const currentTicket = result.data.find(
|
|
|
|
({ origin }) => !origin.includes("/support"),
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!currentTicket) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-03-06 11:13:28 +00:00
|
|
|
setTicketData({
|
2024-03-11 16:02:47 +00:00
|
|
|
ticketId: currentTicket.id,
|
|
|
|
sessionId: currentTicket.sess,
|
2024-03-06 11:13:28 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
onError: (error: Error) => {
|
|
|
|
const message = getMessageFromFetchError(error);
|
|
|
|
if (message) enqueueSnackbar(message);
|
|
|
|
},
|
2024-03-09 21:01:57 +00:00
|
|
|
onFetchStateChange: () => {},
|
|
|
|
enabled: Boolean(user),
|
2024-03-06 11:13:28 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
useTicketMessages({
|
|
|
|
url: process.env.REACT_APP_DOMAIN + "/heruvym/getMessages",
|
|
|
|
isUnauth: true,
|
|
|
|
ticketId: ticket.sessionData?.ticketId,
|
|
|
|
messagesPerPage: ticket.messagesPerPage,
|
|
|
|
messageApiPage: ticket.apiPage,
|
|
|
|
onSuccess: useCallback((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) => {
|
|
|
|
updateSSEValue(ticketMessages);
|
|
|
|
addOrUpdateUnauthMessages(ticketMessages);
|
|
|
|
},
|
|
|
|
onDisconnect: useCallback(() => {
|
|
|
|
setUnauthIsPreventAutoscroll(false);
|
|
|
|
}, []),
|
|
|
|
marker: "ticket",
|
|
|
|
});
|
|
|
|
|
|
|
|
useEffect(() => {
|
2024-03-09 21:01:57 +00:00
|
|
|
cleanAuthTicketData();
|
|
|
|
}, [user]);
|
2024-03-06 11:13:28 +00:00
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
if (isChatOpened) {
|
2024-03-09 21:01:57 +00:00
|
|
|
const newMessages = ticket.messages.filter(
|
|
|
|
({ shown }) => shown?.me !== 1,
|
|
|
|
);
|
2024-03-06 11:13:28 +00:00
|
|
|
|
|
|
|
newMessages.map(async ({ id }) => {
|
|
|
|
await shownMessage(id);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}, [isChatOpened, ticket.messages]);
|
|
|
|
|
|
|
|
const sendMessage = async (messageField: string) => {
|
|
|
|
if (!messageField || ticket.isMessageSending) return false;
|
|
|
|
|
2024-03-09 21:01:57 +00:00
|
|
|
let successful = false;
|
2024-03-06 11:13:28 +00:00
|
|
|
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),
|
2024-03-09 21:01:57 +00:00
|
|
|
});
|
|
|
|
successful = true;
|
2024-03-06 11:13:28 +00:00
|
|
|
setTicketData({
|
|
|
|
ticketId: data.Ticket,
|
|
|
|
sessionId: data.sess,
|
|
|
|
});
|
|
|
|
} catch (error: any) {
|
2024-03-09 21:01:57 +00:00
|
|
|
successful = false;
|
2024-03-06 11:13:28 +00:00
|
|
|
const errorMessage = getMessageFromFetchError(error);
|
|
|
|
if (errorMessage) enqueueSnackbar(errorMessage);
|
|
|
|
}
|
|
|
|
setIsMessageSending(false);
|
|
|
|
} else {
|
|
|
|
const [_, sendTicketMessageError] = await sendTicketMessage(
|
|
|
|
ticket.sessionData?.ticketId,
|
|
|
|
messageField,
|
|
|
|
);
|
2024-03-09 21:01:57 +00:00
|
|
|
successful = true;
|
2024-03-06 11:13:28 +00:00
|
|
|
|
|
|
|
if (sendTicketMessageError) {
|
2024-03-09 21:01:57 +00:00
|
|
|
successful = false;
|
2024-03-06 11:13:28 +00:00
|
|
|
enqueueSnackbar(sendTicketMessageError);
|
|
|
|
}
|
|
|
|
setIsMessageSending(false);
|
|
|
|
}
|
|
|
|
|
2024-03-09 21:01:57 +00:00
|
|
|
return successful;
|
|
|
|
};
|
2024-03-06 11:13:28 +00:00
|
|
|
const sendFile = async (file: File) => {
|
2024-03-09 21:01:57 +00:00
|
|
|
if (file === undefined) return true;
|
|
|
|
|
|
|
|
// const isFileTypeAccepted = ACCEPT_SEND_FILE_TYPES_MAP.some(
|
|
|
|
// fileType => file.name.toLowerCase().endsWith(fileType)
|
|
|
|
// );
|
|
|
|
// if (!isFileTypeAccepted) return setModalWarningType("errorType");
|
|
|
|
let data;
|
2024-03-06 11:13:28 +00:00
|
|
|
if (!ticket.sessionData?.ticketId) {
|
|
|
|
try {
|
|
|
|
data = await createTicket({
|
|
|
|
url: process.env.REACT_APP_DOMAIN + "/heruvym/create",
|
|
|
|
body: {
|
|
|
|
Title: "Unauth title",
|
|
|
|
Message: "",
|
|
|
|
},
|
|
|
|
useToken: Boolean(user),
|
2024-03-09 21:01:57 +00:00
|
|
|
});
|
2024-03-06 11:13:28 +00:00
|
|
|
setTicketData({
|
|
|
|
ticketId: data.Ticket,
|
|
|
|
sessionId: data.sess,
|
|
|
|
});
|
|
|
|
} catch (error: any) {
|
|
|
|
const errorMessage = getMessageFromFetchError(error);
|
|
|
|
if (errorMessage) enqueueSnackbar(errorMessage);
|
|
|
|
}
|
|
|
|
setIsMessageSending(false);
|
|
|
|
}
|
|
|
|
|
2024-03-09 21:01:57 +00:00
|
|
|
const ticketId = ticket.sessionData?.ticketId || data?.Ticket;
|
2024-03-06 11:13:28 +00:00
|
|
|
if (ticketId !== undefined) {
|
2024-03-09 21:01:57 +00:00
|
|
|
if (file.size > MAX_FILE_SIZE) return setModalWarningType("errorSize");
|
2024-03-06 11:13:28 +00:00
|
|
|
try {
|
2024-03-09 21:01:57 +00:00
|
|
|
const body = new FormData();
|
2024-03-06 11:13:28 +00:00
|
|
|
|
2024-03-09 21:01:57 +00:00
|
|
|
body.append(file.name, file);
|
|
|
|
body.append("ticket", ticketId);
|
2024-03-06 11:13:28 +00:00
|
|
|
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);
|
|
|
|
}
|
2024-03-09 21:01:57 +00:00
|
|
|
return true;
|
2024-03-06 11:13:28 +00:00
|
|
|
}
|
2024-03-09 21:01:57 +00:00
|
|
|
};
|
2024-03-06 11:13:28 +00:00
|
|
|
|
2024-03-09 21:01:57 +00:00
|
|
|
return (
|
|
|
|
<FloatingSupportChat
|
|
|
|
isChatOpened={isChatOpened}
|
|
|
|
handleChatClickOpen={handleChatClickOpen}
|
|
|
|
handleChatClickClose={handleChatClickClose}
|
|
|
|
handleChatClickSwitch={handleChatClickSwitch}
|
|
|
|
sendMessage={sendMessage}
|
|
|
|
sendFile={sendFile}
|
|
|
|
modalWarningType={modalWarningType}
|
|
|
|
setModalWarningType={setModalWarningType}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
};
|