| 
						
						
							
								
							
						
						
					 | 
					@ -8,8 +8,44 @@ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      Your Ideas | 
					 | 
					 | 
					      Your Ideas | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    </h1> | 
					 | 
					 | 
					    </h1> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    <!-- Quick Search --> | 
					 | 
					 | 
					    <!-- Result Tabs --> | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    <div class="text-center text-slate-500 border-b border-slate-300"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      <ul class="flex flex-wrap justify-center gap-4 -mb-px"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        <li> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          <a | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            href="#" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            @click=" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              offers = []; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              projects = []; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              showOffers = true; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              showProjects = false; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              loadOffers(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            " | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            v-bind:class="computedOfferTabClassNames()" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          > | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            Offers | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          </a> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        </li> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        <li> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          <a | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            href="#" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            @click=" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              offers = []; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              projects = []; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              showOffers = false; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              showProjects = true; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              loadProjects(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            " | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            v-bind:class="computedProjectTabClassNames()" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          > | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            Projects | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          </a> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        </li> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      </ul> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    </div> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    <!-- Quick Search --> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    <!-- | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    <div id="QuickSearch" class="mb-4 flex"> | 
					 | 
					 | 
					    <div id="QuickSearch" class="mb-4 flex"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      <input | 
					 | 
					 | 
					      <input | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        type="text" | 
					 | 
					 | 
					        type="text" | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -22,9 +58,11 @@ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        <fa icon="magnifying-glass" class="fa-fw"></fa> | 
					 | 
					 | 
					        <fa icon="magnifying-glass" class="fa-fw"></fa> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      </button> | 
					 | 
					 | 
					      </button> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    </div> | 
					 | 
					 | 
					    </div> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    --> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    <!-- New Project --> | 
					 | 
					 | 
					    <!-- New Project --> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    <button | 
					 | 
					 | 
					    <button | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      v-if="showProjects" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      class="fixed right-6 bottom-24 text-center text-4xl leading-none bg-blue-600 text-white w-14 py-2.5 rounded-full" | 
					 | 
					 | 
					      class="fixed right-6 bottom-24 text-center text-4xl leading-none bg-blue-600 text-white w-14 py-2.5 rounded-full" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      @click="onClickNewProject()" | 
					 | 
					 | 
					      @click="onClickNewProject()" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    > | 
					 | 
					 | 
					    > | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -39,8 +77,108 @@ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      <fa icon="spinner" class="fa-spin-pulse"></fa> | 
					 | 
					 | 
					      <fa icon="spinner" class="fa-spin-pulse"></fa> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    </div> | 
					 | 
					 | 
					    </div> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    <!-- Results List --> | 
					 | 
					 | 
					    <!-- Offer Results List --> | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    <InfiniteScroll @reached-bottom="loadMoreData"> | 
					 | 
					 | 
					    <InfiniteScroll v-if="showOffers" @reached-bottom="loadMoreOfferData"> | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      <ul class="border-t border-slate-300"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        <li | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          class="border-b border-slate-300" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          v-for="offer in offers" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          :key="offer.handleId" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        > | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          <div class="block py-4 flex gap-4"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            <div v-if="offer.fulfillsPlanHandleId" class="flex-none w-12"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              <ProjectIcon | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                :entityId="offer.fulfillsPlanHandleId" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                :iconSize="48" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                class="inline-block align-middle border border-slate-300 rounded-md" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              ></ProjectIcon> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            </div> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            <div v-if="offer.recipientDid" class="flex-none w-12"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              <EntityIcon | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                :entityId="offer.recipientDid" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                :iconSize="48" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                class="inline-block align-middle border border-slate-300 rounded-md" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              ></EntityIcon> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            </div> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            <div> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              <div> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                {{ offer.objectDescription }} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              </div> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              <span class="text-sm"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                <span v-if="offer.amount"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  <fa | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    :icon="libsUtil.iconForUnitCode(offer.unit)" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    class="fa-fw text-slate-400" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  /> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  <span v-if="offer.amountGiven >= offer.amount"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    <fa icon="check-circle" class="fa-fw text-green-500" /> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    All {{ offer.amount }} given | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  </span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  <span v-else> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    <fa | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                      icon="triangle-exclamation" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                      class="fa-fw text-yellow-500" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    /> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    {{ offer.amountGiven ? "" : "All" }} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    {{ offer.amount - (offer.amountGiven || 0) }} remaining | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  </span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  <span v-if="offer.amountGiven > 0"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    <span class="text-sm text-slate-400"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                      ({{ offer.amountGiven }} given, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                      <span | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        v-if="offer.amountGivenConfirmed >= offer.amountGiven" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                      > | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        <!-- no need for green icon; unnecessary if there's already a green, confusing if there's a yellow --> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        all | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                      </span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                      <span v-else> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        <!-- only show icon if there's not already a warning --> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        <fa | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                          v-if="offer.amountGiven >= offer.amount" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                          icon="triangle-exclamation" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                          class="fa-fw text-yellow-300" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        /> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                        {{ offer.amountGivenConfirmed || 0 }} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                      </span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                      of that is confirmed) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    </span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  </span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                </span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                <span v-else> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  <!-- Non-amount offer --> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  <span v-if="offer.nonAmountGivenConfirmed"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    <fa icon="check-circle" class="fa-fw text-green-500" /> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    {{ offer.nonAmountGivenConfirmed }} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    {{ offer.nonAmountGivenConfirmed == 1 ? "give" : "gives" }} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    are confirmed. | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  </span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  <span v-else> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    <fa | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                      icon="triangle-exclamation" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                      class="fa-fw text-yellow-500" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    /> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    <span class="text-sm">Not confirmed by anyone</span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  </span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                </span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                <a @click="onClickLoadClaim(offer.jwtId)"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  <fa | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    icon="circle-info" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                    class="pl-2 text-blue-500 cursor-pointer" | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                  ></fa> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					                </a> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					              </span> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            </div> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          </div> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        </li> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      </ul> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    </InfiniteScroll> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    <!-- Project Results List --> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    <InfiniteScroll v-if="showProjects" @reached-bottom="loadMoreProjectData"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      <ul class="border-t border-slate-300"> | 
					 | 
					 | 
					      <ul class="border-t border-slate-300"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        <li | 
					 | 
					 | 
					        <li | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          class="border-b border-slate-300" | 
					 | 
					 | 
					          class="border-b border-slate-300" | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					@ -74,15 +212,18 @@ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					<script lang="ts"> | 
					 | 
					 | 
					<script lang="ts"> | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { Component, Vue } from "vue-facing-decorator"; | 
					 | 
					 | 
					import { Component, Vue } from "vue-facing-decorator"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { accountsDB, db } from "@/db/index"; | 
					 | 
					 | 
					import { accountsDB, db } from "@/db/index"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; | 
					 | 
					 | 
					import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { accessToken } from "@/libs/crypto"; | 
					 | 
					 | 
					import { accessToken } from "@/libs/crypto"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					import * as libsUtil from "@/libs/util"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import { IIdentifier } from "@veramo/core"; | 
					 | 
					 | 
					import { IIdentifier } from "@veramo/core"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import InfiniteScroll from "@/components/InfiniteScroll.vue"; | 
					 | 
					 | 
					import InfiniteScroll from "@/components/InfiniteScroll.vue"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import QuickNav from "@/components/QuickNav.vue"; | 
					 | 
					 | 
					import QuickNav from "@/components/QuickNav.vue"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import ProjectIcon from "@/components/ProjectIcon.vue"; | 
					 | 
					 | 
					import ProjectIcon from "@/components/ProjectIcon.vue"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					import TopMessage from "@/components/TopMessage.vue"; | 
					 | 
					 | 
					import TopMessage from "@/components/TopMessage.vue"; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					import { ProjectData } from "@/libs/endorserServer"; | 
					 | 
					 | 
					import { OfferServerRecord, PlanData } from "@/libs/endorserServer"; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					import EntityIcon from "@/components/EntityIcon.vue"; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					interface Notification { | 
					 | 
					 | 
					interface Notification { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  group: string; | 
					 | 
					 | 
					  group: string; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -92,16 +233,21 @@ interface Notification { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					@Component({ | 
					 | 
					 | 
					@Component({ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  components: { InfiniteScroll, QuickNav, ProjectIcon, TopMessage }, | 
					 | 
					 | 
					  components: { EntityIcon, InfiniteScroll, QuickNav, ProjectIcon, TopMessage }, | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					}) | 
					 | 
					 | 
					}) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					export default class ProjectsView extends Vue { | 
					 | 
					 | 
					export default class ProjectsView extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  $notify!: (notification: Notification, timeout?: number) => void; | 
					 | 
					 | 
					  $notify!: (notification: Notification, timeout?: number) => void; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  apiServer = ""; | 
					 | 
					 | 
					  apiServer = ""; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  projects: ProjectData[] = []; | 
					 | 
					 | 
					  projects: PlanData[] = []; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					  current: IIdentifier; | 
					 | 
					 | 
					  currentIid: IIdentifier; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					  isLoading = false; | 
					 | 
					 | 
					  isLoading = false; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  numAccounts = 0; | 
					 | 
					 | 
					  numAccounts = 0; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  offers: OfferServerRecord[] = []; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  showOffers = true; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  showProjects = false; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  libsUtil = libsUtil; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  /** | 
					 | 
					 | 
					  /** | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   * 'created' hook runs when the Vue instance is first created | 
					 | 
					 | 
					   * 'created' hook runs when the Vue instance is first created | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -110,8 +256,8 @@ export default class ProjectsView extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    try { | 
					 | 
					 | 
					    try { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      await db.open(); | 
					 | 
					 | 
					      await db.open(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      const settings = await db.settings.get(MASTER_SETTINGS_KEY); | 
					 | 
					 | 
					      const settings = await db.settings.get(MASTER_SETTINGS_KEY); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					      const activeDid = settings?.activeDid || ""; | 
					 | 
					 | 
					      const activeDid: string = (settings?.activeDid as string) || ""; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					      this.apiServer = settings?.apiServer || ""; | 
					 | 
					 | 
					      this.apiServer = (settings?.apiServer as string) || ""; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      await accountsDB.open(); | 
					 | 
					 | 
					      await accountsDB.open(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      this.numAccounts = await accountsDB.accounts.count(); | 
					 | 
					 | 
					      this.numAccounts = await accountsDB.accounts.count(); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -127,12 +273,11 @@ export default class ProjectsView extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          -1, | 
					 | 
					 | 
					          -1, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        ); | 
					 | 
					 | 
					        ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      } else { | 
					 | 
					 | 
					      } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        const identity = await this.getIdentity(activeDid); | 
					 | 
					 | 
					        this.currentIid = await this.getIdentity(activeDid); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					        this.current = identity; | 
					 | 
					 | 
					        await this.loadOffers(); | 
				
			
			
				
				
			
		
	
		
		
			
				
					 | 
					 | 
					        this.loadProjects(identity); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      } | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } catch (err) { | 
					 | 
					 | 
					    } catch (err) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					      console.log("Error initializing:", err); | 
					 | 
					 | 
					      console.error("Error initializing:", err); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      this.$notify( | 
					 | 
					 | 
					      this.$notify( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        { | 
					 | 
					 | 
					        { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          group: "alert", | 
					 | 
					 | 
					          group: "alert", | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -150,7 +295,7 @@ export default class ProjectsView extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   * @param url the url used to fetch the data | 
					 | 
					 | 
					   * @param url the url used to fetch the data | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   * @param token Authorization token | 
					 | 
					 | 
					   * @param token Authorization token | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   **/ | 
					 | 
					 | 
					   **/ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  async dataLoader(url: string, token: string) { | 
					 | 
					 | 
					  async projectDataLoader(url: string, token: string) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    const headers: { [key: string]: string } = { | 
					 | 
					 | 
					    const headers: { [key: string]: string } = { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      "Content-Type": "application/json", | 
					 | 
					 | 
					      "Content-Type": "application/json", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      Authorization: `Bearer ${token}`, | 
					 | 
					 | 
					      Authorization: `Bearer ${token}`, | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -160,13 +305,17 @@ export default class ProjectsView extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      this.isLoading = true; | 
					 | 
					 | 
					      this.isLoading = true; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      const resp = await this.axios.get(url, { headers }); | 
					 | 
					 | 
					      const resp = await this.axios.get(url, { headers }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      if (resp.status === 200 || !resp.data.data) { | 
					 | 
					 | 
					      if (resp.status === 200 || !resp.data.data) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        const plans: ProjectData[] = resp.data.data; | 
					 | 
					 | 
					        const plans: PlanData[] = resp.data.data; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					        for (const plan of plans) { | 
					 | 
					 | 
					        for (const plan of plans) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          const { name, description, handleId, issuerDid, rowid } = plan; | 
					 | 
					 | 
					          const { name, description, handleId, issuerDid, rowid } = plan; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          this.projects.push({ name, description, handleId, issuerDid, rowid }); | 
					 | 
					 | 
					          this.projects.push({ name, description, handleId, issuerDid, rowid }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        } | 
					 | 
					 | 
					        } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      } else { | 
					 | 
					 | 
					      } else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					        console.log("Bad server response & data:", resp.status, resp.data); | 
					 | 
					 | 
					        console.error( | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          "Bad server response & data for plans:", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          resp.status, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          resp.data, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        this.$notify( | 
					 | 
					 | 
					        this.$notify( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          { | 
					 | 
					 | 
					          { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					            group: "alert", | 
					 | 
					 | 
					            group: "alert", | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -179,7 +328,7 @@ export default class ProjectsView extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      } | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      // eslint-disable-next-line @typescript-eslint/no-explicit-any | 
					 | 
					 | 
					      // eslint-disable-next-line @typescript-eslint/no-explicit-any | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    } catch (error: any) { | 
					 | 
					 | 
					    } catch (error: any) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					      console.error("Got error loading projects:", error.message || error); | 
					 | 
					 | 
					      console.error("Got error loading plans:", error.message || error); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					      this.$notify( | 
					 | 
					 | 
					      this.$notify( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					        { | 
					 | 
					 | 
					        { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					          group: "alert", | 
					 | 
					 | 
					          group: "alert", | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -198,44 +347,35 @@ export default class ProjectsView extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   * Data loader used by infinite scroller | 
					 | 
					 | 
					   * Data loader used by infinite scroller | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   * @param payload is the flag from the InfiniteScroll indicating if it should load | 
					 | 
					 | 
					   * @param payload is the flag from the InfiniteScroll indicating if it should load | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   **/ | 
					 | 
					 | 
					   **/ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  async loadMoreData(payload: boolean) { | 
					 | 
					 | 
					  async loadMoreProjectData(payload: boolean) { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    if (this.projects.length > 0 && payload) { | 
					 | 
					 | 
					    if (this.projects.length > 0 && payload) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      const latestProject = this.projects[this.projects.length - 1]; | 
					 | 
					 | 
					      const latestProject = this.projects[this.projects.length - 1]; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					      const url = `${this.apiServer}/api/v2/report/plansByIssuer?beforeId=${latestProject.rowid}`; | 
					 | 
					 | 
					      await this.loadProjects( | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					      const token = await accessToken(this.current); | 
					 | 
					 | 
					        this.currentIid, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					      await this.dataLoader(url, token); | 
					 | 
					 | 
					        `beforeId=${latestProject.rowid}`, | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    } | 
					 | 
					 | 
					      ); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    } | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  /** | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   * Handle clicking on a project entry found in the list | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   * @param id of the project | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   **/ | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  onClickLoadProject(id: string) { | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    localStorage.setItem("projectId", id); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    const route = { | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      path: "/project/" + encodeURIComponent(id), | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    }; | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    this.$router.push(route); | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  } | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  /** | 
					 | 
					 | 
					  /** | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   * Load projects initially | 
					 | 
					 | 
					   * Load projects initially | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					   * @param identity of the user | 
					 | 
					 | 
					   * @param identifier of the user | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   * @param urlExtra additional url parameters in a string | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   **/ | 
					 | 
					 | 
					   **/ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  async loadProjects(identity: IIdentifier) { | 
					 | 
					 | 
					  async loadProjects(identifier?: IIdentifier, urlExtra: string = "") { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					    const url = `${this.apiServer}/api/v2/report/plansByIssuer`; | 
					 | 
					 | 
					    const identity = identifier || this.currentIid; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    const url = `${this.apiServer}/api/v2/report/plansByIssuer?${urlExtra}`; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    const token: string = await accessToken(identity); | 
					 | 
					 | 
					    const token: string = await accessToken(identity); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    await this.dataLoader(url, token); | 
					 | 
					 | 
					    await this.projectDataLoader(url, token); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					  } | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					  public async getIdentity(activeDid: string) { | 
					 | 
					 | 
					  public async getIdentity(activeDid: string): Promise<IIdentifier> { | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					    await accountsDB.open(); | 
					 | 
					 | 
					    await accountsDB.open(); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    const account = await accountsDB.accounts | 
					 | 
					 | 
					    const account = await accountsDB.accounts | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      .where("did") | 
					 | 
					 | 
					      .where("did") | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      .equals(activeDid) | 
					 | 
					 | 
					      .equals(activeDid) | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      .first(); | 
					 | 
					 | 
					      .first(); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					    const identity = JSON.parse(account?.identity || "null"); | 
					 | 
					 | 
					    const identity = JSON.parse((account?.identity as string) || "null"); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    if (!identity) { | 
					 | 
					 | 
					    if (!identity) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					      throw new Error( | 
					 | 
					 | 
					      throw new Error( | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -245,6 +385,18 @@ export default class ProjectsView extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    return identity; | 
					 | 
					 | 
					    return identity; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  } | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					
 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  /** | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   * Handle clicking on a project entry found in the list | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   * @param id of the project | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   **/ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  onClickLoadProject(id: string) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    localStorage.setItem("projectId", id); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    const route = { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      path: "/project/" + encodeURIComponent(id), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    this.$router.push(route); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  /** | 
					 | 
					 | 
					  /** | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   * Handling clicking on the new project button | 
					 | 
					 | 
					   * Handling clicking on the new project button | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					   **/ | 
					 | 
					 | 
					   **/ | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					@ -255,5 +407,120 @@ export default class ProjectsView extends Vue { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    }; | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					    this.$router.push(route); | 
					 | 
					 | 
					    this.$router.push(route); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					  } | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  onClickLoadClaim(jwtId: string) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    const route = { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      path: "/claim/" + encodeURIComponent(jwtId), | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    this.$router.push(route); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  /** | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   * Core offer data loader | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   * @param url the url used to fetch the data | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   * @param token Authorization token | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   **/ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  async offerDataLoader(url: string, token: string) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    const headers: { [key: string]: string } = { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "Content-Type": "application/json", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      Authorization: `Bearer ${token}`, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    try { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      this.isLoading = true; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      const resp = await this.axios.get(url, { headers }); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      if (resp.status === 200 || !resp.data.data) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        this.offers = this.offers.concat(resp.data.data); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      } else { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        console.error( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          "Bad server response & data for offers:", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          resp.status, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          resp.data, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        this.$notify( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            group: "alert", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            type: "danger", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            title: "Error", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					            text: "Failed to get offers from the server. Try again later.", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          }, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          -1, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      // eslint-disable-next-line @typescript-eslint/no-explicit-any | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } catch (error: any) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      console.error("Got error loading offers:", error.message || error); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      this.$notify( | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          group: "alert", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          type: "danger", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          title: "Error", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					          text: "Got an error loading offers.", | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        }, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					        -1, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      ); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } finally { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      this.isLoading = false; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  /** | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   * Data loader used by infinite scroller | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   * @param payload is the flag from the InfiniteScroll indicating if it should load | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   **/ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  async loadMoreOfferData(payload: boolean) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    if (this.offers.length > 0 && payload) { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      const latestOffer = this.offers[this.offers.length - 1]; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      await this.loadOffers(this.currentIid, `&beforeId=${latestOffer.jwtId}`); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  /** | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   * Load offers initially | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   * @param identifier of the user | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   * @param urlExtra additional url parameters in a string | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					   **/ | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  async loadOffers(identifier?: IIdentifier, urlExtra: string = "") { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    const identity = identifier || this.currentIid; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    const url = `${this.apiServer}/api/v2/report/offers?offeredByDid=${identity.did}${urlExtra}`; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    const token: string = await accessToken(identity); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    await this.offerDataLoader(url, token); | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  public computedOfferTabClassNames() { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    return { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "inline-block": true, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "py-3": true, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "rounded-t-lg": true, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "border-b-2": true, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      active: this.showOffers, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "text-black": this.showOffers, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "border-black": this.showOffers, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "font-semibold": this.showOffers, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "text-blue-600": !this.showOffers, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "border-transparent": !this.showOffers, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "hover:border-slate-400": !this.showOffers, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  public computedProjectTabClassNames() { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    return { | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "inline-block": true, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "py-3": true, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "rounded-t-lg": true, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "border-b-2": true, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      active: this.showProjects, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "text-black": this.showProjects, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "border-black": this.showProjects, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "font-semibold": this.showProjects, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "text-blue-600": !this.showProjects, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "border-transparent": !this.showProjects, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					      "hover:border-slate-400": !this.showProjects, | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					    }; | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					 | 
					 | 
					 | 
					  } | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					} | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					 | 
					 | 
					</script> | 
					 | 
					 | 
					</script> | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
					 | 
					
  |