Skip to content

Commit d47f6e1

Browse files
committed
adding services for community app basic info, etc.
1 parent 1ce0b88 commit d47f6e1

File tree

11 files changed

+1442
-1819
lines changed

11 files changed

+1442
-1819
lines changed

package-lock.json

Lines changed: 997 additions & 1815 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/actions/basicInfo.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @module "actions.basicInfo"
3+
* @desc Actions for interactions with profile details API.
4+
*/
5+
import { createActions } from 'redux-actions';
6+
7+
import { getService as getBasicInfoService } from '../services/basicInfo';
8+
9+
function getBasicInfoInit() {}
10+
/**
11+
* @static
12+
* @desc Creates an action that gets linked accounts.
13+
*
14+
* @param {Object} handle Topcoder member profile.basicInfo: null
15+
* @param {String} tokenV3 Topcoder auth token v3.
16+
* @return {Action}
17+
*/
18+
function getBasicInfoDone(handle, tokenV3) {
19+
const token= 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJhZG1pbmlzdHJhdG9yIl0sImlzcyI6Imh0dHBzOi8vYXBpLnRvcGNvZGVyLWRldi5jb20iLCJoYW5kbGUiOiJoZWZmYW4iLCJleHAiOjE3NjYyODkyNDYsInVzZXJJZCI6IjEzMjQ1NiIsImlhdCI6MTQ1MDkyOTI0NiwiZW1haWwiOm51bGwsImp0aSI6IjEzNjljNjAwLWUwYTEtNDUyNS1hN2M3LTU2YmU3ZDgxM2Y1MSJ9.hp5peSoj-fh3KFkskvBpfUFIcJNtsv4zIMFV-D8F3JA';
20+
return getBasicInfoService(token).getBasicInfo(handle, tokenV3);
21+
//.then(data => data.json());
22+
}
23+
24+
function updateBasicInfoInit() {}
25+
26+
function updateBasicInfoDone(basicInfo) {
27+
console.log("Updated basic info/basic info actions: ", basicInfo);
28+
const token= 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJhZG1pbmlzdHJhdG9yIl0sImlzcyI6Imh0dHBzOi8vYXBpLnRvcGNvZGVyLWRldi5jb20iLCJoYW5kbGUiOiJoZWZmYW4iLCJleHAiOjE3NjYyODkyNDYsInVzZXJJZCI6IjEzMjQ1NiIsImlhdCI6MTQ1MDkyOTI0NiwiZW1haWwiOm51bGwsImp0aSI6IjEzNjljNjAwLWUwYTEtNDUyNS1hN2M3LTU2YmU3ZDgxM2Y1MSJ9.hp5peSoj-fh3KFkskvBpfUFIcJNtsv4zIMFV-D8F3JA';
29+
const service= getBasicInfoService(token);
30+
return service.updateBasicInfo(basicInfo);
31+
}
32+
export default createActions({
33+
BASIC_INFO: {
34+
GET_BASIC_INFO_INIT: getBasicInfoInit,
35+
GET_BASIC_INFO_DONE: getBasicInfoDone,
36+
UPDATE_BASIC_INFO_INIT: updateBasicInfoInit,
37+
UPDATE_BASIC_INFO_DONE: updateBasicInfoDone
38+
}
39+
});

