Skip to content

Commit 292181e

Browse files
authored
Merge pull request #4567 from nursoltan-s/issue-4557
fix my challenges page
2 parents bd7a835 + 7902941 commit 292181e

File tree

5 files changed

+74
-54
lines changed

5 files changed

+74
-54
lines changed

src/shared/components/Dashboard/CurrentActivity/Challenges/ChallengeCard/index.jsx

+40-53
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import NumSubmissions from
77
'components/challenge-listing/ChallengeCard/NumSubmissions';
88
import PT from 'prop-types';
99
import React from 'react';
10+
import {
11+
getTimeLeft,
12+
} from 'utils/challenge-detail/helper';
1013

1114
import { config, Link } from 'topcoder-react-utils';
1215

@@ -23,12 +26,6 @@ import {
2326

2427
import style from './style.scss';
2528

26-
/* Holds day and hour range in ms. */
27-
const HOUR_MS = 60 * 60 * 1000;
28-
const DAY_MS = 24 * HOUR_MS;
29-
30-
const ALERT_TIME = 24 * HOUR_MS;
31-
3229
function normalizeSubTrackTagForRendering(subTrack) {
3330
let x;
3431
switch (subTrack) {
@@ -43,14 +40,15 @@ export default function ChallengeCard({
4340
selectChallengeDetailsTab,
4441
setChallengeListingFilter,
4542
// unregisterFromChallenge,
43+
userResources,
4644
}) {
4745
const {
4846
phases,
4947
legacy,
5048
id,
51-
registrationStartDate,
5249
status,
5350
userDetails,
51+
type,
5452
} = challenge;
5553

5654
const { track } = legacy;
@@ -74,6 +72,9 @@ export default function ChallengeCard({
7472
EventTag = DevelopmentTrackEventTag;
7573
}
7674

75+
const STALLED_MSG = 'Stalled';
76+
const DRAFT_MSG = 'In Draft';
77+
7778
const forumEndpoint = _.toLower(legacy.track) === 'design'
7879
? `/?module=ThreadList&forumID=${legacy.forumId}`
7980
: `/?module=Category&categoryID=${legacy.forumId}`;
@@ -82,6 +83,7 @@ export default function ChallengeCard({
8283
&& challenge.events.find(x => x.eventName && x.eventName.match(/tco\d{2}/));
8384

8485
const roles = _.get(userDetails, 'roles') || [];
86+
const role = _.find(userResources, { id }) || {};
8587

8688
const showDirectLink = _.intersection(roles, [
8789
'Approver',
@@ -94,63 +96,42 @@ export default function ChallengeCard({
9496
'Reviewer',
9597
]).length;
9698

97-
const submitter = roles.includes('Submitter');
99+
const submitter = role.name === 'Submitter';
98100
const submitted = _.get(userDetails, 'hasUserSubmittedForReview');
99101
const nextPhase = phases && _.last(phases);
100102

103+
const submissionPhase = _.find(phases, { name: 'Submission' });
101104
const nextPhaseType = _.get(nextPhase, 'phaseType');
102105

103106
if (submitted && _.intersection(nextPhaseType, [
104107
'Appeals',
105108
'Appeal Response',
106109
]).length) showOrLink = true;
107110

108-
const submissionOpen = nextPhaseType === 'Submission';
109-
110-
let statusMsg;
111-
let deadlineMsg;
112-
let msgStyleModifier = '';
113-
const now = moment();
114-
if (nextPhase) {
115-
statusMsg = nextPhase.name;
116-
const deadlineEnd = moment(nextPhase.scheduledEndDate);
117-
deadlineMsg = deadlineEnd.diff(now);
118-
const late = deadlineMsg <= 0;
119-
deadlineMsg = Math.abs(deadlineMsg);
120-
121-
if (late) msgStyleModifier = ' alert';
122-
else if (deadlineMsg < ALERT_TIME) msgStyleModifier = ' warning';
111+
const submissionOpen = moment(submissionPhase.scheduledEndDate).isSameOrAfter(new Date());
123112

124-
let format;
125-
if (deadlineMsg > DAY_MS) format = 'D[d] H[h]';
126-
else if (deadlineMsg > HOUR_MS) format = 'H[h] m[min]';
127-
else format = 'm[min] s[s]';
113+
const allPhases = phases || [];
114+
let statusPhase = allPhases
115+
.filter(p => p.name !== 'Registration' && p.isOpen)
116+
.sort((a, b) => moment(a.scheduledEndDate).diff(b.scheduledEndDate))[0];
128117

129-
deadlineMsg = moment.duration(deadlineMsg).format(format);
130-
deadlineMsg = late ? `Late for ${deadlineMsg}` : `Ends in ${deadlineMsg}`;
131-
} else if (moment(registrationStartDate).isAfter(now)) {
132-
deadlineMsg = moment(registrationStartDate).diff(now);
133-
const late = deadlineMsg <= 0;
134-
deadlineMsg = Math.abs(deadlineMsg);
118+
if (!statusPhase && type === 'FIRST_2_FINISH' && allPhases.length) {
119+
statusPhase = _.clone(allPhases[0]);
120+
statusPhase.name = 'Submission';
121+
}
135122

136-
if (late) msgStyleModifier = ' alert';
137-
else if (deadlineMsg < ALERT_TIME) msgStyleModifier = ' warning';
123+
let phaseMessage = STALLED_MSG;
124+
if (statusPhase) phaseMessage = statusPhase.name;
125+
else if (status === 'Draft') phaseMessage = DRAFT_MSG;
138126

139-
let format;
140-
if (deadlineMsg > DAY_MS) format = 'D[d] H[h]';
141-
else if (deadlineMsg > HOUR_MS) format = 'H[h] m[min]';
142-
else format = 'm[min] s[s]';
127+
let msgStyleModifier = '';
128+
const now = moment();
129+
const deadlineEnd = moment(nextPhase.scheduledEndDate);
130+
const late = deadlineEnd.diff(now) <= 0;
131+
const statusMsg = phaseMessage;
132+
const deadlineMsg = getTimeLeft(statusPhase, 'to go').text;
143133

144-
deadlineMsg = moment.duration(deadlineMsg).format(format);
145-
deadlineMsg = late ? `Late by ${deadlineMsg}` : `Starts in ${deadlineMsg}`;
146-
147-
statusMsg = 'Scheduled';
148-
} else if (status === 'Completed') {
149-
statusMsg = 'Completed';
150-
} else {
151-
msgStyleModifier = ' alert';
152-
statusMsg = 'Stalled';
153-
}
134+
if (late || phaseMessage === STALLED_MSG) msgStyleModifier = ' alert';
154135

155136
return (
156137
<div styleName="container">
@@ -160,14 +141,14 @@ export default function ChallengeCard({
160141
<EventTag
161142
onClick={
162143
() => setImmediate(
163-
() => setChallengeListingFilter({ subtracks: [track] }),
144+
() => setChallengeListingFilter({ subtracks: [type] }),
164145
)
165146
}
166147
theme={{ button: style.tag }}
167148
to={`/challenges?filter[subtracks][0]=${
168-
encodeURIComponent(track)}`}
149+
encodeURIComponent(type)}`}
169150
>
170-
{normalizeSubTrackTagForRendering(track)}
151+
{normalizeSubTrackTagForRendering(type)}
171152
</EventTag>
172153
{
173154
isTco ? (
@@ -267,13 +248,17 @@ export default function ChallengeCard({
267248
</div>
268249
<div>
269250
<div styleName="roles">
270-
{roles.join(', ')}
251+
{ role.name }
271252
</div>
272253
</div>
273254
</div>
274255
);
275256
}
276257

258+
ChallengeCard.defaultProps = {
259+
userResources: [],
260+
};
261+
277262
ChallengeCard.propTypes = {
278263
challenge: PT.shape({
279264
legacy: PT.shape({
@@ -287,8 +272,10 @@ ChallengeCard.propTypes = {
287272
status: PT.any,
288273
userDetails: PT.any,
289274
events: PT.any,
275+
type: PT.string,
290276
}).isRequired,
291277
selectChallengeDetailsTab: PT.func.isRequired,
292278
setChallengeListingFilter: PT.func.isRequired,
293279
// unregisterFromChallenge: PT.func.isRequired,
280+
userResources: PT.arrayOf(PT.shape()),
294281
};

src/shared/components/Dashboard/CurrentActivity/Challenges/index.jsx

+7
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export default function Challenges({
2727
switchChallengeFilter,
2828
switchShowChallengeFilter,
2929
unregisterFromChallenge,
30+
userResources,
3031
}) {
3132
if (challengesLoading) {
3233
return (
@@ -74,6 +75,7 @@ export default function Challenges({
7475
selectChallengeDetailsTab={selectChallengeDetailsTab}
7576
setChallengeListingFilter={setChallengeListingFilter}
7677
unregisterFromChallenge={unregisterFromChallenge}
78+
userResources={userResources}
7779
/>
7880
))
7981
) : (
@@ -144,6 +146,10 @@ export default function Challenges({
144146
);
145147
}
146148

149+
Challenges.defaultProps = {
150+
userResources: [],
151+
};
152+
147153
Challenges.propTypes = {
148154
challengeFilter: PT.string.isRequired,
149155
challenges: PT.arrayOf(PT.object).isRequired,
@@ -156,4 +162,5 @@ Challenges.propTypes = {
156162
switchChallengeFilter: PT.func.isRequired,
157163
switchShowChallengeFilter: PT.func.isRequired,
158164
unregisterFromChallenge: PT.func.isRequired,
165+
userResources: PT.arrayOf(PT.shape()),
159166
};

src/shared/components/Dashboard/CurrentActivity/index.jsx

+4
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ export default class MyChallenges extends React.Component {
6969
tab,
7070
unregisterFromChallenge,
7171
userGroups,
72+
userResources,
7273
} = this.props;
7374

7475
const myCommunities = communities.filter(x => _.intersection(userGroups, x.groupIds).length)
@@ -105,6 +106,7 @@ export default class MyChallenges extends React.Component {
105106
switchChallengeFilter={switchChallengeFilter}
106107
switchShowChallengeFilter={switchShowChallengeFilter}
107108
unregisterFromChallenge={unregisterFromChallenge}
109+
userResources={userResources}
108110
/>
109111
) : null
110112
}
@@ -132,6 +134,7 @@ export default class MyChallenges extends React.Component {
132134

133135
MyChallenges.defaultProps = {
134136
challenges: [],
137+
userResources: [],
135138
};
136139

137140
MyChallenges.propTypes = {
@@ -152,4 +155,5 @@ MyChallenges.propTypes = {
152155
tab: PT.oneOf(_.values(TABS)).isRequired,
153156
unregisterFromChallenge: PT.func.isRequired,
154157
userGroups: PT.arrayOf(PT.string).isRequired,
158+
userResources: PT.arrayOf(PT.shape()),
155159
};

src/shared/components/Dashboard/index.jsx

+4
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export default function Dashboard({
4141
userGroups,
4242
xlBadge,
4343
// errorLoadingRss,
44+
userResources,
4445
}) {
4546
return (
4647
<div styleName="container">
@@ -81,6 +82,7 @@ export default function Dashboard({
8182
tab={tab}
8283
unregisterFromChallenge={unregisterFromChallenge}
8384
userGroups={userGroups}
85+
userResources={userResources}
8486
/>
8587
{/* {!errorLoadingRss && (
8688
<CommunityBlog isLoading={tcBlogLoading} posts={tcBlogPosts} />
@@ -92,6 +94,7 @@ export default function Dashboard({
9294

9395
Dashboard.defaultProps = {
9496
announcementPreviewId: '',
97+
userResources: [],
9598
};
9699

97100
Dashboard.propTypes = {
@@ -126,4 +129,5 @@ Dashboard.propTypes = {
126129
userGroups: PT.arrayOf(PT.string).isRequired,
127130
xlBadge: PT.string.isRequired,
128131
// errorLoadingRss: PT.bool.isRequired,
132+
userResources: PT.arrayOf(PT.shape()),
129133
};

src/shared/containers/Dashboard/index.jsx

+19-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { updateChallengeType } from 'utils/challenge';
2525
import challengeListingActions from 'actions/challenge-listing';
2626
import communityActions from 'actions/tc-communities';
2727

28-
import { isTokenExpired } from 'tc-accounts';
28+
import { isTokenExpired, decodeToken } from 'tc-accounts';
2929
import { config, isomorphy } from 'topcoder-react-utils';
3030

3131
import './styles.scss';
@@ -62,11 +62,16 @@ export class DashboardPageContainer extends React.Component {
6262
const {
6363
challengeFilter,
6464
switchChallengeFilter,
65+
getMemberResources,
66+
tokenV3,
6567
} = this.props;
6668

6769
this.updateData(this.props);
6870

6971
if (challengeFilter) switchChallengeFilter('');
72+
73+
const user = decodeToken(tokenV3);
74+
getMemberResources(user.userId, tokenV3);
7075
}
7176

7277
componentWillReceiveProps(nextProps) {
@@ -187,8 +192,11 @@ export class DashboardPageContainer extends React.Component {
187192
userGroups,
188193
xlBadge,
189194
errorLoadingRss,
195+
userResources,
190196
} = this.props;
191197

198+
// console.log('r', userResources);
199+
192200
if (authenticating) return <LoadingIndicator />;
193201

194202
let announcementPreviewId;
@@ -229,6 +237,7 @@ export class DashboardPageContainer extends React.Component {
229237
userGroups={userGroups.map(x => x.id)}
230238
xlBadge={xlBadge}
231239
errorLoadingRss={errorLoadingRss}
240+
userResources={userResources ? userResources.resources : []}
232241
/>
233242
);
234243
}
@@ -249,6 +258,7 @@ DashboardPageContainer.defaultProps = {
249258
tokenV2: null,
250259
tokenV3: null,
251260
errorLoadingRss: false,
261+
userResources: {},
252262
};
253263

254264
DashboardPageContainer.propTypes = {
@@ -302,6 +312,8 @@ DashboardPageContainer.propTypes = {
302312
userGroups: PT.arrayOf(PT.object).isRequired,
303313
xlBadge: PT.string.isRequired,
304314
errorLoadingRss: PT.bool,
315+
getMemberResources: PT.func.isRequired,
316+
userResources: PT.shape(),
305317
};
306318

307319
function mapStateToProps(state, props) {
@@ -357,6 +369,7 @@ function mapStateToProps(state, props) {
357369
userGroups: _.get(state.auth.profile, 'groups', []),
358370
xlBadge: dash.xlBadge,
359371
errorLoadingRss: state.rss.errorLoadingRss,
372+
userResources: state.members.userResources,
360373
};
361374
}
362375

@@ -395,6 +408,11 @@ function mapDispatchToProps(dispatch) {
395408
dispatch(members.getStatsInit(handle, uuid));
396409
dispatch(members.getStatsDone(handle, uuid, tokenV3));
397410
},
411+
getMemberResources: (memberId, tokenV3) => {
412+
const uuid = shortId();
413+
dispatch(members.getUserResourcesInit(memberId, uuid));
414+
dispatch(members.getUserResourcesDone(memberId, tokenV3, uuid));
415+
},
398416
getSrms: (handle, tokenV3) => {
399417
const uuid = shortId();
400418
const a = challengeListingActions.challengeListing;

0 commit comments

Comments
 (0)