-
-
-
+
{ /*
TODO: At the moment we just fetch downloads from the legacy
Topcoder Studio API, and we don't need any JS code to this.
diff --git a/src/shared/components/SubmissionManagement/SubmissionManagement/index.jsx b/src/shared/components/SubmissionManagement/SubmissionManagement/index.jsx
index de38655fa3..04ba96e3a4 100644
--- a/src/shared/components/SubmissionManagement/SubmissionManagement/index.jsx
+++ b/src/shared/components/SubmissionManagement/SubmissionManagement/index.jsx
@@ -72,10 +72,18 @@ export default function SubmissionManagement(props) {
Find a challenge that interests you on the challenge listings page. You can filter by challenge types, prizes, deadlines, etc. Look for challenges that are still open for registration. If you see something that interests you, click it and then you can read the details and register for the challenge. Watch the video.
-
-
-
Do all of your coding/design work offline, or as specified in the challenge spec. When you are ready to submit, come back to the challenge page and click the Submit button. The Submit page will give instructions to upload your submission. Watch the video.
-
-
-
If you are a reviewer or copilot and need information about managing projects and challenges, please visit the Help Center.
-
-
-
+
+
+
+
If you are new to Topcoder challenges, learn more about the overall concepts of challenges by watching this video.
Find a challenge that interests you on the challenge listings page. You can filter by challenge types, prizes, deadlines, etc. Look for challenges that are still open for registration. If you see something that interests you, click it and then you can read the details and register for the challenge. Watch the video.
+
+
+
Do all of your coding/design work offline, or as specified in the challenge spec. When you are ready to submit, come back to the challenge page and click the Submit button. The Submit page will give instructions to upload your submission. Watch the video.
+
+
+
If you are a reviewer or copilot and need information about managing projects and challenges, please visit the Help Center.
+
+
+
No role restrictions or band restrictions for participating in challenges.
+
+
+
In Home page click on Challenges; Look for challenges that are still open for registration. Click on the Challenge to see skills/technology involved and other details; Register to participate in the challenge OR go through video
+
+
+
Yes you can participate in more than one challenge simultaneously
+
+
+
Each challenge details will have details about winner prize and TopGear points associated
+
+
+
You can use Challenge Forum to get clarifications for your queries
+
+
+
On the Home page click on Learning; Navigate to communities to see skills available on platform.
+
+
+
In Home page click on Learning; Navigate to communities; Join a community where you want to enhance your skills; Join training/case study projects and complete the same.
+
+
+
Yes. The resume gets updated automatically after approval of submissions corresponding to training/case study and challenge.
+
+
+
No. Contribution time in participating will not be considered for over-time benefits.
+
+
+
TopGear points can be earned by completing training/case study projects and by participating and submitting qualified submission in a challenge.
+
+
+
a. TopGear points accumulated by the employees after redemption post periodic contest/promotion shall be valid till the last working day of the employee. Beyond this period the points shall lapse.
+
+
+
No, the reward points cannot be exchanged for any other benefits.
+
+
+
If you are eligible for periodic contest – spot awards and you are exiting prior to contest/promotion scheduled date, the points get lapsed.
+
+
+
TopGear contribution credits are considered under Organization Contribution category of TrendNxt.
+
+
+
TopGear points earned may be considered for periodic contests.
+
+
+
TopGear points earned may be considered for periodic contests.
+
+
+
Send a mail to ask.topgear@wipro.com and TopGear team will get back to you with details and process.
a. On Home Page select ‘Initiate Project’ and provide initial information about projects OR send a mail to ask.topgear@wipro.com and TopGear team will get back to you with details OR go through video.
+
+
+
+
);
diff --git a/src/shared/components/tc-communities/communities/wipro/FAQ/style.scss b/src/shared/components/tc-communities/communities/wipro/FAQ/style.scss
index f9fc9c3037..5fa94ebde0 100644
--- a/src/shared/components/tc-communities/communities/wipro/FAQ/style.scss
+++ b/src/shared/components/tc-communities/communities/wipro/FAQ/style.scss
@@ -9,6 +9,14 @@
padding-bottom: 60px;
}
+.faqContainer {
+ padding-top: 0;
+}
+
+.faqTitle {
+ padding-top: 0;
+}
+
.highlighted {
background: #ffc;
}
diff --git a/src/shared/components/tc-communities/communities/wipro/Home/themes/banner.scss b/src/shared/components/tc-communities/communities/wipro/Home/themes/banner.scss
index 0303bddb1c..1de3a0a2a3 100644
--- a/src/shared/components/tc-communities/communities/wipro/Home/themes/banner.scss
+++ b/src/shared/components/tc-communities/communities/wipro/Home/themes/banner.scss
@@ -1,5 +1,11 @@
@import '~styles/tc-styles';
+.container {
+ @include xxs-to-xs {
+ height: 470px;
+ }
+}
+
.content {
position: absolute;
bottom: 0;
@@ -9,53 +15,56 @@
height: 364px;
transform: none;
overflow: visible;
+
+ @include xxs-to-xs {
+ top: 50%;
+ }
}
.contentBg {
- background: #0e3750;
+ background: #00a2e0;
position: absolute;
bottom: -135px;
left: -30px;
- opacity: 0.85;
border-radius: 100%;
width: 364px;
height: 364px;
transform: none;
@include xxs-to-xs {
- left: 0;
- bottom: 0;
+ left: -30px;
transform: none;
}
}
.contentInner {
color: #fff;
- padding: 76px 30px 0;
+ padding: 76px 0;
position: relative;
z-index: 1;
@include xxs-to-xs {
- padding: 86px 15px 80px;
- text-align: center;
+ padding: 76px 0;
+ text-align: left;
}
}
h2.title {
+ border-bottom: 2px solid white;
+ display: block;
font-family: 'Akkurat mono';
font-size: 20px;
- line-height: 136.11%;
- text-decoration: underline;
+ line-height: 100%;
+ padding-left: 30px;
text-transform: none;
-
- @include xxs-to-xs {
- font-size: 30px;
- }
+ width: 167px;
}
.text {
font-family: 'Akkurat regular';
line-height: 20px;
+ margin-left: 30px;
+ margin-right: 30px;
}
.linkWrap {
diff --git a/src/shared/containers/challenge-detail/index.jsx b/src/shared/containers/challenge-detail/index.jsx
index 3e0c871e15..eff5cc890f 100644
--- a/src/shared/containers/challenge-detail/index.jsx
+++ b/src/shared/containers/challenge-detail/index.jsx
@@ -54,7 +54,8 @@ class ChallengeDetailPageContainer extends React.Component {
componentDidMount() {
const { challenge, loadChallengeDetails, loadTerms,
- openTermsModal, authTokens, challengeId } = this.props;
+ openTermsModal, authTokens, challengeId,
+ challengeSubtracksMap, getSubtracks } = this.props;
if (challenge.id !== challengeId) {
loadChallengeDetails(authTokens, challengeId);
@@ -65,6 +66,10 @@ class ChallengeDetailPageContainer extends React.Component {
if (authTokens.tokenV2 && location.search.indexOf('showTerms=true') > 0) {
openTermsModal();
}
+
+ if (_.isEmpty(challengeSubtracksMap)) {
+ getSubtracks();
+ }
}
componentWillReceiveProps(nextProps) {
@@ -147,6 +152,7 @@ class ChallengeDetailPageContainer extends React.Component {
unregistering={this.props.unregistering}
checkpoints={this.props.checkpoints}
hasRegistered={hasRegistered}
+ challengeSubtracksMap={this.props.challengeSubtracksMap}
/>
}
{
@@ -286,6 +292,8 @@ ChallengeDetailPageContainer.propTypes = {
agreedTerms: PT.shape(),
loadingDocuSignUrl: PT.string,
setChallengeListingFilter: PT.func.isRequired,
+ challengeSubtracksMap: PT.shape().isRequired,
+ getSubtracks: PT.func.isRequired,
};
function extractChallengeDetail(v3, v2, challengeId) {
@@ -392,6 +400,7 @@ const mapStateToProps = (state, props) => ({
agreeingTerm: state.terms.agreeingTerm,
agreedTerms: state.terms.agreedTerms,
isLoadingTerms: state.terms.loadingTermsForChallengeId === props.match.params.challengeId,
+ challengeSubtracksMap: state.challengeListing.challengeSubtracksMap,
});
const mapDispatchToProps = (dispatch) => {
@@ -463,6 +472,11 @@ const mapDispatchToProps = (dispatch) => {
dispatch(t.agreeTermInit(termId));
dispatch(t.agreeTermDone(termId, tokens.tokenV2));
},
+ getSubtracks: () => {
+ const cl = challengeListingActions.challengeListing;
+ dispatch(cl.getChallengeSubtracksInit());
+ dispatch(cl.getChallengeSubtracksDone());
+ },
};
};
diff --git a/src/shared/containers/challenge-listing/Listing/index.jsx b/src/shared/containers/challenge-listing/Listing/index.jsx
index 327ee359da..7e9f22f14a 100644
--- a/src/shared/containers/challenge-listing/Listing/index.jsx
+++ b/src/shared/containers/challenge-listing/Listing/index.jsx
@@ -224,7 +224,7 @@ ListingContainer.propTypes = {
allDraftChallengesLoaded: PT.bool.isRequired,
allPastChallengesLoaded: PT.bool.isRequired,
challenges: PT.arrayOf(PT.shape({})).isRequired,
- challengeSubtracks: PT.arrayOf(PT.string).isRequired,
+ challengeSubtracks: PT.arrayOf(PT.shape()).isRequired,
challengeTags: PT.arrayOf(PT.string).isRequired,
communityFilters: PT.arrayOf(PT.shape({
challengeFilter: PT.shape(),
diff --git a/src/shared/reducers/challenge-listing/index.js b/src/shared/reducers/challenge-listing/index.js
index 18b762adb2..b586b45b1d 100644
--- a/src/shared/reducers/challenge-listing/index.js
+++ b/src/shared/reducers/challenge-listing/index.js
@@ -8,6 +8,7 @@ import logger from 'utils/logger';
import { handleActions } from 'redux-actions';
import { combine, resolveReducers } from 'utils/redux';
import { updateQuery } from 'utils/url';
+import moment from 'moment';
import filterPanel from '../challenge-listing/filter-panel';
import sidebar, { factory as sidebarFactory } from '../challenge-listing/sidebar';
@@ -52,6 +53,7 @@ function onGetChallengeSubtracksDone(state, action) {
return {
...state,
challengeSubtracks: action.error ? [] : action.payload,
+ challengeSubtracksMap: action.error ? {} : _.keyBy(action.payload, 'subTrack'),
loadingChallengeSubtracks: false,
};
}
@@ -237,6 +239,7 @@ function create(initialState) {
challenges: [],
challengeSubtracks: [],
+ challengeSubtracksMap: {},
challengeTags: [],
filter: {},
@@ -270,6 +273,21 @@ export function factory(req) {
if (req) {
state.filter = req.query.filter;
+
+ /* TODO: OK, fine, this validation of dates does the server-side part of
+ * the trick, while the frontend part (removing them from URL) is done
+ * elsewhere (/src/shared/routes/Topcoder/ChallengeListing), but it should
+ * be changed that everything is handled here in the reducer code (only
+ * this way we can ensure that it works all around, including community
+ * challenge listings). */
+ if (!!state.filter && !!state.filter.startDate
+ && moment(state.filter.startDate).isValid() === false) {
+ delete state.filter.startDate;
+ }
+ if (!!state.filter && !!state.filter.endDate
+ && moment(state.filter.endDate).isValid() === false) {
+ delete state.filter.endDate;
+ }
state.selectedCommunityId = req.query.communityId;
}
diff --git a/src/shared/routes/Topcoder/ChallengeListing.jsx b/src/shared/routes/Topcoder/ChallengeListing.jsx
index d44eb668fc..ba45a38fed 100644
--- a/src/shared/routes/Topcoder/ChallengeListing.jsx
+++ b/src/shared/routes/Topcoder/ChallengeListing.jsx
@@ -7,7 +7,9 @@ import _ from 'lodash';
import LoadingIndicator from 'components/LoadingIndicator';
import qs from 'qs';
import React from 'react';
+import moment from 'moment';
import { SplitRoute } from 'utils/router';
+import { updateQuery } from 'utils/url';
export default function ChallengeListingRoute() {
return (
@@ -21,6 +23,20 @@ export default function ChallengeListingRoute() {
).then(({ default: ChallengeListing }) => {
const query = renderProps.location.search ?
qs.parse(renderProps.location.search.slice(1)) : null;
+
+ /* TODO: This validation of start and end dates from query params
+ * does the trick of removing invalid dates from URL at the client
+ * side, but it actually should be done in the reducer as well. */
+ if (query.filter && query.filter.startDate
+ && !moment(query.filter.startDate).isValid()) {
+ delete query.filter.startDate;
+ }
+ if (query.filter && query.filter.endDate
+ && !moment(query.filter.endDate).isValid()) {
+ delete query.filter.endDate;
+ }
+ updateQuery({ filter: query.filter });
+
const currencyFromUrl = _.get(query, 'currency');
const prizeMode = currencyFromUrl && `money-${currencyFromUrl}`;
return (
diff --git a/src/shared/routes/Topcoder/Routes.jsx b/src/shared/routes/Topcoder/Routes.jsx
index 1a55423472..6dc6497c34 100644
--- a/src/shared/routes/Topcoder/Routes.jsx
+++ b/src/shared/routes/Topcoder/Routes.jsx
@@ -17,9 +17,11 @@ import ChallengeListing from './ChallengeListing';
import Dashboard from './Dashboard';
import SubmissionManagement from './SubmissionManagement';
+import './styles.scss';
+
export default function Topcoder() {
return (
-
+
diff --git a/src/shared/routes/Topcoder/styles.scss b/src/shared/routes/Topcoder/styles.scss
new file mode 100644
index 0000000000..5abcdacb62
--- /dev/null
+++ b/src/shared/routes/Topcoder/styles.scss
@@ -0,0 +1,11 @@
+.container {
+ display: flex;
+ min-height: 100vh;
+ flex-direction: column;
+ justify-content: space-between;
+
+ > *:nth-child(2):not(:last-child) {
+ flex: 1;
+ display: block;
+ }
+}
diff --git a/src/shared/services/.exchange-rates.cache b/src/shared/services/.exchange-rates.cache
index 6142db830c..087a18a0fb 100644
--- a/src/shared/services/.exchange-rates.cache
+++ b/src/shared/services/.exchange-rates.cache
@@ -1 +1 @@
-{"disclaimer":"Usage subject to terms: https://openexchangerates.org/terms","license":"https://openexchangerates.org/license","timestamp":1504008000,"base":"USD","rates":{"AED":3.673158,"AFN":68.42,"ALL":110.55,"AMD":478.425,"ANG":1.779836,"AOA":165.9205,"ARS":17.2285,"AUD":1.253866,"AWG":1.796499,"AZN":1.7,"BAM":1.63464,"BBD":2,"BDT":81.223201,"BGN":1.624893,"BHD":0.377173,"BIF":1741.05,"BMD":1,"BND":1.352023,"BOB":6.974321,"BRL":3.168183,"BSD":1,"BTC":0.000226567692,"BTN":63.905066,"BWP":10.105259,"BYN":1.925664,"BZD":2.015536,"CAD":1.247363,"CDF":1550.480769,"CHF":0.945376,"CLF":0.02331,"CLP":626.45,"CNH":6.600879,"CNY":6.596,"COP":2946.55,"CRC":576.32,"CUC":1,"CUP":25.5,"CVE":92.35,"CZK":21.698691,"DJF":178.97,"DKK":6.177315,"DOP":47.090437,"DZD":109.906667,"EGP":17.6421,"ERN":15.326727,"ETB":23.387845,"EUR":0.830371,"FJD":2.010101,"FKP":0.771901,"GBP":0.771901,"GEL":2.413575,"GGP":0.771901,"GHS":4.429268,"GIP":0.771901,"GMD":46.075,"GNF":8886.6,"GTQ":7.282729,"GYD":206.253019,"HKD":7.824445,"HNL":23.393616,"HRK":6.1568,"HTG":66.28528,"HUF":253.4892,"IDR":13333.343435,"ILS":3.577819,"IMP":0.771901,"INR":63.985,"IQD":1166.9,"IRR":32919,"ISK":104.447599,"JEP":0.771901,"JMD":127.919589,"JOD":0.709001,"JPY":108.56365136,"KES":103.195,"KGS":68.606942,"KHR":4048.6,"KMF":411.798944,"KPW":900,"KRW":1123.6575,"KWD":0.30123,"KYD":0.833249,"KZT":335.562793,"LAK":8282.7,"LBP":1507.9,"LKR":152.844139,"LRD":115.030245,"LSL":13.001568,"LYD":1.363155,"MAD":9.3071,"MDL":17.80191,"MGA":2962.05,"MKD":51.11,"MMK":1350.35,"MNT":2430.401732,"MOP":8.058874,"MRO":364.99315,"MUR":32.5805,"MVR":15.450233,"MWK":725.55,"MXN":17.828889,"MYR":4.265758,"MZN":61.148857,"NAD":13.001635,"NGN":359.658899,"NIO":29.889868,"NOK":7.714787,"NPR":102.428065,"NZD":1.371709,"OMR":0.384975,"PAB":1,"PEN":3.238705,"PGK":3.184036,"PHP":51.047,"PKR":105.225,"PLN":3.541809,"PYG":5642.9,"QAR":3.680008,"RON":3.817028,"RSD":98.961351,"RUB":58.75494,"RWF":829.737066,"SAR":3.750363,"SBD":7.77689,"SCR":13.721597,"SDG":6.675627,"SEK":7.920206,"SGD":1.351116,"SHP":0.771901,"SLL":7553.652075,"SOS":579.460007,"SRD":7.438,"SSP":125.5349,"STD":20483.772901,"SVC":8.74962,"SYP":515,"SZL":13.05099,"THB":33.1675,"TJS":8.813642,"TMT":3.50998,"TND":2.417192,"TOP":2.2143,"TRY":3.438635,"TTD":6.749017,"TWD":30.0989,"TZS":2241.15,"UAH":25.450974,"UGX":3618.483069,"USD":1,"UYU":28.801823,"UZS":4181.8,"VEF":10.18335,"VND":22688.140692,"VUV":105.176794,"WST":2.493173,"XAF":544.687917,"XAG":0.05696877,"XAU":0.00075716,"XCD":2.70255,"XDR":0.705414,"XOF":544.687917,"XPD":0.00105842,"XPF":99.089663,"XPT":0.00100001,"YER":250.281642,"ZAR":12.960817,"ZMW":9.058585,"ZWL":322.355011}}
\ No newline at end of file
+{"disclaimer":"Usage subject to terms: https://openexchangerates.org/terms","license":"https://openexchangerates.org/license","timestamp":1504137600,"base":"USD","rates":{"AED":3.673097,"AFN":68.445423,"ALL":111.791078,"AMD":480.27149,"ANG":1.78843,"AOA":165.9205,"ARS":17.395,"AUD":1.264894,"AWG":1.794996,"AZN":1.7,"BAM":1.644699,"BBD":2,"BDT":81.689034,"BGN":1.64397,"BHD":0.377055,"BIF":1749.75,"BMD":1,"BND":1.356545,"BOB":7.008005,"BRL":3.1603,"BSD":1,"BTC":0.00021700956,"BTN":63.98413,"BWP":10.164186,"BYN":1.941205,"BZD":2.025258,"CAD":1.263078,"CDF":1550.740385,"CHF":0.963759,"CLF":0.02349,"CLP":631.9,"CNH":6.599327,"CNY":6.595577,"COP":2953.5,"CRC":579.374449,"CUC":1,"CUP":25.5,"CVE":92.8,"CZK":21.92111,"DJF":178.77,"DKK":6.256053,"DOP":47.279238,"DZD":110.9295,"EGP":17.643,"ERN":15.335471,"ETB":23.319528,"EUR":0.840993,"FJD":2.034645,"FKP":0.774009,"GBP":0.774009,"GEL":2.4245,"GGP":0.774009,"GHS":4.456015,"GIP":0.774009,"GMD":46.15,"GNF":8930.05,"GTQ":7.320704,"GYD":207.972754,"HKD":7.824991,"HNL":23.509381,"HRK":6.2329,"HTG":63.506176,"HUF":257.132505,"IDR":13345.175458,"ILS":3.58885,"IMP":0.774009,"INR":63.9874,"IQD":1172.5,"IRR":33062.267348,"ISK":105.747443,"JEP":0.774009,"JMD":128.693699,"JOD":0.709001,"JPY":110.4721,"KES":103.18,"KGS":68.664403,"KHR":4075.766667,"KMF":414.090225,"KPW":900,"KRW":1124.28,"KWD":0.301448,"KYD":0.837333,"KZT":336.825303,"LAK":8328.65,"LBP":1509.062443,"LKR":153.581733,"LRD":115.030245,"LSL":13.085258,"LYD":1.368959,"MAD":9.370738,"MDL":17.864359,"MGA":2982.444875,"MKD":51.78,"MMK":1369.51006,"MNT":2428.158099,"MOP":8.098407,"MRO":366.89879,"MUR":32.6185,"MVR":15.450233,"MWK":725.046611,"MXN":17.74,"MYR":4.2715,"MZN":61.160857,"NAD":13.085258,"NGN":355,"NIO":29.996418,"NOK":7.80381,"NPR":102.833791,"NZD":1.388156,"OMR":0.384992,"PAB":1,"PEN":3.240393,"PGK":3.199435,"PHP":51.149,"PKR":105.725129,"PLN":3.57795,"PYG":5696.477124,"QAR":3.685006,"RON":3.863137,"RSD":100.15515,"RUB":58.4901,"RWF":831,"SAR":3.7503,"SBD":7.797375,"SCR":13.631694,"SDG":6.708373,"SEK":7.975026,"SGD":1.358101,"SHP":0.774009,"SLL":7550.184032,"SOS":580.38334,"SRD":7.438,"SSP":124.9444,"STD":20528.502691,"SVC":8.791576,"SYP":515,"SZL":13.096402,"THB":33.2155,"TJS":8.856445,"TMT":3.499986,"TND":2.434089,"TOP":2.193576,"TRY":3.456008,"TTD":6.757558,"TWD":30.151,"TZS":2241.25,"UAH":25.716003,"UGX":3627.308069,"USD":1,"UYU":28.773276,"UZS":4201.65,"VEF":10.05845,"VND":22722.55232,"VUV":105.013288,"WST":2.497571,"XAF":551.655496,"XAG":0.05750432,"XAU":0.00076489,"XCD":2.70255,"XDR":0.7051,"XOF":551.655496,"XPD":0.0010724,"XPF":100.357205,"XPT":0.0010091,"YER":250.35,"ZAR":13.01652,"ZMW":9.077975,"ZWL":322.355011}}
\ No newline at end of file
diff --git a/src/shared/services/challenges.js b/src/shared/services/challenges.js
index af35c1e150..ce0139442c 100644
--- a/src/shared/services/challenges.js
+++ b/src/shared/services/challenges.js
@@ -140,12 +140,13 @@ class ChallengesService {
* @return {Promise} Resolves to the array of subtrack names.
*/
getChallengeSubtracks() {
- return Promise.all([
- this.private.apiV2.get('/design/challengetypes')
- .then(res => (res.ok ? res.json() : new Error(res.statusText))),
- this.private.apiV2.get('/develop/challengetypes')
- .then(res => (res.ok ? res.json() : new Error(res.statusText))),
- ]).then(([a, b]) => a.concat(b));
+ return this.private.api.get('/challenge-types')
+ .then(res => (res.ok ? res.json() : new Error(res.statusText)))
+ .then(res => (
+ res.result.status === 200 ?
+ res.result.content :
+ new Error(res.result.content)
+ ));
}
/**
diff --git a/src/shared/utils/challenge-listing/buckets.js b/src/shared/utils/challenge-listing/buckets.js
index a1bba25679..0e2445812c 100644
--- a/src/shared/utils/challenge-listing/buckets.js
+++ b/src/shared/utils/challenge-listing/buckets.js
@@ -58,7 +58,7 @@ export function getBuckets(userHandle) {
sorts: [
SORTS.MOST_RECENT,
SORTS.TIME_TO_REGISTER,
- SORTS.PHASE_END_TIME,
+ SORTS.TIME_TO_SUBMIT,
SORTS.NUM_REGISTRANTS,
SORTS.NUM_SUBMISSIONS,
SORTS.PRIZE_HIGH_TO_LOW,
diff --git a/src/shared/utils/challenge-listing/filter.js b/src/shared/utils/challenge-listing/filter.js
index 8e48d395d1..2579649eed 100644
--- a/src/shared/utils/challenge-listing/filter.js
+++ b/src/shared/utils/challenge-listing/filter.js
@@ -73,6 +73,9 @@ function filterByGroupIds(challenge, state) {
function filterByRegistrationOpen(challenge, state) {
if (_.isUndefined(state.registrationOpen)) return true;
const isRegOpen = () => {
+ if (challenge.registrationOpen) {
+ return challenge.registrationOpen === 'Yes';
+ }
if (challenge.subTrack === 'MARATHON_MATCH') {
return challenge.status !== 'PAST';
}
@@ -114,8 +117,8 @@ function filterBySubtracks(challenge, state) {
* why challenge subtracks in challenge objects are different from those
* return from the API as the list of possible subtracks. */
const filterSubtracks = state.subtracks.map(item =>
- item.toLowerCase().replace(/ /g, ''));
- const challengeSubtrack = challenge.subTrack.toLowerCase().replace(/_/g, '');
+ item.toLowerCase().replace(/[_ ]/g, ''));
+ const challengeSubtrack = challenge.subTrack.toLowerCase().replace(/[_ ]/g, '');
return filterSubtracks.includes(challengeSubtrack);
}
@@ -136,6 +139,14 @@ function filterByText(challenge, state) {
function filterByTrack(challenge, state) {
if (!state.tracks) return true;
+
+ /* Development challenges having Data Science tech tag, still should be
+ * included into data science track. */
+ if (state.tracks[COMPETITION_TRACKS.DATA_SCIENCE]
+ && _.includes(challenge.technologies, 'Data Science')) {
+ return true;
+ }
+
return _.keys(state.tracks).some(track => challenge.communities.has(track));
}
@@ -303,6 +314,15 @@ export function mapToBackend(filter) {
const res = {};
if (filter.groupIds) res.groupIds = filter.groupIds.join(',');
+ /* A rapid hack which prevents our code to keep on searching past challenges,
+ * for a filter without any track enabled (i.e. no challenge should match it).
+ * TODO: With this fix, the frontend still does a single round of searching,
+ * which should be prevented.
+ */
+ if (filter.tracks && _.isEmpty(filter.tracks)) {
+ res.name = 'A non existing challenge 230785';
+ }
+
/* NOTE: Right now the frontend challenge filter by tag works different,
* it looks for matches in the challenge name OR in the techs / platforms. */
// if (filter.tags) res.technologies = filter.tags.join(',');
diff --git a/src/shared/utils/challenge-listing/sort.js b/src/shared/utils/challenge-listing/sort.js
index a82dbc0f53..3d724a3f76 100644
--- a/src/shared/utils/challenge-listing/sort.js
+++ b/src/shared/utils/challenge-listing/sort.js
@@ -9,7 +9,6 @@ export const SORTS = {
MOST_RECENT: 'most-recent',
NUM_REGISTRANTS: 'num-registrants',
NUM_SUBMISSIONS: 'num-submissions',
- PHASE_END_TIME: 'phase-end-time',
PRIZE_HIGH_TO_LOW: 'prize-high-to-low',
TIME_TO_REGISTER: 'time-to-register',
TIME_TO_SUBMIT: 'time-to-submit',
@@ -33,10 +32,6 @@ export default {
func: (a, b) => b.numSubmissions - a.numSubmissions,
name: '# of submissions',
},
- [SORTS.PHASE_END_TIME]: {
- func: (a, b) => a.currentPhaseRemainingTime - b.currentPhaseRemainingTime,
- name: 'Time to submit',
- },
[SORTS.PRIZE_HIGH_TO_LOW]: {
func: (a, b) => b.totalPrize - a.totalPrize,
name: 'Prize high to low',
@@ -47,7 +42,22 @@ export default {
name: 'Time to register',
},
[SORTS.TIME_TO_SUBMIT]: {
- func: (a, b) => a.submissionEndTimestamp - b.submissionEndTimestamp,
+ func: (a, b) => {
+ function nextSubEndDate(o) {
+ if (o.checkpointSubmissionEndDate && moment(o.checkpointSubmissionEndDate).isAfter()) {
+ return o.checkpointSubmissionEndDate;
+ }
+ return o.submissionEndDate;
+ }
+
+ const aDate = nextSubEndDate(a);
+ const bDate = nextSubEndDate(b);
+
+ if (moment(aDate).isBefore()) return 1;
+ if (moment(bDate).isBefore()) return -1;
+
+ return moment(aDate).diff(bDate);
+ },
name: 'Time to submit',
},
[SORTS.TITLE_A_TO_Z]: {
diff --git a/src/shared/utils/url.js b/src/shared/utils/url.js
index c5717aca23..ca48322c08 100644
--- a/src/shared/utils/url.js
+++ b/src/shared/utils/url.js
@@ -28,7 +28,6 @@ export function updateQuery(update) {
if (_.isUndefined(value)) delete query[key];
else query[key] = value;
});
-
query = `?${qs.stringify(query, { encode: false })}`;
window.history.replaceState(window.history.state, '', query);
}