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
+ && (
+
+ )
+ }
+
+