@ -23,7 +23,7 @@ 
			
		
	
		
			
				
					      < / h1 >  
			
		
	
		
			
				
					    < / div >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    < div >  
			
		
	
		
			
				
					    < div  class = "text-red-500"  >  
			
		
	
		
			
				
					      { {  errorMessage  } }  
			
		
	
		
			
				
					    < / div >  
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -65,32 +65,84 @@ 
			
		
	
		
			
				
					      < / button >  
			
		
	
		
			
				
					    < / div >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    < button  
			
		
	
		
			
				
					      @ click = "openDialog({ name: 'you', did: activeDid })"  
			
		
	
		
			
				
					      class = "block text-center text-lg font-bold uppercase bg-blue-600 text-white px-2 py-3 rounded-md mb-8"  
			
		
	
		
			
				
					    >  
			
		
	
		
			
				
					      I  gave ...  
			
		
	
		
			
				
					    < / button >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    < div >  
			
		
	
		
			
				
					      < p > ...  or  choose  a  contact  who  gave : < / p >  
			
		
	
		
			
				
					      <!--  similar  contact  selection  code  is  in  multiple  places  -- >  
			
		
	
		
			
				
					      < div  class = "px-4" >  
			
		
	
		
			
				
					      < div  v-if ="activeDid" >  
			
		
	
		
			
				
					        < button  
			
		
	
		
			
				
					          v - for = "contact in allContacts"  
			
		
	
		
			
				
					          : key = "contact.did"  
			
		
	
		
			
				
					          @ click = "openDialog(contact)"  
			
		
	
		
			
				
					          class = "text-blue-500"  
			
		
	
		
			
				
					          @ click = "openDialog({ name: 'you', did: activeDid })"  
			
		
	
		
			
				
					          class = "text-center text-lg font-bold uppercase bg-blue-600 text-white px-2 py-3 rounded-md"  
			
		
	
		
			
				
					        >  
			
		
	
		
			
				
					          & nbsp ; { {  contact . name  } } ,  
			
		
	
		
			
				
					        < / button >  
			
		
	
		
			
				
					        < span  v-if ="allContacts.length > 0" > & nbsp ; or & nbsp ; < / span >  
			
		
	
		
			
				
					        < button  @click ="openDialog()"  class = "text-blue-500" >  
			
		
	
		
			
				
					          someone  not  specified  
			
		
	
		
			
				
					          I  gave ...  
			
		
	
		
			
				
					        < / button >  
			
		
	
		
			
				
					        & horbar ;  or :  
			
		
	
		
			
				
					      < / div >  
			
		
	
		
			
				
					      <!--  similar  contact  selection  code  is  in  multiple  places  -- >  
			
		
	
		
			
				
					      Record  a  gift  from  
			
		
	
		
			
				
					      < span  v-for ="contact in allContacts" :key="contact.did" >  
			
		
	
		
			
				
					        < button  @click ="openDialog(contact)"  class = "text-blue-500" >  
			
		
	
		
			
				
					          & nbsp ; { {  contact . name  } } < / b u t t o n  
			
		
	
		
			
				
					        > ,  
			
		
	
		
			
				
					      < / span >  
			
		
	
		
			
				
					      < span  v-if ="allContacts.length > 0" > & nbsp ; or & nbsp ; < / span >  
			
		
	
		
			
				
					      < button  @click ="openDialog()"  class = "text-blue-500" >  
			
		
	
		
			
				
					        someone  not  specified  
			
		
	
		
			
				
					      < / button >  
			
		
	
		
			
				
					    < / div >  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    <!--  Gifts  to  &  from  this  -- >  
			
		
	
		
			
				
					    < div  class = "mt-8 flex justify-around" >  
			
		
	
		
			
				
					      < div >  
			
		
	
		
			
				
					        < h1  class = "text-xl" > Given  to  this  Project < / h1 >  
			
		
	
		
			
				
					      < / div >  
			
		
	
		
			
				
					      < div >  
			
		
	
		
			
				
					        < h1  class = "text-xl" > ...  and  from  this  Project < / h1 >  
			
		
	
		
			
				
					      < / div >  
			
		
	
		
			
				
					    < / div >  
			
		
	
		
			
				
					    < div  class = "flex justify-around" >  
			
		
	
		
			
				
					      < div  class = "w-1/2" >  
			
		
	
		
			
				
					        < div  v-for ="give in givesToThis" :key="give.id" >  
			
		
	
		
			
				
					          < div  class = "flex justify-between" >  
			
		
	
		
			
				
					            < div  class = "flex gap-3" >  
			
		
	
		
			
				
					              < div  class = "flex gap-2" >  
			
		
	
		
			
				
					                < fa  icon = "user"  class = "fa-fw text-slate-400" > < / fa >  
			
		
	
		
			
				
					                < span > { {  
			
		
	
		
			
				
					                  didInfo ( give . agentDid ,  activeDid ,  accounts ,  allContacts )  
			
		
	
		
			
				
					                } } < / span >  
			
		
	
		
			
				
					              < / div >  
			
		
	
		
			
				
					              < div  class = "flex gap-2"  v-if ="give.amount" >  
			
		
	
		
			
				
					                < fa  icon = "coins"  class = "fa-fw text-slate-400" > < / fa >  
			
		
	
		
			
				
					                < span > { {  give . amount  } } < / span >  
			
		
	
		
			
				
					              < / div >  
			
		
	
		
			
				
					              < div  class = "flex gap-2"  v-if ="give.description" >  
			
		
	
		
			
				
					                < fa  icon = "comment"  class = "fa-fw text-slate-400" > < / fa >  
			
		
	
		
			
				
					                < span > { {  give . description  } } < / span >  
			
		
	
		
			
				
					              < / div >  
			
		
	
		
			
				
					            < / div >  
			
		
	
		
			
				
					          < / div >  
			
		
	
		
			
				
					        < / div >  
			
		
	
		
			
				
					      < / div >  
			
		
	
		
			
				
					      < div  class = "w-1/2" >  
			
		
	
		
			
				
					        < div  v-for ="give in givesByThis" :key="give.id" >  
			
		
	
		
			
				
					          < div  class = "flex justify-between" >  
			
		
	
		
			
				
					            < div  class = "flex gap-3" >  
			
		
	
		
			
				
					              < div  class = "flex gap-2" >  
			
		
	
		
			
				
					                < fa  icon = "user"  class = "fa-fw text-slate-400" > < / fa >  
			
		
	
		
			
				
					                < span > { {  
			
		
	
		
			
				
					                  didInfo ( give . agentDid ,  activeDid ,  accounts ,  allContacts )  
			
		
	
		
			
				
					                } } < / span >  
			
		
	
		
			
				
					              < / div >  
			
		
	
		
			
				
					              < div  class = "flex gap-2"  v-if ="give.amount" >  
			
		
	
		
			
				
					                < fa  icon = "coins"  class = "fa-fw text-slate-400" > < / fa >  
			
		
	
		
			
				
					                < span > { {  give . amount  } } < / span >  
			
		
	
		
			
				
					              < / div >  
			
		
	
		
			
				
					              < div  class = "flex gap-2" >  
			
		
	
		
			
				
					                < fa  icon = "comment"  class = "fa-fw text-slate-400" > < / fa >  
			
		
	
		
			
				
					                < span > { {  give . description  } } < / span >  
			
		
	
		
			
				
					              < / div >  
			
		
	
		
			
				
					            < / div >  
			
		
	
		
			
				
					          < / div >  
			
		
	
		
			
				
					        < / div >  
			
		
	
		
			
				
					      < / div >  
			
		
	
		
			
				
					    < / div >  
			
		
	
		
			
				
					    < GiftedDialog  
			
		
	
		
			
				
					      ref = "customDialog"  
			
		
	
		
			
				
					      @ dialog - result = "handleDialogResult"  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -107,15 +159,20 @@ 
			
		
	
		
			
				
					< script  lang = "ts" >  
			
		
	
		
			
				
					import  {  AxiosError  }  from  "axios" ;  
			
		
	
		
			
				
					import  *  as  moment  from  "moment" ;  
			
		
	
		
			
				
					import  {  IIdentifier  }  from  "@veramo/core" ;  
			
		
	
		
			
				
					import  {  Component ,  Vue  }  from  "vue-facing-decorator" ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					import  GiftedDialog  from  "@/components/GiftedDialog.vue" ;  
			
		
	
		
			
				
					import  {  accountsDB ,  db  }  from  "@/db" ;  
			
		
	
		
			
				
					import  {  AccountsSchema  }  from  "@/db/tables/accounts" ;  
			
		
	
		
			
				
					import  {  Contact  }  from  "@/db/tables/contacts" ;  
			
		
	
		
			
				
					import  {  MASTER_SETTINGS_KEY  }  from  "@/db/tables/settings" ;  
			
		
	
		
			
				
					import  {  createAndSubmitGive  }  from  "@/libs/endorserServer" ;  
			
		
	
		
			
				
					import  {  accessToken  }  from  "@/libs/crypto" ;  
			
		
	
		
			
				
					import  {  IIdentifier  }  from  "@veramo/core" ;  
			
		
	
		
			
				
					import  {  
			
		
	
		
			
				
					  createAndSubmitGive ,  
			
		
	
		
			
				
					  didInfo ,  
			
		
	
		
			
				
					  GiveServerRecord ,  
			
		
	
		
			
				
					}  from  "@/libs/endorserServer" ;  
			
		
	
		
			
				
					import  AlertMessage  from  "@/components/AlertMessage" ;  
			
		
	
		
			
				
					import  QuickNav  from  "@/components/QuickNav" ;  
			
		
	
		
			
				
					
 
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -123,26 +180,42 @@ import QuickNav from "@/components/QuickNav"; 
			
		
	
		
			
				
					  components :  {  GiftedDialog ,  AlertMessage ,  QuickNav  } ,  
			
		
	
		
			
				
					} )  
			
		
	
		
			
				
					export  default  class  ProjectViewView  extends  Vue  {  
			
		
	
		
			
				
					  accounts :  AccountsSchema ;  
			
		
	
		
			
				
					  activeDid  =  "" ;  
			
		
	
		
			
				
					  alertMessage  =  "" ;  
			
		
	
		
			
				
					  alertTitle  =  "" ;  
			
		
	
		
			
				
					  allContacts :  Array < Contact >  =  [ ] ;  
			
		
	
		
			
				
					  apiServer  =  "" ;  
			
		
	
		
			
				
					  description  =  "" ;  
			
		
	
		
			
				
					  errorMessage  =  "" ;  
			
		
	
		
			
				
					  expanded  =  false ;  
			
		
	
		
			
				
					  givesToThis :  Array < GiveServerRecord >  =  [ ] ;  
			
		
	
		
			
				
					  givesByThis :  Array < GiveServerRecord >  =  [ ] ;  
			
		
	
		
			
				
					  name  =  "" ;  
			
		
	
		
			
				
					  description  =  "" ;  
			
		
	
		
			
				
					  numAccounts  =  0 ;  
			
		
	
		
			
				
					  projectId  =  localStorage . getItem ( "projectId" )  ||  "" ;  / /   h a n d l e   I D  
			
		
	
		
			
				
					  timeSince  =  "" ;  
			
		
	
		
			
				
					  truncatedDesc  =  "" ;  
			
		
	
		
			
				
					  truncateLength  =  40 ;  
			
		
	
		
			
				
					  timeSince  =  "" ;  
			
		
	
		
			
				
					  projectId  =  localStorage . getItem ( "projectId" )  ||  "" ;  / /   h a n d l e   I D  
			
		
	
		
			
				
					  errorMessage  =  "" ;  
			
		
	
		
			
				
					  alertMessage  =  "" ;  
			
		
	
		
			
				
					  alertTitle  =  "" ;  
			
		
	
		
			
				
					  accounts :  AccountsSchema ;  
			
		
	
		
			
				
					  numAccounts  =  0 ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  async  beforeCreate ( )  {  
			
		
	
		
			
				
					    accountsDB . open ( ) ;  
			
		
	
		
			
				
					    this . accounts  =  accountsDB . accounts ;  
			
		
	
		
			
				
					    this . numAccounts  =  await  this . accounts . count ( ) ;  
			
		
	
		
			
				
					    this . numAccounts  =  ( await  this . accounts ? . count ( ) )  ||  0 ;  
			
		
	
		
			
				
					  }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  async  created ( )  {  
			
		
	
		
			
				
					    await  db . open ( ) ;  
			
		
	
		
			
				
					    const  settings  =  await  db . settings . get ( MASTER_SETTINGS_KEY ) ;  
			
		
	
		
			
				
					    this . activeDid  =  settings ? . activeDid  ||  "" ;  
			
		
	
		
			
				
					    this . apiServer  =  settings ? . apiServer  ||  "" ;  
			
		
	
		
			
				
					    this . allContacts  =  await  db . contacts . toArray ( ) ;  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    this . accounts  =  accountsDB . accounts ;  
			
		
	
		
			
				
					    const  accountsArr  =  await  this . accounts ? . toArray ( ) ;  
			
		
	
		
			
				
					    const  account  =  accountsArr . find ( ( acc )  =>  acc . did  ===  this . activeDid ) ;  
			
		
	
		
			
				
					    const  identity  =  JSON . parse ( account ? . identity  ||  "null" ) ;  
			
		
	
		
			
				
					    this . LoadProject ( identity ) ;  
			
		
	
		
			
				
					  }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  public  async  getIdentity ( activeDid )  {  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -178,6 +251,11 @@ export default class ProjectViewView extends Vue { 
			
		
	
		
			
				
					    this . $router . push ( route ) ;  
			
		
	
		
			
				
					  }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  / /   I s n ' t   t h e r e   a   b e t t e r   w a y   t o   m a k e   t h i s   a v a i l a b l e   t o   t h e   t e m p l a t e ?  
			
		
	
		
			
				
					  didInfo ( did ,  activeDid ,  identities ,  contacts )  {  
			
		
	
		
			
				
					    return  didInfo ( did ,  activeDid ,  identities ,  contacts ) ;  
			
		
	
		
			
				
					  }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  expandText ( )  {  
			
		
	
		
			
				
					    this . expanded  =  true ;  
			
		
	
		
			
				
					  }  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -191,21 +269,24 @@ export default class ProjectViewView extends Vue { 
			
		
	
		
			
				
					      this . apiServer  +  
			
		
	
		
			
				
					      "/api/claim/byHandle/"  +  
			
		
	
		
			
				
					      encodeURIComponent ( this . projectId ) ;  
			
		
	
		
			
				
					    const  token  =  await  accessToken ( identity ) ;  
			
		
	
		
			
				
					    const  headers  =  {  
			
		
	
		
			
				
					      "Content-Type" :  "application/json" ,  
			
		
	
		
			
				
					      Authorization :  "Bearer "  +  token ,  
			
		
	
		
			
				
					    } ;  
			
		
	
		
			
				
					    if  ( identity )  {  
			
		
	
		
			
				
					      const  token  =  await  accessToken ( identity ) ;  
			
		
	
		
			
				
					      headers [ "Authorization" ]  =  "Bearer "  +  token ;  
			
		
	
		
			
				
					    }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    try  {  
			
		
	
		
			
				
					      const  resp  =  await  this . axios . get ( url ,  {  headers  } ) ;  
			
		
	
		
			
				
					      if  ( resp . status  ===  200 )  {  
			
		
	
		
			
				
					        / /   f e e l   f r e e   t o   r e m o v e   t h i s ;   I   h a v e n ' t   y e t   b e c a u s e   i t ' s   h e l p f u l  
			
		
	
		
			
				
					        console . log ( 'Loaded project: ' ,  resp . data ) ;  
			
		
	
		
			
				
					        const  startTime  =  resp . data . startTime ;  
			
		
	
		
			
				
					        if  ( startTime  !=  null )  {  
			
		
	
		
			
				
					          const  eventDate  =  new  Date ( startTime ) ;  
			
		
	
		
			
				
					          const  now  =  moment . now ( ) ;  
			
		
	
		
			
				
					          this . timeSince  =  moment . utc ( now ) . to ( eventDate ) ;  
			
		
	
		
			
				
					          errorMessage ;  
			
		
	
		
			
				
					        }  
			
		
	
		
			
				
					        this . name  =  resp . data . claim ? . name  ||  "(no name)" ;  
			
		
	
		
			
				
					        this . description  =  resp . data . claim ? . description  ||  "(no description)" ;  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -225,27 +306,41 @@ export default class ProjectViewView extends Vue { 
			
		
	
		
			
				
					        console . error ( "Error retrieving project:" ,  error ) ;  
			
		
	
		
			
				
					      }  
			
		
	
		
			
				
					    }  
			
		
	
		
			
				
					  }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					  async  created ( )  {  
			
		
	
		
			
				
					    await  db . open ( ) ;  
			
		
	
		
			
				
					    const  settings  =  await  db . settings . get ( MASTER_SETTINGS_KEY ) ;  
			
		
	
		
			
				
					    this . activeDid  =  settings ? . activeDid  ||  "" ;  
			
		
	
		
			
				
					    this . apiServer  =  settings ? . apiServer  ||  "" ;  
			
		
	
		
			
				
					    this . allContacts  =  await  db . contacts . toArray ( ) ;  
			
		
	
		
			
				
					    const  givesInUrl  =  
			
		
	
		
			
				
					      this . apiServer  +  
			
		
	
		
			
				
					      "/api/v2/report/givesForPlans?planIds="  +  
			
		
	
		
			
				
					      encodeURIComponent ( JSON . stringify ( [ this . projectId ] ) ) ;  
			
		
	
		
			
				
					    try  {  
			
		
	
		
			
				
					      const  resp  =  await  this . axios . get ( givesInUrl ,  {  headers  } ) ;  
			
		
	
		
			
				
					      if  ( resp . status  ===  200  &&  resp . data . data )  {  
			
		
	
		
			
				
					        this . givesToThis  =  resp . data . data ;  
			
		
	
		
			
				
					      }  else  {  
			
		
	
		
			
				
					        this . errorMessage  =  "Failed to retrieve gives to this project." ;  
			
		
	
		
			
				
					      }  
			
		
	
		
			
				
					    }  catch  ( error :  unknown )  {  
			
		
	
		
			
				
					      console . error ( "Error retrieving gives to this project:" ,  error ) ;  
			
		
	
		
			
				
					      const  serverError  =  error  as  AxiosError ;  
			
		
	
		
			
				
					      this . errorMessage  =  
			
		
	
		
			
				
					        "Something went wrong retrieving gives to this project." ;  
			
		
	
		
			
				
					    }  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					    if  ( this . numAccounts  ===  0 )  {  
			
		
	
		
			
				
					      console . error ( "Problem!  Should have a profile!" ) ;  
			
		
	
		
			
				
					    }  else  {  
			
		
	
		
			
				
					      const  accounts  =  await  accountsDB . accounts . toArray ( ) ;  
			
		
	
		
			
				
					      const  account  =  accounts . find ( ( acc )  =>  acc . did  ===  this . activeDid ) ;  
			
		
	
		
			
				
					      const  identity  =  JSON . parse ( account ? . identity  ||  "null" ) ;  
			
		
	
		
			
				
					      if  ( ! identity )  {  
			
		
	
		
			
				
					        throw  new  Error (  
			
		
	
		
			
				
					          "An ID is chosen but there are no keys for it so it cannot be used to talk with the service." ,  
			
		
	
		
			
				
					        ) ;  
			
		
	
		
			
				
					    const  givesOutUrl  =  
			
		
	
		
			
				
					      this . apiServer  +  
			
		
	
		
			
				
					      "/api/v2/report/givesProvidedBy?providerId="  +   
			
		
	
		
			
				
					      encodeURIComponent ( this . projectId ) ;  
			
		
	
		
			
				
					    try  {  
			
		
	
		
			
				
					      const  resp  =  await  this . axios . get ( givesOutUrl ,  {  headers  } ) ;  
			
		
	
		
			
				
					      if  ( resp . status  ===  200  &&  resp . data . data )  {  
			
		
	
		
			
				
					        this . givesByThis  =  resp . data . data ;   
			
		
	
		
			
				
					      }  else  {  
			
		
	
		
			
				
					        this . errorMessage  =  "Failed to retrieve gives by this project." ;  
			
		
	
		
			
				
					      }  
			
		
	
		
			
				
					      this . LoadProject ( identity ) ;  
			
		
	
		
			
				
					    }  catch  ( error :  unknown )  {  
			
		
	
		
			
				
					      console . error ( "Error retrieving gives by this project:" ,  error ) ;  
			
		
	
		
			
				
					      const  serverError  =  error  as  AxiosError ;  
			
		
	
		
			
				
					      this . errorMessage  =  
			
		
	
		
			
				
					        "Something went wrong retrieving gives by project." ;  
			
		
	
		
			
				
					    }  
			
		
	
		
			
				
					  }