@kiwicom/smart-faq
Version: 
152 lines (128 loc) • 3.74 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 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> {
  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;
    this.setState({ isChatReady: true });
    if (window.webchat.isAutoJoined()) {
      this.props.toggleIsChatActive(true);
      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);
    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}
          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;