Skip to content

fix my challenges page #4567

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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) {
Expand All @@ -43,14 +40,15 @@ export default function ChallengeCard({
selectChallengeDetailsTab,
setChallengeListingFilter,
// unregisterFromChallenge,
userResources,
}) {
const {
phases,
legacy,
id,
registrationStartDate,
status,
userDetails,
type,
} = challenge;

const { track } = legacy;
Expand All @@ -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}`;
Expand All @@ -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',
Expand All @@ -94,63 +96,42 @@ 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, [
'Appeals',
'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 (
<div styleName="container">
Expand All @@ -160,14 +141,14 @@ export default function ChallengeCard({
<EventTag
onClick={
() => setImmediate(
() => setChallengeListingFilter({ subtracks: [track] }),
() => setChallengeListingFilter({ subtracks: [type] }),
)
}
theme={{ button: style.tag }}
to={`/challenges?filter[subtracks][0]=${
encodeURIComponent(track)}`}
encodeURIComponent(type)}`}
>
{normalizeSubTrackTagForRendering(track)}
{normalizeSubTrackTagForRendering(type)}
</EventTag>
{
isTco ? (
Expand Down Expand Up @@ -267,13 +248,17 @@ export default function ChallengeCard({
</div>
<div>
<div styleName="roles">
{roles.join(', ')}
{ role.name }
</div>
</div>
</div>
);
}

ChallengeCard.defaultProps = {
userResources: [],
};

ChallengeCard.propTypes = {
challenge: PT.shape({
legacy: PT.shape({
Expand All @@ -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()),
};
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export default function Challenges({
switchChallengeFilter,
switchShowChallengeFilter,
unregisterFromChallenge,
userResources,
}) {
if (challengesLoading) {
return (
Expand Down Expand Up @@ -74,6 +75,7 @@ export default function Challenges({
selectChallengeDetailsTab={selectChallengeDetailsTab}
setChallengeListingFilter={setChallengeListingFilter}
unregisterFromChallenge={unregisterFromChallenge}
userResources={userResources}
/>
))
) : (
Expand Down Expand Up @@ -144,6 +146,10 @@ export default function Challenges({
);
}

Challenges.defaultProps = {
userResources: [],
};

Challenges.propTypes = {
challengeFilter: PT.string.isRequired,
challenges: PT.arrayOf(PT.object).isRequired,
Expand All @@ -156,4 +162,5 @@ Challenges.propTypes = {
switchChallengeFilter: PT.func.isRequired,
switchShowChallengeFilter: PT.func.isRequired,
unregisterFromChallenge: PT.func.isRequired,
userResources: PT.arrayOf(PT.shape()),
};
4 changes: 4 additions & 0 deletions src/shared/components/Dashboard/CurrentActivity/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -105,6 +106,7 @@ export default class MyChallenges extends React.Component {
switchChallengeFilter={switchChallengeFilter}
switchShowChallengeFilter={switchShowChallengeFilter}
unregisterFromChallenge={unregisterFromChallenge}
userResources={userResources}
/>
) : null
}
Expand Down Expand Up @@ -132,6 +134,7 @@ export default class MyChallenges extends React.Component {

MyChallenges.defaultProps = {
challenges: [],
userResources: [],
};

MyChallenges.propTypes = {
Expand All @@ -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()),
};
4 changes: 4 additions & 0 deletions src/shared/components/Dashboard/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export default function Dashboard({
userGroups,
xlBadge,
// errorLoadingRss,
userResources,
}) {
return (
<div styleName="container">
Expand Down Expand Up @@ -81,6 +82,7 @@ export default function Dashboard({
tab={tab}
unregisterFromChallenge={unregisterFromChallenge}
userGroups={userGroups}
userResources={userResources}
/>
{/* {!errorLoadingRss && (
<CommunityBlog isLoading={tcBlogLoading} posts={tcBlogPosts} />
Expand All @@ -92,6 +94,7 @@ export default function Dashboard({

Dashboard.defaultProps = {
announcementPreviewId: '',
userResources: [],
};

Dashboard.propTypes = {
Expand Down Expand Up @@ -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()),
};
20 changes: 19 additions & 1 deletion src/shared/containers/Dashboard/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -187,8 +192,11 @@ export class DashboardPageContainer extends React.Component {
userGroups,
xlBadge,
errorLoadingRss,
userResources,
} = this.props;

// console.log('r', userResources);

if (authenticating) return <LoadingIndicator />;

let announcementPreviewId;
Expand Down Expand Up @@ -229,6 +237,7 @@ export class DashboardPageContainer extends React.Component {
userGroups={userGroups.map(x => x.id)}
xlBadge={xlBadge}
errorLoadingRss={errorLoadingRss}
userResources={userResources ? userResources.resources : []}
/>
);
}
Expand All @@ -249,6 +258,7 @@ DashboardPageContainer.defaultProps = {
tokenV2: null,
tokenV3: null,
errorLoadingRss: false,
userResources: {},
};

DashboardPageContainer.propTypes = {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
};
}

Expand Down Expand Up @@ -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;
Expand Down