Skip to content

Feature contentful - gig work updates #4886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Sep 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ workflows:
filters:
branches:
only:
- develop
- feature-contentful
# Production builds are exectuted
# when PR is merged to the master
# Don't change anything in this configuration
Expand Down
23 changes: 22 additions & 1 deletion src/shared/components/Contentful/Article/Article.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import LoadingIndicator from 'components/LoadingIndicator';
import YouTubeVideo from 'components/YouTubeVideo';
import moment from 'moment';
import localStorage from 'localStorage';
import { config, Link, isomorphy } from 'topcoder-react-utils';
import { Helmet } from 'react-helmet';
import {
config, Link, isomorphy,
} from 'topcoder-react-utils';
import qs from 'qs';
// SVGs and assets
import GestureIcon from 'assets/images/icon-gesture.svg';
Expand Down Expand Up @@ -110,9 +113,27 @@ export default class Article extends React.Component {
if (isomorphy.isClientSide()) {
shareUrl = encodeURIComponent(window.location.href);
}
const description = htmlToText.fromString(
ReactDOMServer.renderToString(markdown(fields.content)),
{
ignoreHref: true,
ignoreImage: true,
singleNewLineParagraphs: true,
uppercaseHeadings: false,
},
).substring(0, CONTENT_PREVIEW_LENGTH);

return (
<React.Fragment>
<Helmet>
<title>{fields.title}</title>
<meta name="title" property="og:title" content={fields.title} />
<meta name="description" property="og:description" content={description} />
<meta name="description" property="description" content={description} />
<meta name="twitter:description" content={description} />
<meta name="image" property="og:image" content={fields.featuredImage ? `https:${subData.assets.items[fields.featuredImage.sys.id].fields.file.url}` : null} />
<meta name="twitter:image" content={fields.featuredImage ? `https:${subData.assets.items[fields.featuredImage.sys.id].fields.file.url}` : null} />
</Helmet>
{/* Banner */}
{
fields.featuredImage ? (
Expand Down
48 changes: 43 additions & 5 deletions src/shared/components/Contentful/SearchBar/SearchBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export class SearchBarInner extends Component {
this.getSuggestionList = this.getSuggestionList.bind(this);
this.handleSearchChange = this.handleSearchChange.bind(this);
this.handleClickOutside = this.handleClickOutside.bind(this);
this.onKeyDown = this.onKeyDown.bind(this);
// using debounce to avoid processing or requesting too much
this.updateSuggestionListWithNewSearch = _.debounce(
this.updateSuggestionListWithNewSearch.bind(this), 400,
Expand All @@ -71,6 +72,29 @@ export class SearchBarInner extends Component {
document.removeEventListener('mousedown', this.handleClickOutside);
}

onKeyDown(e) {
const { inputlVal, selectedFilter } = this.state;
if (inputlVal && e.which === 13) {
const searchQuery = {};
if (this.searchFieldRef && this.searchFieldRef.value) {
if (selectedFilter.name === 'Tags') {
searchQuery.tags = [this.searchFieldRef.value];
}
if (selectedFilter.name === 'All') {
searchQuery.phrase = this.searchFieldRef.value;
}
if (selectedFilter.name === 'Title') {
searchQuery.title = this.searchFieldRef.value;
}
}
if (selectedFilter.name !== 'Author') {
window.location.href = `${config.TC_EDU_BASE_PATH}${config.TC_EDU_SEARCH_PATH}?${qs.stringify(searchQuery)}`;
} else {
window.location.href = `${config.TC_EDU_BASE_PATH}${config.TC_EDU_SEARCH_PATH}?author=${inputlVal}`;
}
}
}

/**
* Set the search field ref
*/
Expand Down Expand Up @@ -136,6 +160,7 @@ export class SearchBarInner extends Component {
isShowSuggestion,
suggestionList,
selectedFilter,
noResults,
} = this.state;

const searchQuery = {};
Expand All @@ -151,7 +176,8 @@ export class SearchBarInner extends Component {
}
}

return (suggestionList && !_.isEmpty(suggestionList) && isShowSuggestion && (
// eslint-disable-next-line no-nested-ternary
return suggestionList && !_.isEmpty(suggestionList) && isShowSuggestion ? (
<div
className={theme['popup-search-result']}
ref={this.setPopupSearchResultRef}
Expand Down Expand Up @@ -319,7 +345,14 @@ export class SearchBarInner extends Component {
) : null
}
</div>
));
) : noResults ? (
<div
className={theme['popup-search-result']}
ref={this.setPopupSearchResultRef}
>
<span>No Results</span>
</div>
) : null;
}

handleClickOutside(e) {
Expand Down Expand Up @@ -379,23 +412,26 @@ export class SearchBarInner extends Component {
.then((results) => {
// Nothing found?
if (!results.total) {
this.setState({ suggestionList: {} });
this.setState({
suggestionList: {},
noResults: true,
});
return;
}
// Author query?
if (selectedFilter.name === 'Author') {
const suggestionList = {
Author: _.map(results.items, item => ({ ...item.fields })),
};
this.setState({ suggestionList });
this.setState({ suggestionList, noResults: false });
return;
}
// ALL && Tags
const suggestionList = this.groupResults(results);
this.setState({ suggestionList });
});
} else {
this.setState({ suggestionList: {} });
this.setState({ suggestionList: {}, noResults: false });
}
}

Expand All @@ -419,6 +455,7 @@ export class SearchBarInner extends Component {
contentAuthor: contentAuthor.fields,
externalArticle: fields.externalArticle,
contentUrl: fields.contentUrl,
slug: fields.slug,
};
}),
'type',
Expand Down Expand Up @@ -471,6 +508,7 @@ export class SearchBarInner extends Component {
document.addEventListener('mousedown', this.handleClickOutside);
}}
onChange={this.handleSearchChange}
onKeyDown={this.onKeyDown}
/>
<div className={theme.dropdown}>
<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ $link-color: #0d61bf;
overflow-y: auto;
box-shadow: 0 25px 50px 0 rgba(0, 0, 0, 0.15);
z-index: 999;

