Files
bodyshop/client/src/components/chat-popup/chat-popup.component.jsx
Dave Richer 3690ea0332 - Merge client update into test-beta
Signed-off-by: Dave Richer <dave@imexsystems.ca>
2024-01-18 19:20:08 -05:00

134 lines
5.4 KiB
JavaScript

import {InfoCircleOutlined, MessageOutlined, ShrinkOutlined, SyncOutlined,} from "@ant-design/icons";
import {useLazyQuery, useQuery} from "@apollo/client";
import {Badge, Card, Col, Row, Space, Tag, Tooltip, Typography} from "antd";
import React, {useCallback, useEffect, useState} from "react";
import {useTranslation} from "react-i18next";
import {connect} from "react-redux";
import {createStructuredSelector} from "reselect";
import {CONVERSATION_LIST_QUERY, UNREAD_CONVERSATION_COUNT,} from "../../graphql/conversations.queries";
import {toggleChatVisible} from "../../redux/messaging/messaging.actions";
import {selectChatVisible, selectSelectedConversation,} from "../../redux/messaging/messaging.selectors";
import ChatConversationListComponent from "../chat-conversation-list/chat-conversation-list.component";
import ChatConversationContainer from "../chat-conversation/chat-conversation.container";
import ChatNewConversation from "../chat-new-conversation/chat-new-conversation.component";
import LoadingSpinner from "../loading-spinner/loading-spinner.component";
import "./chat-popup.styles.scss";
const mapStateToProps = createStructuredSelector({
selectedConversation: selectSelectedConversation,
chatVisible: selectChatVisible,
});
const mapDispatchToProps = (dispatch) => ({
toggleChatVisible: () => dispatch(toggleChatVisible()),
});
export function ChatPopupComponent({
chatVisible,
selectedConversation,
toggleChatVisible,
}) {
const {t} = useTranslation();
const [pollInterval, setpollInterval] = useState(0);
const {data: unreadData} = useQuery(UNREAD_CONVERSATION_COUNT, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
...(pollInterval > 0 ? {pollInterval} : {}),
});
const [getConversations, {loading, data, refetch, fetchMore}] =
useLazyQuery(CONVERSATION_LIST_QUERY, {
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
skip: !chatVisible,
...(pollInterval > 0 ? {pollInterval} : {}),
});
const fcmToken = sessionStorage.getItem("fcmtoken");
useEffect(() => {
if (fcmToken) {
setpollInterval(0);
} else {
setpollInterval(60000);
}
}, [fcmToken]);
useEffect(() => {
if (chatVisible)
getConversations({
variables: {
offset: 0,
},
});
}, [chatVisible, getConversations]);
const loadMoreConversations = useCallback(() => {
if (data)
fetchMore({
variables: {
offset: data.conversations.length,
},
});
}, [data, fetchMore]);
const unreadCount = unreadData?.messages_aggregate.aggregate.count || 0;
return (
<Badge count={unreadCount}>
<Card size="small">
{chatVisible ? (
<div className="chat-popup">
<Space align="center">
<Typography.Title level={4}>
{t("messaging.labels.messaging")}
</Typography.Title>
<ChatNewConversation/>
<Tooltip title={t("messaging.labels.recentonly")}>
<InfoCircleOutlined/>
</Tooltip>
<SyncOutlined
style={{cursor: "pointer"}}
onClick={() => refetch()}
/>
{pollInterval > 0 && (
<Tag color="yellow">{t("messaging.labels.nopush")}</Tag>
)}
</Space>
<ShrinkOutlined
onClick={() => toggleChatVisible()}
style={{position: "absolute", right: ".5rem", top: ".5rem"}}
/>
<Row gutter={[8, 8]} className="chat-popup-content">
<Col span={8}>
{loading ? (
<LoadingSpinner/>
) : (
<ChatConversationListComponent
conversationList={data ? data.conversations : []}
loadMoreConversations={loadMoreConversations}
/>
)}
</Col>
<Col span={16}>
{selectedConversation ? <ChatConversationContainer/> : null}
</Col>
</Row>
</div>
) : (
<div
onClick={() => toggleChatVisible()}
style={{cursor: "pointer"}}
>
<MessageOutlined className="chat-popup-info-icon"/>
<strong>{t("messaging.labels.messaging")}</strong>
</div>
)}
</Card>
</Badge>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(ChatPopupComponent);