Skip to content

Commit a4305e0

Browse files
authored
Merge pull request #1406 from topcoder-platform/develop
Billing account start / end date additions
2 parents a0f5a07 + 6d5fcb4 commit a4305e0

File tree

6 files changed

+120
-12
lines changed

6 files changed

+120
-12
lines changed

server.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,16 @@ function check () {
1616
return true
1717
}
1818
app.use(healthCheck.middleware([check]))
19+
app.use((req, res, next) => {
20+
res.header('Referrer-Policy', 'strict-origin-when-cross-origin');
21+
res.header('Permissions-Policy', 'geolocation=(), microphone=(), camera=()');
22+
res.header('X-Content-Type-Options', 'nosniff');
23+
res.header('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
24+
res.header('Cache-control', 'public, max-age=0');
25+
res.header('Pragma', 'no-cache');
26+
27+
next();
28+
});
1929
// app.use(requireHTTPS) // removed because app servers don't handle https
2030
// app.use(express.static(__dirname))
2131
app.use(express.static(path.join(__dirname, 'build')))

src/components/ChallengesComponent/ChallengeList/ChallengeList.module.scss

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,20 @@
2020
padding-bottom: 10px;
2121
}
2222
}
23+
24+
.title {
25+
font-weight: bold;
26+
}
27+
.error {
28+
font-weight: bold;
29+
color: #BE405E;
30+
}
31+
.active {
32+
color: #008000;
33+
}
34+
.inactive {
35+
color: #BE405E;
36+
}
2337
}
2438

