diff --git a/__tests__/shared/components/challenge-listing/Filters/__snapshots__/FiltersPanel.jsx.snap b/__tests__/shared/components/challenge-listing/Filters/__snapshots__/FiltersPanel.jsx.snap index 5297459e04..e59c87c240 100644 --- a/__tests__/shared/components/challenge-listing/Filters/__snapshots__/FiltersPanel.jsx.snap +++ b/__tests__/shared/components/challenge-listing/Filters/__snapshots__/FiltersPanel.jsx.snap @@ -184,6 +184,7 @@ exports[`Matches shallow shapshot 2`] = ` +
diff --git a/src/shared/components/challenge-listing/ChallengeCard/MatchScore/index.jsx b/src/shared/components/challenge-listing/ChallengeCard/MatchScore/index.jsx new file mode 100644 index 0000000000..4e7296408d --- /dev/null +++ b/src/shared/components/challenge-listing/ChallengeCard/MatchScore/index.jsx @@ -0,0 +1,20 @@ +import PT from 'prop-types'; +import React from 'react'; + +import './style.scss'; + +export default function MatchScore({ score }) { + return ( + + {score}% match + + ); +} + +MatchScore.defaultProps = { + score: 0, +}; + +MatchScore.propTypes = { + score: PT.number, +}; diff --git a/src/shared/components/challenge-listing/ChallengeCard/MatchScore/style.scss b/src/shared/components/challenge-listing/ChallengeCard/MatchScore/style.scss new file mode 100644 index 0000000000..563eebd007 --- /dev/null +++ b/src/shared/components/challenge-listing/ChallengeCard/MatchScore/style.scss @@ -0,0 +1,12 @@ +@import "~styles/mixins"; + +.match-score { + background-color: $tc-light-blue-30; + color: $tc-dark-blue-100; + font-size: 10px; + line-height: 12px; + padding: 3px; + border-radius: 2px; + margin-left: 5px; + margin-top: 1px; +} diff --git a/src/shared/components/challenge-listing/ChallengeCard/index.jsx b/src/shared/components/challenge-listing/ChallengeCard/index.jsx index ab1dec84e4..ac8c1941cd 100644 --- a/src/shared/components/challenge-listing/ChallengeCard/index.jsx +++ b/src/shared/components/challenge-listing/ChallengeCard/index.jsx @@ -13,6 +13,8 @@ import Tags from '../Tags'; import ChallengeStatus from './Status'; import TrackAbbreviationTooltip from '../Tooltips/TrackAbbreviationTooltip'; +import MatchScore from './MatchScore'; +import { calculateScore } from '../../../utils/challenge-listing/helper'; import './style.scss'; /* TODO: Note that this component uses a dirty trick to cheat linter and to be @@ -67,13 +69,19 @@ function ChallengeCard({
- selectChallengeDetailsTab(DETAIL_TABS.DETAILS)} - to={challengeDetailLink} - styleName="challenge-title" - openNewTab={openChallengesInNewTabs} - >

{challenge.name}

- +
+ selectChallengeDetailsTab(DETAIL_TABS.DETAILS)} + to={challengeDetailLink} + styleName="challenge-title" + openNewTab={openChallengesInNewTabs} + >

{challenge.name}

+ + { + challenge.matchScore + && + } +
{challenge.status === 'Active' ? 'Ends ' : 'Ended '} diff --git a/src/shared/components/challenge-listing/ChallengeCard/style.scss b/src/shared/components/challenge-listing/ChallengeCard/style.scss index 31bb19c0ed..d8277e6c0e 100644 --- a/src/shared/components/challenge-listing/ChallengeCard/style.scss +++ b/src/shared/components/challenge-listing/ChallengeCard/style.scss @@ -106,6 +106,10 @@ $challenge-radius-4: $corner-radius * 2; display: inline-block; } } + + .challenge-detail-header { + display: flex; + } } // date and technologies .details-footer { diff --git a/src/shared/components/challenge-listing/Filters/FiltersPanel/index.jsx b/src/shared/components/challenge-listing/Filters/FiltersPanel/index.jsx index 4771035e5d..2b097830b7 100644 --- a/src/shared/components/challenge-listing/Filters/FiltersPanel/index.jsx +++ b/src/shared/components/challenge-listing/Filters/FiltersPanel/index.jsx @@ -22,7 +22,7 @@ /* eslint-disable jsx-a11y/label-has-for */ import _ from 'lodash'; -import React from 'react'; +import React, { useState, useEffect } from 'react'; import PT from 'prop-types'; import Select from 'components/Select'; import DateRangePicker from 'components/DateRangePicker'; @@ -250,8 +250,30 @@ export default function FiltersPanel({ const past = isPastBucket(activeBucket); const disableClearFilterButtons = isFilterEmpty(filterState, past ? 'past' : '', activeBucket); - const availableTypes = activeBucket === 'openForRegistration' - ? validTypes : validTypes.filter(item => item.abbreviation !== 'REC'); + const availableTypes = validTypes.filter(item => item.abbreviation !== 'REC'); + const isRecommendedChallengesVisible = activeBucket === 'openForRegistration'; + const [recommendedToggle, setRecommendedToggle] = useState(false); + + useEffect(() => { + if (recommendedToggle) { + const types = _.union(filterState.types, ['REC']); + setFilterState({ ..._.clone(filterState), types }); + } + }, []); + + const onSwitchRecommendedChallenge = (on) => { + const { types } = filterState; + types.push('REC'); + setRecommendedToggle(on); + + if (on) { + setSort('openForRegistration', 'updatedBy'); + setFilterState({ ..._.clone(filterState), types }); + } else { + setFilterState({ ..._.clone(filterState), types: ['TSK', 'CH', 'F2F'] }); + setSort('openForRegistration', 'startDate'); + } + }; const handleTypeChange = (option, e) => { let { types } = filterState; @@ -261,20 +283,14 @@ export default function FiltersPanel({ types = types.filter(type => type !== option.value); } - if (option.label === 'Recommended') { - types = types.filter(type => type === 'REC'); - if (!e.target.checked) { - setFilterState({ ..._.clone(filterState), types: ['TSK', 'CH', 'F2F'] }); - setSort('openForRegistration', 'startDate'); - } else { - setSort('openForRegistration', 'updatedBy'); - setFilterState({ ..._.clone(filterState), types }); - } + if (recommendedToggle) { + types = [...types, 'REC']; } else { types = types.filter(type => type !== 'REC'); - setFilterState({ ..._.clone(filterState), types }); - setSort('openForRegistration', 'startDate'); } + + setFilterState({ ..._.clone(filterState), types }); + setSort('openForRegistration', 'startDate'); }; const recommendedCheckboxTip = ( @@ -462,24 +478,7 @@ export default function FiltersPanel({ checked={filterState.types.includes(option.value)} onChange={e => handleTypeChange(option, e)} /> - { - option.label === 'Recommended' - ? ( - - ) - - : - } + )) } @@ -579,8 +578,41 @@ export default function FiltersPanel({
) } + + { + isRecommendedChallengesVisible + && ( +
+ + + + +
+ +