UNPKG

@kiwicom/smart-faq

Version:

Smart FAQ

156 lines (133 loc) 4.12 kB
// @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 { GuaranteeChatInfoState } 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, onToggleIsClosable: boolean => void, }; type State = {| showButton: boolean, isClosable: boolean, isChatReady: boolean, |}; class GuaranteeChatWrapper extends React.Component<Props, State> { chatContainer: ?Element; state = { showButton: true, isClosable: 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.onChangeIsClosable(false); // eslint-disable-next-line react/no-did-mount-set-state this.setState({ showButton: false }); } } onChangeIsClosable = (isClosable: boolean) => { this.setState({ isClosable }); this.props.onToggleIsClosable(isClosable); }; 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('Guarantee Chat', 'chatOpened', { where: this.props.eventSource }); window.webchat.renderFrame({ containerEl: this.props.elementId }); this.onChangeIsClosable(false); }; onChatEnded = () => { this.onChangeIsClosable(true); }; render() { const { showButton, isChatReady, isClosable } = this.state; return ( <React.Fragment> {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={!isClosable} message={intl.translate( __('smartfaq.guarantee_chat.confirmation'), )} /> )} </IntlConsumer> )} <style jsx> {` .guaranteeChat.open { height: 500px; } `} </style> </React.Fragment> ); } } export const GuaranteeChatWrapperRaw = GuaranteeChatWrapper; const WrappedGuaranteeChat = (props: ContainerProps) => ( <GuaranteeChatInfoState.Consumer> {({ guaranteeChatBookingInfo, chatConfig, onToggleIsClosable }) => ( <GuaranteeChatWrapper {...props} guaranteeChatBookingInfo={guaranteeChatBookingInfo} chatConfig={chatConfig} onToggleIsClosable={onToggleIsClosable} /> )} </GuaranteeChatInfoState.Consumer> ); export default WrappedGuaranteeChat;