Implemented ticket closure, message clearing, and addition of welcome message

This commit is contained in:
aleksandr-raw 2024-04-24 17:51:03 +04:00
parent c8882ef5bd
commit a29758a413

@ -21,8 +21,15 @@ import {
useTicketsFetcher, useTicketsFetcher,
} from "@frontend/kitui"; } from "@frontend/kitui";
import {enqueueSnackbar} from "notistack"; import {enqueueSnackbar} from "notistack";
import type {TouchEvent, WheelEvent} from "react"; import {
import {useCallback, useEffect, useMemo, useRef, useState} from "react"; TouchEvent,
useCallback,
useEffect,
useMemo,
useRef,
useState,
WheelEvent
} from "react";
import ChatMessage from "../ChatMessage"; import ChatMessage from "../ChatMessage";
import SendIcon from "../icons/SendIcon"; import SendIcon from "../icons/SendIcon";
import ArrowLeft from "@root/assets/Icons/arrowLeft"; import ArrowLeft from "@root/assets/Icons/arrowLeft";
@ -36,6 +43,7 @@ import {
} from "@utils/checkAcceptableMediaType"; } from "@utils/checkAcceptableMediaType";
import { import {
addOrUpdateUnauthMessages, addOrUpdateUnauthMessages,
clearTickets,
incrementUnauthMessage, incrementUnauthMessage,
setIsMessageSending, setIsMessageSending,
setTicketData, setTicketData,
@ -49,11 +57,6 @@ import ChatDocument from "./ChatDocument";
import ChatImage from "./ChatImage"; import ChatImage from "./ChatImage";
import ChatVideo from "./ChatVideo"; import ChatVideo from "./ChatVideo";
const workingHoursMessage =
"Здравствуйте, задайте ваш вопрос и наш оператор вам ответит в течение 10 минут";
const offHoursMessage =
"Здравствуйте, к сожалению, сейчас операторы не работают. Задайте ваш вопрос, и вам ответят в 10:00 по московскому времени";
type ModalWarningType = type ModalWarningType =
| "errorType" | "errorType"
| "errorSize" | "errorSize"
@ -74,6 +77,7 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) {
const isMobile = useMediaQuery(theme.breakpoints.down(800)); const isMobile = useMediaQuery(theme.breakpoints.down(800));
const [messageField, setMessageField] = useState<string>(""); const [messageField, setMessageField] = useState<string>("");
const [disableFileButton, setDisableFileButton] = useState(false); const [disableFileButton, setDisableFileButton] = useState(false);
const [sseEnabled, setSseEnabled] = useState(true);
const [modalWarningType, setModalWarningType] = const [modalWarningType, setModalWarningType] =
useState<ModalWarningType>(null); useState<ModalWarningType>(null);
const chatBoxRef = useRef<HTMLDivElement>(null); const chatBoxRef = useRef<HTMLDivElement>(null);
@ -92,12 +96,39 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) {
unauthTicketMessageFetchState: fetchState, unauthTicketMessageFetchState: fetchState,
apiPage: messageApiPage, apiPage: messageApiPage,
} = ticket; } = ticket;
const { isActiveSSETab, updateSSEValue } = useSSETab<TicketMessage[]>( const { isActiveSSETab, updateSSEValue } = useSSETab<TicketMessage[]>(
"ticket", "ticket",
addOrUpdateUnauthMessages addOrUpdateUnauthMessages
); );
const getGreetingMessage: TicketMessage = useMemo(() => {
const workingHoursMessage =
"Здравствуйте, задайте ваш вопрос и наш оператор вам ответит в течение 10 минут";
const offHoursMessage =
"Здравствуйте, к сожалению, сейчас операторы не работают. Задайте ваш вопрос, и вам ответят в 10:00 по московскому времени";
const date = new Date();
const currentHourUTC = date.getUTCHours();
const MscTime = 3; // Москва UTC+3;
const moscowHour = (currentHourUTC + MscTime) % 24;
const greetingMessage =
moscowHour >= 10 && moscowHour < 15
? workingHoursMessage
: offHoursMessage;
return ( {
created_at: new Date().toISOString(),
files: [],
id: "111",
message: greetingMessage,
request_screenshot: "",
session_id: "greetingMessage",
shown: { me: 1 },
ticket_id: "111",
user_id: "greetingMessage",
});
}, [open]);
useTicketMessages({ useTicketMessages({
url: process.env.REACT_APP_DOMAIN + "/heruvym/getMessages", url: process.env.REACT_APP_DOMAIN + "/heruvym/getMessages",
isUnauth: true, isUnauth: true,
@ -117,19 +148,29 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) {
}, []), }, []),
onFetchStateChange: setUnauthTicketMessageFetchState, onFetchStateChange: setUnauthTicketMessageFetchState,
}); });
useSSESubscription<TicketMessage>({ useSSESubscription<TicketMessage>({
enabled: isActiveSSETab && Boolean(sessionData), enabled: sseEnabled && isActiveSSETab && Boolean(sessionData),
url: url:
process.env.REACT_APP_DOMAIN + process.env.REACT_APP_DOMAIN +
`/heruvym/ticket?ticket=${sessionData?.ticketId}&s=${sessionData?.sessionId}`, `/heruvym/ticket?ticket=${sessionData?.ticketId}&s=${sessionData?.sessionId}`,
onNewData: (ticketMessages) => { onNewData: (ticketMessages) => {
const isTicketClosed = ticketMessages.some(
(message) => message.session_id === "close"
);
if(isTicketClosed){
clearTickets();
addOrUpdateUnauthMessages([getGreetingMessage]);
if (!user) {
localStorage.removeItem("unauth-ticket");
}
return;
}
updateSSEValue(ticketMessages); updateSSEValue(ticketMessages);
addOrUpdateUnauthMessages(ticketMessages); addOrUpdateUnauthMessages(ticketMessages);
}, },
onDisconnect: useCallback(() => { onDisconnect: useCallback(() => {
setUnauthIsPreventAutoscroll(false); setUnauthIsPreventAutoscroll(false);
setSseEnabled(false);
}, []), }, []),
marker: "ticket", marker: "ticket",
}); });
@ -141,7 +182,7 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) {
onSuccess: (result) => { onSuccess: (result) => {
if (result.data?.length) { if (result.data?.length) {
const currentTicket = result.data.find( const currentTicket = result.data.find(
({ origin }) => !origin.includes("/support") ({ origin, state }) => !origin.includes("/support") && state !== "close"
); );
if (!currentTicket) { if (!currentTicket) {
@ -183,34 +224,11 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) {
); );
useEffect(() => { useEffect(() => {
const date = new Date(); addOrUpdateUnauthMessages([getGreetingMessage]);
const currentHourUTC = date.getUTCHours();
const MscTime = 3; // Москва UTC+3;
const moscowHour = (currentHourUTC + MscTime) % 24;
const greetingMessage =
moscowHour >= 10 && moscowHour < 15
? workingHoursMessage
: offHoursMessage;
const greetingMessageObj = {
created_at: new Date().toISOString(),
files: [],
id: "111ck2tepkvc9g6irk3fugg",
message: greetingMessage,
request_screenshot: "",
session_id: "111",
shown: { me: 1 },
ticket_id: "111",
user_id: "111",
};
addOrUpdateUnauthMessages([greetingMessageObj]);
if (open) {
scrollToBottom(); scrollToBottom();
}
}, [open]); }, [open]);
useEffect( useEffect(
function scrollOnNewMessage() { function scrollOnNewMessage() {
if (!chatBoxRef.current) return; if (!chatBoxRef.current) return;
@ -260,6 +278,7 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) {
ticketId: response.Ticket, ticketId: response.Ticket,
sessionId: response.sess, sessionId: response.sess,
}); });
setSseEnabled(true);
}) })
.catch((error) => { .catch((error) => {
const errorMessage = getMessageFromFetchError(error); const errorMessage = getMessageFromFetchError(error);
@ -527,6 +546,9 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) {
/> />
); );
})} })}
{!ticket.sessionData?.ticketId && (
<ChatMessage unAuthenticated text={getGreetingMessage.message} createdAt={getGreetingMessage.created_at} isSelf={false} />)
}
</Box> </Box>
<FormControl fullWidth sx={{ borderTop: "1px solid black" }}> <FormControl fullWidth sx={{ borderTop: "1px solid black" }}>
<InputBase <InputBase