diff --git a/src/components/LenderProfile/LenderBadges.vue b/src/components/LenderProfile/LenderBadges.vue
index 7f73727961..5646944d61 100644
--- a/src/components/LenderProfile/LenderBadges.vue
+++ b/src/components/LenderProfile/LenderBadges.vue
@@ -1,6 +1,6 @@
-
-
diff --git a/src/composables/useBadgeData.js b/src/composables/useBadgeData.js
index 7f93611da4..245389aacc 100644
--- a/src/composables/useBadgeData.js
+++ b/src/composables/useBadgeData.js
@@ -50,9 +50,10 @@ export default function useBadgeData() {
* Calls Apollo to get the badge achievement service data
*
* @param apollo The current instance of Apollo
+ * @param publicId Whether to get achievement data for a specific user
*/
- const fetchAchievementData = apollo => {
- apollo.query({ query: userAchievementProgressQuery })
+ const fetchAchievementData = (apollo, publicId = null) => {
+ apollo.query({ query: userAchievementProgressQuery, variables: { publicId } })
.then(result => {
badgeAchievementData.value = [
...(result.data?.userAchievementProgress?.lendingAchievements ?? []),
@@ -343,7 +344,7 @@ export default function useBadgeData() {
levelName: contentfulData.challengeName,
};
}
- } else if (badge.achievementData?.tiers?.length) {
+ } else if (badge?.achievementData?.tiers?.length) {
const tiers = JSON.parse(JSON.stringify(badge.achievementData.tiers));
tiers.sort((a, b) => new Date(a.completedDate) - new Date(b.completedDate));
const levelIndex = tiers[0].level - 1;
@@ -388,6 +389,58 @@ export default function useBadgeData() {
return displayedBadge ?? {};
};
+ /**
+ * Get completed badges of a user
+ *
+ * @param badges The badges to get the completed badges from
+ * @returns Completed badges
+ */
+ const getCompletedBadges = badges => {
+ const completedBadgesArr = [];
+
+ badges?.forEach(badge => {
+ if (badge?.achievementData?.tiers?.length) {
+ const { tiers } = badge.achievementData;
+ tiers.forEach(tier => {
+ if (tier.completedDate) {
+ completedBadgesArr.push({
+ ...badge,
+ earnedAtDate: tier.completedDate,
+ level: tier.level,
+ });
+ }
+ });
+ }
+ if (badge?.achievementData?.milestoneProgress?.length) {
+ const earnedAtDate = badge.achievementData?.milestoneProgress?.[0]?.earnedAtDate;
+ if (earnedAtDate) {
+ completedBadgesArr.push({
+ ...badge,
+ earnedAtDate,
+ level: 0,
+ });
+ }
+ }
+ });
+
+ return completedBadgesArr;
+ };
+
+ /**
+ * Get completed badges sorted by earned date
+ *
+ * @returns Completed badges sorted by earned date
+ */
+ const completedBadges = computed(() => {
+ const completedBadgesArr = getCompletedBadges(badgeData.value);
+
+ completedBadgesArr.sort((a, b) => {
+ return new Date(a.earnedAtDate) - new Date(b.earnedAtDate);
+ });
+
+ return completedBadgesArr;
+ });
+
return {
fetchAchievementData,
fetchContentfulData,
@@ -400,9 +453,11 @@ export default function useBadgeData() {
getBadgeWithVisibleTiers,
getLastCompletedBadgeLevelData,
getHighestPriorityDisplayBadge,
+ getCompletedBadges,
badgeAchievementData,
badgeData,
badgeLoanIdData,
isBadgeKeyValid,
+ completedBadges,
};
}
diff --git a/src/graphql/query/userAchievementProgress.graphql b/src/graphql/query/userAchievementProgress.graphql
index 319de66b97..7450817ca1 100644
--- a/src/graphql/query/userAchievementProgress.graphql
+++ b/src/graphql/query/userAchievementProgress.graphql
@@ -1,5 +1,5 @@
-query UserAchievementProgress {
- userAchievementProgress {
+query UserAchievementProgress($publicId: String) {
+ userAchievementProgress(publicId: $publicId) {
id
lendingAchievements {
id
diff --git a/src/pages/Portfolio/LendingStats/BadgesList.vue b/src/pages/Portfolio/LendingStats/BadgesList.vue
index 8ae5a04a3b..d11ccbf87d 100644
--- a/src/pages/Portfolio/LendingStats/BadgesList.vue
+++ b/src/pages/Portfolio/LendingStats/BadgesList.vue
@@ -22,16 +22,21 @@
-
+
-
{{ challenge.challengeName }}
-
- {{ challenge.dateTagline }}
+
+ {{ getBadgeTitle(badge) }}
+
+
+ {{ getBadgeDate(badge) }}
@@ -39,9 +44,8 @@
diff --git a/src/pages/Portfolio/LendingStats/LendingStatsPage.vue b/src/pages/Portfolio/LendingStats/LendingStatsPage.vue
index 92a98f2632..cfa6900d1a 100644
--- a/src/pages/Portfolio/LendingStats/LendingStatsPage.vue
+++ b/src/pages/Portfolio/LendingStats/LendingStatsPage.vue
@@ -23,7 +23,7 @@
@@ -88,12 +88,13 @@
import _differenceBy from 'lodash/differenceBy';
import _sortBy from 'lodash/sortBy';
import lendingStatsQuery from '#src/graphql/query/myLendingStats.graphql';
-import userAchievementProgressQuery from '#src/graphql/query/userAchievementProgress.graphql';
import WwwPage from '#src/components/WwwFrame/WwwPage';
import TheMyKivaSecondaryMenu from '#src/components/WwwFrame/Menus/TheMyKivaSecondaryMenu';
import ThePortfolioTertiaryMenu from '#src/components/WwwFrame/Menus/ThePortfolioTertiaryMenu';
import KvGrid from '#kv-components/KvGrid';
import KvPageContainer from '#kv-components/KvPageContainer';
+import lenderProfileBadgeDataQuery from '#src/graphql/query/lenderProfileBadgeData.graphql';
+import useBadgeData from '#src/composables/useBadgeData';
import BadgesSection from './BadgesSection';
import StatsSection from './StatsSection';
@@ -124,6 +125,7 @@ export default {
partnersNotLentTo: [],
userId: null,
allAchievements: [],
+ badgesData: [],
};
},
apollo: {
@@ -157,19 +159,46 @@ export default {
},
created() {
this.apollo.query({
- query: userAchievementProgressQuery,
+ query: lenderProfileBadgeDataQuery,
+ variables: {
+ contentType: 'challenge',
+ limit: 200,
+ }
}).then(({ data }) => {
- this.allAchievements = data?.userAchievementProgress?.lendingAchievements ?? [];
+ this.allAchievements = data ?? {};
});
},
computed: {
completedAchievements() {
- return this.allAchievements.filter(
- achievement => achievement.milestoneProgress?.[0]?.milestoneStatus === 'COMPLETE'
- );
+ const completedBadgesArr = this.getBadgesData();
+
+ completedBadgesArr.sort((a, b) => {
+ return new Date(a.earnedAtDate) - new Date(b.earnedAtDate);
+ });
+
+ return completedBadgesArr;
},
+ badgesLoading() {
+ return !this.badgesData.length;
+ }
},
methods: {
+ getBadgesData() {
+ const {
+ combineBadgeData, getCompletedBadges, getContentfulLevelData
+ } = useBadgeData();
+
+ const badgeAchievementData = [
+ ...(this.allAchievements?.userAchievementProgress?.lendingAchievements ?? []),
+ ...(this.allAchievements?.userAchievementProgress?.tieredLendingAchievements ?? [])
+ ];
+ const badgeContentfulData = (this.allAchievements?.contentful?.entries?.items ?? [])
+ .map(entry => getContentfulLevelData(entry));
+
+ this.badgesData = combineBadgeData(badgeAchievementData, badgeContentfulData);
+
+ return getCompletedBadges(this.badgesData);
+ },
iconForSector(sector) {
return `sector-${sector.name.toLowerCase().replace(' ', '-')}`;
}
diff --git a/test/unit/specs/composables/useBadgeData.spec.js b/test/unit/specs/composables/useBadgeData.spec.js
index c22c00ee3a..5bc2114cf5 100644
--- a/test/unit/specs/composables/useBadgeData.spec.js
+++ b/test/unit/specs/composables/useBadgeData.spec.js
@@ -502,4 +502,75 @@ describe('useBadgeData.js', () => {
expect(getHighestPriorityDisplayBadge(badges)).toEqual({ id: ID_CLIMATE_ACTION, level: 3 });
});
});
+
+ describe('getCompletedBadges', () => {
+ it('should return the completed badges', () => {
+ const { getCompletedBadges } = useBadgeData();
+ const badges = [
+ {
+ achievementData: {
+ milestoneProgress: [
+ { earnedAtDate: '2024-10-22T18:49:21Z' }
+ ]
+ },
+ },
+ {
+ achievementData: {
+ milestoneProgress: []
+ },
+ },
+ {
+ achievementData: {
+ milestoneProgress: [
+ { earnedAtDate: '2024-10-23T18:49:21Z' }
+ ]
+ },
+ },
+ ];
+
+ expect(getCompletedBadges(badges)).toEqual([
+ {
+ achievementData: {
+ milestoneProgress: [
+ { earnedAtDate: '2024-10-22T18:49:21Z' }
+ ]
+ },
+ earnedAtDate: '2024-10-22T18:49:21Z',
+ level: 0,
+ },
+ {
+ achievementData: {
+ milestoneProgress: [
+ { earnedAtDate: '2024-10-23T18:49:21Z' }
+ ]
+ },
+ earnedAtDate: '2024-10-23T18:49:21Z',
+ level: 0,
+ }
+ ]);
+ });
+ it('should return empty array when not badges', () => {
+ const { getCompletedBadges } = useBadgeData();
+ expect(getCompletedBadges(null)).toEqual([]);
+ });
+ it('should return empty array when badges are not well formatted', () => {
+ const { getCompletedBadges } = useBadgeData();
+ expect(getCompletedBadges([
+ {
+ achievementData: {
+ milestoneProgress: [
+ { earnedAtDate: null }
+ ]
+ },
+ },
+ {
+ achievementData: {
+ milestoneProgress: [
+ { earnedAtDate: undefined }
+ ]
+ },
+ }
+ ])).toEqual([]);
+ });
+ });
});