diff --git a/__tests__/shared/components/Contentful/SearchBar/__snapshots__/SearchBar.jsx.snap b/__tests__/shared/components/Contentful/SearchBar/__snapshots__/SearchBar.jsx.snap index c27a0e21fd..1772d9ce45 100644 --- a/__tests__/shared/components/Contentful/SearchBar/__snapshots__/SearchBar.jsx.snap +++ b/__tests__/shared/components/Contentful/SearchBar/__snapshots__/SearchBar.jsx.snap @@ -13,7 +13,7 @@ exports[`Matches shallow shapshot 1`] = ` onBlur={[Function]} onChange={[Function]} onFocus={[Function]} - placeholder="Search.." + placeholder="Search..." type="text" value="" /> diff --git a/__tests__/shared/components/Settings/Preferences/__snapshots__/index.jsx.snap b/__tests__/shared/components/Settings/Preferences/__snapshots__/index.jsx.snap index 286844d3c8..c4e74aa901 100644 --- a/__tests__/shared/components/Settings/Preferences/__snapshots__/index.jsx.snap +++ b/__tests__/shared/components/Settings/Preferences/__snapshots__/index.jsx.snap @@ -23,22 +23,10 @@ exports[`renders preferences setting page correctly 1`] = ` width="30" xmlns="http://www.w3.org/2000/svg" />, - "invitation letter": , "payment": , - "referrals": , } } names={ @@ -46,8 +34,6 @@ exports[`renders preferences setting page correctly 1`] = ` "e-mail", "forum", "payment", - "invitation letter", - "referrals", ] } toggle={[Function]} diff --git a/__tests__/shared/components/__snapshots__/TopcoderFooter.jsx.snap b/__tests__/shared/components/__snapshots__/TopcoderFooter.jsx.snap index 4f93109c1e..6b3d2bb144 100644 --- a/__tests__/shared/components/__snapshots__/TopcoderFooter.jsx.snap +++ b/__tests__/shared/components/__snapshots__/TopcoderFooter.jsx.snap @@ -5,158 +5,575 @@ exports[`Matches shallow shapshot 1`] = ` className="src-shared-components-TopcoderFooter-___style__footer___28yQ6" role="contentinfo" > -
    -
  1. - - ABOUT US - -
  2. -
  3. - - CONTACT US - -
  4. -
  5. - - HELP CENTER - -
  6. -
  7. - - PRIVACY POLICY - -
  8. -
  9. - - TERMS - -
  10. -
-
- - - icon facebook - - - +
- - - icon twitter - - + COMPETE + + +
- - icon linkedln - - + TRACKS + + +
+

+ COMMUNITY +

+ +
+

+ HELP CENTER +

+ +
+

+ ABOUT +

+ +
+

+ FOLLOW US +

+ +
+
+
- - - icon instagram - - + COMPETE + + + TRACKS + +
+ + +
+ +
+ + © 2020 Topcoder + + Policies + + +
-

- © 2020 Topcoder. All Rights Reserved -

`; diff --git a/src/assets/images/preferences/invletter.svg b/src/assets/images/preferences/invletter.svg deleted file mode 100755 index 5dd1a0c792..0000000000 --- a/src/assets/images/preferences/invletter.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/assets/images/preferences/referral.svg b/src/assets/images/preferences/referral.svg deleted file mode 100755 index 99cf40e58c..0000000000 --- a/src/assets/images/preferences/referral.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/server/services/contentful.js b/src/server/services/contentful.js index 231da070b2..8dba5cf7e2 100644 --- a/src/server/services/contentful.js +++ b/src/server/services/contentful.js @@ -69,8 +69,8 @@ function mapAssetFileUrlToCdn(asset) { * Creates a promise that resolves two second after its creation. * @return {Promise} */ -function threeSecondDelay() { - return new Promise(resolve => setTimeout(resolve, 3000)); +function oneSecondDelay() { + return new Promise(resolve => setTimeout(resolve, 1000)); } /** @@ -94,6 +94,10 @@ class ApiService { * @return {Promise} */ async fetch(endpoint, query) { + // Contentful API rate limits, which are 78 requests within 1 second + // we await 14ms before each request to make sure we don't break this limitation + await new Promise(resolve => setTimeout(resolve, 14)); + // fire calls to Contentful API let url = `${this.private.baseUrl}${endpoint}`; if (query) url += `?${qs.stringify(query)}`; let res; @@ -108,7 +112,7 @@ class ApiService { }); /* 429 = "Too Many Requests" */ if (res.status !== 429) break; - await threeSecondDelay(); + await oneSecondDelay(); /* eslint-enable no-await-in-loop */ } if (!res.ok) throw new Error(res.statusText); diff --git a/src/shared/components/Contentful/ArticleCard/ArticleCard.jsx b/src/shared/components/Contentful/ArticleCard/ArticleCard.jsx index f6e2e8e166..e153e91d5d 100644 --- a/src/shared/components/Contentful/ArticleCard/ArticleCard.jsx +++ b/src/shared/components/Contentful/ArticleCard/ArticleCard.jsx @@ -128,14 +128,14 @@ class ArticleCard extends React.Component { const title = ( themeName === 'Article small' && article.title.length > ART_SMALL_TITLE_MAX_LENGTH) - ? `${article.title.substring(0, ART_SMALL_TITLE_MAX_LENGTH)}..` + ? `${article.title.substring(0, ART_SMALL_TITLE_MAX_LENGTH)}...` : article.title; // truncate content for 'Article large' cards const content = ( (themeName === 'Article large' || themeName === 'Recommended') && article.content.length > CONTENT_PREVIEW_LENGTH) - ? markdown(`${article.content.substring(0, CONTENT_PREVIEW_LENGTH)}..`) + ? markdown(`${article.content.substring(0, CONTENT_PREVIEW_LENGTH)}...`) : undefined; // set the correct format to apply to the `article.creationDate` diff --git a/src/shared/components/Contentful/ArticleCard/themes/article_large.scss b/src/shared/components/Contentful/ArticleCard/themes/article_large.scss index 8e0c9cd4e8..1ec8bdcb82 100644 --- a/src/shared/components/Contentful/ArticleCard/themes/article_large.scss +++ b/src/shared/components/Contentful/ArticleCard/themes/article_large.scss @@ -45,7 +45,8 @@ .tags { display: flex; flex-direction: row; - margin: 28px 0 15px; + margin: 23px 0 15px; + flex-wrap: wrap; @include xs-to-sm { margin: 17px 0 7px; @@ -57,6 +58,7 @@ border-radius: 5px; padding: 4px 6px; margin-right: 3px; + margin-top: 5px; font-family: 'Roboto', Helvetica, Arial, sans-serif; font-size: 11px; font-weight: 400; diff --git a/src/shared/components/Contentful/ArticleCard/themes/forum_post.scss b/src/shared/components/Contentful/ArticleCard/themes/forum_post.scss index 4e689d1879..d0f60f62ad 100644 --- a/src/shared/components/Contentful/ArticleCard/themes/forum_post.scss +++ b/src/shared/components/Contentful/ArticleCard/themes/forum_post.scss @@ -44,10 +44,7 @@ display: flex; flex-direction: row; margin: 0 0 15px; - - @include xs-to-sm { - margin: 17px 0 7px; - } + flex-wrap: wrap; } .tag { @@ -55,6 +52,7 @@ border-radius: 5px; padding: 4px 6px; margin-right: 3px; + margin-top: 5px; font-family: 'Roboto', Helvetica, Arial, sans-serif; font-size: 11px; font-weight: 400; diff --git a/src/shared/components/Contentful/SearchBar/SearchBar.jsx b/src/shared/components/Contentful/SearchBar/SearchBar.jsx index 83aa24c709..3e3c53b58a 100644 --- a/src/shared/components/Contentful/SearchBar/SearchBar.jsx +++ b/src/shared/components/Contentful/SearchBar/SearchBar.jsx @@ -158,13 +158,24 @@ export class SearchBarInner extends Component { { _.map(suggestionList.Article, item => (
{ + window.location.href = (item.externalArticle && item.contentUrl) + ? item.contentUrl : `${config.TC_EDU_BASE_PATH}${config.TC_EDU_ARTICLES_PATH}/${item.title}`; + }} + onKeyPress={_.noop} > { + e.nativeEvent.stopImmediatePropagation(); + e.stopPropagation(); + }} > { item.featuredImage ? ( @@ -199,12 +210,23 @@ export class SearchBarInner extends Component { _.map(suggestionList.Video, item => (
{ + window.location.href = (item.externalArticle && item.contentUrl) + ? item.contentUrl : `${config.TC_EDU_BASE_PATH}${config.TC_EDU_ARTICLES_PATH}/${item.title}`; + }} + onKeyPress={_.noop} > { + e.nativeEvent.stopImmediatePropagation(); + e.stopPropagation(); + }} > { item.featuredImage ? ( @@ -430,7 +452,7 @@ export class SearchBarInner extends Component { value={inputlVal} ref={this.setSearchFieldRef} type="text" - placeholder="Search.." + placeholder="Search..." onBlur={() => { _.delay(() => { this.setState({ isShowSuggestion: false }); diff --git a/src/shared/components/Contentful/SearchPageFilter/SearchPageFilter.jsx b/src/shared/components/Contentful/SearchPageFilter/SearchPageFilter.jsx index b4d74cd1af..448544e525 100644 --- a/src/shared/components/Contentful/SearchPageFilter/SearchPageFilter.jsx +++ b/src/shared/components/Contentful/SearchPageFilter/SearchPageFilter.jsx @@ -201,7 +201,7 @@ SearchPageFilterInner.defaultProps = { onApply: () => { }, selectedAuthor: DEF_SELECTED_AUTHOR, authorList: [DEF_SELECTED_AUTHOR], - startDate: moment().subtract(1, 'months'), + startDate: moment('2001-01-02'), endDate: moment(), tags: [], selectedCategory: '', diff --git a/src/shared/components/Contentful/TracksFilter/TracksFilter.jsx b/src/shared/components/Contentful/TracksFilter/TracksFilter.jsx index cf30cd066c..77cd842919 100644 --- a/src/shared/components/Contentful/TracksFilter/TracksFilter.jsx +++ b/src/shared/components/Contentful/TracksFilter/TracksFilter.jsx @@ -153,7 +153,7 @@ TracksFilterInner.defaultProps = { onApply: () => {}, selectedAuthor: DEF_SELECTED_AUTHOR, authorList: [DEF_SELECTED_AUTHOR], - startDate: moment().subtract(1, 'months'), + startDate: moment('2001-01-02'), endDate: moment(), tags: [], }; diff --git a/src/shared/components/Settings/Preferences/index.jsx b/src/shared/components/Settings/Preferences/index.jsx index 8a3082a6fe..18ee9f971f 100644 --- a/src/shared/components/Settings/Preferences/index.jsx +++ b/src/shared/components/Settings/Preferences/index.jsx @@ -12,9 +12,7 @@ import Accordion from 'components/Settings/Accordion'; import LoadingIndicator from 'components/LoadingIndicator'; import EmailIcon from 'assets/images/preferences/email.svg'; import Forum from 'assets/images/preferences/forum.svg'; -import Invletter from 'assets/images/preferences/invletter.svg'; import Payment from 'assets/images/preferences/payment.svg'; -import Referral from 'assets/images/preferences/referral.svg'; import SideBar from 'components/Settings/SideBar'; import ErrorWrapper from 'components/Settings/ErrorWrapper'; import Email from './Email'; @@ -26,16 +24,12 @@ const tabs = { EMAIL: 'e-mail', FORUM: 'forum', PAYMENT: 'payment', - LETTER: 'invitation letter', - REFERRALS: 'referrals', }; const icons = { 'e-mail': , forum: , payment: , - 'invitation letter': , - referrals: , }; export default class Preferences extends React.Component { @@ -96,10 +90,6 @@ export default class Preferences extends React.Component { return (window.location.href = `${config.URL.FORUMS}/?module=Settings`) && ; case 'payment': return (window.location.href = `${config.URL.COMMUNITY}/tc?module=EditPaymentPreferences`) && ; - case 'invitation letter': - return (window.location.href = `${config.URL.COMMUNITY}/tc?module=VisaSelection`) && ; - case 'referrals': - return (window.location.href = `${config.URL.COMMUNITY}/tc?module=ViewReferrals`) && ; default: return null; } diff --git a/src/shared/components/TopcoderFooter/icons/TC-logo-inverted.svg b/src/shared/components/TopcoderFooter/icons/TC-logo-inverted.svg new file mode 100644 index 0000000000..916d2ba198 --- /dev/null +++ b/src/shared/components/TopcoderFooter/icons/TC-logo-inverted.svg @@ -0,0 +1,18 @@ + + + + Created with sketchtool. + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/shared/components/TopcoderFooter/icons/facebook.svg b/src/shared/components/TopcoderFooter/icons/facebook.svg deleted file mode 100644 index 99e1acd934..0000000000 --- a/src/shared/components/TopcoderFooter/icons/facebook.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - icon facebook - Created with Sketch. - - - - - - - - - \ No newline at end of file diff --git a/src/shared/components/TopcoderFooter/icons/google_plus.svg b/src/shared/components/TopcoderFooter/icons/google_plus.svg deleted file mode 100644 index d099d5c0b3..0000000000 --- a/src/shared/components/TopcoderFooter/icons/google_plus.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - icon google plus - Created with Sketch. - - - - - - - - - \ No newline at end of file diff --git a/src/shared/components/TopcoderFooter/icons/icon-fb.svg b/src/shared/components/TopcoderFooter/icons/icon-fb.svg new file mode 100644 index 0000000000..7996d92d38 --- /dev/null +++ b/src/shared/components/TopcoderFooter/icons/icon-fb.svg @@ -0,0 +1,10 @@ + + + + Created with sketchtool. + + + + + + \ No newline at end of file diff --git a/src/shared/components/TopcoderFooter/icons/icon-instagram.svg b/src/shared/components/TopcoderFooter/icons/icon-instagram.svg new file mode 100644 index 0000000000..97add14a02 --- /dev/null +++ b/src/shared/components/TopcoderFooter/icons/icon-instagram.svg @@ -0,0 +1,10 @@ + + + + Created with sketchtool. + + + + + + \ No newline at end of file diff --git a/src/shared/components/TopcoderFooter/icons/icon-linkedln.svg b/src/shared/components/TopcoderFooter/icons/icon-linkedln.svg new file mode 100644 index 0000000000..4fe185d0e8 --- /dev/null +++ b/src/shared/components/TopcoderFooter/icons/icon-linkedln.svg @@ -0,0 +1,10 @@ + + + + Created with sketchtool. + + + + + + \ No newline at end of file diff --git a/src/shared/components/TopcoderFooter/icons/icon-twitter.svg b/src/shared/components/TopcoderFooter/icons/icon-twitter.svg new file mode 100644 index 0000000000..0c1c8cc120 --- /dev/null +++ b/src/shared/components/TopcoderFooter/icons/icon-twitter.svg @@ -0,0 +1,10 @@ + + + + Created with sketchtool. + + + + + + \ No newline at end of file diff --git a/src/shared/components/TopcoderFooter/icons/icon-youtube.svg b/src/shared/components/TopcoderFooter/icons/icon-youtube.svg new file mode 100644 index 0000000000..256b29321f --- /dev/null +++ b/src/shared/components/TopcoderFooter/icons/icon-youtube.svg @@ -0,0 +1,10 @@ + + + + Created with sketchtool. + + + + + + \ No newline at end of file diff --git a/src/shared/components/TopcoderFooter/icons/instagram.svg b/src/shared/components/TopcoderFooter/icons/instagram.svg deleted file mode 100644 index d4a4b11bf6..0000000000 --- a/src/shared/components/TopcoderFooter/icons/instagram.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - icon instagram - Created with Sketch. - - - - - - - - - \ No newline at end of file diff --git a/src/shared/components/TopcoderFooter/icons/linkedin.svg b/src/shared/components/TopcoderFooter/icons/linkedin.svg deleted file mode 100644 index 0602c28e5a..0000000000 --- a/src/shared/components/TopcoderFooter/icons/linkedin.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - icon linkedln - Created with Sketch. - - - - - - - - - \ No newline at end of file diff --git a/src/shared/components/TopcoderFooter/icons/twitter.svg b/src/shared/components/TopcoderFooter/icons/twitter.svg deleted file mode 100644 index fc72da67ea..0000000000 --- a/src/shared/components/TopcoderFooter/icons/twitter.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - icon twitter - Created with Sketch. - - - - - - - - - \ No newline at end of file diff --git a/src/shared/components/TopcoderFooter/index.jsx b/src/shared/components/TopcoderFooter/index.jsx index 9546fde49c..70acbf4905 100644 --- a/src/shared/components/TopcoderFooter/index.jsx +++ b/src/shared/components/TopcoderFooter/index.jsx @@ -4,10 +4,12 @@ import React from 'react'; import { config } from 'topcoder-react-utils'; -import FacebookIcon from './icons/facebook.svg'; -import InstagramIcon from './icons/instagram.svg'; -import LinkedInIcon from './icons/linkedin.svg'; -import TwitterIcon from './icons/twitter.svg'; +import FacebookIcon from './icons/icon-fb.svg'; +import YouTubeIcon from './icons/icon-youtube.svg'; +import LinkedInIcon from './icons/icon-linkedln.svg'; +import TwitterIcon from './icons/icon-twitter.svg'; +import InstagramIcon from './icons/icon-instagram.svg'; +import TCLogo from './icons/TC-logo-inverted.svg'; import './style.scss'; @@ -34,41 +36,102 @@ export default function TopcoderFooter() { const currentYear = moment().year(); return (
-
    - - ABOUT US - - - CONTACT US - - - HELP CENTER - - - PRIVACY POLICY - - - TERMS - -
-
-
-
- - - - - - - - - - - +
+
+
+
+

COMPETE

+
+
    + All Challenges + Competitive Programming + Gig Work +
+
+
+

TRACKS

+
+
    + Competitive Programming + Data Science + Design + Development + QA +
+
+
+

COMMUNITY

+
+
    + TCO + Programs + Forums + Statistics + Blog + Thrive +
+
+
+

HELP CENTER

+
+
    + Getting Paid + FAQ + General Info + Website Help +
+
+
+

ABOUT

+
+
    + Admins + Contact Us + Join Community + About Community + Talk to Sales +
+
+
+

FOLLOW US

+
+
+ + + + + +
+
+
+
+
+
+ COMPETE + TRACKS +
+ +
+ ABOUT +
+
+
+ + + + + +
+
+ + {`© ${currentYear} Topcoder`} + Policies + +
-

- {`© ${currentYear} Topcoder. All Rights Reserved`} -

); } diff --git a/src/shared/components/TopcoderFooter/style.scss b/src/shared/components/TopcoderFooter/style.scss index 0d8467df6d..a5d20be0b4 100644 --- a/src/shared/components/TopcoderFooter/style.scss +++ b/src/shared/components/TopcoderFooter/style.scss @@ -1,75 +1,139 @@ @import '~styles/mixins'; -.copyright-notice { - text-align: center; - font-family: "Roboto", Helvetica, Arial, sans-serif; - font-size: 12px; - color: $tc-gray-40; +.mobile-only { + @include md-to-xl { + display: none; + } } -.footer { - background-color: $tc-gray-90; - font-family: "Roboto", Helvetica, Arial, sans-serif; - overflow: hidden; - padding: 45px; - padding-bottom: 30px; - text-align: center; - height: 220px; - flex: none; +.link a { + color: #e9e9e9 !important; } -.social-links { - text-align: center; - margin: 40px auto 0; - display: inline-block; - color: $tc-gray-30; +.sep-line { + height: 2px; + background-color: #555; + border-radius: 1px; width: 100%; - hr { - border: none; - border-top: solid 2px $tc-gray-70; - opacity: 0.2; - margin: 0 auto; - width: 205px; + @include xs-to-sm { + display: none; + } +} + +.social-icons { + margin-top: 15px; + + @include xs-to-sm { + display: flex; + justify-content: center; } a { - display: inline-block; - margin: 15px; - margin-bottom: 28px; - margin-top: 10px; + margin-right: 5px; + + &:last-child { + margin-right: 0; + } } } -.link { - display: inline-block; - cursor: pointer; - line-height: 24px; - margin: 0 24px; - text-align: center; - - a, - a:visited, - a:focus, - a:hover { - color: $tc-gray-30; - font-family: "Roboto", Helvetica, Arial, sans-serif; - font-weight: normal; - font-size: 15px; - text-decoration: none; - - &:hover { - color: $tc-white; +.mobile-navi { + display: flex; + justify-content: center; + + @include md-to-xl { + display: none; + } + + .mobile-navi-col { + display: flex; + flex-direction: column; + margin-right: 43px; + + &:last-child { + margin-right: 0; + } + + a { + color: #e9e9e9; + font-size: 12px; + font-weight: 500; + line-height: 21px; } } } -@include xs-to-md { - .footer { - height: auto; +.footer { + background-color: #2a2a2a; + padding: 30px 80px 21px 80px; + font-family: Roboto, sans-serif; + font-size: 14px; + font-weight: 400; + line-height: 21px; + position: relative; + + @include xs-to-sm { + padding: 30px 30px 21px 30px; + } + + .footer-wrap { + max-width: $screen-lg; + margin: auto; + + .logo-wrap { + display: flex; + justify-content: center; + margin-bottom: 30px; + } + } + + .navi-links { + margin-bottom: 39px; + display: grid; + grid-template-columns: repeat(6, 1fr); + gap: 20px; + + @include xs-to-sm { + display: none; + } + + .navi-col { + .navi-col-title { + color: white; + font-family: Roboto, sans-serif; + font-size: 14px; + font-weight: 500; + line-height: 21px; + margin-bottom: 1px; + } + + .navi-col-links { + margin-top: 7px; + } + } + } + + .bottom { + display: flex; + justify-content: space-between; + padding-top: 22px; + + .copyright-notice { + color: #aaa; + + @include xs-to-sm { + font-size: 11px; + line-height: 21px; + + a { + text-decoration: underline; + } + } - .link { - display: inline-block; + a { + margin-left: 20px; + } } } }