From 7902941d74f6067f5955a00bdf3185dc12a5f7f3 Mon Sep 17 00:00:00 2001 From: Nursoltan Saipolda Date: Fri, 19 Jun 2020 15:23:28 +0800 Subject: [PATCH] fix my challenges page --- .../Challenges/ChallengeCard/index.jsx | 93 ++++++++----------- .../CurrentActivity/Challenges/index.jsx | 7 ++ .../Dashboard/CurrentActivity/index.jsx | 4 + src/shared/components/Dashboard/index.jsx | 4 + src/shared/containers/Dashboard/index.jsx | 20 +++- 5 files changed, 74 insertions(+), 54 deletions(-) diff --git a/src/shared/components/Dashboard/CurrentActivity/Challenges/ChallengeCard/index.jsx b/src/shared/components/Dashboard/CurrentActivity/Challenges/ChallengeCard/index.jsx index dcca9fa9a9..4f4822c6fa 100644 --- a/src/shared/components/Dashboard/CurrentActivity/Challenges/ChallengeCard/index.jsx +++ b/src/shared/components/Dashboard/CurrentActivity/Challenges/ChallengeCard/index.jsx @@ -7,6 +7,9 @@ import NumSubmissions from 'components/challenge-listing/ChallengeCard/NumSubmissions'; import PT from 'prop-types'; import React from 'react'; +import { + getTimeLeft, +} from 'utils/challenge-detail/helper'; import { config, Link } from 'topcoder-react-utils'; @@ -23,12 +26,6 @@ import { import style from './style.scss'; -/* Holds day and hour range in ms. */ -const HOUR_MS = 60 * 60 * 1000; -const DAY_MS = 24 * HOUR_MS; - -const ALERT_TIME = 24 * HOUR_MS; - function normalizeSubTrackTagForRendering(subTrack) { let x; switch (subTrack) { @@ -43,14 +40,15 @@ export default function ChallengeCard({ selectChallengeDetailsTab, setChallengeListingFilter, // unregisterFromChallenge, + userResources, }) { const { phases, legacy, id, - registrationStartDate, status, userDetails, + type, } = challenge; const { track } = legacy; @@ -74,6 +72,9 @@ export default function ChallengeCard({ EventTag = DevelopmentTrackEventTag; } + const STALLED_MSG = 'Stalled'; + const DRAFT_MSG = 'In Draft'; + const forumEndpoint = _.toLower(legacy.track) === 'design' ? `/?module=ThreadList&forumID=${legacy.forumId}` : `/?module=Category&categoryID=${legacy.forumId}`; @@ -82,6 +83,7 @@ export default function ChallengeCard({ && challenge.events.find(x => x.eventName && x.eventName.match(/tco\d{2}/)); const roles = _.get(userDetails, 'roles') || []; + const role = _.find(userResources, { id }) || {}; const showDirectLink = _.intersection(roles, [ 'Approver', @@ -94,10 +96,11 @@ export default function ChallengeCard({ 'Reviewer', ]).length; - const submitter = roles.includes('Submitter'); + const submitter = role.name === 'Submitter'; const submitted = _.get(userDetails, 'hasUserSubmittedForReview'); const nextPhase = phases && _.last(phases); + const submissionPhase = _.find(phases, { name: 'Submission' }); const nextPhaseType = _.get(nextPhase, 'phaseType'); if (submitted && _.intersection(nextPhaseType, [ @@ -105,52 +108,30 @@ export default function ChallengeCard({ 'Appeal Response', ]).length) showOrLink = true; - const submissionOpen = nextPhaseType === 'Submission'; - - let statusMsg; - let deadlineMsg; - let msgStyleModifier = ''; - const now = moment(); - if (nextPhase) { - statusMsg = nextPhase.name; - const deadlineEnd = moment(nextPhase.scheduledEndDate); - deadlineMsg = deadlineEnd.diff(now); - const late = deadlineMsg <= 0; - deadlineMsg = Math.abs(deadlineMsg); - - if (late) msgStyleModifier = ' alert'; - else if (deadlineMsg < ALERT_TIME) msgStyleModifier = ' warning'; + const submissionOpen = moment(submissionPhase.scheduledEndDate).isSameOrAfter(new Date()); - let format; - if (deadlineMsg > DAY_MS) format = 'D[d] H[h]'; - else if (deadlineMsg > HOUR_MS) format = 'H[h] m[min]'; - else format = 'm[min] s[s]'; + const allPhases = phases || []; + let statusPhase = allPhases + .filter(p => p.name !== 'Registration' && p.isOpen) + .sort((a, b) => moment(a.scheduledEndDate).diff(b.scheduledEndDate))[0]; - deadlineMsg = moment.duration(deadlineMsg).format(format); - deadlineMsg = late ? `Late for ${deadlineMsg}` : `Ends in ${deadlineMsg}`; - } else if (moment(registrationStartDate).isAfter(now)) { - deadlineMsg = moment(registrationStartDate).diff(now); - const late = deadlineMsg <= 0; - deadlineMsg = Math.abs(deadlineMsg); + if (!statusPhase && type === 'FIRST_2_FINISH' && allPhases.length) { + statusPhase = _.clone(allPhases[0]); + statusPhase.name = 'Submission'; + } - if (late) msgStyleModifier = ' alert'; - else if (deadlineMsg < ALERT_TIME) msgStyleModifier = ' warning'; + let phaseMessage = STALLED_MSG; + if (statusPhase) phaseMessage = statusPhase.name; + else if (status === 'Draft') phaseMessage = DRAFT_MSG; - let format; - if (deadlineMsg > DAY_MS) format = 'D[d] H[h]'; - else if (deadlineMsg > HOUR_MS) format = 'H[h] m[min]'; - else format = 'm[min] s[s]'; + let msgStyleModifier = ''; + const now = moment(); + const deadlineEnd = moment(nextPhase.scheduledEndDate); + const late = deadlineEnd.diff(now) <= 0; + const statusMsg = phaseMessage; + const deadlineMsg = getTimeLeft(statusPhase, 'to go').text; - deadlineMsg = moment.duration(deadlineMsg).format(format); - deadlineMsg = late ? `Late by ${deadlineMsg}` : `Starts in ${deadlineMsg}`; - - statusMsg = 'Scheduled'; - } else if (status === 'Completed') { - statusMsg = 'Completed'; - } else { - msgStyleModifier = ' alert'; - statusMsg = 'Stalled'; - } + if (late || phaseMessage === STALLED_MSG) msgStyleModifier = ' alert'; return (
@@ -160,14 +141,14 @@ export default function ChallengeCard({ setImmediate( - () => setChallengeListingFilter({ subtracks: [track] }), + () => setChallengeListingFilter({ subtracks: [type] }), ) } theme={{ button: style.tag }} to={`/challenges?filter[subtracks][0]=${ - encodeURIComponent(track)}`} + encodeURIComponent(type)}`} > - {normalizeSubTrackTagForRendering(track)} + {normalizeSubTrackTagForRendering(type)} { isTco ? ( @@ -267,13 +248,17 @@ export default function ChallengeCard({
- {roles.join(', ')} + { role.name }
); } +ChallengeCard.defaultProps = { + userResources: [], +}; + ChallengeCard.propTypes = { challenge: PT.shape({ legacy: PT.shape({ @@ -287,8 +272,10 @@ ChallengeCard.propTypes = { status: PT.any, userDetails: PT.any, events: PT.any, + type: PT.string, }).isRequired, selectChallengeDetailsTab: PT.func.isRequired, setChallengeListingFilter: PT.func.isRequired, // unregisterFromChallenge: PT.func.isRequired, + userResources: PT.arrayOf(PT.shape()), }; diff --git a/src/shared/components/Dashboard/CurrentActivity/Challenges/index.jsx b/src/shared/components/Dashboard/CurrentActivity/Challenges/index.jsx index f653268537..7b25cb68af 100644 --- a/src/shared/components/Dashboard/CurrentActivity/Challenges/index.jsx +++ b/src/shared/components/Dashboard/CurrentActivity/Challenges/index.jsx @@ -27,6 +27,7 @@ export default function Challenges({ switchChallengeFilter, switchShowChallengeFilter, unregisterFromChallenge, + userResources, }) { if (challengesLoading) { return ( @@ -74,6 +75,7 @@ export default function Challenges({ selectChallengeDetailsTab={selectChallengeDetailsTab} setChallengeListingFilter={setChallengeListingFilter} unregisterFromChallenge={unregisterFromChallenge} + userResources={userResources} /> )) ) : ( @@ -144,6 +146,10 @@ export default function Challenges({ ); } +Challenges.defaultProps = { + userResources: [], +}; + Challenges.propTypes = { challengeFilter: PT.string.isRequired, challenges: PT.arrayOf(PT.object).isRequired, @@ -156,4 +162,5 @@ Challenges.propTypes = { switchChallengeFilter: PT.func.isRequired, switchShowChallengeFilter: PT.func.isRequired, unregisterFromChallenge: PT.func.isRequired, + userResources: PT.arrayOf(PT.shape()), }; diff --git a/src/shared/components/Dashboard/CurrentActivity/index.jsx b/src/shared/components/Dashboard/CurrentActivity/index.jsx index d6232dc52a..c949629257 100644 --- a/src/shared/components/Dashboard/CurrentActivity/index.jsx +++ b/src/shared/components/Dashboard/CurrentActivity/index.jsx @@ -69,6 +69,7 @@ export default class MyChallenges extends React.Component { tab, unregisterFromChallenge, userGroups, + userResources, } = this.props; const myCommunities = communities.filter(x => _.intersection(userGroups, x.groupIds).length) @@ -105,6 +106,7 @@ export default class MyChallenges extends React.Component { switchChallengeFilter={switchChallengeFilter} switchShowChallengeFilter={switchShowChallengeFilter} unregisterFromChallenge={unregisterFromChallenge} + userResources={userResources} /> ) : null } @@ -132,6 +134,7 @@ export default class MyChallenges extends React.Component { MyChallenges.defaultProps = { challenges: [], + userResources: [], }; MyChallenges.propTypes = { @@ -152,4 +155,5 @@ MyChallenges.propTypes = { tab: PT.oneOf(_.values(TABS)).isRequired, unregisterFromChallenge: PT.func.isRequired, userGroups: PT.arrayOf(PT.string).isRequired, + userResources: PT.arrayOf(PT.shape()), }; diff --git a/src/shared/components/Dashboard/index.jsx b/src/shared/components/Dashboard/index.jsx index 4879945940..09fe332d66 100644 --- a/src/shared/components/Dashboard/index.jsx +++ b/src/shared/components/Dashboard/index.jsx @@ -41,6 +41,7 @@ export default function Dashboard({ userGroups, xlBadge, // errorLoadingRss, + userResources, }) { return (
@@ -81,6 +82,7 @@ export default function Dashboard({ tab={tab} unregisterFromChallenge={unregisterFromChallenge} userGroups={userGroups} + userResources={userResources} /> {/* {!errorLoadingRss && ( @@ -92,6 +94,7 @@ export default function Dashboard({ Dashboard.defaultProps = { announcementPreviewId: '', + userResources: [], }; Dashboard.propTypes = { @@ -126,4 +129,5 @@ Dashboard.propTypes = { userGroups: PT.arrayOf(PT.string).isRequired, xlBadge: PT.string.isRequired, // errorLoadingRss: PT.bool.isRequired, + userResources: PT.arrayOf(PT.shape()), }; diff --git a/src/shared/containers/Dashboard/index.jsx b/src/shared/containers/Dashboard/index.jsx index 91545fd723..bb1aaefaa0 100644 --- a/src/shared/containers/Dashboard/index.jsx +++ b/src/shared/containers/Dashboard/index.jsx @@ -25,7 +25,7 @@ import { updateChallengeType } from 'utils/challenge'; import challengeListingActions from 'actions/challenge-listing'; import communityActions from 'actions/tc-communities'; -import { isTokenExpired } from 'tc-accounts'; +import { isTokenExpired, decodeToken } from 'tc-accounts'; import { config, isomorphy } from 'topcoder-react-utils'; import './styles.scss'; @@ -62,11 +62,16 @@ export class DashboardPageContainer extends React.Component { const { challengeFilter, switchChallengeFilter, + getMemberResources, + tokenV3, } = this.props; this.updateData(this.props); if (challengeFilter) switchChallengeFilter(''); + + const user = decodeToken(tokenV3); + getMemberResources(user.userId, tokenV3); } componentWillReceiveProps(nextProps) { @@ -187,8 +192,11 @@ export class DashboardPageContainer extends React.Component { userGroups, xlBadge, errorLoadingRss, + userResources, } = this.props; + // console.log('r', userResources); + if (authenticating) return ; let announcementPreviewId; @@ -229,6 +237,7 @@ export class DashboardPageContainer extends React.Component { userGroups={userGroups.map(x => x.id)} xlBadge={xlBadge} errorLoadingRss={errorLoadingRss} + userResources={userResources ? userResources.resources : []} /> ); } @@ -249,6 +258,7 @@ DashboardPageContainer.defaultProps = { tokenV2: null, tokenV3: null, errorLoadingRss: false, + userResources: {}, }; DashboardPageContainer.propTypes = { @@ -302,6 +312,8 @@ DashboardPageContainer.propTypes = { userGroups: PT.arrayOf(PT.object).isRequired, xlBadge: PT.string.isRequired, errorLoadingRss: PT.bool, + getMemberResources: PT.func.isRequired, + userResources: PT.shape(), }; function mapStateToProps(state, props) { @@ -357,6 +369,7 @@ function mapStateToProps(state, props) { userGroups: _.get(state.auth.profile, 'groups', []), xlBadge: dash.xlBadge, errorLoadingRss: state.rss.errorLoadingRss, + userResources: state.members.userResources, }; } @@ -395,6 +408,11 @@ function mapDispatchToProps(dispatch) { dispatch(members.getStatsInit(handle, uuid)); dispatch(members.getStatsDone(handle, uuid, tokenV3)); }, + getMemberResources: (memberId, tokenV3) => { + const uuid = shortId(); + dispatch(members.getUserResourcesInit(memberId, uuid)); + dispatch(members.getUserResourcesDone(memberId, tokenV3, uuid)); + }, getSrms: (handle, tokenV3) => { const uuid = shortId(); const a = challengeListingActions.challengeListing;