@kiwicom/smart-faq
Version:
235 lines (221 loc) • 6.79 kB
JavaScript
// @flow
import * as React from 'react';
import Head from 'next/head';
import { withRouter } from 'react-router-dom';
import Text from '@kiwicom/orbit-components/lib/Text';
import Heading from '@kiwicom/orbit-components/lib/Heading';
import Separator from '@kiwicom/orbit-components/lib/Separator';
import type { ThemeProps } from '@kiwicom/nitro/lib/records/Theme';
import { createFragmentContainer, graphql } from 'react-relay';
import Translate from '@kiwicom/nitro/lib/components/Translate';
import { withTheme } from 'styled-components';
import type { ContextRouter } from 'react-router-dom';
import FAQContentRender from '../../../SmartFAQ/common/FAQContentRender';
import GuaranteeChat from './GuaranteeChat';
import FAQArticleFeedback from '../ArticleFeedback/FAQArticleFeedback';
import { GuaranteeChatContext } from '../../context/GuaranteeChatInfo';
import {
SidebarVersion,
FullPageVersion,
} from '../../../SmartFAQ/common/PageVariant';
import type { ArticleContent_article as ArticleContentType } from './__generated__/ArticleContent_article.graphql';
import { BookingState } from '../../../SmartFAQ/context/BookingState';
import { isWebView } from '../../../SmartFAQ/helpers/UrlHelpers';
import LogLifecycle from '../../cuckoo/components/LogLifecycle';
export const GUARANTEE_ARTICLE_ID = 'RkFRQXJ0aWNsZToyOA==';
export const THRESHOLD = 4;
type ContainerProps = {|
...ContextRouter,
article: ArticleContentType,
|};
type Props = {|
...ContainerProps,
...ThemeProps,
loginToken: ?string,
simpleToken: ?string,
kwAuthToken: ?string,
isInGuaranteeArticle: boolean,
showGuaranteeChat: boolean,
|};
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 && !isWebView;
const { showBooking } = React.useContext(BookingState);
const globalStyle = `
.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 (
<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>
<Separator />
{article.content && (
<div className="faq-article-text">
<FAQContentRender>{article.content}</FAQContentRender>
</div>
)}
{showGuaranteeChat && <GuaranteeChat />}
{showMessage && (
<div className="guaranteeLoggedOut">
<Translate
html
t="smartfaq.faq.article.guarantee.logged_out"
values={{ guaranteeChatThreshold: THRESHOLD }}
/>
</div>
)}
<Separator spaceAfter="medium" />
<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-text {
padding: 24px 0;
}
.guaranteeLoggedOut {
margin-bottom: 40px;
}
@media only screen and (max-width: 901px) {
.articleContentLoggedIn,
.articleContentLoggedOut {
padding: 16px;
}
}
`}
</style>
<style dangerouslySetInnerHTML={{ __html: globalStyle }} />
</div>
);
});
export const UnwrappedArticleContent = ArticleContent;
const WrappedArticle = (props: ContainerProps) => {
const { showGuaranteeChat } = React.useContext(GuaranteeChatContext);
// show Guarantee Chat only in Guarantee article
const articleId = props.match.params.articleId;
const isInGuaranteeArticle = articleId === GUARANTEE_ARTICLE_ID;
return (
<>
<Head>
<title>{`${props.article.title || ''}`} - Kiwi.com - Helpcenter</title>
</Head>
<ArticleContent
{...props}
showGuaranteeChat={showGuaranteeChat && isInGuaranteeArticle}
isInGuaranteeArticle={isInGuaranteeArticle}
/>
<LogLifecycle
subCategory="FAQs"
actionMount="articleOpened"
actionUnmount="articleClosed"
props={{
articleId: articleId || '',
articleName: props.article.title || '',
}}
/>
</>
);
};
export default createFragmentContainer(
withRouter(WrappedArticle),
graphql`
fragment ArticleContent_article on FAQArticle {
id
originalId: id(opaque: false)
title
perex
content
}
`,
);