src/actions/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import groupActions from './groups';
77
import errorActions from './errors';
88
import challengeActions from './challenge';
99
import profileActions from './profile';
10+
import basicInfoActions from './basicInfo';
11+
import languageActions from './language';
1012
import memberActions from './members';
1113
import memberTaskActions from './member-tasks';
1214
import reviewOpportunityActions from './reviewOpportunity';
@@ -22,6 +24,8 @@ export const actions = {
2224
groups: groupActions.groups,
2325
errors: errorActions.errors,
2426
profile: profileActions.profile,
27+
basicInfo: basicInfoActions.basicInfo,
28+
language: languageActions.language,
2529
members: memberActions.members,
2630
memberTasks: memberTaskActions.memberTasks,
2731
reviewOpportunity: reviewOpportunityActions.reviewOpportunity,

src/actions/language.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* @module "actions.language"
3+
* @desc Actions for interactions with profile details API.
4+
*/
5+
import { createActions } from 'redux-actions';
6+
7+
import { getService as getLanguageService } from '../services/language';
8+
9+
function getLanguageInit() {}
10+
/**
11+
* @static
12+
* @desc Creates an action that gets linked accounts.
13+
*
14+
* @param {Object} handle Topcoder member profile.basicInfo: null
15+
* @param {String} tokenV3 Topcoder auth token v3.
16+
* @return {Action}
17+
*/
18+
function getLanguageDone(handle, tokenV3) {
19+
const token= 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJhZG1pbmlzdHJhdG9yIl0sImlzcyI6Imh0dHBzOi8vYXBpLnRvcGNvZGVyLWRldi5jb20iLCJoYW5kbGUiOiJoZWZmYW4iLCJleHAiOjE3NjYyODkyNDYsInVzZXJJZCI6IjEzMjQ1NiIsImlhdCI6MTQ1MDkyOTI0NiwiZW1haWwiOm51bGwsImp0aSI6IjEzNjljNjAwLWUwYTEtNDUyNS1hN2M3LTU2YmU3ZDgxM2Y1MSJ9.hp5peSoj-fh3KFkskvBpfUFIcJNtsv4zIMFV-D8F3JA';
20+
return getLanguageService(token).getLanguage(handle, tokenV3);
21+
//.then(data => data.json());
22+
}
23+
24+
function updateLanguageInit() {}
25+
26+
// function updateBasicInfoDone(basicInfo) {
27+
// console.log("Updated basic info/basic info actions: ", basicInfo);
28+
// const token= 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJhZG1pbmlzdHJhdG9yIl0sImlzcyI6Imh0dHBzOi8vYXBpLnRvcGNvZGVyLWRldi5jb20iLCJoYW5kbGUiOiJoZWZmYW4iLCJleHAiOjE3NjYyODkyNDYsInVzZXJJZCI6IjEzMjQ1NiIsImlhdCI6MTQ1MDkyOTI0NiwiZW1haWwiOm51bGwsImp0aSI6IjEzNjljNjAwLWUwYTEtNDUyNS1hN2M3LTU2YmU3ZDgxM2Y1MSJ9.hp5peSoj-fh3KFkskvBpfUFIcJNtsv4zIMFV-D8F3JA';
29+
// const service= getBasicInfoService(token);
30+
// return service.updateBasicInfo(basicInfo);
31+
// }
32+
export default createActions({
33+
LANGUAGE: {
34+
GET_LANGUAGE_INIT: getLanguageInit,
35+
GET_LANGUAGE_DONE: getLanguageDone,
36+
// UPDATE_BASIC_INFO_INIT: updateBasicInfoInit,
37+
// UPDATE_BASIC_INFO_DONE: updateBasicInfoDone
38+
}
39+
});

src/reducers/basicInfo.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* @module "reducers.profile"
3+
* @desc Reducer for Profile API data
4+
* @todo Document reducer state structure.
5+
*/
6+
import _ from 'lodash';
7+
import { handleActions } from 'redux-actions';
8+
import actions from '../actions/basicInfo';
9+
import logger from '../utils/logger';
10+
import { fireErrorMessage } from '../utils/errors';
11+
12+
13+
14+
/**
15+
* Handles PROFILE/GET_EXTERNAL_ACCOUNTS_DONE action.
16+
* @param {Object} state
17+
* @param {Object} action Payload will be JSON from api call
18+
* @return {Object} New state
19+
*/
20+
function onGetBasicInfoDone(state, { payload, error }) {
21+
console.log("payload", payload);
22+
if (error) {
23+
return { ...state };
24+
}
25+
console.log("basicInfo", payload.result.content[0]);
26+
return ({
27+
...state, basicInfo: payload.result.content[0]
28+
});
29+
}
30+
31+
function onUpdateBasicInfoDone(state, { payload, error }) {
32+
const newState = { ...state, updatingBasicInfo: false };
33+
34+
if (error) {
35+
logger.error('Failed to update user basic info', payload);
36+
fireErrorMessage('ERROR: Failed to update user basic info!');
37+
return newState;
38+
}
39+
console.log("{Payload Update basic info/ basic info reducers: ", payload);
40+
// if (!newState.info || newState.info.handle !== payload.handle) {
41+
// return newState;
42+
// }
43+
console.log("{New State Update basic info/ basic info reducers: ", newState);
44+
return {
45+
...newState,
46+
basicInfo: {
47+
...newState.basicInfo,
48+
...payload,
49+
},
50+
};
51+
}
52+
53+
/**
54+
* Creates a new Profile reducer with the specified initial state.
55+
* @param {Object} initialState Optional. Initial state.
56+
* @return {Function} Profile reducer.
57+
*/
58+
function create(initialState) {
59+
const a = actions.basicInfo;
60+
return handleActions({
61+
[a.getBasicInfoInit]: state => state,
62+
[a.getBasicInfoDone]: onGetBasicInfoDone,
63+
[a.updateBasicInfoInit]: state => ({ ...state, updatingBasicInfo: true }),
64+
[a.updateBasicInfoDone]: onUpdateBasicInfoDone,
65+
}, _.defaults(initialState, {basicInfo: null}));
66+
}
67+
68+
/**
69+
* Factory which creates a new reducer with its initial state tailored to the
70+
* given options object, if specified (for server-side rendering). If options
71+
* object is not specified, it creates just the default reducer. Accepted options are:
72+
* @returns {Promise}
73+
* @resolves {Function(state, action): state} New reducer.
74+
*/
75+
export function factory() {
76+
return Promise.resolve(create());
77+
}
78+
79+
/* Reducer with the default initial state. */
80+
export default create();

src/reducers/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import groups, { factory as groupsFactory } from './groups';
1111
import errors, { factory as errorsFactory } from './errors';
1212
import challenge, { factory as challengeFactory } from './challenge';
1313
import profile, { factory as profileFactory } from './profile';
14+
import basicInfo, { factory as basicInfoFactory } from './basicInfo';
15+
import language, { factory as languageFactory } from './language';
1416
import members, { factory as membersFactory } from './members';
1517
import lookup, { factory as lookupFactory } from './lookup';
1618
import memberTasks, { factory as memberTasksFactory } from './member-tasks';
@@ -30,6 +32,8 @@ export function factory(options) {
3032
errors: errorsFactory(options),
3133
challenge: challengeFactory(options),
3234
profile: profileFactory(options),
35+
basicInfo: basicInfoFactory(options),
36+
language: languageFactory(options),
3337
lookup: lookupFactory(options),
3438
members: membersFactory(options),
3539
memberTasks: memberTasksFactory(options),
@@ -47,6 +51,8 @@ export default ({
4751
errors,
4852
challenge,
4953
profile,
54+
basicInfo,
55+
language,
5056
lookup,
5157
members,
5258
memberTasks,

src/reducers/language.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* @module "reducers.profile"
3+
* @desc Reducer for Profile API data
4+
* @todo Document reducer state structure.
5+
*/
6+
import _ from 'lodash';
7+
import { handleActions } from 'redux-actions';
8+
import actions from '../actions/language';
9+
import logger from '../utils/logger';
10+
import { fireErrorMessage } from '../utils/errors';
11+
12+
13+
14+
/**
15+
* Handles PROFILE/GET_EXTERNAL_ACCOUNTS_DONE action.
16+
* @param {Object} state
17+
* @param {Object} action Payload will be JSON from api call
18+
* @return {Object} New state
19+
*/
20+
function onGetLanguageDone(state, { payload, error }) {
21+
console.log("payload", payload);
22+
if (error) {
23+
return { ...state };
24+
}
25+
console.log("Language", payload.result.content[0]);
26+
return ({
27+
...state, language: payload.result.content[0]
28+
});
29+
}
30+
31+
// function onUpdateLanguageDone(state, { payload, error }) {
32+
// const newState = { ...state, updatingLanguage: false };
33+
34+
// if (error) {
35+
// logger.error('Failed to update user language', payload);
36+
// fireErrorMessage('ERROR: Failed to update user language!');
37+
// return newState;
38+
// }
39+
// // console.log("{Payload Update basic info/ basic info reducers: ", payload);
40+
// // if (!newState.info || newState.info.handle !== payload.handle) {
41+
// // return newState;
42+
// // }
43+
// // console.log("{New State Update basic info/ basic info reducers: ", newState);
44+
// return {
45+
// ...newState,
46+
// language: {
47+
// ...newState.language,
48+
// ...payload,
49+
// },
50+
// };
51+
// }
52+
53+
/**
54+
* Creates a new Profile reducer with the specified initial state.
55+
* @param {Object} initialState Optional. Initial state.
56+
* @return {Function} Profile reducer.
57+
*/
58+
function create(initialState) {
59+
const a = actions.language;
60+
return handleActions({
61+
[a.getLanguageInit]: state => state,
62+
[a.getLanguageDone]: onGetLanguageDone,
63+
// [a.updateLanguageInit]: state => ({ ...state, updatingBasicInfo: true }),
64+
// [a.updateLanguageDone]: onUpdateBasicInfoDone,
65+
}, _.defaults(initialState, {language: null}));
66+
}
67+
68+
/**
69+
* Factory which creates a new reducer with its initial state tailored to the
70+
* given options object, if specified (for server-side rendering). If options
71+
* object is not specified, it creates just the default reducer. Accepted options are:
72+
* @returns {Promise}
73+
* @resolves {Function(state, action): state} New reducer.
74+
*/
75+
export function factory() {
76+
return Promise.resolve(create());
77+
}
78+
79+
/* Reducer with the default initial state. */
80+
export default create();

src/reducers/profile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ function onGetAchievementsDone(state, { payload, error }) {
1919
if (error) {
2020
return { ...state, loadingError: true };
2121
}
22-
22+
console.log("GETACHIEVEMENTS", state);
2323
return ({
2424
...state,
2525
achievements: payload.Achievements,

src/services/api.js

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,43 @@ class Api {
101101
throw e;
102102
});
103103
}
104+
async fetchTraits(endpoint, options = {}) {
105+
const {
106+
base,
107+
token,
108+
} = this.private;
109+
const headers = options.headers ? _.clone(options.headers) : {};
110+
if (token) headers.Authorization = `Bearer ${token}`;
111+
112+
switch (headers['Content-Type']) {
113+
case null:
114+
delete headers['Content-Type'];
115+
break;
116+
case undefined:
117+
headers['Content-Type'] = 'application/json';
118+
break;
119+
default:
120+
}
121+
console.log("Headers", headers);
122+
console.log("Endpoint", endpoint);
123+
/* Throttling of API calls should not happen at server in production. */
124+
if (API_THROTTLING && (isomorphy.isClientSide() || isomorphy.isDevBuild())) {
125+
const now = Date.now();
126+
lastApiCallTimestamp += MIN_API_CALL_DELAY;
127+
if (lastApiCallTimestamp > now) {
128+
await delay(lastApiCallTimestamp - now);
129+
} else lastApiCallTimestamp = now;
130+
}
104131

132+
return fetch(`${endpoint}`, {
133+
...options,
134+
headers,
135+
})
136+
.catch((e) => {
137+
setErrorIcon(ERROR_ICON_TYPES.NETWORK, `${endpoint}`, e.message);
138+
throw e;
139+
});
140+
}
105141
/**
106142
* Sends DELETE request to the specified endpoint.
107143
* @param {String} endpoint
@@ -123,7 +159,9 @@ class Api {
123159
get(endpoint) {
124160
return this.fetch(endpoint);
125161
}
126-
162+
getTraits(endpoint) {
163+
return this.fetchTraits(endpoint);
164+
}
127165
/**
128166
* Sends POST request to the specified endpoint.
129167
* @param {String} endpoint
@@ -154,22 +192,33 @@ class Api {
154192
* @return {Promise}
155193
*/
156194
put(endpoint, body) {
195+
console.log("Body put", body);
157196
return this.fetch(endpoint, {
158197
body,
159198
method: 'PUT',
160199
});
161200
}
162-
201+
putTraits(endpoint, body) {
202+
console.log("Body", body);
203+
return this.fetchTraits(endpoint, {
204+
body,
205+
method: 'PUT',
206+
});
207+
}
163208
/**
164209
* Sends PUT request to the specified endpoint.
165210
* @param {String} endpoint
166211
* @param {JSON} json
167212
* @return {Promise}
168213
*/
169214
putJson(endpoint, json) {
215+
170216
return this.put(endpoint, JSON.stringify(json));
171217
}
172-
218+
putJsonTraits(endpoint, json) {
219+
console.log("Json", json);
220+
return this.putTraits(endpoint, JSON.stringify(json));
221+
}
173222
/**
174223
* Sends PATCH request to the specified endpoint.
175224
* @param {String} endpoint

0 commit comments

Comments
 (0)