diff --git a/__tests__/__snapshots__/index.js.snap b/__tests__/__snapshots__/index.js.snap index 7bc989b4..f1c7c70a 100644 --- a/__tests__/__snapshots__/index.js.snap +++ b/__tests__/__snapshots__/index.js.snap @@ -111,6 +111,8 @@ Object { "getSubtrackChallengesInit": [Function], "getUserMarathonDone": [Function], "getUserMarathonInit": [Function], + "getUserResourcesDone": [Function], + "getUserResourcesInit": [Function], "getUserSrmDone": [Function], "getUserSrmInit": [Function], }, diff --git a/src/actions/members.js b/src/actions/members.js index ac7bd701..13a14fdb 100644 --- a/src/actions/members.js +++ b/src/actions/members.js @@ -357,6 +357,30 @@ async function getUserMarathonDone( })); } +/** + * @static + * @desc Create an action that fetch user registered challenge's resources. + * @param {String} memberId Member id. + * @param {String} uuid Operation UUID. + * @return {Action} + */ +async function getUserResourcesInit(memberId, uuid) { + return { memberId, uuid }; +} + +/** + * @static + * @desc Create an action that fetch user registered challenge's resources. + * @param {String} handle Member handle. + * @param {String} uuid Operation UUID. + * @return {Action} + */ +async function getUserResourcesDone(memberId, tokenV3, uuid) { + const resources = await getService(tokenV3).getUserResources(memberId); + + return { resources, uuid }; +} + export default createActions({ MEMBERS: { DROP: drop, @@ -380,5 +404,7 @@ export default createActions({ GET_USER_SRM_DONE: getUserSRMDone, GET_USER_MARATHON_INIT: getUserMarathonInit, GET_USER_MARATHON_DONE: getUserMarathonDone, + GET_USER_RESOURCES_INIT: getUserResourcesInit, + GET_USER_RESOURCES_DONE: getUserResourcesDone, }, }); diff --git a/src/reducers/members.js b/src/reducers/members.js index 23d0a08b..76c70d52 100644 --- a/src/reducers/members.js +++ b/src/reducers/members.js @@ -426,6 +426,43 @@ function onGetUserMarathonDone(state, { error, payload }) { }; } +/** + * Inits the loading of user challenge resources. + * @param {Object} state + * @param {Object} action + * @return {Object} New state. + */ +function onGetUserResourcesInit(state, { payload }) { + const { uuid } = payload; + return { + ...state, + userResources: { resources: [], loadingUserResources: uuid }, + }; +} + +/** + * Finalizes the loading of user challenge resources. + * @param {Object} state + * @param {Object} action + * @return {Object} New state. + */ +function onGetUserResourcesDone(state, { error, payload }) { + if (error) { + logger.error('Failed to get user resources', payload); + fireErrorMessage('Failed to get user resources', ''); + return state; + } + + const { uuid, resources } = payload; + + if (uuid !== state.userResources.loadingUserResources) return state; + + return { + ...state, + userResources: { resources, loadingUserResources: '' }, + }; +} + /** * Creates a new Members reducer with the specified initial state. * @param {Object} initialState Optional. Initial state. @@ -455,6 +492,8 @@ function create(initialState = {}) { [a.getUserSrmDone]: onGetUserSRMDone, [a.getUserMarathonInit]: onGetUserMarathonInit, [a.getUserMarathonDone]: onGetUserMarathonDone, + [a.getUserResourcesInit]: onGetUserResourcesInit, + [a.getUserResourcesDone]: onGetUserResourcesDone, }, initialState); } diff --git a/src/services/members.js b/src/services/members.js index 128a61f4..7716c91d 100644 --- a/src/services/members.js +++ b/src/services/members.js @@ -21,6 +21,7 @@ class MembersService { constructor(tokenV3) { this.private = { api: getApi('V3', tokenV3), + apiV5: getApi('V5', tokenV3), tokenV3, }; } @@ -312,6 +313,63 @@ class MembersService { const res = await this.private.api.get(url); return getApiResponsePayload(res); } + + /** + * Fetch resources roles + * @param {Array} memberId the member id + */ + async getResourceRoles() { + const res = await this.private.apiV5.get('/resource-roles'); + const roles = await res.json(); + return roles; + } + + /** + * Fetch user challenge resources + * @param {Array} challengeId the challenge id + */ + async getChallengeResources(challengeId) { + const url = `/resources?challengeId=${challengeId}`; + let res = null; + + try { + res = await this.private.apiV5.get(url); + } catch (error) { + // logger.error('Failed to load challenge resource', error); + } + + return res.json(); + } + + /** + * Fetch user registered challenge's resources + * @param {Array} memberId the member id + */ + async getUserResources(memberId) { + const url = `/resources/${memberId}/challenges`; + const res = await this.private.apiV5.get(url); + const challenges = await res.json(); + const roles = await this.getResourceRoles(); + const calls = []; + + challenges.forEach(async (ch) => { + calls.push(this.getChallengeResources(ch)); + }); + + return Promise.all(calls).then((resources) => { + const results = []; + resources.forEach((resource) => { + const userResource = _.find(resource, { memberId }); + if (userResource) { + const challengeRole = _.find(roles, { id: userResource.roleId }); + const { name } = challengeRole || ''; + results.push({ id: userResource.challengeId, name }); + } + }); + + return results; + }); + } } let lastInstance = null;