Skip to content

Commit 0a002bc

Browse files
committed
1 parent c2a328a commit 0a002bc

File tree

8 files changed

+141
-6
lines changed

8 files changed

+141
-6
lines changed

__tests__/shared/components/challenge-listing/Filters/FiltersPanel.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const mockDatas = [{
3030
selectedCommunityId: '1',
3131
setFilterState,
3232
setSearchText,
33+
activeBucket: 'all',
3334
validKeywords: ['key', 'word'],
3435
validTypes: [{ name: 'sub', subTrack: 'sub' }, { name: 'track', subTrack: 'track' }],
3536
onClose,
@@ -47,6 +48,7 @@ const mockDatas = [{
4748
filterState: {
4849
groups: [],
4950
},
51+
activeBucket: 'openForRegistration',
5052
hidden: false,
5153
onSaveFilter,
5254
selectCommunity,

__tests__/shared/components/challenge-listing/Filters/__snapshots__/FiltersPanel.jsx.snap

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ exports[`Matches shallow shapshot 2`] = `
6262
className="src-shared-components-challenge-listing-Filters-FiltersPanel-___style__bucket-selector-mobile___JbE2n"
6363
>
6464
<BucketSelector
65+
activeBucket="openForRegistration"
6566
disabled={false}
6667
expanding={false}
6768
isAuth={false}
@@ -209,7 +210,79 @@ exports[`Matches shallow shapshot 2`] = `
209210
<hr
210211
className="src-shared-components-challenge-listing-Filters-FiltersPanel-___style__hr___1WvP7"
211212
/>
213+
<React.Fragment>
214+
<div
215+
className="src-shared-components-challenge-listing-Filters-FiltersPanel-___style__filter-row___2Vfd_ src-shared-components-challenge-listing-Filters-FiltersPanel-___style__tco-challenges-filter___3XG63"
216+
>
217+
<span
218+
aria-checked={false}
219+
aria-label="Tco eligible challenge toggle button pressed Off"
220+
className="src-shared-components-challenge-listing-Filters-FiltersPanel-___style__tco-select-label___3ATak"
221+
role="switch"
222+
>
223+
<ThemedSwitchWithLabel
224+
composeAdhocTheme="deeply"
225+
composeContextTheme="softly"
226+
enabled={false}
227+
labelAfter="TCO Eligible Challenges"
228+
labelBefore=""
229+
mapThemrProps={[Function]}
230+
onSwitch={[Function]}
231+
themePriority="adhoc-context-default"
232+
/>
233+
</span>
234+
<div
235+
className="src-shared-components-challenge-listing-Filters-FiltersPanel-___style__tco-challenge-tooltip___17i7n"
236+
>
237+
<Tooltip
238+
align={Object {}}
239+
className=""
240+
content={
241+
<div
242+
className="src-shared-components-challenge-listing-Filters-FiltersPanel-___style__tctooltiptext___2Lyji"
243+
>
244+
<p>
245+
Earn TCO points by participating in these
246+
<br />
247+
challenges.
248+
<a
249+
href="https://www.topcoder-dev.com/community/member-programs/topcoder-open"
250+
rel="noreferrer noopener"
251+
target="_blank"
252+
>
253+
Learn more about TCO
254+
</a>
255+
</p>
256+
</div>
257+
}
258+
defaultVisible={false}
259+
id="tco-tip"
260+
onTooltipHover={[Function]}
261+
placeArrow={[Function]}
262+
position="top"
263+
suppressDiv={false}
264+
trigger={
265+
Array [
266+
"hover",
267+
"focus",
268+
]
269+
}
270+
>
271+
<CircleIcon
272+
fill="none"
273+
height="14"
274+
viewBox="0 0 14 14"
275+
width="14"
276+
xmlns="http://www.w3.org/2000/svg"
277+
/>
278+
</Tooltip>
279+
</div>
280+
</div>
281+
</React.Fragment>
212282
</div>
283+
<hr
284+
className="src-shared-components-challenge-listing-Filters-FiltersPanel-___style__hr___1WvP7"
285+
/>
213286
<div
214287
className="src-shared-components-challenge-listing-Filters-FiltersPanel-___style__buttons___2r3xW"
215288
>

config/default.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ module.exports = {
103103
* as a more verbose name for the param. */
104104
COMMUNITY_APP: 'https://community-app.topcoder-dev.com',
105105
CHALLENGES_URL: 'https://www.topcoder-dev.com/challenges',
106-
106+
TCO_OPEN_URL: 'https://www.topcoder-dev.com/community/member-programs/topcoder-open',
107107
ARENA: 'https://arena.topcoder-dev.com',
108108
AUTH: 'https://accounts-auth0.topcoder-dev.com',
109109
BASE: 'https://www.topcoder-dev.com',

config/production.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ module.exports = {
2626
* as a more verbose name for the param. */
2727
COMMUNITY_APP: 'https://community-app.topcoder.com',
2828
CHALLENGES_URL: 'https://www.topcoder.com/challenges',
29+
TCO_OPEN_URL: 'https://www.topcoder.com/community/member-programs/topcoder-open',
2930

3031
AUTH: 'https://accounts-auth0.topcoder.com',
3132
BASE: 'https://www.topcoder.com',

src/shared/components/challenge-listing/Filters/FiltersPanel/index.jsx

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,9 @@ export default function FiltersPanel({
257257
const disableClearFilterButtons = isFilterEmpty(filterState, past ? 'past' : '', activeBucket);
258258

259259
const isRecommendedChallengesVisible = (activeBucket === 'openForRegistration' && config.ENABLE_RECOMMENDER);
260+
const isTcoChallengesVisible = (activeBucket === 'openForRegistration' || activeBucket === 'all' || activeBucket === 'allPast' || activeBucket === 'myPast');
260261
const [recommendedToggle, setRecommendedToggle] = useState(false);
262+
const [tcoToggle, setTcoToggle] = useState(false);
261263

262264
useEffect(() => {
263265
if (!isFilterEmpty(filterState, past ? 'past' : '', activeBucket)
@@ -270,11 +272,19 @@ export default function FiltersPanel({
270272
});
271273
}
272274

275+
if (filterState.tco) {
276+
setTcoToggle(true);
277+
}
273278
if (filterState.recommended) {
274279
setRecommendedToggle(true);
275280
}
276281
}, [filterState]);
277282

283+
const onSwitchTcoChallenge = (on) => {
284+
setFilterState({ ..._.clone(filterState), tco: on ? on.toString() : on });
285+
setTcoToggle(on);
286+
};
287+
278288
const onSwitchRecommendedChallenge = (on) => {
279289
setFilterState({ ..._.clone(filterState), recommended: on });
280290
selectBucket(BUCKETS.OPEN_FOR_REGISTRATION);
@@ -314,6 +324,14 @@ export default function FiltersPanel({
314324
</div>
315325
);
316326

327+
const tcoCheckboxTip = (
328+
<div styleName="tctooltiptext">
329+
<p>Earn TCO points by participating in these <br />
330+
challenges. <a href={config.URL.TCO_OPEN_URL} target="_blank" rel="noreferrer noopener">Learn more about TCO</a>
331+
</p>
332+
</div>
333+
);
334+
317335
return (
318336
<div styleName="FiltersPanel">
319337
<div styleName="header">
@@ -648,10 +666,42 @@ export default function FiltersPanel({
648666
</React.Fragment>
649667
)
650668
}
669+
{isTcoChallengesVisible
670+
&& (
671+
<React.Fragment>
672+
<div styleName="filter-row tco-challenges-filter">
673+
<span
674+
styleName="tco-select-label"
675+
aria-label={`Tco eligible challenge toggle button pressed ${tcoToggle ? 'On' : 'Off'}`}
676+
role="switch"
677+
aria-checked={tcoToggle}
678+
>
679+
<SwitchWithLabel
680+
enabled={tcoToggle}
681+
labelAfter="TCO Eligible Challenges"
682+
onSwitch={onSwitchTcoChallenge}
683+
/>
684+
</span>
685+
686+
<div styleName="tco-challenge-tooltip">
687+
<Tooltip
688+
id="tco-tip"
689+
content={tcoCheckboxTip}
690+
className={style['tooltip-overlay']}
691+
trigger={['hover', 'focus']}
692+
>
693+
<CircleIcon />
694+
</Tooltip>
695+
</div>
696+
</div>
697+
</React.Fragment>
698+
)
699+
}
700+
651701
</div>
652702

653703
{
654-
isRecommendedChallengesVisible && _.get(auth, 'user.userId')
704+
((isRecommendedChallengesVisible && _.get(auth, 'user.userId')) || isTcoChallengesVisible)
655705
&& (<hr styleName="hr" />)
656706
}
657707

@@ -661,6 +711,7 @@ export default function FiltersPanel({
661711
disabled={disableClearFilterButtons}
662712
onClick={() => {
663713
setRecommendedToggle(false);
714+
setTcoToggle(false);
664715
setSort('openForRegistration', 'startDate');
665716
setFilterState({
666717
tracks: {

src/shared/components/challenge-listing/Filters/FiltersPanel/style.scss

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ hr.hr {
118118
.filter-row {
119119
display: flex;
120120

121-
.recommended-select-label {
121+
.recommended-select-label,
122+
.tco-select-label {
122123
width: 45%;
123124
margin-bottom: 16px;
124125
display: flex;
@@ -606,7 +607,8 @@ hr.hr {
606607
}
607608
}
608609

609-
.recommended-challenges-filter {
610+
.recommended-challenges-filter,
611+
.tco-challenges-filter {
610612
display: flex;
611613
margin: 0;
612614
position: relative;
@@ -619,7 +621,8 @@ hr.hr {
619621
flex-direction: row;
620622
}
621623

622-
.recommended-challenge-tooltip {
624+
.recommended-challenge-tooltip,
625+
.tco-challenge-tooltip {
623626
position: absolute;
624627
left: 210px;
625628
display: flex;
@@ -639,6 +642,10 @@ hr.hr {
639642
color: $tc-white;
640643
border-radius: 8px;
641644
padding: 10px;
645+
646+
a {
647+
font-weight: bold;
648+
}
642649
}
643650

644651
.tctooltiptext::after {

src/shared/reducers/challenge-listing/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ function onSetFilter(state, { payload }) {
422422
* do it very carefuly (many params are not validated). */
423423
const filter = _.pickBy(_.pick(
424424
payload,
425-
['tags', 'types', 'search', 'startDateEnd', 'endDateStart', 'groups', 'events', 'tracks'],
425+
['tags', 'types', 'search', 'startDateEnd', 'endDateStart', 'groups', 'events', 'tracks', 'tco'],
426426
), value => (!_.isArray(value) && value && value !== '') || (_.isArray(value) && value.length > 0));
427427

428428
const emptyArrayAllowedFields = ['types'];

src/shared/utils/challenge-listing/buckets.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ export function filterChanged(filter, prevFilter) {
190190
}
191191
return (!_.isEqual(filter.tracks, prevFilter.tracks))
192192
|| (filter.search !== prevFilter.search)
193+
|| (filter.tco !== prevFilter.tco)
193194
|| (filter.startDateEnd !== prevFilter.startDateEnd)
194195
|| (filter.endDateStart !== prevFilter.endDateStart)
195196
// eslint-disable-next-line max-len

0 commit comments

Comments
 (0)