- {getBucket(BUCKETS.ALL)}
- {isAuth ? getBucket(BUCKETS.MY) : null}
- {/* {extraBucket ? getBucket(extraBucket) : null} */}
- {getBucket(BUCKETS.OPEN_FOR_REGISTRATION)}
- {/* DISABLED: Until api receive fix community-app#5073 */}
- {/* {getBucket(BUCKETS.ONGOING)} */}
-
- {getBucket(BUCKETS.REVIEW_OPPORTUNITIES)}
- {/* {getBucket(BUCKETS.PAST)} */}
- {/* NOTE: We do not show upcoming challenges for now, for various reasons,
- * more political than technical ;)
- getBucket(BUCKETS.UPCOMING) */
- }
- {/* {
- savedFilters.length
- ? (
-
-
-
- My filters
-
-
setEditSavedFiltersMode(true)}
- onKeyPress={() => setEditSavedFiltersMode(true)}
- role="button"
- styleName="edit-link"
- tabIndex={0}
- >
- edit
-
+ return (!past
+ ? (
+
+ {getBucket(BUCKETS.ALL)}
+ {isAuth ? getBucket(BUCKETS.MY) : null}
+ {/* {extraBucket ? getBucket(extraBucket) : null} */}
+ {getBucket(BUCKETS.OPEN_FOR_REGISTRATION)}
+ {/* DISABLED: Until api receive fix community-app#5073 */}
+ {/* {getBucket(BUCKETS.ONGOING)} */}
+
+ {getBucket(BUCKETS.REVIEW_OPPORTUNITIES)}
+ {/* {getBucket(BUCKETS.PAST)} */}
+ {/* NOTE: We do not show upcoming challenges for now, for various reasons,
+ * more political than technical ;)
+ getBucket(BUCKETS.UPCOMING) */
+ }
+ {/* {
+ savedFilters.length
+ ? (
+
- {savedFiltersRender}
-
- ) : ''
- } */}
-
- {/* DISABLED: Until feeds.topcoder.com domain fixed community-app#4606 */}
- {/*
-
-
- Get the RSS feed
-
+ ) : ''
+ } */}
+
+ {/* DISABLED: Until feeds.topcoder.com domain fixed community-app#4606 */}
+ {/*
+
+ */}
- */}
-
+ ) : (
+
+ {getBucket(BUCKETS.ALL_PAST)}
+ {isAuth ? getBucket(BUCKETS.MY_PAST) : null}
+
+ )
);
}
@@ -133,6 +143,7 @@ BucketSelector.defaultProps = {
// extraBucket: null,
isAuth: false,
expanding: false,
+ past: false,
};
BucketSelector.propTypes = {
@@ -151,4 +162,5 @@ BucketSelector.propTypes = {
selectBucket: PT.func.isRequired,
// selectSavedFilter: PT.func.isRequired,
// setEditSavedFiltersMode: PT.func.isRequired,
+ past: PT.bool,
};
diff --git a/src/shared/components/challenge-listing/Sidebar/index.jsx b/src/shared/components/challenge-listing/Sidebar/index.jsx
index cfa51585c7..b6d50b915d 100644
--- a/src/shared/components/challenge-listing/Sidebar/index.jsx
+++ b/src/shared/components/challenge-listing/Sidebar/index.jsx
@@ -17,10 +17,11 @@
import React from 'react';
import PT from 'prop-types';
-
+// import _ from 'lodash';
+import { BUCKETS, isPastBucket } from 'utils/challenge-listing/buckets';
import BucketSelector from './BucketSelector';
// import FiltersEditor from './FiltersEditor';
-import Footer from './Footer';
+// import Footer from './Footer';
import './style.scss';
export default function SideBarFilters({
@@ -48,9 +49,68 @@ export default function SideBarFilters({
// setEditSavedFiltersMode,
// updateAllSavedFilters,
// updateSavedFilter,
+ // setFilter,
+ previousBucketOfActiveTab,
+ previousBucketOfPastChallengesTab,
+ setPreviousBucketOfActiveTab,
+ setPreviousBucketOfPastChallengesTab,
}) {
+ const past = isPastBucket(activeBucket);
+
+ const onActiveClick = () => {
+ if (!past) {
+ return;
+ }
+ setPreviousBucketOfPastChallengesTab(activeBucket);
+ if (previousBucketOfActiveTab) {
+ selectBucket(previousBucketOfActiveTab);
+ } else {
+ selectBucket(BUCKETS.OPEN_FOR_REGISTRATION);
+ }
+ };
+
+ const onPastChallengesClick = () => {
+ if (past) {
+ return;
+ }
+ setPreviousBucketOfActiveTab(activeBucket);
+ if (previousBucketOfPastChallengesTab) {
+ selectBucket(previousBucketOfPastChallengesTab);
+ } else {
+ selectBucket(BUCKETS.ALL_PAST);
+ }
+ };
+
return (
+
+ - {
+ if (e.key !== 'Enter') {
+ return;
+ }
+ onActiveClick();
+ }}
+ role="presentation"
+ >
+ Active
+
+ - {
+ if (e.key !== 'Enter') {
+ return;
+ }
+ onPastChallengesClick();
+ }}
+ role="presentation"
+ >
+ Past Challenges
+
+
{/* { editSavedFiltersMode ? (
{/* )} */}
-
+ {/*
*/}
);
}
@@ -97,6 +158,10 @@ SideBarFilters.defaultProps = {
// hideTcLinksInFooter: false,
isAuth: false,
expanding: false,
+ previousBucketOfActiveTab: null,
+ previousBucketOfPastChallengesTab: null,
+ setPreviousBucketOfActiveTab: () => {},
+ setPreviousBucketOfPastChallengesTab: () => {},
};
SideBarFilters.propTypes = {
@@ -125,4 +190,9 @@ SideBarFilters.propTypes = {
// setEditSavedFiltersMode: PT.func.isRequired,
// updateAllSavedFilters: PT.func.isRequired,
// updateSavedFilter: PT.func.isRequired,
+ // setFilter: PT.func.isRequired,
+ previousBucketOfActiveTab: PT.string,
+ previousBucketOfPastChallengesTab: PT.string,
+ setPreviousBucketOfActiveTab: PT.func,
+ setPreviousBucketOfPastChallengesTab: PT.func,
};
diff --git a/src/shared/components/challenge-listing/Sidebar/style.scss b/src/shared/components/challenge-listing/Sidebar/style.scss
index 3c2e76d24c..211df578c1 100644
--- a/src/shared/components/challenge-listing/Sidebar/style.scss
+++ b/src/shared/components/challenge-listing/Sidebar/style.scss
@@ -7,6 +7,31 @@
line-height: 30px;
width: 100%;
+ .StatusBar {
+ display: flex;
+ padding: 10px 24px 0;
+ background: #fafafb;
+ border-bottom: 1px solid #d5d5d5;
+ border-radius: 4px 4px 0 0;
+
+ .Status {
+ font-size: 12px;
+ line-height: 30px;
+ color: #151516;
+ border-bottom: 1px solid transparent;
+ cursor: pointer;
+
+ &.active {
+ font-weight: bold;
+ border-bottom-color: #43d7b0;
+ }
+ }
+
+ .Status + .Status {
+ margin-left: 30px;
+ }
+ }
+
.FilterBox {
background: $tc-white;
padding: 2 * $base-unit;
diff --git a/src/shared/components/challenge-listing/index.jsx b/src/shared/components/challenge-listing/index.jsx
index a2a3e9db12..87b2e12176 100644
--- a/src/shared/components/challenge-listing/index.jsx
+++ b/src/shared/components/challenge-listing/index.jsx
@@ -4,15 +4,16 @@
*/
// import _ from 'lodash';
-import ChallengeFilters from 'containers/challenge-listing/FilterPanel';
+import FilterPanel from 'containers/challenge-listing/FilterPanel';
+import ChallengeSearchBar from 'containers/challenge-listing/ChallengeSearchBar';
// import moment from 'moment';
import React from 'react';
import PT from 'prop-types';
-import Sticky from 'react-stickynode';
// import { challenge as challengeUtils } from 'topcoder-react-lib';
import Sidebar from 'containers/challenge-listing/Sidebar';
// import { isReviewOpportunitiesBucket } from 'utils/challenge-listing/buckets';
// import { config } from 'topcoder-react-utils';
+import { useMediaQuery } from 'react-responsive';
import Listing from './Listing';
// import ChallengeCardPlaceholder from './placeholders/ChallengeCard';
@@ -31,8 +32,9 @@ export default function ChallengeListing(props) {
challenges,
openForRegistrationChallenges,
myChallenges,
+ myPastChallenges,
allChallenges,
- // pastChallenges,
+ pastChallenges,
// communityFilter,
communityName,
defaultCommunityId,
@@ -40,13 +42,14 @@ export default function ChallengeListing(props) {
// extraBucket,
// filterState,
hideSrm,
- hideTcLinksInFooter,
+ // hideTcLinksInFooter,
keepPastPlaceholders,
// loadingChallenges,
preListingMsg,
// isBucketSwitching,
isLoggedIn,
meta,
+ setSearchText,
} = props;
// const { challenges } = props;
@@ -101,8 +104,9 @@ export default function ChallengeListing(props) {
challenges={challenges}
openForRegistrationChallenges={openForRegistrationChallenges}
myChallenges={myChallenges}
+ myPastChallenges={myPastChallenges}
allChallenges={allChallenges}
- // pastChallenges={pastChallenges}
+ pastChallenges={pastChallenges}
challengesUrl={props.challengesUrl}
communityName={props.communityName}
expandedTags={props.expandedTags}
@@ -110,17 +114,19 @@ export default function ChallengeListing(props) {
// extraBucket={extraBucket}
filterState={props.filterState}
keepPastPlaceholders={keepPastPlaceholders}
- // loadingPastChallenges={props.loadingPastChallenges}
+ loadingPastChallenges={props.loadingPastChallenges}
loadingMyChallenges={props.loadingMyChallenges}
+ loadingMyPastChallenges={props.loadingMyPastChallenges}
loadingAllChallenges={props.loadingAllChallenges}
loadingOpenForRegistrationChallenges={props.loadingOpenForRegistrationChallenges}
loadingOnGoingChallenges={props.loadingOnGoingChallenges}
loadingReviewOpportunities={props.loadingReviewOpportunities}
loadMoreMy={props.loadMoreMy}
+ loadMoreMyPast={props.loadMoreMyPast}
loadMoreAll={props.loadMoreAll}
loadMoreOpenForRegistration={props.loadMoreOpenForRegistration}
loadMoreOnGoing={props.loadMoreOnGoing}
- // loadMorePast={props.loadMorePast}
+ loadMorePast={props.loadMorePast}
loadMoreReviewOpportunities={props.loadMoreReviewOpportunities}
newChallengeDetails={props.newChallengeDetails}
openChallengesInNewTabs={props.openChallengesInNewTabs}
@@ -139,39 +145,37 @@ export default function ChallengeListing(props) {
// userChallenges={props.userChallenges}
isLoggedIn={isLoggedIn}
meta={meta}
+ setSearchText={setSearchText}
/>
);
// }
+ const desktop = useMediaQuery({ minWidth: 1024 });
+
return (
-
-
-
+
+
+
+
{challengeCardContainer}
-
-
-
-
-
);
@@ -182,12 +186,13 @@ ChallengeListing.defaultProps = {
// communityFilter: null,
communityName: null,
// extraBucket: null,
- hideTcLinksInFooter: false,
+ // hideTcLinksInFooter: false,
loadMoreMy: null,
+ loadMoreMyPast: null,
loadMoreAll: null,
loadMoreOpenForRegistration: null,
loadMoreOnGoing: null,
- // loadMorePast: null,
+ loadMorePast: null,
loadMoreReviewOpportunities: null,
newChallengeDetails: false,
openChallengesInNewTabs: false,
@@ -207,9 +212,10 @@ ChallengeListing.propTypes = {
expanding: PT.bool,
challenges: PT.arrayOf(PT.shape()).isRequired,
openForRegistrationChallenges: PT.arrayOf(PT.shape()).isRequired,
- myChallenges: PT.arrayOf(PT.arrayOf()).isRequired,
- allChallenges: PT.arrayOf(PT.arrayOf()).isRequired,
- // pastChallenges: PT.arrayOf(PT.arrayOf()).isRequired,
+ myChallenges: PT.arrayOf(PT.shape()).isRequired,
+ myPastChallenges: PT.arrayOf(PT.shape()).isRequired,
+ allChallenges: PT.arrayOf(PT.shape()).isRequired,
+ pastChallenges: PT.arrayOf(PT.shape()).isRequired,
challengesUrl: PT.string.isRequired,
// communityFilter: PT.shape(),
communityName: PT.string,
@@ -219,21 +225,23 @@ ChallengeListing.propTypes = {
// extraBucket: PT.string,
filterState: PT.shape().isRequired,
hideSrm: PT.bool.isRequired,
- hideTcLinksInFooter: PT.bool,
+ // hideTcLinksInFooter: PT.bool,
keepPastPlaceholders: PT.bool.isRequired,
// lastUpdateOfActiveChallenges: PT.number.isRequired,
// loadingChallenges: PT.bool.isRequired,
loadingMyChallenges: PT.bool.isRequired,
+ loadingMyPastChallenges: PT.bool.isRequired,
loadingAllChallenges: PT.bool.isRequired,
loadingOpenForRegistrationChallenges: PT.bool.isRequired,
loadingOnGoingChallenges: PT.bool.isRequired,
- // loadingPastChallenges: PT.bool.isRequired,
+ loadingPastChallenges: PT.bool.isRequired,
loadingReviewOpportunities: PT.bool.isRequired,
loadMoreMy: PT.func,
+ loadMoreMyPast: PT.func,
loadMoreAll: PT.func,
loadMoreOpenForRegistration: PT.func,
loadMoreOnGoing: PT.func,
- // loadMorePast: PT.func,
+ loadMorePast: PT.func,
loadMoreReviewOpportunities: PT.func,
newChallengeDetails: PT.bool,
openChallengesInNewTabs: PT.bool,
@@ -252,4 +260,5 @@ ChallengeListing.propTypes = {
// userChallenges: PT.arrayOf(PT.string),
isLoggedIn: PT.bool.isRequired,
meta: PT.shape().isRequired,
+ setSearchText: PT.func.isRequired,
};
diff --git a/src/shared/components/challenge-listing/style.scss b/src/shared/components/challenge-listing/style.scss
index 6080cc23bf..85975c3649 100644
--- a/src/shared/components/challenge-listing/style.scss
+++ b/src/shared/components/challenge-listing/style.scss
@@ -1,20 +1,21 @@
@import '~styles/mixins';
+$challenge-space-5: $base-unit;
$challenge-space-10: $base-unit * 2;
$challenge-space-15: $base-unit * 3;
$challenge-space-20: $base-unit * 4;
$challenge-radius-4: $corner-radius * 2;
-.ChallengeCardExamples {
- &.wrapper {
- display: block;
- width: 100%;
- padding: $challenge-space-20;
+// .ChallengeCardExamples {
+// &.wrapper {
+// display: block;
+// width: 100%;
+// padding: $challenge-space-20;
- @include xs-to-sm {
- padding: $challenge-space-10;
- }
- }
-}
+// @include xs-to-sm {
+// padding: $challenge-space-10;
+// }
+// }
+// }
.ChallengeFiltersExample {
background: $tc-gray-neutral-dark;
@@ -30,42 +31,42 @@ $challenge-radius-4: $corner-radius * 2;
}
}
- .challenge-cards-container {
- width: 70%;
- padding: $challenge-space-10;
-
- @include xs-to-md {
- width: 100%;
- padding-top: 0;
- }
- }
-
- .challenges-container.SRMs-container {
- width: 70%;
- padding: $challenge-space-10;
-
- @include xs-to-md {
- width: 100%;
- padding-top: 0;
- }
-
- .title {
- @include roboto-medium;
-
- font-size: 13px;
- color: $tc-gray-80;
- line-height: $base-unit * 4;
- padding: $base-unit * 2 $base-unit * 4;
- background: $tc-gray-neutral-light;
- border-top-left-radius: $corner-radius * 2;
- border-top-right-radius: $corner-radius * 2;
- margin-top: $base-unit * 4;
-
- @include xs-to-md {
- margin-top: $base-unit * 2;
- }
- }
- }
+ // .challenge-cards-container {
+ // width: 70%;
+ // padding: $challenge-space-10;
+
+ // @include xs-to-md {
+ // width: 100%;
+ // padding-top: 0;
+ // }
+ // }
+
+ // .challenges-container.SRMs-container {
+ // width: 70%;
+ // padding: $challenge-space-10;
+
+ // @include xs-to-md {
+ // width: 100%;
+ // padding-top: 0;
+ // }
+
+ // .title {
+ // @include roboto-medium;
+
+ // font-size: 13px;
+ // color: $tc-gray-80;
+ // line-height: $base-unit * 4;
+ // padding: $base-unit * 2 $base-unit * 4;
+ // background: $tc-gray-neutral-light;
+ // border-top-left-radius: $corner-radius * 2;
+ // border-top-right-radius: $corner-radius * 2;
+ // margin-top: $base-unit * 4;
+
+ // @include xs-to-md {
+ // margin-top: $base-unit * 2;
+ // }
+ // }
+ // }
.sidebar-container-mobile {
margin: $challenge-space-20 $challenge-space-10 $challenge-space-10;
@@ -80,12 +81,16 @@ $challenge-radius-4: $corner-radius * 2;
}
.sidebar-container-desktop {
- margin: $challenge-space-20 $challenge-space-10 $challenge-space-10;
+ margin: $challenge-space-20 $challenge-space-5 $challenge-space-10;
width: 30%;
@include xs-to-md {
display: none;
}
+
+ > * + * {
+ margin-top: 12px;
+ }
}
.hidden {
diff --git a/src/shared/containers/challenge-detail/index.jsx b/src/shared/containers/challenge-detail/index.jsx
index fc53688834..3966ac53d5 100644
--- a/src/shared/containers/challenge-detail/index.jsx
+++ b/src/shared/containers/challenge-detail/index.jsx
@@ -14,6 +14,7 @@ import pageActions from 'actions/page';
import ChallengeHeader from 'components/challenge-detail/Header';
import challengeListingActions from 'actions/challenge-listing';
import challengeListingSidebarActions from 'actions/challenge-listing/sidebar';
+import challengeListingFilterPanelActions from 'actions/challenge-listing/filter-panel';
import Registrants from 'components/challenge-detail/Registrants';
import shortId from 'shortid';
import Submissions from 'components/challenge-detail/Submissions';
@@ -877,12 +878,18 @@ const mapDispatchToProps = (dispatch) => {
return challengeDetails;
});
},
- setChallengeListingFilter: (filter) => {
+ setChallengeListingFilter: (filter, stateProps) => {
const cl = challengeListingActions.challengeListing;
const cls = challengeListingSidebarActions.challengeListing.sidebar;
- const newFilter = _.assign({}, { types: [], tags: [] }, filter);
+ const fp = challengeListingFilterPanelActions.challengeListing.filterPanel;
+ const newFilter = _.assign(
+ {},
+ { types: stateProps.challengeTypes.map(type => type.abbreviation), search: '' },
+ filter,
+ );
dispatch(cls.selectBucket(BUCKETS.OPEN_FOR_REGISTRATION));
dispatch(cl.setFilter(newFilter));
+ dispatch(fp.setSearchText(newFilter.search));
},
setSpecsTabState: state => dispatch(pageActions.page.challengeDetails.setSpecsTabState(state)),
unregisterFromChallenge: (auth, challengeId) => {
@@ -943,9 +950,17 @@ const mapDispatchToProps = (dispatch) => {
};
};
+const mergeProps = (stateProps, dispatchProps, ownProps) => ({
+ ...ownProps,
+ ...stateProps,
+ ...dispatchProps,
+ setChallengeListingFilter: filter => dispatchProps.setChallengeListingFilter(filter, stateProps),
+});
+
const ChallengeDetailContainer = connect(
mapStateToProps,
mapDispatchToProps,
+ mergeProps,
)(ChallengeDetailPageContainer);
export default ChallengeDetailContainer;
diff --git a/src/shared/containers/challenge-listing/ChallengeSearchBar.jsx b/src/shared/containers/challenge-listing/ChallengeSearchBar.jsx
new file mode 100644
index 0000000000..a8d1275137
--- /dev/null
+++ b/src/shared/containers/challenge-listing/ChallengeSearchBar.jsx
@@ -0,0 +1,81 @@
+/**
+ * Container for the challenge search bar.
+ */
+
+import actions from 'actions/challenge-listing/filter-panel';
+import challengeListingActions from 'actions/challenge-listing';
+import ChallengeSearchBar from 'components/challenge-listing/Filters/ChallengeSearchBar';
+import PT from 'prop-types';
+import React from 'react';
+import { isReviewOpportunitiesBucket } from 'utils/challenge-listing/buckets';
+import { connect } from 'react-redux';
+import _ from 'lodash';
+
+export class Container extends React.Component {
+ constructor(props) {
+ super(props);
+ this.onSearch = _.debounce(this.onSearch.bind(this), 1000);
+ }
+
+ onSearch(text) {
+ const {
+ setFilterState,
+ filterState,
+ } = this.props;
+
+ setFilterState({ ..._.clone(filterState), search: text });
+ }
+
+ render() {
+ const {
+ activeBucket,
+ searchText,
+ setSearchText,
+ } = this.props;
+
+ const isForReviewOpportunities = isReviewOpportunitiesBucket(activeBucket);
+
+ return (
+
{
+ setSearchText(text);
+ this.onSearch(text);
+ }}
+ placeholder={isForReviewOpportunities ? 'Search Review Opportunities' : 'Search for Challenge'}
+ query={searchText}
+ />
+ );
+ }
+}
+
+Container.defaultProps = {
+ searchText: '',
+};
+
+Container.propTypes = {
+ activeBucket: PT.string.isRequired,
+ filterState: PT.shape().isRequired,
+ setFilterState: PT.func.isRequired,
+ searchText: PT.string,
+ setSearchText: PT.func.isRequired,
+};
+
+function mapDispatchToProps(dispatch) {
+ const a = actions.challengeListing.filterPanel;
+ const cla = challengeListingActions.challengeListing;
+ return {
+ setSearchText: text => dispatch(a.setSearchText(text)),
+ setFilterState: s => dispatch(cla.setFilter(s)),
+ };
+}
+
+function mapStateToProps(state) {
+ const cl = state.challengeListing;
+ return {
+ activeBucket: cl.sidebar.activeBucket,
+ filterState: cl.filter,
+ searchText: state.challengeListing.filterPanel.searchText,
+ };
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(Container);
diff --git a/src/shared/containers/challenge-listing/FilterPanel.jsx b/src/shared/containers/challenge-listing/FilterPanel.jsx
index c83d7d1277..045710dd89 100644
--- a/src/shared/containers/challenge-listing/FilterPanel.jsx
+++ b/src/shared/containers/challenge-listing/FilterPanel.jsx
@@ -1,47 +1,31 @@
/**
- * Container for the header filters panel.
+ * Container for the filters panel.
*/
-/* global window */
import actions from 'actions/challenge-listing/filter-panel';
import challengeListingActions from 'actions/challenge-listing';
import communityActions from 'actions/tc-communities';
import shortId from 'shortid';
-import FilterPanel from 'components/challenge-listing/Filters/ChallengeFilters';
+import FilterPanel from 'components/challenge-listing/Filters/FiltersPanel';
import PT from 'prop-types';
import React from 'react';
-// import localStorage from 'localStorage';
-// import sidebarActions from 'actions/challenge-listing/sidebar';
-// import { BUCKETS, isReviewOpportunitiesBucket } from 'utils/challenge-listing/buckets';
-import { isReviewOpportunitiesBucket } from 'utils/challenge-listing/buckets';
+import ReactDOM from 'react-dom';
+import { BUCKETS, isReviewOpportunitiesBucket } from 'utils/challenge-listing/buckets';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import qs from 'qs';
import _ from 'lodash';
+import { createStaticRanges } from 'utils/challenge-listing/date-range';
-/* The default name for user-saved challenge filters. An integer
- * number will be appended to it, when necessary, to keep filter
- * names unique. */
-// const DEFAULT_SAVED_FILTER_NAME = 'My Filter';
const MIN = 60 * 1000;
-/**
- * Returns a vacant name for the user saved filter.
- * @param {Object} state Redux state.
- * @return {String}
- */
-// function getAvailableFilterName(savedFilters) {
-// let res = DEFAULT_SAVED_FILTER_NAME;
-// let id = 0;
-// savedFilters.forEach((f) => {
-// while (res === f.name) {
-// res = `${DEFAULT_SAVED_FILTER_NAME} ${id += 1}`;
-// }
-// });
-// return res;
-// }
export class Container extends React.Component {
+ constructor(props) {
+ super(props);
+ this.initialDefaultChallengeTypes = false;
+ }
+
componentDidMount() {
const {
getKeywords,
@@ -49,10 +33,11 @@ export class Container extends React.Component {
loadingKeywords,
loadingTypes,
setFilterState,
- filterState,
+ // filterState,
communityList,
getCommunityList,
auth,
+ setSearchText,
} = this.props;
if (communityList && !communityList.loadingUuid
@@ -62,31 +47,80 @@ export class Container extends React.Component {
if (!loadingTypes) getTypes();
if (!loadingKeywords) getKeywords();
-
const query = qs.parse(window.location.search.slice(1));
- if (!_.isEmpty(query) && !filterState.track) {
+
+ if (query.tracks) {
+ _.forEach(query.tracks, (value, key) => {
+ query.tracks[key] = value === 'true';
+ });
+ }
+
+ if (query.bucket) {
+ if (query.bucket !== BUCKETS.ALL_PAST && query.bucket !== BUCKETS.MY_PAST) {
+ delete query.endDateStart;
+ delete query.startDateEnd;
+ }
+ delete query.bucket;
+ }
+
+ if (query.endDateStart || query.startDateEnd) {
+ let customDate = true;
+ createStaticRanges().forEach((range) => {
+ if (!range.isCustom && range.isSelected({
+ startDate: query.endDateStart,
+ endDate: query.startDateEnd,
+ })) {
+ customDate = false;
+ }
+ });
+ query.customDate = customDate;
+ }
+
+ if (query.types && query.types.length) {
+ this.initialDefaultChallengeTypes = true;
+ }
+
+ if (query.search) {
+ setSearchText(query.search);
+ }
+
+ if (!_.isEmpty(query)) {
setFilterState(query);
}
- // const trackStatus = localStorage.getItem('trackStatus');
- // const filterObj = trackStatus ? JSON.parse(trackStatus) : null;
- // if (filterObj) {
- // setFilterState(filterObj);
- // }
- // }
+
+ this.outlet = document.createElement('div');
+ document.body.appendChild(this.outlet);
+ }
+
+ componentDidUpdate() {
+ const {
+ filterState,
+ setFilterState,
+ validTypes,
+ } = this.props;
+
+ if (validTypes.length && !this.initialDefaultChallengeTypes) {
+ setFilterState({
+ ..._.clone(filterState),
+ types: validTypes.map(item => item.abbreviation),
+ });
+ this.initialDefaultChallengeTypes = true;
+ }
+ }
+
+ componentWillUnmount() {
+ this.outlet.parentElement.removeChild(this.outlet);
}
render() {
const {
activeBucket,
communityFilters,
- // filterState,
- // isSavingFilter,
- // saveFilter,
- // savedFilters,
- // selectBucket,
- // selectedCommunityId,
setFilterState,
- // tokenV2,
+ expanded,
+ setExpanded,
+ hidden,
+ onClose,
} = this.props;
const communityFilters2 = [
{
@@ -99,41 +133,33 @@ export class Container extends React.Component {
const isForReviewOpportunities = isReviewOpportunitiesBucket(activeBucket);
- return (
+ const filterPanel = (
{
- // const name = getAvailableFilterName(savedFilters);
- // const filter = {
- // ...filterState,
- // communityId: selectedCommunityId,
- // };
-
- // if (isForReviewOpportunities) filter.isForReviewOpportunities = true;
-
- // saveFilter(name, filter, tokenV2);
- // }}
setFilterState={(state) => {
setFilterState(state);
- // if (activeBucket === BUCKETS.SAVED_FILTER) {
- // selectBucket(BUCKETS.ALL);
- // } else if (activeBucket === BUCKETS.SAVED_REVIEW_OPPORTUNITIES_FILTER) {
- // selectBucket(BUCKETS.REVIEW_OPPORTUNITIES);
- // }
}}
- // isSavingFilter={isSavingFilter}
isReviewOpportunitiesBucket={isForReviewOpportunities}
activeBucket={activeBucket}
+ expanded={expanded}
+ setExpanded={setExpanded}
+ hidden={hidden}
+ onClose={onClose}
/>
);
+
+ if (hidden) {
+ return expanded ? ReactDOM.createPortal(filterPanel, this.outlet) : filterPanel;
+ }
+
+ return filterPanel;
}
}
Container.defaultProps = {
- // isSavingFilter: false,
tokenV2: '',
- // challenges: [],
+ hidden: false,
};
Container.propTypes = {
@@ -150,25 +176,25 @@ Container.propTypes = {
timestamp: PT.number.isRequired,
}).isRequired,
filterState: PT.shape().isRequired,
- // challenges: PT.arrayOf(PT.shape()),
selectedCommunityId: PT.string.isRequired,
getKeywords: PT.func.isRequired,
getTypes: PT.func.isRequired,
- // isSavingFilter: PT.bool,
- // savedFilters: PT.arrayOf(PT.shape()).isRequired,
loadingKeywords: PT.bool.isRequired,
loadingTypes: PT.bool.isRequired,
- // saveFilter: PT.func.isRequired,
- // selectBucket: PT.func.isRequired,
setFilterState: PT.func.isRequired,
auth: PT.shape().isRequired,
tokenV2: PT.string,
+ expanded: PT.bool.isRequired,
+ setExpanded: PT.func.isRequired,
+ hidden: PT.bool,
+ onClose: PT.func.isRequired,
+ validTypes: PT.arrayOf(PT.shape()).isRequired,
+ setSearchText: PT.func.isRequired,
};
function mapDispatchToProps(dispatch) {
const a = actions.challengeListing.filterPanel;
const cla = challengeListingActions.challengeListing;
- // const sa = sidebarActions.challengeListing.sidebar;
return {
...bindActionCreators(a, dispatch),
getTypes: () => {
@@ -184,13 +210,9 @@ function mapDispatchToProps(dispatch) {
dispatch(cla.getChallengeTagsInit());
dispatch(cla.getChallengeTagsDone());
},
- // saveFilter: (...rest) => {
- // dispatch(sa.saveFilterInit());
- // dispatch(sa.saveFilterDone(...rest));
- // },
- // selectBucket: bucket => dispatch(sa.selectBucket(bucket)),
selectCommunity: id => dispatch(cla.selectCommunity(id)),
setFilterState: s => dispatch(cla.setFilter(s)),
+ onClose: () => dispatch(a.setExpanded(false)),
};
}
@@ -212,8 +234,6 @@ function mapStateToProps(state, ownProps) {
selectedCommunityId: cl.selectedCommunityId,
auth: state.auth,
tokenV2: state.auth.tokenV2,
- // isSavingFilter: cl.sidebar.isSavingFilter,
- // savedFilters: cl.sidebar.savedFilters,
};
}
diff --git a/src/shared/containers/challenge-listing/Listing/index.jsx b/src/shared/containers/challenge-listing/Listing/index.jsx
index 9c15f5776a..8c996bd8e8 100644
--- a/src/shared/containers/challenge-listing/Listing/index.jsx
+++ b/src/shared/containers/challenge-listing/Listing/index.jsx
@@ -12,7 +12,6 @@
import _ from 'lodash';
import actions from 'actions/challenge-listing';
import challengeDetailsActions from 'actions/page/challenge-details';
-import filterPanelActions from 'actions/challenge-listing/filter-panel';
import headerActions from 'actions/topcoder_header';
import { logger, challenge as challengeUtils } from 'topcoder-react-lib';
import React from 'react';
@@ -22,6 +21,7 @@ import { connect } from 'react-redux';
import ChallengeListing from 'components/challenge-listing';
import Banner from 'components/tc-communities/Banner';
import sidebarActions from 'actions/challenge-listing/sidebar';
+import filterPanelActions from 'actions/challenge-listing/filter-panel';
import communityActions from 'actions/tc-communities';
// import SORT from 'utils/challenge-listing/sort';
import { BUCKETS, filterChanged, sortChangedBucket } from 'utils/challenge-listing/buckets';
@@ -104,14 +104,16 @@ export class ListingContainer extends React.Component {
sorts,
dropMyChallenges,
getMyChallenges,
+ dropMyPastChallenges,
+ getMyPastChallenges,
dropAllChallenges,
getAllChallenges,
getOpenForRegistrationChallenges,
getActiveChallenges,
dropActiveChallenges,
dropOpenForRegistrationChallenges,
- // dropPastChallenges,
- // getPastChallenges,
+ dropPastChallenges,
+ getPastChallenges,
} = this.props;
const oldUserId = _.get(prevProps, 'auth.user.userId');
const userId = _.get(this.props, 'auth.user.userId');
@@ -135,11 +137,25 @@ export class ListingContainer extends React.Component {
// }
const bucket = sortChangedBucket(sorts, prevProps.sorts);
const f = this.getBackendFilter();
+ const fA = {
+ back: { ..._.clone(f.back), startDateEnd: null, endDateStart: null },
+ front: { ..._.clone(f.front), startDateEnd: null, endDateStart: null },
+ };
if (bucket) {
switch (bucket) {
case BUCKETS.MY: {
dropMyChallenges();
getMyChallenges(
+ 0,
+ fA.back,
+ auth.tokenV3,
+ fA.front,
+ );
+ break;
+ }
+ case BUCKETS.MY_PAST: {
+ dropMyPastChallenges();
+ getMyPastChallenges(
0,
f.back,
auth.tokenV3,
@@ -151,9 +167,9 @@ export class ListingContainer extends React.Component {
dropOpenForRegistrationChallenges();
getOpenForRegistrationChallenges(
0,
- f.back,
+ fA.back,
auth.tokenV3,
- f.front,
+ fA.front,
);
break;
}
@@ -161,9 +177,9 @@ export class ListingContainer extends React.Component {
dropActiveChallenges();
getActiveChallenges(
0,
- f.back,
+ fA.back,
auth.tokenV3,
- f.front,
+ fA.front,
);
break;
}
@@ -187,6 +203,16 @@ export class ListingContainer extends React.Component {
// );
// break;
// }
+ case BUCKETS.ALL_PAST: {
+ dropPastChallenges();
+ getPastChallenges(
+ 0,
+ f.back,
+ auth.tokenV3,
+ f.front,
+ );
+ break;
+ }
default: {
break;
}
@@ -220,7 +246,7 @@ export class ListingContainer extends React.Component {
sorts,
filter,
} = this.props;
- const filterTemp = _.clone(filter);
+ const filterTemp = _.omit(filter, 'reviewOpportunityTypes', 'customDate');
// let communityFilter = communitiesList.data.find(
// item => item.communityId === selectedCommunityId,
// );
@@ -255,8 +281,9 @@ export class ListingContainer extends React.Component {
// getActiveChallenges,
getOpenForRegistrationChallenges,
getMyChallenges,
+ getMyPastChallenges,
getAllChallenges,
- // getPastChallenges,
+ getPastChallenges,
// lastRequestedPageOfActiveChallenges,
// lastRequestedPageOfOpenForRegistrationChallenges,
// lastRequestedPageOfMyChallenges,
@@ -295,13 +322,19 @@ export class ListingContainer extends React.Component {
auth.tokenV3,
f.front,
);
+ getMyPastChallenges(
+ 0,
+ f.back,
+ auth.tokenV3,
+ f.front,
+ );
}
- // getPastChallenges(
- // 0,
- // f.back,
- // auth.tokenV3,
- // f.front,
- // );
+ getPastChallenges(
+ 0,
+ f.back,
+ auth.tokenV3,
+ f.front,
+ );
getTotalChallengesCount(auth.tokenV3, f.front);
}
@@ -360,8 +393,9 @@ export class ListingContainer extends React.Component {
challenges,
openForRegistrationChallenges,
myChallenges,
+ myPastChallenges,
allChallenges,
- // pastChallenges,
+ pastChallenges,
challengeTypes,
challengesUrl,
challengeTags,
@@ -376,24 +410,27 @@ export class ListingContainer extends React.Component {
groupIds,
getActiveChallenges,
getMyChallenges,
+ getMyPastChallenges,
getAllChallenges,
getOpenForRegistrationChallenges,
- // getPastChallenges,
+ getPastChallenges,
getReviewOpportunities,
hideSrm,
keepPastPlaceholders,
lastRequestedPageOfMyChallenges,
+ lastRequestedPageOfMyPastChallenges,
lastRequestedPageOfAllChallenges,
lastRequestedPageOfActiveChallenges,
lastRequestedPageOfOpenForRegistrationChallenges,
- // lastRequestedPageOfPastChallenges,
+ lastRequestedPageOfPastChallenges,
lastRequestedPageOfReviewOpportunities,
// lastUpdateOfActiveChallenges,
loadingActiveChallengesUUID,
loadingOpenForRegistrationChallengesUUID,
loadingMyChallengesUUID,
+ loadingMyPastChallengesUUID,
loadingAllChallengesUUID,
- // loadingPastChallengesUUID,
+ loadingPastChallengesUUID,
loadingReviewOpportunitiesUUID,
listingOnly,
newChallengeDetails,
@@ -405,41 +442,28 @@ export class ListingContainer extends React.Component {
selectChallengeDetailsTab,
selectedCommunityId,
setFilter,
- setSearchText,
setSort,
sorts,
- hideTcLinksInSidebarFooter,
+ // hideTcLinksInSidebarFooter,
// isBucketSwitching,
// userChallenges,
meta,
+ setSearchText,
} = this.props;
const { tokenV3 } = auth;
const isLoggedIn = !_.isEmpty(auth.tokenV3);
- // let loadMorePast;
- // if (!allPastChallengesLoaded) {
- // loadMorePast = () => {
- // const f = this.getBackendFilter();
- // getPastChallenges(
- // 1 + lastRequestedPageOfPastChallenges,
- // f.back,
- // tokenV3,
- // f.front,
- // );
- // };
- // }
-
- // const loadMorePast = () => {
- // const f = this.getBackendFilter();
- // getPastChallenges(
- // 1 + lastRequestedPageOfPastChallenges,
- // f.back,
- // tokenV3,
- // f.front,
- // );
- // };
+ const loadMorePast = () => {
+ const f = this.getBackendFilter();
+ getPastChallenges(
+ 1 + lastRequestedPageOfPastChallenges,
+ f.back,
+ tokenV3,
+ f.front,
+ );
+ };
const loadMoreMy = () => {
const f = this.getBackendFilter();
@@ -451,6 +475,16 @@ export class ListingContainer extends React.Component {
);
};
+ const loadMoreMyPast = () => {
+ const f = this.getBackendFilter();
+ getMyPastChallenges(
+ 1 + lastRequestedPageOfMyPastChallenges,
+ f.back,
+ tokenV3,
+ f.front,
+ );
+ };
+
const loadMoreOpenForRegistration = () => {
const f = this.getBackendFilter();
getOpenForRegistrationChallenges(
@@ -526,8 +560,9 @@ export class ListingContainer extends React.Component {
challenges={challenges}
openForRegistrationChallenges={openForRegistrationChallenges}
myChallenges={myChallenges}
+ myPastChallenges={myPastChallenges}
allChallenges={allChallenges}
- // pastChallenges={pastChallenges}
+ pastChallenges={pastChallenges}
challengeTypes={challengeTypes}
challengeTags={challengeTags}
challengesUrl={challengesUrl}
@@ -540,17 +575,18 @@ export class ListingContainer extends React.Component {
// extraBucket={extraBucket}
filterState={filter}
hideSrm={hideSrm}
- hideTcLinksInFooter={hideTcLinksInSidebarFooter}
+ // hideTcLinksInFooter={hideTcLinksInSidebarFooter}
keepPastPlaceholders={keepPastPlaceholders}
// lastUpdateOfActiveChallenges={lastUpdateOfActiveChallenges}
// eslint-disable-next-line max-len
loadingMyChallenges={Boolean(loadingMyChallengesUUID)}
+ loadingMyPastChallenges={Boolean(loadingMyPastChallengesUUID)}
loadingAllChallenges={Boolean(loadingAllChallengesUUID)}
loadingOpenForRegistrationChallenges={Boolean(loadingOpenForRegistrationChallengesUUID)}
loadingOnGoingChallenges={Boolean(loadingActiveChallengesUUID)}
// eslint-disable-next-line max-len
// loadingChallenges={Boolean(loadingActiveChallengesUUID) && Boolean(loadingOpenForRegistrationChallengesUUID) && Boolean(loadingMyChallengesUUID)}
- // loadingPastChallenges={Boolean(loadingPastChallengesUUID)}
+ loadingPastChallenges={Boolean(loadingPastChallengesUUID)}
loadingReviewOpportunities={Boolean(loadingReviewOpportunitiesUUID)}
newChallengeDetails={newChallengeDetails}
openChallengesInNewTabs={openChallengesInNewTabs}
@@ -559,16 +595,16 @@ export class ListingContainer extends React.Component {
selectBucket={selectBucket}
selectChallengeDetailsTab={selectChallengeDetailsTab}
selectedCommunityId={selectedCommunityId}
- // loadMorePast={loadMorePast}
+ loadMorePast={loadMorePast}
loadMoreReviewOpportunities={loadMoreReviewOpportunities}
loadMoreMy={loadMoreMy}
+ loadMoreMyPast={loadMoreMyPast}
loadMoreAll={loadMoreAll}
loadMoreOpenForRegistration={loadMoreOpenForRegistration}
loadMoreOnGoing={loadMoreOnGoing}
reviewOpportunities={reviewOpportunities}
setFilterState={(state) => {
setFilter(state);
- setSearchText(state.search || '');
// if (activeBucket === BUCKETS.SAVED_FILTER) {
// selectBucket(BUCKETS.OPEN_FOR_REGISTRATION);
// } else if (activeBucket === BUCKETS.SAVED_REVIEW_OPPORTUNITIES_FILTER) {
@@ -583,6 +619,7 @@ export class ListingContainer extends React.Component {
// userChallenges={[]}
isLoggedIn={isLoggedIn}
meta={meta}
+ setSearchText={setSearchText}
/>
);
@@ -592,13 +629,13 @@ export class ListingContainer extends React.Component {
ListingContainer.defaultProps = {
ChallengeListingBanner: null,
challengeTypes: [],
- // pastChallenges: [],
+ pastChallenges: [],
defaultCommunityId: '',
// extraBucket: null,
hideSrm: false,
selectedCommunityId: '',
groupIds: [''],
- hideTcLinksInSidebarFooter: false,
+ // hideTcLinksInSidebarFooter: false,
challengesUrl: '/challenges',
communityId: null,
communityName: null,
@@ -627,8 +664,9 @@ ListingContainer.propTypes = {
challenges: PT.arrayOf(PT.shape({})).isRequired, // active challenges.
openForRegistrationChallenges: PT.arrayOf(PT.shape({})).isRequired,
myChallenges: PT.arrayOf(PT.shape({})).isRequired,
+ myPastChallenges: PT.arrayOf(PT.shape({})).isRequired,
allChallenges: PT.arrayOf(PT.shape({})).isRequired,
- // pastChallenges: PT.arrayOf(PT.shape({})),
+ pastChallenges: PT.arrayOf(PT.shape({})),
challengeTypes: PT.arrayOf(PT.shape()),
challengesUrl: PT.string,
challengeTags: PT.arrayOf(PT.string).isRequired,
@@ -643,13 +681,14 @@ ListingContainer.propTypes = {
defaultCommunityId: PT.string,
dropChallenges: PT.func.isRequired,
dropMyChallenges: PT.func.isRequired,
+ dropMyPastChallenges: PT.func.isRequired,
dropAllChallenges: PT.func.isRequired,
dropOpenForRegistrationChallenges: PT.func.isRequired,
dropActiveChallenges: PT.func.isRequired,
- // dropPastChallenges: PT.func.isRequired,
+ dropPastChallenges: PT.func.isRequired,
filter: PT.shape().isRequired,
hideSrm: PT.bool,
- hideTcLinksInSidebarFooter: PT.bool,
+ // hideTcLinksInSidebarFooter: PT.bool,
communityId: PT.string,
communityName: PT.string,
communityFilters: PT.arrayOf(PT.object).isRequired,
@@ -657,24 +696,27 @@ ListingContainer.propTypes = {
getActiveChallenges: PT.func.isRequired,
getOpenForRegistrationChallenges: PT.func.isRequired,
getMyChallenges: PT.func.isRequired,
+ getMyPastChallenges: PT.func.isRequired,
getAllChallenges: PT.func.isRequired,
// getRestActiveChallenges: PT.func.isRequired,
getCommunitiesList: PT.func.isRequired,
- // getPastChallenges: PT.func.isRequired,
+ getPastChallenges: PT.func.isRequired,
getReviewOpportunities: PT.func.isRequired,
keepPastPlaceholders: PT.bool.isRequired,
lastRequestedPageOfActiveChallenges: PT.number.isRequired,
lastRequestedPageOfOpenForRegistrationChallenges: PT.number.isRequired,
lastRequestedPageOfMyChallenges: PT.number.isRequired,
+ lastRequestedPageOfMyPastChallenges: PT.number.isRequired,
lastRequestedPageOfAllChallenges: PT.number.isRequired,
- // lastRequestedPageOfPastChallenges: PT.number.isRequired,
+ lastRequestedPageOfPastChallenges: PT.number.isRequired,
lastRequestedPageOfReviewOpportunities: PT.number.isRequired,
// lastUpdateOfActiveChallenges: PT.number.isRequired,
loadingActiveChallengesUUID: PT.string.isRequired,
loadingOpenForRegistrationChallengesUUID: PT.string.isRequired,
loadingMyChallengesUUID: PT.string.isRequired,
+ loadingMyPastChallengesUUID: PT.string.isRequired,
loadingAllChallengesUUID: PT.string.isRequired,
- // loadingPastChallengesUUID: PT.string.isRequired,
+ loadingPastChallengesUUID: PT.string.isRequired,
loadingReviewOpportunitiesUUID: PT.string.isRequired,
markHeaderMenu: PT.func.isRequired,
newChallengeDetails: PT.bool,
@@ -690,7 +732,6 @@ ListingContainer.propTypes = {
expanding: PT.bool,
selectedCommunityId: PT.string,
sorts: PT.shape().isRequired,
- setSearchText: PT.func.isRequired,
setSort: PT.func.isRequired,
listingOnly: PT.bool,
groupIds: PT.arrayOf(PT.string),
@@ -703,6 +744,7 @@ ListingContainer.propTypes = {
getTotalChallengesCount: PT.func.isRequired,
// userChallenges: PT.arrayOf(PT.string),
// getUserChallenges: PT.func.isRequired,
+ setSearchText: PT.func.isRequired,
};
const mapStateToProps = (state, ownProps) => {
@@ -714,35 +756,38 @@ const mapStateToProps = (state, ownProps) => {
return {
auth: state.auth,
// allActiveChallengesLoaded: cl.allActiveChallengesLoaded,
- // allPastChallengesLoaded: cl.allPastChallengesLoaded,
+ allPastChallengesLoaded: cl.allPastChallengesLoaded,
allReviewOpportunitiesLoaded: cl.allReviewOpportunitiesLoaded,
filter: cl.filter,
challenges: cl.challenges,
openForRegistrationChallenges: cl.openForRegistrationChallenges,
myChallenges: cl.myChallenges,
+ myPastChallenges: cl.myPastChallenges,
allChallenges: cl.allChallenges,
- // pastChallenges: cl.pastChallenges,
+ pastChallenges: cl.pastChallenges,
challengeTypes: cl.challengeTypes,
challengeTags: cl.challengeTags,
communitiesList: tc.list,
communityFilters: tc.list.data,
domain: state.domain,
// extraBucket: ownProps.extraBucket,
- hideTcLinksInSidebarFooter: ownProps.hideTcLinksInSidebarFooter,
+ // hideTcLinksInSidebarFooter: ownProps.hideTcLinksInSidebarFooter,
keepPastPlaceholders: cl.keepPastPlaceholders,
lastRequestedPageOfActiveChallenges: cl.lastRequestedPageOfActiveChallenges,
// eslint-disable-next-line max-len
lastRequestedPageOfOpenForRegistrationChallenges: cl.lastRequestedPageOfOpenForRegistrationChallenges,
lastRequestedPageOfMyChallenges: cl.lastRequestedPageOfMyChallenges,
+ lastRequestedPageOfMyPastChallenges: cl.lastRequestedPageOfMyPastChallenges,
lastRequestedPageOfAllChallenges: cl.lastRequestedPageOfAllChallenges,
- // lastRequestedPageOfPastChallenges: cl.lastRequestedPageOfPastChallenges,
+ lastRequestedPageOfPastChallenges: cl.lastRequestedPageOfPastChallenges,
lastRequestedPageOfReviewOpportunities: cl.lastRequestedPageOfReviewOpportunities,
// lastUpdateOfActiveChallenges: cl.lastUpdateOfActiveChallenges,
loadingActiveChallengesUUID: cl.loadingActiveChallengesUUID,
loadingOpenForRegistrationChallengesUUID: cl.loadingOpenForRegistrationChallengesUUID,
loadingMyChallengesUUID: cl.loadingMyChallengesUUID,
+ loadingMyPastChallengesUUID: cl.loadingMyPastChallengesUUID,
loadingAllChallengesUUID: cl.loadingAllChallengesUUID,
- // loadingPastChallengesUUID: cl.loadingPastChallengesUUID,
+ loadingPastChallengesUUID: cl.loadingPastChallengesUUID,
loadingReviewOpportunitiesUUID: cl.loadingReviewOpportunitiesUUID,
loadingChallengeTypes: cl.loadingChallengeTypes,
loadingChallengeTags: cl.loadingChallengeTags,
@@ -765,8 +810,8 @@ const mapStateToProps = (state, ownProps) => {
function mapDispatchToProps(dispatch) {
const a = actions.challengeListing;
const ah = headerActions.topcoderHeader;
- const fpa = filterPanelActions.challengeListing.filterPanel;
const sa = sidebarActions.challengeListing.sidebar;
+ const fp = filterPanelActions.challengeListing.filterPanel;
const ca = communityActions.tcCommunity;
return {
dropChallenges: () => dispatch(a.dropChallenges()),
@@ -787,7 +832,13 @@ function mapDispatchToProps(dispatch) {
dispatch(a.getMyChallengesInit(uuid, page, frontFilter));
dispatch(a.getMyChallengesDone(uuid, page, filter, token, frontFilter));
},
+ getMyPastChallenges: (page, filter, token, frontFilter) => {
+ const uuid = shortId();
+ dispatch(a.getMyPastChallengesInit(uuid, page, frontFilter));
+ dispatch(a.getMyPastChallengesDone(uuid, page, filter, token, frontFilter));
+ },
dropMyChallenges: () => dispatch(a.dropMyChallenges()),
+ dropMyPastChallenges: () => dispatch(a.dropMyPastChallenges()),
getAllChallenges: (page, filter, token, frontFilter) => {
const uuid = shortId();
dispatch(a.getAllChallengesInit(uuid, page, frontFilter));
@@ -809,12 +860,12 @@ function mapDispatchToProps(dispatch) {
dispatch(ca.getListInit(uuid));
dispatch(ca.getListDone(uuid, auth));
},
- // dropPastChallenges: () => dispatch(a.dropPastChallenges()),
- // getPastChallenges: (page, filter, token, frontFilter) => {
- // const uuid = shortId();
- // dispatch(a.getPastChallengesInit(uuid, page, frontFilter));
- // dispatch(a.getPastChallengesDone(uuid, page, filter, token, frontFilter));
- // },
+ dropPastChallenges: () => dispatch(a.dropPastChallenges()),
+ getPastChallenges: (page, filter, token, frontFilter) => {
+ const uuid = shortId();
+ dispatch(a.getPastChallengesInit(uuid, page, frontFilter));
+ dispatch(a.getPastChallengesDone(uuid, page, filter, token, frontFilter));
+ },
getReviewOpportunities: (page, token) => {
const uuid = shortId();
dispatch(a.getReviewOpportunitiesInit(uuid, page));
@@ -826,7 +877,6 @@ function mapDispatchToProps(dispatch) {
tab => dispatch(challengeDetailsActions.page.challengeDetails.selectTab(tab)),
selectCommunity: id => dispatch(a.selectCommunity(id)),
setFilter: state => dispatch(a.setFilter(state)),
- setSearchText: text => dispatch(fpa.setSearchText(text)),
setSort: (bucket, sort) => dispatch(a.setSort(bucket, sort)),
markHeaderMenu: () => dispatch(ah.setCurrentNav('Compete', 'All Challenges')),
expandTag: id => dispatch(a.expandTag(id)),
@@ -835,6 +885,7 @@ function mapDispatchToProps(dispatch) {
// dispatch(a.getUserChallengesInit(uuid));
// dispatch(a.getUserChallengesDone(userId, tokenV3));
// },
+ setSearchText: text => dispatch(fp.setSearchText(text)),
};
}
diff --git a/src/shared/containers/challenge-listing/Sidebar.jsx b/src/shared/containers/challenge-listing/Sidebar.jsx
index 034024fbac..cd53b07d1d 100644
--- a/src/shared/containers/challenge-listing/Sidebar.jsx
+++ b/src/shared/containers/challenge-listing/Sidebar.jsx
@@ -4,7 +4,7 @@
// import _ from 'lodash';
import actions from 'actions/challenge-listing/sidebar';
-// import challengeListingActions from 'actions/challenge-listing';
+import challengeListingActions from 'actions/challenge-listing';
// import { config } from 'topcoder-react-utils';
// import filterPanelActions from 'actions/challenge-listing/filter-panel';
import PT from 'prop-types';
@@ -39,6 +39,15 @@ export const SidebarPureComponent = Sidebar;
// }
export class SidebarContainer extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ previousBucketOfActiveTab: null,
+ previousBucketOfPastChallengesTab: null,
+ };
+ }
+
componentDidMount() {
// const { tokenV2, getSavedFilters } = this.props;
// const token = tokenV2;
@@ -56,13 +65,17 @@ export class SidebarContainer extends React.Component {
// selectSavedFilter,
// selectedCommunityId,
// setFilter,
- // setSearchText,
// tokenV2,
// updateAllSavedFilters,
// updateSavedFilter,
// userChallenges,
// } = this.props;
+ const {
+ previousBucketOfActiveTab,
+ previousBucketOfPastChallengesTab,
+ } = this.state;
+
// const buckets = getBuckets(userChallenges);
// if (extraBucket) {
@@ -97,7 +110,6 @@ export class SidebarContainer extends React.Component {
// const { filter } = origSavedFilters[index];
// selectSavedFilter(index);
// setFilter(_.omit(filter, 'communityId'));
- // setSearchText(filter.text || '');
// selectCommunity(filter.communityId || '');
// }}
// updateAllSavedFilters={() => updateAllSavedFilters(
@@ -106,6 +118,14 @@ export class SidebarContainer extends React.Component {
// )
// }
// updateSavedFilter={filter => updateSavedFilter(filter, tokenV2)}
+ previousBucketOfActiveTab={previousBucketOfActiveTab}
+ previousBucketOfPastChallengesTab={previousBucketOfPastChallengesTab}
+ setPreviousBucketOfActiveTab={(bucket) => {
+ this.setState({ previousBucketOfActiveTab: bucket });
+ }}
+ setPreviousBucketOfPastChallengesTab={(bucket) => {
+ this.setState({ previousBucketOfPastChallengesTab: bucket });
+ }}
/>
);
}
@@ -117,6 +137,7 @@ SidebarContainer.defaultProps = {
// tokenV2: null,
// user: null,
// userChallenges: [],
+ expanding: false,
};
SidebarContainer.propTypes = {
@@ -131,48 +152,49 @@ SidebarContainer.propTypes = {
// savedFilters: PT.arrayOf(PT.shape()).isRequired,
// selectedCommunityId: PT.string,
// selectSavedFilter: PT.func.isRequired,
- // setFilter: PT.func.isRequired,
+ setFilter: PT.func.isRequired,
// selectCommunity: PT.func.isRequired,
- // setSearchText: PT.func.isRequired,
// tokenV2: PT.string,
// updateAllSavedFilters: PT.func.isRequired,
// updateSavedFilter: PT.func.isRequired,
// user: PT.shape(),
// userChallenges: PT.arrayOf(PT.string),
+ expanding: PT.bool,
};
function mapDispatchToProps(dispatch) {
const a = actions.challengeListing.sidebar;
- // const cla = challengeListingActions.challengeListing;
+ const cla = challengeListingActions.challengeListing;
// const fpa = filterPanelActions.challengeListing.filterPanel;
return {
...bindActionCreators(a, dispatch),
- // setFilter: filter => dispatch(cla.setFilter(filter)),
+ setFilter: filter => dispatch(cla.setFilter(filter)),
// selectCommunity: communityId => dispatch(cla.selectCommunity(communityId)),
- // setSearchText: text => dispatch(fpa.setSearchText(text)),
};
}
-function mapStateToProps(state, ownProps) {
+function mapStateToProps(state) {
// const { activeBucket } = state.challengeListing.sidebar;
// const pending = _.keys(state.challengeListing.pendingRequests);
// updateChallengeType(
// state.challengeListing.challenges, state.challengeListing.challengeTypesMap,
// );
+ const sb = state.challengeListing.sidebar;
return {
activeBucket: state.challengeListing.sidebar.activeBucket,
// ...state.challengeListing.sidebar,
// challenges: state.challengeListing.challenges,
// disabled: (activeBucket === BUCKETS.ALL) && Boolean(pending.length),
// extraBucket: ownProps.extraBucket,
- hideTcLinksInFooter: ownProps.hideTcLinksInFooter,
- // filterState: state.challengeListing.filter,
+ // hideTcLinksInFooter: ownProps.hideTcLinksInFooter,
+ filterState: state.challengeListing.filter,
isAuth: Boolean(state.auth.user),
// communityFilters: state.tcCommunities.list.data,
// selectedCommunityId: state.challengeListing.selectedCommunityId,
// tokenV2: state.auth.tokenV2,
// user: state.auth.user,
// userChallenges: state.challengeListing.userChallenges,
+ expanding: sb.expanding,
};
}
diff --git a/src/shared/index.jsx b/src/shared/index.jsx
index ec75190656..2a15346bf6 100644
--- a/src/shared/index.jsx
+++ b/src/shared/index.jsx
@@ -22,6 +22,9 @@ require('styles/global.scss');
require('slick-carousel/slick/slick.css');
require('slick-carousel/slick/slick-theme.css');
+require('react-date-range/dist/styles.css');
+require('react-date-range/dist/theme/default.css');
+
const App = require('./app').default;
export default App;
diff --git a/src/shared/reducers/challenge-listing/index.js b/src/shared/reducers/challenge-listing/index.js
index fc656771f7..41ecc6b941 100644
--- a/src/shared/reducers/challenge-listing/index.js
+++ b/src/shared/reducers/challenge-listing/index.js
@@ -14,7 +14,7 @@ import {
// challenge as challengeUtils,
actions as actionsUtils,
} from 'topcoder-react-lib';
-
+import { REVIEW_OPPORTUNITY_TYPES } from 'utils/tc';
import filterPanel from './filter-panel';
import sidebar, { factory as sidebarFactory } from './sidebar';
@@ -149,6 +149,14 @@ function onGetAllChallengesInit(state, { payload }) {
};
}
+function onGetMyPastChallengesInit(state, { payload }) {
+ return {
+ ...state,
+ loadingMyPastChallengesUUID: payload.uuid,
+ lastRequestedPageOfMyPastChallenges: payload.page,
+ };
+}
+
// function onGetRestActiveChallengesInit(state, { payload }) {
// return {
// ...state,
@@ -312,37 +320,42 @@ function onGetChallengeTagsDone(state, action) {
};
}
-// function onGetPastChallengesInit(state, action) {
-// const { frontFilter, page, uuid } = action.payload;
-// const tracks = frontFilter && frontFilter.tracks;
-// if (tracks && _.isEmpty(tracks)) {
-// return {
-// ...state,
-// allPastChallengesLoaded: true,
-// loadingPastChallengesUUID: '',
-// };
-// }
+function onGetPastChallengesInit(state, action) {
+ const { frontFilter, page, uuid } = action.payload;
+ const tracks = frontFilter && frontFilter.tracks;
+ if (tracks && _.isEmpty(tracks)) {
+ return {
+ ...state,
+ allPastChallengesLoaded: true,
+ loadingPastChallengesUUID: '',
+ };
+ }
-// return {
-// ...state,
-// lastRequestedPageOfPastChallenges: page,
-// loadingPastChallengesUUID: uuid,
-// };
-// }
+ return {
+ ...state,
+ lastRequestedPageOfPastChallenges: page,
+ loadingPastChallengesUUID: uuid,
+ };
+}
-// function onGetPastChallengesDone(state, { error, payload }) {
-// if (error) {
-// logger.error(payload);
-// return state;
-// }
-// const { uuid, pastChallenges: loaded } = payload;
-// if (uuid !== state.loadingPastChallengesUUID) return state;
-// const challenges = state.pastChallenges.concat(loaded);
-// return {
-// ...state,
-// pastChallenges: challenges,
-// loadingPastChallengesUUID: '',
-// };
+function onGetPastChallengesDone(state, { error, payload }) {
+ if (error) {
+ logger.error(payload);
+ return state;
+ }
+ const { uuid, pastChallenges: loaded } = payload;
+ if (uuid !== state.loadingPastChallengesUUID) return state;
+ const challenges = state.pastChallenges.concat(loaded);
+ return {
+ ...state,
+ pastChallenges: challenges,
+ loadingPastChallengesUUID: '',
+ allPastChallengesLoaded: challenges.length >= payload.meta.allChallengesCount,
+ meta: {
+ ...state.meta,
+ pastChallengesCount: payload.meta.allChallengesCount,
+ },
+ };
// if (error) {
// logger.error(payload);
// return state;
@@ -378,7 +391,7 @@ function onGetChallengeTagsDone(state, action) {
// loadingPastChallengesUUID: '',
// // pastSearchTimestamp,
// };
-// }
+}
function onSelectCommunity(state, { payload }) {
updateQuery({ communityId: payload || undefined });
@@ -409,8 +422,16 @@ function onSetFilter(state, { payload }) {
* do it very carefuly (many params are not validated). */
const filter = _.pickBy(_.pick(
payload,
- ['tags', 'types', 'name', 'startDateEnd', 'endDateStart', 'groups', 'events', 'tracks'],
+ ['tags', 'types', 'search', 'startDateEnd', 'endDateStart', 'groups', 'events', 'tracks'],
), value => (!_.isArray(value) && value && value !== '') || (_.isArray(value) && value.length > 0));
+
+ const emptyArrayAllowedFields = ['types'];
+ emptyArrayAllowedFields.forEach((field) => {
+ if (_.isEqual(payload[field], [])) {
+ filter[field] = payload[field];
+ }
+ });
+
// if (_.isPlainObject(filter.tags)) {
// filter.tags = _.values(filter.tags);
// }
@@ -615,6 +636,26 @@ function onGetAllChallengesDone(state, { error, payload }) {
};
}
+function onGetMyPastChallengesDone(state, { error, payload }) {
+ if (error) {
+ logger.error(payload);
+ return state;
+ }
+ const { uuid, myPastChallenges: loaded } = payload;
+ if (uuid !== state.loadingMyPastChallengesUUID) return state;
+ const challenges = state.myPastChallenges.concat(loaded);
+ return {
+ ...state,
+ myPastChallenges: challenges,
+ loadingMyPastChallengesUUID: '',
+ allMyPastChallengesLoaded: challenges.length >= payload.meta.allChallengesCount,
+ meta: {
+ ...state.meta,
+ myPastChallengesCount: payload.meta.allChallengesCount,
+ },
+ };
+}
+
function onGetTotalChallengesCountInit(state, { payload }) {
return {
...state,
@@ -654,25 +695,28 @@ function create(initialState) {
allMyChallengesLoaded: false,
allChallengesLoaded: false,
allOpenForRegistrationChallengesLoaded: false,
- // allPastChallengesLoaded: false,
+ allPastChallengesLoaded: false,
// allReviewOpportunitiesLoaded: false,
challenges: [],
allChallenges: [],
myChallenges: [],
+ myPastChallenges: [],
openForRegistrationChallenges: [],
- // pastChallenges: [],
+ pastChallenges: [],
lastRequestedPageOfActiveChallenges: -1,
lastRequestedPageOfOpenForRegistrationChallenges: -1,
lastRequestedPageOfMyChallenges: -1,
+ lastRequestedPageOfMyPastChallenges: -1,
lastRequestedPageOfAllChallenges: -1,
- // lastRequestedPageOfPastChallenges: -1,
+ lastRequestedPageOfPastChallenges: -1,
// lastRequestedPageOfReviewOpportunities: -1,
// lastUpdateOfActiveChallenges: 0,
loadingActiveChallengesUUID: '',
loadingOpenForRegistrationChallengesUUID: '',
loadingMyChallengesUUID: '',
+ loadingMyPastChallengesUUID: '',
// loadingRestActiveChallengesUUID: '',
- // loadingPastChallengesUUID: '',
+ loadingPastChallengesUUID: '',
// loadingReviewOpportunitiesUUID: '',
loadingTotalChallengesCountUUID: '',
@@ -717,18 +761,24 @@ function create(initialState) {
lastRequestedPageOfMyChallenges: -1,
loadingMyChallengesUUID: '',
}),
+ [a.dropMyPastChallenges]: state => ({
+ ...state,
+ myPastChallenges: [],
+ lastRequestedPageOfMyPastChallenges: -1,
+ loadingMyPastChallengesUUID: '',
+ }),
[a.dropAllChallenges]: state => ({
...state,
allChallenges: [],
lastRequestedPageOfAllChallenges: -1,
loadingAllChallengesUUID: '',
}),
- // [a.dropPastChallenges]: state => ({
- // ...state,
- // pastChallenges: [],
- // lastRequestedPageOfPastChallenges: -1,
- // loadingPastChallengesUUID: '',
- // }),
+ [a.dropPastChallenges]: state => ({
+ ...state,
+ pastChallenges: [],
+ lastRequestedPageOfPastChallenges: -1,
+ loadingPastChallengesUUID: '',
+ }),
[a.expandTag]: (state, { payload }) => ({
...state,
expandedTags: [...state.expandedTags, payload],
@@ -755,6 +805,9 @@ function create(initialState) {
[a.getMyChallengesInit]: onGetMyChallengesInit,
[a.getMyChallengesDone]: onGetMyChallengesDone,
+ [a.getMyPastChallengesInit]: onGetMyPastChallengesInit,
+ [a.getMyPastChallengesDone]: onGetMyPastChallengesDone,
+
[a.getAllChallengesInit]: onGetAllChallengesInit,
[a.getAllChallengesDone]: onGetAllChallengesDone,
@@ -776,8 +829,8 @@ function create(initialState) {
}),
[a.getChallengeTagsDone]: onGetChallengeTagsDone,
- // [a.getPastChallengesInit]: onGetPastChallengesInit,
- // [a.getPastChallengesDone]: onGetPastChallengesDone,
+ [a.getPastChallengesInit]: onGetPastChallengesInit,
+ [a.getPastChallengesDone]: onGetPastChallengesDone,
[a.getReviewOpportunitiesInit]: onGetReviewOpportunitiesInit,
[a.getReviewOpportunitiesDone]: onGetReviewOpportunitiesDone,
@@ -801,16 +854,18 @@ function create(initialState) {
}, _.defaults(_.clone(initialState) || {}, {
allActiveChallengesLoaded: false,
allMyChallengesLoaded: false,
+ allMyPastChallengesLoaded: false,
allOpenForRegistrationChallengesLoaded: false,
allChallengesLoaded: false,
- // allPastChallengesLoaded: false,
+ allPastChallengesLoaded: false,
allReviewOpportunitiesLoaded: false,
challenges: [],
allChallenges: [],
myChallenges: [],
openForRegistrationChallenges: [],
- // pastChallenges: [],
+ pastChallenges: [],
+ myPastChallenges: [],
recommendedChallenges: {},
challengeTypes: [],
challengeTypesMap: {},
@@ -824,7 +879,8 @@ function create(initialState) {
lastRequestedPageOfOpenForRegistrationChallenges: -1,
lastRequestedPageOfMyChallenges: -1,
lastRequestedPageOfAllChallenges: -1,
- // lastRequestedPageOfPastChallenges: -1,
+ lastRequestedPageOfMyPastChallenges: -1,
+ lastRequestedPageOfPastChallenges: -1,
lastRequestedPageOfReviewOpportunities: -1,
// lastUpdateOfActiveChallenges: 0,
@@ -832,11 +888,12 @@ function create(initialState) {
loadingOpenForRegistrationChallengesUUID: '',
loadingMyChallengesUUID: '',
loadingAllChallengesUUID: '',
+ loadingMyPastChallengesUUID: '',
loadingRecommendedChallengesUUID: '',
// loadingRestActiveChallengesUUID: '',
loadingRecommendedChallengesTechnologies: '',
loadingTotalChallengesCountUUID: '',
- // loadingPastChallengesUUID: '',
+ loadingPastChallengesUUID: '',
loadingReviewOpportunitiesUUID: '',
loadingChallengeTypes: false,
@@ -850,14 +907,14 @@ function create(initialState) {
DS: true,
QA: true,
},
- name: '',
+ search: '',
tags: [],
types: [],
groups: [],
events: [],
startDateEnd: null,
endDateStart: null,
- status: 'Active',
+ reviewOpportunityTypes: _.keys(REVIEW_OPPORTUNITY_TYPES),
},
selectedCommunityId: 'All',
@@ -869,6 +926,8 @@ function create(initialState) {
all: 'startDate',
// past: 'updated',
reviewOpportunities: 'review-opportunities-start-date',
+ allPast: 'startDate',
+ myPast: 'startDate',
},
srms: {
@@ -882,6 +941,8 @@ function create(initialState) {
myChallengesCount: 0,
ongoingChallengesCount: 0,
openChallengesCount: 0,
+ pastChallengesCount: 0,
+ myPastChallengesCount: 0,
totalCount: 0,
},
diff --git a/src/shared/utils/challenge-listing/buckets.js b/src/shared/utils/challenge-listing/buckets.js
index 8e441e00b0..e50a724de3 100644
--- a/src/shared/utils/challenge-listing/buckets.js
+++ b/src/shared/utils/challenge-listing/buckets.js
@@ -3,6 +3,7 @@
*/
import _ from 'lodash';
+import { REVIEW_OPPORTUNITY_TYPES } from 'utils/tc';
import { SORTS } from './sort';
export const BUCKETS = {
@@ -10,11 +11,13 @@ export const BUCKETS = {
MY: 'my',
OPEN_FOR_REGISTRATION: 'openForRegistration',
ONGOING: 'ongoing',
- // PAST: 'past',
+ PAST: 'past',
// SAVED_FILTER: 'saved-filter',
// UPCOMING: 'upcoming',
REVIEW_OPPORTUNITIES: 'reviewOpportunities',
// SAVED_REVIEW_OPPORTUNITIES_FILTER: 'savedReviewOpportunitiesFilter',
+ ALL_PAST: 'allPast',
+ MY_PAST: 'myPast',
};
export const BUCKET_DATA = {
@@ -120,6 +123,20 @@ export const BUCKET_DATA = {
// // SORTS.REVIEW_OPPORTUNITIES_TITLE_A_TO_Z,
// ],
// },
+ [BUCKETS.ALL_PAST]: {
+ name: 'All Past Challenges',
+ sorts: [
+ SORTS.MOST_RECENT_START_DATE,
+ SORTS.TITLE_A_TO_Z,
+ ],
+ },
+ [BUCKETS.MY_PAST]: {
+ name: 'My Past Challenges',
+ sorts: [
+ SORTS.MOST_RECENT_START_DATE,
+ SORTS.TITLE_A_TO_Z,
+ ],
+ },
};
export const NO_LIVE_CHALLENGES_CONFIG = {
@@ -130,6 +147,8 @@ export const NO_LIVE_CHALLENGES_CONFIG = {
// [BUCKETS.PAST]: 'No challenges found in Past Challenges',
// [BUCKETS.SAVED_FILTER]: 'No challenges found in Saved filter Challenges',
// [BUCKETS.UPCOMING]: 'No challenges found in Upcoming Challenges',
+ [BUCKETS.ALL_PAST]: 'No challenges found in All Past Challenges',
+ [BUCKETS.MY_PAST]: 'No challenges found in My Past Challenges',
};
/**
@@ -164,15 +183,12 @@ export function registerBucket(id, bucket) {
BUCKETS[id] = id;
BUCKET_DATA[id] = bucket;
}
-
-
export function filterChanged(filter, prevFilter) {
if (!filter || !prevFilter) {
return true;
}
return (!_.isEqual(filter.tracks, prevFilter.tracks))
|| (filter.search !== prevFilter.search)
- || (filter.status !== prevFilter.status)
|| (filter.startDateEnd !== prevFilter.startDateEnd)
|| (filter.endDateStart !== prevFilter.endDateStart)
// eslint-disable-next-line max-len
@@ -190,26 +206,62 @@ export function sortChangedBucket(sorts, prevSorts) {
if (sorts.all !== prevSorts.all) return 'all';
if (sorts.openForRegistration !== prevSorts.openForRegistration) return 'openForRegistration';
// if (sorts.past !== prevSorts.past) return 'past';
+ if (sorts.allPast !== prevSorts.allPast) return 'allPast';
+ if (sorts.myPast !== prevSorts.myPast) return 'myPast';
return '';
}
-export function isFilterEmpty(filter) {
- return _.isEqual(filter, {
- tracks: {
- Dev: true,
- Des: true,
- DS: true,
- QA: true,
- },
- name: '',
- tags: [],
- types: [],
- groups: [],
- events: [],
- startDateStart: null,
- endDateEnd: null,
- status: 'Active',
- });
+export function isFilterEmpty(filter, tab, bucket) {
+ let f;
+ let empty;
+
+ if (tab === 'past') {
+ f = _.pick(filter, 'tracks', 'search', 'types', 'startDateEnd', 'endDateStart');
+ if (f.types) f.types = [...f.types].sort();
+ empty = {
+ tracks: {
+ Dev: true,
+ Des: true,
+ DS: true,
+ QA: true,
+ },
+ search: '',
+ types: ['CH', 'F2F', 'TSK'],
+ startDateEnd: null,
+ endDateStart: null,
+ };
+ } else if (bucket === BUCKETS.REVIEW_OPPORTUNITIES) {
+ f = _.pick(filter, 'tracks', 'search', 'reviewOpportunityTypes');
+ empty = {
+ tracks: {
+ Dev: true,
+ Des: true,
+ DS: true,
+ QA: true,
+ },
+ search: '',
+ reviewOpportunityTypes: _.keys(REVIEW_OPPORTUNITY_TYPES),
+ };
+ } else {
+ f = _.pick(filter, 'tracks', 'search', 'types');
+ if (f.types) f.types = [...f.types].sort();
+ empty = {
+ tracks: {
+ Dev: true,
+ Des: true,
+ DS: true,
+ QA: true,
+ },
+ search: '',
+ types: ['CH', 'F2F', 'TSK'],
+ };
+ }
+
+ return _.isEqual(f, empty);
+}
+
+export function isPastBucket(bucket) {
+ return [BUCKETS.ALL_PAST, BUCKETS.MY_PAST].indexOf(bucket) !== -1;
}
export default undefined;
diff --git a/src/shared/utils/challenge-listing/date-range.js b/src/shared/utils/challenge-listing/date-range.js
new file mode 100644
index 0000000000..ead001ec34
--- /dev/null
+++ b/src/shared/utils/challenge-listing/date-range.js
@@ -0,0 +1,62 @@
+import moment from 'moment';
+
+const isSameDay = (date1, date2) => {
+ if (!date1 || !date2) return false;
+ return moment(date1).isSame(moment(date2), 'day');
+};
+
+const staticRangeHandler = {
+ isSelected(range) {
+ const definedRange = { startDate: this.startDate, endDate: this.endDate };
+ return (
+ isSameDay(range.startDate, definedRange.startDate)
+ && isSameDay(range.endDate, definedRange.endDate)
+ );
+ },
+};
+
+/**
+ * Create defined date ranges
+ * @return {object[]} list of defined ranges
+ */
+export function createStaticRanges() {
+ const now = moment().utcOffset(0);
+ const pastMonth = now.clone().subtract(1, 'month');
+ const past3Months = now.clone().subtract(3, 'month');
+ const past6Months = now.clone().subtract(6, 'month');
+ const pastYear = now.clone().subtract(1, 'year');
+
+ const ranges = [
+ {
+ label: 'Past Month',
+ startDate: pastMonth.startOf('day').toDate(),
+ endDate: now.clone().endOf('day').toDate(),
+ },
+ {
+ label: 'Past 6 Months',
+ startDate: past6Months.startOf('day').toDate(),
+ endDate: now.clone().endOf('day').toDate(),
+ },
+ {
+ label: 'Custom Date',
+ startDate: null,
+ endDate: null,
+ isCustom: true,
+ },
+ {
+ label: 'Past 3 Month',
+ startDate: past3Months.startOf('day').toDate(),
+ endDate: now.clone().endOf('day').toDate(),
+ },
+ {
+ label: 'Past 1 Year',
+ startDate: pastYear.startOf('day').toDate(),
+ endDate: now.clone().endOf('day').toDate(),
+ },
+
+ ];
+
+ return ranges.map(range => ({ ...staticRangeHandler, ...range }));
+}
+
+export default createStaticRanges;
diff --git a/src/shared/utils/url.js b/src/shared/utils/url.js
index 52ad5430a8..a705d57ed4 100644
--- a/src/shared/utils/url.js
+++ b/src/shared/utils/url.js
@@ -65,6 +65,16 @@ export function updateQuery(update) {
...update,
};
}
+
+ if (filterObj.bucket === BUCKETS.REVIEW_OPPORTUNITIES) {
+ delete filterObj.types;
+ }
+
+ if (filterObj.bucket !== BUCKETS.ALL_PAST && filterObj.bucket !== BUCKETS.MY_PAST) {
+ delete filterObj.endDateStart;
+ delete filterObj.startDateEnd;
+ }
+
let query = '?';
const { hash } = window.location;
const filterArray = [];
@@ -94,6 +104,7 @@ export function updateQuery(update) {
query += `&${filterArray.join('&')}`;
}
}
+ query = `?${query.substring(1).split('&').sort().join('&')}`;
if (hash) {
query += hash;
}