UNPKG

@kiwicom/smart-faq

Version:

Smart FAQ

279 lines (262 loc) 7.89 kB
// @flow import * as React from 'react'; import { withRouter } from 'react-router-dom'; import { Heading, Text } from '@kiwicom/orbit-components'; import type { ThemeProps } from '@kiwicom/nitro/lib/records/Theme'; import { createFragmentContainer, graphql } from 'react-relay'; import css from 'styled-jsx/css'; import idx from 'idx'; import Translate from '@kiwicom/nitro/lib/components/Translate'; import { withTheme } from 'styled-components'; import Markdown from '../../../SmartFAQ/common/Markdown'; import GuaranteeChat from './GuaranteeChat'; import FAQArticleFeedback from '../ArticleFeedback/FAQArticleFeedback'; import { LogladyTracker, LogladyTimeTracker, EnterTracker, TimeTracker, } from '../../helpers/analytics/trackers'; import { GuaranteeChatContext } from '../../context/GuaranteeChatInfo'; import { withToken } from '../../../SmartFAQ/context/User'; import { SidebarVersion, FullPageVersion, } from '../../../SmartFAQ/common/PageVariant'; import type { ArticleContent_article } from './__generated__/ArticleContent_article.graphql'; import { BookingState } from '../../../SmartFAQ/context/BookingState'; export const GUARANTEE_ARTICLE_ID = 'RkFRQXJ0aWNsZToyOA=='; export const THRESHOLD = 4; type Props = { loginToken: ?string, simpleToken: ?string, kwAuthToken: ?string, isInGuaranteeArticle: boolean, article: ArticleContent_article, showGuaranteeChat: boolean, ...ThemeProps, }; const ArticleContent = withTheme((props: Props) => ( <> <FullPageVersion> <div style={{ border: `${props.theme.orbit.borderWidthCard} ${ props.theme.orbit.borderStyleCard } ${props.theme.orbit.borderColorCard}`, background: props.theme.orbit.backgroundCard, borderRadius: props.theme.orbit.borderRadiusNormal, paddingTop: '28px', }} > <NakedArticleContent {...props} /> </div> </FullPageVersion> <SidebarVersion> <NakedArticleContent {...props} /> </SidebarVersion> </> )); const NakedArticleContent = withTheme((props: Props) => { const isLoggedIn = props.loginToken || props.simpleToken || props.kwAuthToken; const { article, isInGuaranteeArticle, showGuaranteeChat } = props; const showMessage = isInGuaranteeArticle && !showGuaranteeChat && !isLoggedIn; const globalStyle = css` .guaranteeLoggedOut a { color: ${props.theme.orbit.colorTextLinkPrimaryHover}; text-decoration: none; } .faq-article-text ul { padding-left: 43px; list-style: none; } .faq-article-text ul, .faq-article-text ol { margin-left: 20px; padding-bottom: 20px; margin-bottom: 10px; } .faq-article-text li:before { content: ''; display: inline-block; margin-right: 19px; width: 6px; height: 6px; margin-bottom: 2px; } :global([dir='rtl']) .faq-article-text li:before { margin-right: 0; margin-left: 19px; } .faq-article-text ul li:before { background-color: #d5dee7; } .faq-article-text a { color: ${props.theme.orbit.colorTextLinkPrimaryHover}; text-decoration: none; } .faq-article-text img { width: 100%; height: auto; object-fit: contain; } .faq-article-text li { display: list-item; padding-top: 10px; text-indent: -25px; } .faq-article-text li, .faq-article-text div { font-size: 14px; font-weight: 400; line-height: 22px; } `; return ( <BookingState.Consumer> {({ showBooking }) => ( <div className={ showBooking && isLoggedIn ? 'articleContentLoggedIn' : 'articleContentLoggedOut' } data-cy="faq-article-content" > <Heading type="title2">{article.title || ''}</Heading> <div className="faq-article-perex"> <Text type="attention" weight="bold" element="span"> <Translate t={__('smartfaq.faq.article.summary')} /> </Text> <Text element="span"> {article.perex}</Text> </div> <hr className="faq-article-delimiter" /> <div className="faq-article-text"> <Markdown>{article.content}</Markdown> </div> {showGuaranteeChat && <GuaranteeChat />} {showMessage && ( <div className="guaranteeLoggedOut"> <Translate html t={__('smartfaq.faq.article.guarantee.logged_out')} values={{ guaranteeChatThreshold: THRESHOLD }} /> </div> )} <hr className="faq-article-delimiter" /> <FAQArticleFeedback articleId={article.id} /> <style jsx> {` .articleContentLoggedIn { padding: 16px 72px 40px 80px; } .articleContentLoggedOut { padding: 16px 36px 40px; } .faq-article-perex { padding: 24px 0; line-height: 20px; } .faq-article-delimiter { border: 0; height: 1px; background-color: #e8edf1; margin: 0; } .faq-article-text { padding: 24px 0; } .guaranteeLoggedOut { margin-bottom: 40px; } @media only screen and (max-width: 901px) { .articleContentLoggedIn, .articleContentLoggedOut { padding: 16px; } } `} </style> <style jsx global> {globalStyle} </style> </div> )} </BookingState.Consumer> ); }); export const UnwrappedArticleContent = ArticleContent; const LogladyTrackedDetail = LogladyTracker( withToken(ArticleContent), 'FAQs', 'articleOpened', (props: Props) => ({ articleId: idx(props.article, _ => _.originalId) || '', articleName: idx(props.article, _ => _.title) || '', }), ); const EnterTrackedDetail = EnterTracker( LogladyTrackedDetail, 'smartFAQCategories', (props: Props) => ({ action: 'clickOnArticle', articleId: idx(props.article, _ => _.id) || '', articleName: idx(props.article, _ => _.title) || '', }), ); const LogladyTimeTracked = LogladyTimeTracker( EnterTrackedDetail, 'FAQs', 'articleClosed', (props: Props) => ({ articleId: idx(props.article, _ => _.id) || '', articleName: idx(props.article, _ => _.title) || '', }), ); const TimeTrackedDetail = TimeTracker( LogladyTimeTracked, 'smartFAQCategories', (props: Props) => ({ action: 'articleClose', articleId: idx(props.article, _ => _.id) || '', articleName: idx(props.article, _ => _.title) || '', }), ); type ContainerProps = { match: { params: { articleId: string, categoryId: string, [key: string]: ?string, }, }, }; const WrappedArticle = (props: Props & ContainerProps) => ( <GuaranteeChatContext.Consumer> {({ showGuaranteeChat }) => { // show Guarantee Chat only in Guarantee article const articleId = idx(props.match, _ => _.params.articleId); const isInGuaranteeArticle = articleId === GUARANTEE_ARTICLE_ID; return ( <TimeTrackedDetail showGuaranteeChat={showGuaranteeChat && isInGuaranteeArticle} isInGuaranteeArticle={isInGuaranteeArticle} {...props} /> ); }} </GuaranteeChatContext.Consumer> ); export default createFragmentContainer( withRouter(WrappedArticle), graphql` fragment ArticleContent_article on FAQArticle { id originalId: id(opaque: false) title perex content } `, );