From 61afba3bca11003283dbda6ac2eec2ff64eedd9a Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Sat, 22 Feb 2025 20:34:23 -0700 Subject: [PATCH] show totals of gives to a project --- CHANGELOG.md | 7 +++ src/views/ProjectViewView.vue | 102 +++++++++++++++++++++++++++++++--- 2 files changed, 102 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dafcf0d..dfacfb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 +## [0.4.5] - 2025.02.23 +### Added +- Total amounts of gives on project page +### Changed in DB or environment +- Requires Endorser.ch version 4.2.6+ + + ## [0.4.4] - 2025.02.17 ### Fixed - On production (due to data?) the search results would disappear after scrolling down. Now we don't show any results when going to the people map with a shortcut. diff --git a/src/views/ProjectViewView.vue b/src/views/ProjectViewView.vue index 5fc0acd..70be78d 100644 --- a/src/views/ProjectViewView.vue +++ b/src/views/ProjectViewView.vue @@ -325,16 +325,55 @@ -

Given To This Idea

+

Given To This Idea

-
+
(None yet. If you've seen something, say something by clicking a contact above.)
-
- - + + +
@@ -554,6 +594,7 @@ export default class ProjectViewView extends Vue { givesHitLimit = false; givesProvidedByThis: Array = []; givesProvidedByHitLimit = false; + givesTotalsByUnit: Array<{unit: string, amount: number}> = []; imageUrl = ""; isRegistered = false; issuer = ""; @@ -564,6 +605,7 @@ export default class ProjectViewView extends Vue { } | null = null; issuerVisibleToDids: Array = []; latitude = 0; + loadingTotals = false; longitude = 0; name = ""; offersToThis: Array = []; @@ -571,6 +613,7 @@ export default class ProjectViewView extends Vue { projectId = ""; // handle ID recentlyCheckedAndUnconfirmableJwts: string[] = []; startTime = ""; + totalsExpanded = false; truncatedDesc = ""; truncateLength = 40; url = ""; @@ -609,6 +652,7 @@ export default class ProjectViewView extends Vue { this.projectId = decodeURIComponent(pathParam); } this.loadProject(this.projectId, this.activeDid); + this.loadTotals(); } onEditClick() { @@ -1207,5 +1251,49 @@ export default class ProjectViewView extends Vue { this.allMyDids, ); } + + async loadTotals() { + this.loadingTotals = true; + const url = this.apiServer + "/api/v2/report/givesToPlans?planIds=" + encodeURIComponent(JSON.stringify([this.projectId])); + const headers = await serverUtil.getHeaders(this.activeDid); + + try { + const resp = await this.axios.get(url, { headers }); + if (resp.status === 200 && resp.data.data) { + // Calculate totals by unit + const totals: {[key: string]: number} = {}; + resp.data.data.forEach((give: GiveSummaryRecord) => { + const amount = give.fullClaim.object?.amountOfThisGood; + const unit = give.fullClaim.object?.unitCode; + if (amount && unit) { + totals[unit] = (totals[unit] || 0) + amount; + } + }); + + // Convert totals object to array format + this.givesTotalsByUnit = Object.entries(totals).map(([unit, amount]) => ({ + unit, + amount + })); + } + } catch (error) { + console.error("Error loading totals:", error); + this.$notify( + { + group: "alert", + type: "danger", + title: "Error", + text: "Failed to load totals for this project.", + }, + 5000, + ); + } finally { + this.loadingTotals = false; + } + } + + givenTotalHours(): number { + return this.givesTotalsByUnit.find(total => total.unit === "HUR")?.amount || 0; + } }