> span {
margin-left: 15px;
}
}

.icon-search {
Expand Down
8 changes: 8 additions & 0 deletions src/shared/containers/EDU/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
import React from 'react';
import { config } from 'topcoder-react-utils';
import { Helmet } from 'react-helmet';
import Viewport from 'components/Contentful/Viewport';
import SearchBar from 'components/Contentful/SearchBar/SearchBar';
import { getService } from 'services/contentful';
Expand Down Expand Up @@ -45,6 +46,13 @@ export default class EDUHome extends React.Component {
const { taxonomy } = this.state;
return (
<div className={homeTheme.container}>
<Helmet>
<title>THRIVE - Grow with us. Tutorials and workshops that matter.</title>
<meta name="title" property="og:title" content="THRIVE - Grow with us. Tutorials and workshops that matter." />
<meta name="description" property="og:description" content="THRIVE - Grow with us. Tutorials and workshops that matter." />
<meta name="description" property="description" content="THRIVE - Grow with us. Tutorials and workshops that matter." />
<meta name="twitter:description" content="THRIVE - Grow with us. Tutorials and workshops that matter." />
</Helmet>
{/* Banner */}
<div className={homeTheme.bannerContainer}>
<div className={homeTheme.bannerImage} />
Expand Down
8 changes: 8 additions & 0 deletions src/shared/containers/EDU/Search.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { updateQuery } from 'utils/url';
import qs from 'qs';
import LoadingIndicator from 'components/LoadingIndicator';
import SearchPageFilter from 'components/Contentful/SearchPageFilter/SearchPageFilter';
import { Helmet } from 'react-helmet';
// Partials
import ResultTabs from './partials/ResultTabs';
// CSS
Expand Down Expand Up @@ -91,6 +92,13 @@ export default class EDUSearch extends React.Component {
if (!taxonomy) return <LoadingIndicator />;
return (
<div className={searchTheme.container}>
<Helmet>
<title>THRIVE - Search {`${query.title}`}</title>
<meta name="title" property="og:title" content="THRIVE - Grow with us. Tutorials and workshops that matter." />
<meta name="description" property="og:description" content="THRIVE - Grow with us. Tutorials and workshops that matter." />
<meta name="description" property="description" content="THRIVE - Grow with us. Tutorials and workshops that matter." />
<meta name="twitter:description" content="THRIVE - Grow with us. Tutorials and workshops that matter." />
</Helmet>
{/* Banner */}
<div className={searchTheme.bannerContainer}>
<div className={searchTheme.searchBarWrapp}>
Expand Down
8 changes: 8 additions & 0 deletions src/shared/containers/EDU/Tracks.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import qs from 'qs';
import TracksTree from 'components/Contentful/TracksTree/TracksTree';
import LoadingIndicator from 'components/LoadingIndicator';
import TracksFilter from 'components/Contentful/TracksFilter/TracksFilter';
import { Helmet } from 'react-helmet';
// SVGs & Assets
import Dev from 'assets/images/img-development.png';
import Design from 'assets/images/img_design.png';
Expand Down Expand Up @@ -167,6 +168,13 @@ export default class EDUTracks extends React.Component {
if (!taxonomy) return <LoadingIndicator />;
return (
<div className={tracksTheme.container}>
<Helmet>
<title>THRIVE - {`${query.track}`}</title>
<meta name="title" property="og:title" content="THRIVE - Grow with us. Tutorials and workshops that matter." />
<meta name="description" property="og:description" content="THRIVE - Grow with us. Tutorials and workshops that matter." />
<meta name="description" property="description" content="THRIVE - Grow with us. Tutorials and workshops that matter." />
<meta name="twitter:description" content="THRIVE - Grow with us. Tutorials and workshops that matter." />
</Helmet>
{/* Banner */}
<div
className={tracksTheme.bannerContainer}
Expand Down
6 changes: 3 additions & 3 deletions src/shared/containers/EDU/partials/ResultTabs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export default class ResultTabs extends React.Component {
]}
/>
))
) : (<h3>Nothing Found</h3>)
) : (<h3>No results found</h3>)
}
{
articles.total > articles.items.length ? (
Expand Down Expand Up @@ -193,7 +193,7 @@ export default class ResultTabs extends React.Component {
))
}
</div>
) : (<h3>Nothing Found</h3>)
) : (<h3>No results found</h3>)
}
{
videos.total > videos.items.length ? (
Expand Down Expand Up @@ -225,7 +225,7 @@ export default class ResultTabs extends React.Component {
/>
);
})
) : (<h3>Nothing Found</h3>)
) : (<h3>No results found</h3>)
}
{
posts.total > posts.items.length ? (
Expand Down
4 changes: 2 additions & 2 deletions src/shared/services/contentful.js
Original file line number Diff line number Diff line change
Expand Up @@ -346,8 +346,8 @@ class Service {
query.query = tags.join(' ');
}
}
if (startDate) query['sys.createdAt[gte]'] = startDate;
if (endDate) query['sys.createdAt[lte]'] = endDate;
if (startDate) query['fields.creationDate[gte]'] = startDate;
if (endDate) query['fields.creationDate[lte]'] = endDate;
if (phrase) query.query = phrase;
if (title) query['fields.title[match]'] = title;
const content = {};
Expand Down