Implemented ticket closure, message clearing, and addition of welcome message
This commit is contained in:
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
|
||||||
|
Loading…
Reference in New Issue
Block a user