diff --git a/__tests__/shared/components/ProfilePage/__snapshots__/index.jsx.snap b/__tests__/shared/components/ProfilePage/__snapshots__/index.jsx.snap index 3617e4c86f..212ffd27cc 100644 --- a/__tests__/shared/components/ProfilePage/__snapshots__/index.jsx.snap +++ b/__tests__/shared/components/ProfilePage/__snapshots__/index.jsx.snap @@ -30,6 +30,7 @@ exports[`renders a full Profile correctly 1`] = `
{ - [...info.tracks, ...(copilot ? ['COPILOT'] : [])].map(track => ( + [...info.tracks, ...(indexOf(info.track, 'DATA_SCIENCE') === -1 && hasMM ? ['DATA_SCIENCE'] : []), ...(copilot ? ['COPILOT'] : [])].map(track => ( { track === 'COPILOT' && } { track === 'DATA_SCIENCE' && } @@ -140,6 +141,7 @@ class ProfileHeader extends React.Component { ProfileHeader.defaultProps = { copilot: false, + hasMM: false, country: '', info: {}, onShowBadges: noop, @@ -149,6 +151,7 @@ ProfileHeader.defaultProps = { ProfileHeader.propTypes = { copilot: PT.bool, + hasMM: PT.bool, country: PT.string, info: PT.shape(), onShowBadges: PT.func, diff --git a/src/shared/components/ProfilePage/StatsCategory/index.jsx b/src/shared/components/ProfilePage/StatsCategory/index.jsx index a661c0f404..3297b56695 100644 --- a/src/shared/components/ProfilePage/StatsCategory/index.jsx +++ b/src/shared/components/ProfilePage/StatsCategory/index.jsx @@ -59,6 +59,7 @@ const isHidden = (subtrack) => { class StatsCategory extends React.Component { getActiveTracks() { let { stats } = this.props; + const { hasMM } = this.props; if (_.isArray(stats)) { // eslint-disable-next-line prefer-destructuring stats = stats[0]; @@ -87,7 +88,7 @@ class StatsCategory extends React.Component { } subTracks.forEach((subtrack) => { - if (isActiveSubtrack(subtrack) && !isHidden(subtrack)) { + if ((isActiveSubtrack(subtrack) && !isHidden(subtrack)) || (subtrack.name === 'MARATHON MATCH' && hasMM)) { active.push({ ...subtrack, active: true }); } }); @@ -106,6 +107,7 @@ class StatsCategory extends React.Component { render() { const { handle, + hasMM, className, inModal, } = this.props; @@ -148,10 +150,10 @@ class StatsCategory extends React.Component { style={{ color: getRatingColor(subtrack.rank.rating) }} styleName="number" > - {subtrack.rank.rating} + {subtrack.name === 'MARATHON MATCH' && !subtrack.challenges && hasMM ? '' : subtrack.rank.rating}
- Rating + {subtrack.name === 'MARATHON MATCH' && !subtrack.challenges && hasMM ? 'No Rating' : 'Rating'}
) @@ -198,6 +200,7 @@ class StatsCategory extends React.Component { StatsCategory.defaultProps = { className: '', inModal: false, + hasMM: false, }; StatsCategory.propTypes = { @@ -207,6 +210,7 @@ StatsCategory.propTypes = { PT.shape(), ]).isRequired, inModal: PT.bool, + hasMM: PT.bool, className: PT.string, }; diff --git a/src/shared/components/ProfilePage/index.jsx b/src/shared/components/ProfilePage/index.jsx index 2230de0077..56be6153de 100644 --- a/src/shared/components/ProfilePage/index.jsx +++ b/src/shared/components/ProfilePage/index.jsx @@ -124,6 +124,7 @@ class ProfilePage extends React.Component { copilot, externalAccounts, externalLinks, + challenges, skills: propSkills, stats, lookupData, @@ -167,6 +168,8 @@ class ProfilePage extends React.Component { } const activeTracks = this.getActiveTracks(); + // no rating MM + const hasMM = challenges && challenges.length; return (
@@ -192,6 +195,7 @@ class ProfilePage extends React.Component { >
- +
) } @@ -310,6 +318,7 @@ ProfilePage.defaultProps = { externalAccounts: null, externalLinks: null, achievements: [], + challenges: null, skills: null, stats: null, }; @@ -318,6 +327,7 @@ ProfilePage.propTypes = { achievements: PT.arrayOf(PT.shape()), copilot: PT.bool.isRequired, externalAccounts: PT.shape(), + challenges: PT.arrayOf(PT.shape()), externalLinks: PT.arrayOf(PT.shape()), info: PT.shape().isRequired, skills: PT.shape(), diff --git a/src/shared/containers/Profile.jsx b/src/shared/containers/Profile.jsx index 0e5704037a..fbfade7a9a 100644 --- a/src/shared/containers/Profile.jsx +++ b/src/shared/containers/Profile.jsx @@ -7,22 +7,31 @@ import PT from 'prop-types'; import { connect } from 'react-redux'; import { config } from 'topcoder-react-utils'; import { actions } from 'topcoder-react-lib'; +import shortId from 'shortid'; import MetaTags from 'components/MetaTags'; import Error404 from 'components/Error404'; import LoadingIndicator from 'components/LoadingIndicator'; import ProfilePage from 'components/ProfilePage'; import { loadPublicStatsOnly } from 'utils/memberStats'; +// how many challenges to query per batch +const CHALLENGE_PER_PAGE = 36; + class ProfileContainer extends React.Component { componentDidMount() { const { handleParam, loadProfile, + loadMarathon, meta, auth, + info, } = this.props; loadProfile(handleParam, _.get(meta, 'groupIds', []), auth.tokenV3, loadPublicStatsOnly(meta)); + if (info) { + loadMarathon(handleParam, auth.tokenV3, info.userId); + } // Redirect to the communities own profile page if // - the member whose profile is being viewed is part of one of the configured communities // - the user is not a topcoder user (has an email with @topcoder.com) @@ -53,6 +62,7 @@ class ProfileContainer extends React.Component { handleParam, profileForHandle, loadProfile, + loadMarathon, loadMemberGroups, meta, auth, @@ -69,6 +79,9 @@ class ProfileContainer extends React.Component { loadProfile(handleParam, _.get(meta, 'groupIds', []), auth.tokenV3, loadPublicStatsOnly(meta)); } + if (info && info.userId && info !== prevInfo) { + loadMarathon(handleParam, auth.tokenV3, info.userId); + } if (auth.tokenV3 && auth.user && auth.user.handle !== handleParam && info != null && info.userId != null && (prevInfo == null || info.userId !== prevInfo.userId)) { @@ -158,6 +171,7 @@ ProfileContainer.propTypes = { handleParam: PT.string.isRequired, info: PT.shape(), loadingError: PT.bool.isRequired, + loadMarathon: PT.bool.isRequired, loadProfile: PT.func.isRequired, loadMemberGroups: PT.func.isRequired, profileForHandle: PT.string, @@ -170,6 +184,8 @@ ProfileContainer.propTypes = { }; const mapStateToProps = (state, ownProps) => ({ + challenges: state.members[ownProps.match.params.handle] + ? state.members[ownProps.match.params.handle].subtrackChallenges : null, achievements: state.profile.achievements, copilot: state.profile.copilot, country: state.profile.country, @@ -192,6 +208,7 @@ const mapStateToProps = (state, ownProps) => ({ function mapDispatchToProps(dispatch) { const a = actions.profile; const lookupActions = actions.lookup; + const memberActions = actions.members; return { loadMemberGroups: (userId, tokenV3) => { dispatch(actions.groups.getMemberGroups(userId, tokenV3)); @@ -214,6 +231,19 @@ function mapDispatchToProps(dispatch) { dispatch(a.getStatsDone(handle, showPublicStats ? undefined : groupIds, tokenV3)); dispatch(lookupActions.getCountriesDone()); }, + loadMarathon: (handle, tokenV3, memberId) => { + const uuid = shortId(); + dispatch(memberActions.getUserMarathonInit(handle, uuid)); + dispatch(memberActions.getUserMarathonDone( + uuid, + handle, + memberId, + tokenV3, + 1, + CHALLENGE_PER_PAGE, + true, + )); + }, }; }