@@ -7,6 +7,9 @@ import NumSubmissions from
7
7
'components/challenge-listing/ChallengeCard/NumSubmissions' ;
8
8
import PT from 'prop-types' ;
9
9
import React from 'react' ;
10
+ import {
11
+ getTimeLeft ,
12
+ } from 'utils/challenge-detail/helper' ;
10
13
11
14
import { config , Link } from 'topcoder-react-utils' ;
12
15
@@ -23,12 +26,6 @@ import {
23
26
24
27
import style from './style.scss' ;
25
28
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
-
32
29
function normalizeSubTrackTagForRendering ( subTrack ) {
33
30
let x ;
34
31
switch ( subTrack ) {
@@ -43,14 +40,15 @@ export default function ChallengeCard({
43
40
selectChallengeDetailsTab,
44
41
setChallengeListingFilter,
45
42
// unregisterFromChallenge,
43
+ userResources,
46
44
} ) {
47
45
const {
48
46
phases,
49
47
legacy,
50
48
id,
51
- registrationStartDate,
52
49
status,
53
50
userDetails,
51
+ type,
54
52
} = challenge ;
55
53
56
54
const { track } = legacy ;
@@ -74,6 +72,9 @@ export default function ChallengeCard({
74
72
EventTag = DevelopmentTrackEventTag ;
75
73
}
76
74
75
+ const STALLED_MSG = 'Stalled' ;
76
+ const DRAFT_MSG = 'In Draft' ;
77
+
77
78
const forumEndpoint = _ . toLower ( legacy . track ) === 'design'
78
79
? `/?module=ThreadList&forumID=${ legacy . forumId } `
79
80
: `/?module=Category&categoryID=${ legacy . forumId } ` ;
@@ -82,6 +83,7 @@ export default function ChallengeCard({
82
83
&& challenge . events . find ( x => x . eventName && x . eventName . match ( / t c o \d { 2 } / ) ) ;
83
84
84
85
const roles = _ . get ( userDetails , 'roles' ) || [ ] ;
86
+ const role = _ . find ( userResources , { id } ) || { } ;
85
87
86
88
const showDirectLink = _ . intersection ( roles , [
87
89
'Approver' ,
@@ -94,63 +96,42 @@ export default function ChallengeCard({
94
96
'Reviewer' ,
95
97
] ) . length ;
96
98
97
- const submitter = roles . includes ( 'Submitter' ) ;
99
+ const submitter = role . name === 'Submitter' ;
98
100
const submitted = _ . get ( userDetails , 'hasUserSubmittedForReview' ) ;
99
101
const nextPhase = phases && _ . last ( phases ) ;
100
102
103
+ const submissionPhase = _ . find ( phases , { name : 'Submission' } ) ;
101
104
const nextPhaseType = _ . get ( nextPhase , 'phaseType' ) ;
102
105
103
106
if ( submitted && _ . intersection ( nextPhaseType , [
104
107
'Appeals' ,
105
108
'Appeal Response' ,
106
109
] ) . length ) showOrLink = true ;
107
110
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 ( ) ) ;
123
112
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 ] ;
128
117
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
+ }
135
122
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 ;
138
126
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 ;
143
133
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' ;
154
135
155
136
return (
156
137
< div styleName = "container" >
@@ -160,14 +141,14 @@ export default function ChallengeCard({
160
141
< EventTag
161
142
onClick = {
162
143
( ) => setImmediate (
163
- ( ) => setChallengeListingFilter ( { subtracks : [ track ] } ) ,
144
+ ( ) => setChallengeListingFilter ( { subtracks : [ type ] } ) ,
164
145
)
165
146
}
166
147
theme = { { button : style . tag } }
167
148
to = { `/challenges?filter[subtracks][0]=${
168
- encodeURIComponent ( track ) } `}
149
+ encodeURIComponent ( type ) } `}
169
150
>
170
- { normalizeSubTrackTagForRendering ( track ) }
151
+ { normalizeSubTrackTagForRendering ( type ) }
171
152
</ EventTag >
172
153
{
173
154
isTco ? (
@@ -267,13 +248,17 @@ export default function ChallengeCard({
267
248
</ div >
268
249
< div >
269
250
< div styleName = "roles" >
270
- { roles . join ( ', ' ) }
251
+ { role . name }
271
252
</ div >
272
253
</ div >
273
254
</ div >
274
255
) ;
275
256
}
276
257
258
+ ChallengeCard . defaultProps = {
259
+ userResources : [ ] ,
260
+ } ;
261
+
277
262
ChallengeCard . propTypes = {
278
263
challenge : PT . shape ( {
279
264
legacy : PT . shape ( {
@@ -287,8 +272,10 @@ ChallengeCard.propTypes = {
287
272
status : PT . any ,
288
273
userDetails : PT . any ,
289
274
events : PT . any ,
275
+ type : PT . string ,
290
276
} ) . isRequired ,
291
277
selectChallengeDetailsTab : PT . func . isRequired ,
292
278
setChallengeListingFilter : PT . func . isRequired ,
293
279
// unregisterFromChallenge: PT.func.isRequired,
280
+ userResources : PT . arrayOf ( PT . shape ( ) ) ,
294
281
} ;
0 commit comments