2539
.header {

src/components/ChallengesComponent/ChallengeList/index.js

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ class ChallengeList extends Component {
125125
partiallyUpdateChallengeDetails,
126126
deleteChallenge,
127127
isBillingAccountExpired,
128+
billingStartDate,
129+
billingEndDate,
130+
isBillingAccountLoadingFailed,
131+
isBillingAccountLoading,
128132
selfService
129133
} = this.props
130134
if (warnMessage) {
@@ -172,14 +176,29 @@ class ChallengeList extends Component {
172176
return (
173177
<div className={styles.list}>
174178
<div className={styles.row}>
175-
<DebounceInput
176-
className={styles.challengeInput}
177-
minLength={2}
178-
debounceTimeout={300}
179-
placeholder='Search Challenges'
180-
onChange={(e) => this.updateSearchParam(e.target.value, status)}
181-
value={searchText}
182-
/>
179+
{!isBillingAccountLoading && !isBillingAccountLoadingFailed && !isBillingAccountExpired && (
180+
<div className={'col-9'}>
181+
<span className={styles.title}>Billing Account: </span><span className={styles.active}>{status}</span> &nbsp; <span className={styles.title}>Start Date:</span> {billingStartDate} &nbsp; <span className={styles.title}>End Date:</span> {billingEndDate}
182+
</div>
183+
)}
184+
{!isBillingAccountLoading && !isBillingAccountLoadingFailed && isBillingAccountExpired && (
185+
<div className={'col-9'}>
186+
<span className={styles.title}>Billing Account: </span><span className={styles.inactive}>INACTIVE</span> &nbsp; <span className={styles.title}>Start Date:</span> {billingStartDate} &nbsp; <span className={styles.title}>End Date:</span> {billingEndDate}
187+
</div>
188+
)}
189+
{!isBillingAccountLoading && isBillingAccountLoadingFailed && (
190+
<div className={'col-9'}><span className={styles.error}>Billing Account failed to load</span></div>
191+
)}
192+
<div className={'col-3'}>
193+
<DebounceInput
194+
className={styles.challengeInput}
195+
minLength={2}
196+
debounceTimeout={300}
197+
placeholder='Search Challenges'
198+
onChange={(e) => this.updateSearchParam(e.target.value, status)}
199+
value={searchText}
200+
/>
201+
</div>
183202
</div>
184203
{activeProject && (<Tabs
185204
selectedIndex={selectedTab}
@@ -307,6 +326,10 @@ ChallengeList.propTypes = {
307326
partiallyUpdateChallengeDetails: PropTypes.func.isRequired,
308327
deleteChallenge: PropTypes.func.isRequired,
309328
isBillingAccountExpired: PropTypes.bool,
329+
billingStartDate: PropTypes.string,
330+
billingEndDate: PropTypes.string,
331+
isBillingAccountLoadingFailed: PropTypes.bool,
332+
isBillingAccountLoading: PropTypes.bool,
310333
selfService: PropTypes.bool,
311334
auth: PropTypes.object.isRequired
312335
}

src/components/ChallengesComponent/index.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ const ChallengesComponent = ({
2828
partiallyUpdateChallengeDetails,
2929
deleteChallenge,
3030
isBillingAccountExpired,
31+
billingStartDate,
32+
billingEndDate,
33+
isBillingAccountLoadingFailed,
34+
isBillingAccountLoading,
3135
selfService,
3236
auth
3337
}) => {
@@ -78,6 +82,10 @@ const ChallengesComponent = ({
7882
partiallyUpdateChallengeDetails={partiallyUpdateChallengeDetails}
7983
deleteChallenge={deleteChallenge}
8084
isBillingAccountExpired={isBillingAccountExpired}
85+
billingStartDate={billingStartDate}
86+
billingEndDate={billingEndDate}
87+
isBillingAccountLoadingFailed={isBillingAccountLoadingFailed}
88+
isBillingAccountLoading={isBillingAccountLoading}
8189
selfService={selfService}
8290
auth={auth}
8391
/>
@@ -106,6 +114,10 @@ ChallengesComponent.propTypes = {
106114
partiallyUpdateChallengeDetails: PropTypes.func.isRequired,
107115
deleteChallenge: PropTypes.func.isRequired,
108116
isBillingAccountExpired: PropTypes.bool,
117+
billingStartDate: PropTypes.string,
118+
billingEndDate: PropTypes.string,
119+
isBillingAccountLoadingFailed: PropTypes.bool,
120+
isBillingAccountLoading: PropTypes.bool,
109121
selfService: PropTypes.bool,
110122
auth: PropTypes.object.isRequired
111123
}

src/containers/Challenges/index.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Challenges extends Component {
3434
resetSidebarActiveParams()
3535
} else if (projectId || selfService) {
3636
if (projectId) {
37+
window.localStorage.setItem('projectLoading', 'true')
3738
this.props.loadProject(projectId)
3839
}
3940
this.reloadChallenges(this.props)
@@ -51,9 +52,12 @@ class Challenges extends Component {
5152
if (activeProjectId !== challengeProjectId || selfService) {
5253
const isAdmin = checkAdmin(this.props.auth.token)
5354
this.props.loadChallengesByPage(1, projectId ? parseInt(projectId) : -1, CHALLENGE_STATUS.ACTIVE, '', selfService, isAdmin ? null : this.props.auth.user.handle)
54-
if (!selfService && (!reduxProjectInfo || `${reduxProjectInfo.id}` !== projectId)
55+
const projectLoading = window.localStorage.getItem('projectLoading') !== null
56+
if (!selfService && (!reduxProjectInfo || `${reduxProjectInfo.id}` !== projectId) && !projectLoading
5557
) {
5658
loadProject(projectId)
59+
} else {
60+
window.localStorage.removeItem('projectLoading')
5761
}
5862
}
5963
}
@@ -87,6 +91,10 @@ class Challenges extends Component {
8791
partiallyUpdateChallengeDetails,
8892
deleteChallenge,
8993
isBillingAccountExpired,
94+
billingStartDate,
95+
billingEndDate,
96+
isBillingAccountLoadingFailed,
97+
isBillingAccountLoading,
9098
selfService,
9199
auth
92100
} = this.props
@@ -155,6 +163,10 @@ class Challenges extends Component {
155163
partiallyUpdateChallengeDetails={partiallyUpdateChallengeDetails}
156164
deleteChallenge={deleteChallenge}
157165
isBillingAccountExpired={isBillingAccountExpired}
166+
billingStartDate={billingStartDate}
167+
billingEndDate={billingEndDate}
168+
isBillingAccountLoadingFailed={isBillingAccountLoadingFailed}
169+
isBillingAccountLoading={isBillingAccountLoading}
158170
selfService={selfService}
159171
auth={auth}
160172
/>
@@ -186,6 +198,10 @@ Challenges.propTypes = {
186198
partiallyUpdateChallengeDetails: PropTypes.func.isRequired,
187199
deleteChallenge: PropTypes.func.isRequired,
188200
isBillingAccountExpired: PropTypes.bool,
201+
billingStartDate: PropTypes.string,
202+
billingEndDate: PropTypes.string,
203+
isBillingAccountLoadingFailed: PropTypes.bool,
204+
isBillingAccountLoading: PropTypes.bool,
189205
selfService: PropTypes.bool,
190206
auth: PropTypes.object.isRequired
191207
}
@@ -197,6 +213,10 @@ const mapStateToProps = ({ challenges, sidebar, projects, auth }) => ({
197213
projects: sidebar.projects,
198214
projectDetail: projects.projectDetail,
199215
isBillingAccountExpired: projects.isBillingAccountExpired,
216+
billingStartDate: projects.billingStartDate,
217+
billingEndDate: projects.billingEndDate,
218+
isBillingAccountLoadingFailed: projects.isBillingAccountLoadingFailed,
219+
isBillingAccountLoading: projects.isBillingAccountLoading,
200220
auth: auth
201221
})
202222

src/reducers/projects.js

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,33 @@ import {
1313
LOAD_PROJECT_PHASES_PENDING,
1414
LOAD_PROJECT_PHASES_SUCCESS
1515
} from '../config/constants'
16+
import moment from 'moment-timezone'
17+
18+
/**
19+
* checks if billing is expired or not
20+
* @param {boolean} active if billing account is active or not
21+
* @param {string} endDate the end date
22+
* @returns if billing expired or not
23+
*/
24+
const checkBillingExpired = (active, endDate) => {
25+
if (active) {
26+
if (moment().isBefore(endDate)) {
27+
return false
28+
}
29+
return true
30+
}
31+
return true
32+
}
33+
const dateFormat = 'MMM DD, YYYY'
1634

1735
const initialState = {
1836
isLoading: false,
1937
projectDetail: {},
2038
isBillingAccountExpired: false,
2139
isBillingAccountLoading: false,
40+
isBillingAccountLoadingFailed: false,
41+
billingStartDate: null,
42+
billingEndDate: null,
2243
isPhasesLoading: false,
2344
phases: []
2445
}
@@ -42,19 +63,27 @@ export default function (state = initialState, action) {
4263
return {
4364
...state,
4465
isBillingAccountLoading: true,
45-
isBillingAccountExpired: false
66+
isBillingAccountExpired: false,
67+
billingStartDate: '',
68+
billingEndDate: ''
4669
}
4770
case LOAD_PROJECT_BILLING_ACCOUNT_SUCCESS:
4871
return {
4972
...state,
5073
isBillingAccountLoading: false,
51-
isBillingAccountExpired: !action.payload.active
74+
isBillingAccountExpired: checkBillingExpired(action.payload.active, action.payload.endDate),
75+
billingStartDate: moment(action.payload.startDate).format(dateFormat),
76+
billingEndDate: moment(action.payload.endDate).format(dateFormat),
77+
isBillingAccountLoadingFailed: false
5278
}
5379
case LOAD_PROJECT_BILLING_ACCOUNT_FAILURE:
5480
return {
5581
...state,
5682
isBillingAccountLoading: false,
57-
isBillingAccountExpired: false
83+
isBillingAccountExpired: false,
84+
billingStartDate: '',
85+
billingEndDate: '',
86+
isBillingAccountLoadingFailed: true
5887
}
5988
case LOAD_PROJECT_PHASES_PENDING:
6089
return {

0 commit comments

Comments
 (0)