Skip to content

Commit bffe6eb

Browse files
Merge branch 'develop' into feat/fetch-active-review-types-only
2 parents 25faf30 + 1113bd0 commit bffe6eb

File tree

8 files changed

+152
-1
lines changed

8 files changed

+152
-1
lines changed

__tests__/__snapshots__/index.js.snap

+9
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ Object {
206206
"getCommunityStatsDone": [Function],
207207
"getCommunityStatsInit": [Function],
208208
},
209+
"tcAcademy": Object {
210+
"getTcaCertificationsDone": [Function],
211+
"getTcaCertificationsInit": [Function],
212+
},
209213
"terms": Object {
210214
"agreeTermDone": [Function],
211215
"agreeTermInit": [Function],
@@ -288,6 +292,7 @@ Object {
288292
"reviewOpportunity": [Function],
289293
"settings": [Function],
290294
"stats": [Function],
295+
"tcAcademy": [Function],
291296
"terms": [Function],
292297
},
293298
"services": Object {
@@ -354,6 +359,10 @@ Object {
354359
"default": undefined,
355360
"getService": [Function],
356361
},
362+
"tcAcademy": Object {
363+
"default": undefined,
364+
"getService": [Function],
365+
},
357366
"terms": Object {
358367
"default": undefined,
359368
"getService": [Function],

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"lint:js": "./node_modules/.bin/eslint --ext .js,.jsx .",
3232
"test": "npm run lint && npm run jest"
3333
},
34-
"version": "1000.29.5",
34+
"version": "1000.29.8",
3535
"dependencies": {
3636
"auth0-js": "^6.8.4",
3737
"config": "^3.2.0",

src/actions/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import settingsActions from './settings';
1515
import lookerActions from './looker';
1616
import memberSearchActions from './member-search';
1717
import notificationActions from './notifications';
18+
import tcAcademyActions from './tc-academy';
1819

1920
export const actions = {
2021
auth: authActions.auth,
@@ -34,6 +35,7 @@ export const actions = {
3435
looker: lookerActions.looker,
3536
memberSearch: memberSearchActions.memberSearch,
3637
notifications: notificationActions.notifications,
38+
tcAcademy: tcAcademyActions.tcAcademy,
3739
};
3840

3941
export default undefined;

src/actions/tc-academy.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { redux } from 'topcoder-react-utils';
2+
import { getService } from 'services/tc-academy';
3+
4+
const tcAcademyService = getService();
5+
6+
/**
7+
* @static
8+
* @desc Creates an action that signals beginning of user tc-academy certifications loading.
9+
* @return {Action}
10+
*/
11+
function getTcaCertificationsInit(userId) {
12+
return { userId };
13+
}
14+
15+
/**
16+
* @static
17+
* @desc Creates an action that loads user tc-academy certifications from API v2.
18+
* @param {String} userId User id.
19+
* @return {Action}
20+
*/
21+
async function getTcaCertificationsDone(userId) {
22+
const res = await tcAcademyService.getCertifications(userId);
23+
24+
return {
25+
userId,
26+
certifications: res,
27+
};
28+
}
29+
30+
export default redux.createActions({
31+
TC_ACADEMY: {
32+
GET_TCA_CERTIFICATIONS_INIT: getTcaCertificationsInit,
33+
GET_TCA_CERTIFICATIONS_DONE: getTcaCertificationsDone,
34+
},
35+
});

src/reducers/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import challenge, { factory as challengeFactory } from './challenge';
1313
import profile, { factory as profileFactory } from './profile';
1414
import members, { factory as membersFactory } from './members';
1515
import notifications, { factory as notificationsFactory } from './notifications';
16+
import tcAcademy, { factory as tcAcademyFactory } from './tc-academy';
1617
import lookup, { factory as lookupFactory } from './lookup';
1718
import memberTasks, { factory as memberTasksFactory } from './member-tasks';
1819
import reviewOpportunity, { factory as reviewOpportunityFactory }
@@ -44,6 +45,7 @@ export function factory(options) {
4445
looker: lookerFactory(options),
4546
memberSearch: memberSearchFactory(options),
4647
notifications: notificationsFactory(options),
48+
tcAcademy: tcAcademyFactory(options),
4749
});
4850
}
4951

@@ -65,4 +67,5 @@ export default ({
6567
looker,
6668
memberSearch,
6769
notifications,
70+
tcAcademy,
6871
});

src/reducers/tc-academy.js

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Reducer for TC Academy
3+
*/
4+
5+
import { handleActions } from 'redux-actions';
6+
import actions from 'actions/tc-academy';
7+
8+
/**
9+
* Handles TCACADEMY/GET_TCA_CERTIFICATIONS_INIT action.
10+
* @param {Object} state
11+
* @return {Object} New state
12+
*/
13+
function onGetTcaCertificationsInit(state) {
14+
return {
15+
...state,
16+
certifications: [],
17+
failed: false,
18+
loading: true,
19+
};
20+
}
21+
22+
/**
23+
* Handles TCACADEMY/GET_TCA_CERTIFICATIONS_DONE actions.
24+
* @param {Object} state Previous state.
25+
* @param {Object} action Action.
26+
*/
27+
function onGetTcaCertificationsDone(state, action) {
28+
return {
29+
...state,
30+
certifications: [],
31+
...(action.error ? {} : action.payload),
32+
failed: action.error,
33+
loading: false,
34+
};
35+
}
36+
37+
/**
38+
* Creates a new challenges reducer with the specified initial state.
39+
* @param {Object} initialState Optional. Initial state.
40+
* @return challenges reducer.
41+
*/
42+
function create(initialState) {
43+
const a = actions.tcAcademy;
44+
45+
return handleActions({
46+
[a.getTcaCertificationsInit]: onGetTcaCertificationsInit,
47+
[a.getTcaCertificationsDone]: onGetTcaCertificationsDone,
48+
}, initialState || {});
49+
}
50+
51+
/**
52+
* Factory which creates a new reducer with its initial state tailored to the
53+
* given options object, if specified (for server-side rendering). If options
54+
* object is not specified, it creates just the default reducer. Accepted options are:
55+
* @return {Promise}
56+
* @resolves {Function(state, action): state} New reducer.
57+
*/
58+
export function factory() {
59+
return Promise.resolve(create());
60+
}
61+
62+
/* Default reducer with empty initial state. */
63+
export default create();

src/services/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import * as userTraits from './user-traits';
1717
import * as submissions from './submissions';
1818
import * as memberSearch from './member-search';
1919
import * as notifications from './notifications';
20+
import * as tcAcademy from './tc-academy';
2021

2122
export const services = {
2223
api,
@@ -35,6 +36,7 @@ export const services = {
3536
submissions,
3637
memberSearch,
3738
notifications,
39+
tcAcademy,
3840
};
3941

4042
export default undefined;

src/services/tc-academy.js

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { getApi } from './api';
2+
3+
/**
4+
* Topcoder Academy service class
5+
*/
6+
class TcAcademyService {
7+
constructor() {
8+
this.private = {
9+
api: getApi('V5'),
10+
};
11+
}
12+
13+
/**
14+
*
15+
* @param {string} userId Get all user's certifications (completed)
16+
* @returns
17+
*/
18+
getCertifications(userId) {
19+
return this.private.api.get(`/learning-paths/completed-certifications/${userId}`)
20+
.then(res => (res.ok ? res.json() : new Error(res.statusText)));
21+
}
22+
}
23+
24+
/**
25+
* Returns a new or existing service instance.
26+
* @return {TcAcademyService} Topcoder Academy service instance
27+
*/
28+
let lastInstance = null;
29+
export function getService() {
30+
if (!lastInstance) {
31+
lastInstance = new TcAcademyService();
32+
}
33+
return lastInstance;
34+
}
35+
36+
/* Using default export would be confusing in this case. */
37+
export default undefined;

0 commit comments

Comments
 (0)