@kiwicom/smart-faq
Version:
Smart FAQ
162 lines (139 loc) • 4.15 kB
JavaScript
// @flow
import * as React from 'react';
import classNames from 'classnames';
import { Prompt } from 'react-router-dom';
import { Consumer as IntlConsumer } from '@kiwicom/nitro/lib/services/intl/context';
import * as chatUtils from './utils';
import { simpleTracker } from '../helpers/analytics/trackers';
import type {
ChatConfig,
GuaranteeChatBookingInfo,
} from '../context/GuaranteeChatInfo';
import { GuaranteeChatContext } from '../context/GuaranteeChatInfo';
import { track } from '../cuckoo/tracker';
export type RenderButtonProps = {|
isChatReady: boolean,
onClickDisplayChat: () => void,
|};
type ContainerProps = {|
withPrompt?: boolean,
eventSource: 'smartFAQ' | 'contactForm',
elementId: string,
children: (props: RenderButtonProps) => React.Node,
|};
type Props = {|
...ContainerProps,
guaranteeChatBookingInfo: ?GuaranteeChatBookingInfo,
chatConfig: ChatConfig,
isChatActive: boolean,
toggleIsChatActive: (isChatActive: boolean) => void,
|};
type State = {|
showButton: boolean,
isChatReady: boolean,
|};
class GuaranteeChatWrapper extends React.Component<Props, State> {
chatContainer: ?Element;
state = {
showButton: true,
isChatReady: false,
};
async componentDidMount() {
if (typeof window !== 'object') {
return;
}
const { chatConfig, elementId } = this.props;
await chatUtils.initialize(chatConfig, elementId);
window.webchat.chatEnded = this.onChatEnded;
// eslint-disable-next-line react/no-did-mount-set-state
this.setState({ isChatReady: true });
if (window.webchat.isAutoJoined()) {
this.props.toggleIsChatActive(true);
// eslint-disable-next-line react/no-did-mount-set-state
this.setState({ showButton: false });
}
}
componentWillUnmount() {
this.props.toggleIsChatActive(false);
}
onClickDisplayChat = () => {
this.setState({ showButton: false });
if (!window.webchat) {
throw new Error('Unexpected: webchat not initialized.');
}
const { guaranteeChatBookingInfo } = this.props;
chatUtils.setData(window.webchat, guaranteeChatBookingInfo);
simpleTracker('smartFAQBookingOverview', {
action: 'chatOpened',
where: this.props.eventSource,
});
track('GuaranteeChat', 'chatOpened', { where: this.props.eventSource });
window.webchat.renderFrame({ containerEl: this.props.elementId });
this.props.toggleIsChatActive(true);
};
onChatEnded = () => {
this.props.toggleIsChatActive(false);
};
render() {
const { showButton, isChatReady } = this.state;
const { isChatActive } = this.props;
return (
<>
{showButton &&
this.props.children({
isChatReady,
onClickDisplayChat: this.onClickDisplayChat,
})}
<div
id={this.props.elementId}
ref={c => {
this.chatContainer = c;
}}
className={classNames('guaranteeChat', {
open: !showButton,
})}
data-cy="guaranteeChatIFrame"
/>
{this.props.withPrompt && (
<IntlConsumer>
{intl => (
<Prompt
when={isChatActive}
message={intl.translate(
__('smartfaq.guarantee_chat.confirmation'),
)}
/>
)}
</IntlConsumer>
)}
<style jsx>
{`
.guaranteeChat.open {
height: 500px;
}
`}
</style>
</>
);
}
}
export const GuaranteeChatWrapperRaw = GuaranteeChatWrapper;
const WrappedGuaranteeChat = (props: ContainerProps) => (
<GuaranteeChatContext.Consumer>
{({
guaranteeChatBookingInfo,
chatConfig,
isChatActive,
toggleIsChatActive,
}) => (
<GuaranteeChatWrapper
{...props}
guaranteeChatBookingInfo={guaranteeChatBookingInfo}
chatConfig={chatConfig}
isChatActive={isChatActive}
toggleIsChatActive={toggleIsChatActive}
/>
)}
</GuaranteeChatContext.Consumer>
);
export default WrappedGuaranteeChat;