136 lines
4.7 KiB
JavaScript
136 lines
4.7 KiB
JavaScript
import { ExclamationCircleOutlined, LoadingOutlined, SendOutlined } from "@ant-design/icons";
|
|
import { Alert, Input, Space, Spin, Tooltip } from "antd";
|
|
import { useEffect, useRef, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { connect } from "react-redux";
|
|
import { createStructuredSelector } from "reselect";
|
|
import { logImEXEvent } from "../../firebase/firebase.utils";
|
|
import { sendMessage, setMessage } from "../../redux/messaging/messaging.actions";
|
|
import { selectIsSending, selectMessage } from "../../redux/messaging/messaging.selectors";
|
|
import { selectBodyshop } from "../../redux/user/user.selectors";
|
|
import ChatMediaSelector from "../chat-media-selector/chat-media-selector.component";
|
|
import ChatPresetsComponent from "../chat-presets/chat-presets.component";
|
|
import { useQuery } from "@apollo/client/react";
|
|
import { phone } from "phone";
|
|
import { GET_PHONE_NUMBER_OPT_OUT } from "../../graphql/phone-number-opt-out.queries";
|
|
|
|
const mapStateToProps = createStructuredSelector({
|
|
bodyshop: selectBodyshop,
|
|
isSending: selectIsSending,
|
|
message: selectMessage
|
|
});
|
|
|
|
const mapDispatchToProps = (dispatch) => ({
|
|
sendMessage: (message) => dispatch(sendMessage(message)),
|
|
setMessage: (message) => dispatch(setMessage(message))
|
|
});
|
|
|
|
function ChatSendMessageComponent({ conversation, bodyshop, sendMessage, isSending, message, setMessage }) {
|
|
const inputArea = useRef(null);
|
|
const [selectedMedia, setSelectedMedia] = useState([]);
|
|
const { t } = useTranslation();
|
|
|
|
const normalizedPhone = phone(conversation.phone_num, "CA").phoneNumber.replace(/^\+1/, "");
|
|
const { data: optOutData } = useQuery(GET_PHONE_NUMBER_OPT_OUT, {
|
|
variables: { bodyshopid: bodyshop.id, phone_number: normalizedPhone },
|
|
fetchPolicy: "cache-and-network"
|
|
});
|
|
|
|
const isOptedOut = !!optOutData?.phone_number_opt_out?.[0];
|
|
|
|
useEffect(() => {
|
|
inputArea.current.focus();
|
|
}, [isSending, setMessage]);
|
|
|
|
const handleEnter = () => {
|
|
const selectedImages = selectedMedia.filter((i) => i.isSelected);
|
|
if ((message === "" || !message) && selectedImages.length === 0) return;
|
|
if (isOptedOut) return; // Prevent sending if phone number is opted out
|
|
logImEXEvent("messaging_send_message");
|
|
|
|
if (selectedImages.length < 11) {
|
|
const newMessage = {
|
|
to: conversation.phone_num,
|
|
body: message || "",
|
|
messagingServiceSid: bodyshop.messagingservicesid,
|
|
conversationid: conversation.id,
|
|
selectedMedia: selectedImages,
|
|
imexshopid: bodyshop.imexshopid,
|
|
bodyshopid: bodyshop.id
|
|
};
|
|
sendMessage(newMessage);
|
|
setSelectedMedia(
|
|
selectedMedia.map((i) => {
|
|
return { ...i, isSelected: false };
|
|
})
|
|
);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Space orientation="vertical" style={{ width: "100%" }} size="middle">
|
|
{isOptedOut && (
|
|
<Tooltip title={t("consent.text_body")}>
|
|
<Alert
|
|
showIcon={true}
|
|
icon={<ExclamationCircleOutlined />}
|
|
title={t("messaging.errors.no_consent")}
|
|
type="error"
|
|
/>
|
|
</Tooltip>
|
|
)}
|
|
<div className="imex-flex-row" style={{ width: "100%" }}>
|
|
{!isOptedOut && (
|
|
<>
|
|
<ChatPresetsComponent disabled={isSending} className="imex-flex-row__margin" />
|
|
<ChatMediaSelector
|
|
disabled={isSending}
|
|
conversation={conversation}
|
|
selectedMedia={selectedMedia}
|
|
setSelectedMedia={setSelectedMedia}
|
|
/>
|
|
</>
|
|
)}
|
|
<span style={{ flex: 1 }}>
|
|
<Input.TextArea
|
|
className="imex-flex-row__margin imex-flex-row__grow"
|
|
allowClear
|
|
autoFocus
|
|
ref={inputArea}
|
|
autoSize={{ minRows: 1, maxRows: 4 }}
|
|
value={message}
|
|
disabled={isSending || isOptedOut}
|
|
placeholder={t("messaging.labels.typeamessage")}
|
|
onChange={(e) => setMessage(e.target.value)}
|
|
onPressEnter={(event) => {
|
|
event.preventDefault();
|
|
if (!event.shiftKey && !isOptedOut) handleEnter();
|
|
}}
|
|
/>
|
|
</span>
|
|
{!isOptedOut && (
|
|
<SendOutlined
|
|
className="chat-send-message-button"
|
|
disabled={isSending || message === "" || !message}
|
|
onClick={handleEnter}
|
|
/>
|
|
)}
|
|
|
|
<Spin
|
|
style={{ display: `${isSending ? "" : "none"}` }}
|
|
indicator={
|
|
<LoadingOutlined
|
|
style={{
|
|
fontSize: 24
|
|
}}
|
|
spin
|
|
/>
|
|
}
|
|
/>
|
|
</div>
|
|
</Space>
|
|
);
|
|
}
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(ChatSendMessageComponent);
|