Skip to content

Commit 8e48f49

Browse files
authored
Merge pull request #4431 from topcoder-platform/issue-4408
Issue#4408 : Fix registrants and submissions tabs in challenge details
2 parents 4e28176 + e6fdf24 commit 8e48f49

File tree

14 files changed

+74
-65
lines changed

14 files changed

+74
-65
lines changed

src/server/index.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import Application from 'shared';
99
import config from 'config';
1010
import express from 'express';
1111
import fetch from 'isomorphic-fetch';
12-
import { logger } from 'topcoder-react-lib';
12+
import { logger, services } from 'topcoder-react-lib';
1313
import fs from 'fs';
1414
import moment from 'moment';
1515
import path from 'path';
@@ -160,19 +160,21 @@ async function onExpressJsSetup(server) {
160160

161161
/* Proxy endpoint for GET requests (to fetch data from resources prohibiting
162162
* cross-origin requests). */
163-
/* server.use(
163+
server.use(
164164
'/community-app-assets/api/proxy-get',
165165
checkAuthorizationHeader, async (req, res, next) => {
166+
const tokenM2M = await services.api.getTcM2mToken();
166167
try {
167-
let data = await fetch(req.query.url);
168+
let data = await fetch(req.query.url, {
169+
headers: { Authorization: `Bearer ${tokenM2M}` },
170+
});
168171
data = await data.text();
169172
res.send(data);
170173
} catch (err) {
171174
next(err);
172175
}
173176
},
174177
);
175-
*/
176178

177179
/* Proxy endpoint for POST requests (to fetch data from resources prohibiting
178180
* cross-origin requests). */

src/server/sw.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ workbox.routing.registerRoute(/\/challenges(\/)?(\?.*)?$/, async ({ event, url }
8787
}, 'GET');
8888

8989
// Serve challenge details pages like: /challenges/12345678
90-
workbox.routing.registerRoute(/\/challenges\/\d+(\/)?(.*)/, async ({ event, url }) => {
90+
workbox.routing.registerRoute(/\/challenges\/(([\w]{4,12}-?){5}|\d+)\/?(\?.*)?/, async ({ event, url }) => {
9191
if (url.pathname.endsWith('/')) {
9292
// Remove ending '/' char
9393
url.pathname = url.pathname.substring(0, url.pathname.length - 1);

src/shared/components/challenge-detail/Header/TabSelector/index.jsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ export default function ChallengeViewSelector(props) {
2121
const {
2222
challenge,
2323
checkpointCount,
24-
numRegistrants,
25-
numSubmissions,
24+
numOfRegistrants,
25+
numOfSubmissions,
2626
numWinners,
2727
onSelectorClicked,
2828
selectedView,
@@ -86,7 +86,7 @@ export default function ChallengeViewSelector(props) {
8686
DETAILS
8787
</a>
8888
{
89-
numRegistrants ? (
89+
numOfRegistrants ? (
9090
<a
9191
tabIndex="0"
9292
role="tab"
@@ -100,7 +100,7 @@ export default function ChallengeViewSelector(props) {
100100
styleName={getSelectorStyle(selectedView, DETAIL_TABS.REGISTRANTS)}
101101
>
102102
REGISTRANTS (
103-
{numRegistrants}
103+
{numOfRegistrants}
104104
)
105105
</a>
106106
) : null
@@ -123,7 +123,7 @@ export default function ChallengeViewSelector(props) {
123123
)
124124
}
125125
{
126-
numSubmissions ? (
126+
numOfSubmissions ? (
127127
<a
128128
tabIndex="0"
129129
role="tab"
@@ -133,7 +133,7 @@ export default function ChallengeViewSelector(props) {
133133
styleName={getSelectorStyle(selectedView, DETAIL_TABS.SUBMISSIONS)}
134134
>
135135
SUBMISSIONS (
136-
{numSubmissions}
136+
{numOfSubmissions}
137137
)
138138
</a>
139139
) : null
@@ -188,8 +188,8 @@ export default function ChallengeViewSelector(props) {
188188
ChallengeViewSelector.defaultProps = {
189189
challenge: {},
190190
checkpointCount: 0,
191-
numRegistrants: 0,
192-
numSubmissions: 0,
191+
numOfRegistrants: 0,
192+
numOfSubmissions: 0,
193193
// hasRegistered: false,
194194
};
195195

@@ -204,8 +204,8 @@ ChallengeViewSelector.propTypes = {
204204
}),
205205
}),
206206
checkpointCount: PT.number,
207-
numRegistrants: PT.number,
208-
numSubmissions: PT.number,
207+
numOfRegistrants: PT.number,
208+
numOfSubmissions: PT.number,
209209
numWinners: PT.number.isRequired,
210210
onSelectorClicked: PT.func.isRequired,
211211
selectedView: PT.string.isRequired,

src/shared/components/challenge-detail/Header/index.jsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ export default function ChallengeHeader(props) {
6868
prizeSets,
6969
reliabilityBonus,
7070
userDetails,
71-
numRegistrants,
72-
numSubmissions,
71+
numOfRegistrants,
72+
numOfSubmissions,
7373
appealsEndDate,
7474
} = challenge;
7575

@@ -451,10 +451,10 @@ export default function ChallengeHeader(props) {
451451
onSelectorClicked={onSelectorClicked}
452452
trackLower={trackLower}
453453
selectedView={selectedView}
454-
numRegistrants={numRegistrants}
454+
numOfRegistrants={numOfRegistrants}
455455
numWinners={numWinners}
456456
hasCheckpoints={checkpoints && checkpoints.length > 0}
457-
numSubmissions={numSubmissions}
457+
numOfSubmissions={numOfSubmissions}
458458
hasRegistered={hasRegistered}
459459
checkpointCount={checkpointCount}
460460
mySubmissions={mySubmissions}
@@ -492,8 +492,8 @@ ChallengeHeader.propTypes = {
492492
reliabilityBonus: PT.any,
493493
userDetails: PT.any,
494494
currentPhases: PT.any,
495-
numRegistrants: PT.any,
496-
numSubmissions: PT.any,
495+
numOfRegistrants: PT.any,
496+
numOfSubmissions: PT.any,
497497
status: PT.any,
498498
appealsEndDate: PT.any,
499499
allPhases: PT.any,

src/shared/components/challenge-detail/RecommendedActiveChallenges/ChallengesCard/index.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export default function ChallengesCard({
6565
<TrackIcon
6666
track={track}
6767
subTrack={challenge.subTrack}
68-
tcoEligible={challenge.events && challenge.events.length > 0 ? challenge.events[0].eventName : ''}
68+
tcoEligible={!_.isEmpty(challenge.events) ? challenge.events[0].eventName : ''}
6969
isDataScience={challenge.isDataScience}
7070
challengesUrl={challengesUrl}
7171
/>

src/shared/components/challenge-detail/Registrants/index.jsx

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function formatDate(date) {
2020
}
2121

2222
function getDate(arr, handle) {
23-
const results = arr.filter(a => _.toString(a.submitter || a.handle) === _.toString(handle))
23+
const results = arr.filter(a => _.toString(a.submitter || a.memberHandle) === _.toString(handle))
2424
.sort((a, b) => new Date(b.submissionTime || b.submissionDate).getTime()
2525
- new Date(a.submissionTime || a.submissionDate).getTime());
2626
return results[0] ? (results[0].submissionTime || results[0].submissionDate) : '';
@@ -32,7 +32,7 @@ function passedCheckpoint(checkpoints, handle, results) {
3232
}
3333

3434
function getPlace(results, handle, places) {
35-
const found = _.find(results, w => _.toString(w.handle) === _.toString(handle)
35+
const found = _.find(results, w => _.toString(w.memberHandle) === _.toString(handle)
3636
&& w.placement <= places && w.submissionStatus !== 'Failed Review');
3737

3838
if (found) {
@@ -99,7 +99,7 @@ export default class Registrants extends React.Component {
9999

100100
let checkpoint;
101101
if (twoRounds) {
102-
checkpoint = getDate(checkpoints, registrant.handle);
102+
checkpoint = getDate(checkpoints, registrant.memberHandle);
103103
if (!checkpoint
104104
&& moment(registrant.submissionDate).isBefore(checkpointDate)) {
105105
checkpoint = registrant.submissionDate;
@@ -188,8 +188,8 @@ export default class Registrants extends React.Component {
188188
break;
189189
}
190190
case 'Username': {
191-
valueA = `${a.handle}`.toLowerCase();
192-
valueB = `${b.handle}`.toLowerCase();
191+
valueA = `${a.memberHandle}`.toLowerCase();
192+
valueB = `${b.memberHandle}`.toLowerCase();
193193
valueIsString = true;
194194
break;
195195
}
@@ -239,22 +239,22 @@ export default class Registrants extends React.Component {
239239
onSortChange,
240240
} = this.props;
241241
const {
242-
prizes,
242+
prizeSets,
243243
legacy,
244244
} = challenge;
245245
const { track } = legacy;
246246
const { sortedRegistrants } = this.state;
247247
const { field, sort } = this.getRegistrantsSortParam();
248248
const revertSort = (sort === 'desc') ? 'asc' : 'desc';
249249
const isDesign = track.toLowerCase() === 'design';
250-
const isF2F = challenge.subTrack.indexOf('FIRST_2_FINISH') > -1;
251-
const isBugHunt = challenge.subTrack.indexOf('BUG_HUNT') > -1;
250+
const isF2F = challenge.type.toLowerCase().indexOf('first2finish') > -1;
251+
const isBugHunt = challenge.type.toLowerCase() === 'bug hunt';
252252

253253
const checkpoints = challenge.checkpoints || [];
254254

255255
const twoRounds = challenge.round1Introduction
256256
&& challenge.round2Introduction;
257-
const places = prizes.length;
257+
const places = prizeSets.find(ps => ps.type === 'placement').prizes.lenght;
258258
return (
259259
<div styleName={`container ${twoRounds ? 'design' : ''}`} role="table" aria-label="Registrants">
260260
<div styleName="head" role="row">
@@ -379,8 +379,14 @@ export default class Registrants extends React.Component {
379379
<div styleName="body" role="rowgroup">
380380
{
381381
sortedRegistrants.map((r) => {
382-
const placement = getPlace(results, r.handle, places);
383-
const colorStyle = JSON.parse(r.colorStyle.replace(/(\w+):\s*([^;]*)/g, '{"$1": "$2"}'));
382+
const placement = getPlace(results, r.memberHandle, places);
383+
/*
384+
* TODO: Need check as get this back, currenlty V5 API missing this data
385+
* = JSON.parse(r.colorStyle.replace(/(\w+):\s*([^;]*)/g, '{"$1": "$2"}'));
386+
*/
387+
const colorStyle = {
388+
color: '#000000',
389+
};
384390
let checkpoint = this.getCheckPoint(r);
385391
if (checkpoint) {
386392
checkpoint = formatDate(checkpoint);
@@ -393,7 +399,7 @@ export default class Registrants extends React.Component {
393399
}
394400

395401
return (
396-
<div styleName="row" key={r.handle} role="row">
402+
<div styleName="row" key={r.memberHandle} role="row">
397403
{
398404
!isDesign && !isF2F && !isBugHunt && (
399405
<div styleName="col-2">
@@ -411,19 +417,19 @@ export default class Registrants extends React.Component {
411417
<div styleName="col-3">
412418
<span role="cell">
413419
<a
414-
href={`${window.origin}/members/${r.handle}`}
420+
href={`${window.origin}/members/${r.memberHandle}`}
415421
style={colorStyle}
416422
target={`${_.includes(window.origin, 'www') ? '_self' : '_blank'}`}
417423
>
418-
{r.handle}
424+
{r.memberHandle}
419425
</a>
420426
</span>
421427
</div>
422428
<div styleName="col-4">
423429
<div styleName="sm-only title">
424430
Registration Date
425431
</div>
426-
<span role="cell">{formatDate(r.registrationDate)}</span>
432+
<span role="cell">{formatDate(r.created)}</span>
427433
</div>
428434
{
429435
twoRounds
@@ -437,7 +443,7 @@ export default class Registrants extends React.Component {
437443
{checkpoint}
438444
</span>
439445
{
440-
passedCheckpoint(checkpoints, r.handle, checkpointResults)
446+
passedCheckpoint(checkpoints, r.memberHandle, checkpointResults)
441447
&& <CheckMark styleName="passed" />
442448
}
443449
</div>
@@ -482,16 +488,16 @@ Registrants.propTypes = {
482488
challenge: PT.shape({
483489
phases: PT.arrayOf(PT.shape({
484490
actualEndDate: PT.string,
485-
phaseType: PT.string.isRequired,
491+
name: PT.string.isRequired,
486492
scheduledEndDate: PT.string,
487493
})).isRequired,
488494
allPhases: PT.arrayOf(PT.shape()),
489495
checkpoints: PT.arrayOf(PT.shape()),
490496
legacy: PT.shape({
491-
track: PT.any,
497+
track: PT.string,
492498
}),
493-
subTrack: PT.any,
494-
prizes: PT.arrayOf(PT.number).isRequired,
499+
type: PT.string,
500+
prizeSets: PT.arrayOf(PT.shape()).isRequired,
495501
registrants: PT.arrayOf(PT.shape()).isRequired,
496502
round1Introduction: PT.string,
497503
round2Introduction: PT.string,

src/shared/components/challenge-detail/Submissions/index.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,8 @@ class SubmissionsComponent extends React.Component {
327327
</div>
328328
);
329329

330-
const isF2F = challenge.subTrack.indexOf('FIRST_2_FINISH') > -1;
331-
const isBugHunt = challenge.subTrack.indexOf('BUG_HUNT') > -1;
330+
const isF2F = challenge.type.toLowerCase().indexOf('first2finish') > -1;
331+
const isBugHunt = challenge.type.toLowerCase() === 'bug hunt';
332332

333333
// copy colorStyle from registrants to submissions
334334
_.forEach(sortedSubmissions, (s) => {
@@ -785,7 +785,7 @@ SubmissionsComponent.propTypes = {
785785
registrants: PT.any,
786786
allPhases: PT.any,
787787
phases: PT.any,
788-
subTrack: PT.any,
788+
type: PT.any,
789789
}).isRequired,
790790
toggleSubmissionHistory: PT.func.isRequired,
791791
submissionHistoryOpen: PT.shape({}).isRequired,

src/shared/components/challenge-listing/ChallengeCard/index.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ function ChallengeCard({
7171
<TrackIcon
7272
track={track}
7373
subTrack={subTrack}
74-
tcoEligible={challenge.events && challenge.events.length > 0 ? challenge.events[0].eventName : ''}
74+
tcoEligible={!_.isEmpty(challenge.events) ? challenge.events[0].eventName : ''}
7575
isDataScience={challenge.isDataScience}
7676
/>
7777
</span>

src/shared/containers/challenge-detail/index.jsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ function isRegistered(details, registrants, handle) {
116116
if (details && details.roles && details.roles.includes('Submitter')) {
117117
return true;
118118
}
119-
if (_.find(registrants, r => _.toString(r.handle) === _.toString(handle))) {
119+
if (_.find(registrants, r => _.toString(r.memberHandle) === _.toString(handle))) {
120120
return true;
121121
}
122122
return false;
@@ -231,6 +231,7 @@ class ChallengeDetailPageContainer extends React.Component {
231231
challenge
232232
&& challenge.id === challengeId
233233
&& !loadingRecommendedChallengesUUID
234+
&& recommendedTechnology
234235
&& (
235236
!recommendedChallenges[recommendedTechnology]
236237
|| (
@@ -731,15 +732,15 @@ function mapStateToProps(state, props) {
731732
if (challenge.submissions) {
732733
challenge.submissions = challenge.submissions.map(submission => ({
733734
...submission,
734-
registrant: _.find(challenge.registrants, { handle: submission.submitter }),
735+
registrant: _.find(challenge.registrants, { memberHandle: submission.createdBy }),
735736
}));
736737
}
737738

738739
if (mmSubmissions) {
739740
mmSubmissions = mmSubmissions.map((submission) => {
740741
let registrant;
741742
let { member } = submission;
742-
if (auth.user.handle === submission.member) {
743+
if (auth.user.handle === submission.memberHandle) {
743744
mySubmissions = submission.submissions || [];
744745
mySubmissions = mySubmissions.map((mySubmission, index) => {
745746
// eslint-disable-next-line no-param-reassign

src/shared/reducers/index.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ function generateSsrOptions(req) {
4545
const res = {
4646
auth: getAuthTokens(req),
4747
};
48-
if (req.url.match(/^\/challenges\/\d+\/my-submissions/)) {
49-
const challengeId = req.url.match(/\d+/)[0];
48+
if (req.url.match(/^\/challenges\/(([\w]{4,12}-?){5}|\d+)\/my-submissions/)) {
49+
const challengeId = req.url.match(/(([\w]{4,12}-?){5}|\d+)/)[0];
5050
_.set(res, 'challenge.challengeDetails.id', challengeId);
5151
_.set(res, 'challenge.challengeDetails.mySubmission', true);
52-
} else if (req.url.match(/\/challenges\/\d+([?/].*)?$/)) {
53-
const challengeId = req.url.match(/\d+/)[0];
52+
} else if (req.url.match(/\/challenges\/(([\w]{4,12}-?){5}|\d+)\/?(\?.*)?$/)) {
53+
const challengeId = req.url.match(/(([\w]{4,12}-?){5}|\d+)/)[0];
5454
_.set(res, 'challenge.challengeDetails.id', challengeId);
5555
}
5656

@@ -62,8 +62,8 @@ function generateSsrOptions(req) {
6262
let entity;
6363
6464
// if it's challenge details page
65-
if (req.url.match(/^\/challenges\/\d+/)) {
66-
const challengeId = req.url.match(/\d+/)[0];
65+
if (req.url.match(/^\/challenges\/(([\w]{4,12}-?){5}|\d+)/)) {
66+
const challengeId = req.url.match(/(([\w]{4,12}-?){5}|\d+)/)[0];
6767
entity = { type: 'challenge', id: challengeId };
6868
}
6969

0 commit comments

Comments
 (0)