@ -325,14 +325,53 @@
< / div >
< / div >
< / div >
< / div >
< h3 class = "text-lg font-bold mb-3 m t-4" > Given To This Idea < / h3 >
< h3 class = "text-lg font-bold mt-4" > Given To This Idea < / h3 >
< div v-if ="givesToThis.length === 0" >
< div v-if ="givesToThis.length === 0" class="text-sm" >
( None yet . If you ' ve seen something , say something by clicking a
( None yet . If you ' ve seen something , say something by clicking a
contact above . )
contact above . )
< / div >
< / div >
< ul v -else class = "text-sm border-t border-slate-300" >
< div v -else class = "mt-1 text-sm" >
<!-- Totals section -- >
< div class = "mt-1 flex items-center min-h-[1.5rem]" >
< div v-if ="loadingTotals" class="flex-1" >
< fa icon = "spinner" class = "fa-spin-pulse text-blue-500" / >
< / div >
< div v -else -if = " givesTotalsByUnit.length > 0 " class=" flex - 1 " >
< span class = "font-semibold mr-2 shrink-0" > Totals < / span >
< span class = "whitespace-nowrap overflow-hidden text-ellipsis" >
< a @ click = "totalsExpanded = !totalsExpanded" class = "cursor-pointer text-blue-500" >
<!-- just show the hours , or alternatively whatever is first -- >
< span v-if ="givenTotalHours() > 0" >
{ { givenTotalHours ( ) } } { { libsUtil . UNIT_SHORT [ "HUR" ] } }
< / span >
< span v-else >
{ { givesTotalsByUnit [ 0 ] . amount } } { { libsUtil . UNIT_SHORT [ givesTotalsByUnit [ 0 ] . unit ] } }
< / span >
< span v-if ="givesTotalsByUnit.length > 1" > ... < / span >
< span >
< fa : icon = "totalsExpanded ? 'chevron-up' : 'chevron-right'" class = "fa-fw text-xs ml-1" / >
< / span >
< / a >
<!-- show the full list when expanded -- >
< div v-if ="totalsExpanded" >
< div v-for ="(total, index) in givesTotalsByUnit" :key="total.unit" class="ml-2" >
< fa :icon ="libsUtil.iconForUnitCode(total.unit)" class = "fa-fw text-slate-400 mr-1" / >
{ { total . amount } } { { libsUtil . UNIT_LONG [ total . unit ] } }
< / div >
< / div >
< / span >
< / div >
< div v-else >
< span class = "font-semibold mr-2 shrink-0" >
{ { givesToThis . length } } { { givesHitLimit ? "+" : "" } } record { { givesToThis . length === 1 ? "" : "s" } }
< / span >
< / div >
< / div >
<!-- List of gives -- >
< ul class = "mt-2 text-sm border-t border-slate-300" >
< li
< li
v - for = "give in givesToThis"
v - for = "give in givesToThis"
: key = "give.id"
: key = "give.id"
@ -393,6 +432,7 @@
< / div >
< / div >
< / li >
< / li >
< / ul >
< / ul >
< / div >
< div v-if ="givesHitLimit" class="text-center text-blue-500" >
< div v-if ="givesHitLimit" class="text-center text-blue-500" >
< button @click ="loadGives()" > Load More < / button >
< button @click ="loadGives()" > Load More < / button >
< / div >
< / div >
@ -554,6 +594,7 @@ export default class ProjectViewView extends Vue {
givesHitLimit = false ;
givesHitLimit = false ;
givesProvidedByThis : Array < GiveSummaryRecord > = [ ] ;
givesProvidedByThis : Array < GiveSummaryRecord > = [ ] ;
givesProvidedByHitLimit = false ;
givesProvidedByHitLimit = false ;
givesTotalsByUnit : Array < { unit : string , amount : number } > = [ ] ;
imageUrl = "" ;
imageUrl = "" ;
isRegistered = false ;
isRegistered = false ;
issuer = "" ;
issuer = "" ;
@ -564,6 +605,7 @@ export default class ProjectViewView extends Vue {
} | null = null ;
} | null = null ;
issuerVisibleToDids : Array < string > = [ ] ;
issuerVisibleToDids : Array < string > = [ ] ;
latitude = 0 ;
latitude = 0 ;
loadingTotals = false ;
longitude = 0 ;
longitude = 0 ;
name = "" ;
name = "" ;
offersToThis : Array < OfferSummaryRecord > = [ ] ;
offersToThis : Array < OfferSummaryRecord > = [ ] ;
@ -571,6 +613,7 @@ export default class ProjectViewView extends Vue {
projectId = "" ; / / h a n d l e I D
projectId = "" ; / / h a n d l e I D
recentlyCheckedAndUnconfirmableJwts : string [ ] = [ ] ;
recentlyCheckedAndUnconfirmableJwts : string [ ] = [ ] ;
startTime = "" ;
startTime = "" ;
totalsExpanded = false ;
truncatedDesc = "" ;
truncatedDesc = "" ;
truncateLength = 40 ;
truncateLength = 40 ;
url = "" ;
url = "" ;
@ -609,6 +652,7 @@ export default class ProjectViewView extends Vue {
this . projectId = decodeURIComponent ( pathParam ) ;
this . projectId = decodeURIComponent ( pathParam ) ;
}
}
this . loadProject ( this . projectId , this . activeDid ) ;
this . loadProject ( this . projectId , this . activeDid ) ;
this . loadTotals ( ) ;
}
}
onEditClick ( ) {
onEditClick ( ) {
@ -1207,5 +1251,49 @@ export default class ProjectViewView extends Vue {
this . allMyDids ,
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 ) {
/ / C a l c u l a t e t o t a l s b y u n i t
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 ;
}
} ) ;
/ / C o n v e r t t o t a l s o b j e c t t o a r r a y f o r m a t
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 ;
}
}
}
< / script >
< / script >