@kiwicom/smart-faq
Version:
295 lines (263 loc) • 7.66 kB
JavaScript
// @flow
import * as React from 'react';
import { graphql } from 'react-relay';
import css from 'styled-jsx/css';
import { Consumer as IntlConsumer } from '@kiwicom/nitro/lib/services/intl/context';
import Button from '@kiwicom/orbit-components/lib/Button';
import Stack from '@kiwicom/orbit-components/lib/Stack';
import type { Match } from 'react-router-dom';
import QueryRenderer from '../../../SmartFAQ/relay/QueryRenderer';
import Loader from '../../../SmartFAQ/common/Loader';
import {
SidebarVersion,
FullPageVersion,
} from '../../../SmartFAQ/common/PageVariant';
import FAQArticleDetailContent from './ArticleContent';
import FAQArticleNotFound from './FAQArticleNotFound';
import type { ArticleDetailQueryResponse } from './__generated__/ArticleDetailQuery.graphql';
import type { ArticleDetailSearchResultQueryResponse } from './__generated__/ArticleDetailSearchResultQuery.graphql';
import CustomBreadcrumbs from '../breadcrumbs/CustomBreadcrumbs';
import sectionFAQCategories from '../sectionFAQCategories';
import StaticFAQError from '../StaticFAQError';
import ScrollableContent from '../../../SmartFAQ/common/ScrollableContent';
import features from '../../../feature-toggles.json';
const queryFAQArticleDetail = graphql`
query ArticleDetailQuery(
$id: Int!
$categoryId: Int!
$isSubcategory: Boolean!
) {
FAQArticle(originalId: $id) {
title
...ArticleContent_article
}
FAQCategory(originalId: $categoryId) @include(if: $isSubcategory) {
title
originalId: id(opaque: false)
ancestors {
originalId: id(opaque: false)
title
}
}
}
`;
const queryFAQArticleDetailSearchResult = graphql`
query ArticleDetailSearchResultQuery($id: Int!) {
FAQArticle(originalId: $id) {
title
...ArticleContent_article
}
}
`;
type ArticleCategoryProps = {
props: ?ArticleDetailQueryResponse,
error: ?Error,
};
type ArticleSearchProps = {
props: ?ArticleDetailSearchResultQueryResponse,
error: ?Error,
};
type Props = {
match: Match,
};
const style = css.global`
.breadcrumbs {
margin: 24px 36px;
margin-bottom: -2px;
}
@media only screen and (max-width: 901px) {
.breadcrumbs {
margin: 0 auto;
background-color: #f5f7f9;
}
}
`;
class Article extends React.Component<Props> {
getQueryRenderer() {
const categoryId = this.getCategoryId();
const articleId = this.getArticleId();
const isSearchResult = categoryId === -1;
if (isSearchResult) {
return (
<QueryRenderer
query={queryFAQArticleDetailSearchResult}
variables={{ id: articleId }}
render={this.renderArticleFromSearch}
/>
);
}
return (
<QueryRenderer
query={queryFAQArticleDetail}
variables={{
id: articleId,
categoryId,
isSubcategory: !this.isSectionCategory(),
}}
render={this.renderArticleFromCategory}
/>
);
}
getCategoryId = (): number => {
const id = this.props.match.params.categoryId;
return id === 'search' ? -1 : Number(id);
};
getArticleId = (): number => {
return Number(this.props.match.params.articleId);
};
isSectionCategory = (): boolean => {
const categoryId = this.getCategoryId();
return !!categoryId && sectionFAQCategories.includes(`${categoryId}`);
};
renderLoading = () => <Loader fullHeight />;
renderError = () => {
return (
<div className="errorWrapper">
<StaticFAQError />
<style jsx>
{`
.errorWrapper {
height: 100%;
padding: 24px 40px;
}
`}
</style>
</div>
);
};
renderArticleFromCategory = (params: ArticleCategoryProps) => {
const { error, props } = params;
if (error) {
return this.renderError();
}
if (props) {
const category = props.FAQCategory;
const article = props.FAQArticle;
let breadcrumbs = null;
if (!article) {
return <FAQArticleNotFound />;
}
if (this.isSectionCategory()) {
breadcrumbs = (
<IntlConsumer>
{intl => (
<CustomBreadcrumbs
breadcrumbs={[
{ title: intl.translate(__('smartfaq.breadcrumb.home')) },
{ title: article.title },
]}
/>
)}
</IntlConsumer>
);
} else if (category) {
breadcrumbs = (
<IntlConsumer>
{intl => (
<CustomBreadcrumbs
breadcrumbs={[
{ title: intl.translate(__('smartfaq.breadcrumb.home')) },
]
.concat(
category.ancestors
? category.ancestors
.filter(Boolean)
.map(el => ({ title: el.title, id: el.originalId }))
: [],
)
.concat({ title: category.title, id: category.originalId })
.concat([
{
title: intl.translate(__('smartfaq.breadcrumb.article')),
},
])}
/>
)}
</IntlConsumer>
);
}
return (
<>
<div>{breadcrumbs}</div>
<FAQArticleDetailContent article={article} />
<SidebarVersion>
<style jsx>{style}</style>
</SidebarVersion>
</>
);
}
return this.renderLoading();
};
renderArticleFromSearch = (params: ArticleSearchProps) => {
if (params.error) {
return this.renderError();
}
if (params.props) {
const article = params.props.FAQArticle;
if (!article) {
return <FAQArticleNotFound />;
}
return (
<>
<IntlConsumer>
{intl => (
<div>
<CustomBreadcrumbs
breadcrumbs={[
{
title: intl.translate(__('smartfaq.breadcrumb.search')),
},
{ title: article.title },
]}
/>
</div>
)}
</IntlConsumer>
<FAQArticleDetailContent article={article} />
<SidebarVersion>
<style jsx global>
{style}
</style>
</SidebarVersion>
</>
);
}
return this.renderLoading();
};
render() {
return (
<>
<FullPageVersion>
{this.getQueryRenderer()}
{features.fullpage_loggedIn && (
<Stack direction="row" flex={false} spacing="loose">
<Button>Sign In</Button>
<p>
Sign In with your booking and we will try to personalise the
help towards your case as much as possible.
</p>
</Stack>
)}
</FullPageVersion>
<SidebarVersion>
<ScrollableContent styles="background-color: #ffffff">
<div className="faq-article-detail">
{this.getQueryRenderer()}
<style jsx>
{`
.faq-article-detail {
background-color: #ffffff;
width: 100%;
max-width: 100vw;
height: 100%;
}
`}
</style>
</div>
</ScrollableContent>
</SidebarVersion>
</>
);
}
}
export default Article;