7 changed files with 374 additions and 48 deletions
			
			
		| @ -0,0 +1,150 @@ | |||
| <template> | |||
|   <QuickNav selected="Home"></QuickNav> | |||
|   <!-- CONTENT --> | |||
|   <section id="Content" class="p-6 pb-24 max-w-3xl mx-auto"> | |||
|     <!-- Breadcrumb --> | |||
|     <div id="ViewBreadcrumb" class="mb-8"> | |||
|       <h1 class="text-lg text-center font-light relative px-7"> | |||
|         <!-- Back --> | |||
|         <fa | |||
|           icon="chevron-left" | |||
|           @click="$router.back()" | |||
|           class="fa-fw text-lg text-center px-2 py-1 absolute -left-2 -top-1" | |||
|         /> | |||
|         Offers to Your Projects | |||
|       </h1> | |||
|     </div> | |||
| 
 | |||
|     <InfiniteScroll @reached-bottom="loadMoreOffersToUserProjects"> | |||
|       <ul id="listLatestActivity" class="border-t border-slate-300"> | |||
|         <li | |||
|           v-for="offer in newOffersToUserProjects" | |||
|           :key="offer.jwtId" | |||
|           class="mt-4 relative group" | |||
|         > | |||
|           <div | |||
|             class="border-b border-slate-300 text-orange-400 pb-2 mb-2 font-bold text-sm" | |||
|             v-if="offer.jwtId == lastAckedOfferToUserProjectsJwtId" | |||
|           > | |||
|             You've already seen all the following | |||
|           </div> | |||
| 
 | |||
|           <span>{{ | |||
|             didInfo(offer.offeredByDid, activeDid, allMyDids, allContacts) | |||
|           }}</span> | |||
|           offered | |||
|           <span v-if="offer.objectDescription">{{ | |||
|             offer.objectDescription | |||
|           }}</span | |||
|           >{{ offer.objectDescription && offer.amount ? ", and " : "" }} | |||
|           <span v-if="offer.amount">{{ | |||
|             displayAmount(offer.unit, offer.amount) | |||
|           }}</span> | |||
|           to | |||
|           <span>{{ offer.planName }}</span> | |||
|           <router-link | |||
|             :to="{ path: '/claim/' + encodeURIComponent(offer.jwtId) }" | |||
|             class="text-blue-500" | |||
|           > | |||
|             <fa icon="file-lines" class="pl-2 text-blue-500 cursor-pointer" /> | |||
|           </router-link> | |||
|         </li> | |||
|       </ul> | |||
|     </InfiniteScroll> | |||
|   </section> | |||
| </template> | |||
| 
 | |||
| <script lang="ts"> | |||
| import { Component, Vue } from "vue-facing-decorator"; | |||
| 
 | |||
| import EntityIcon from "@/components/EntityIcon.vue"; | |||
| import GiftedDialog from "@/components/GiftedDialog.vue"; | |||
| import InfiniteScroll from "@/components/InfiniteScroll.vue"; | |||
| import QuickNav from "@/components/QuickNav.vue"; | |||
| import { NotificationIface } from "@/constants/app"; | |||
| import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index"; | |||
| import { Contact } from "@/db/tables/contacts"; | |||
| import { | |||
|   didInfo, | |||
|   displayAmount, | |||
|   getNewOffersToUserProjects, | |||
|   OfferToPlanSummaryRecord, | |||
| } from "@/libs/endorserServer"; | |||
| 
 | |||
| @Component({ | |||
|   components: { EntityIcon, GiftedDialog, InfiniteScroll, QuickNav }, | |||
| }) | |||
| export default class RecentOffersToUserView extends Vue { | |||
|   $notify!: (notification: NotificationIface, timeout?: number) => void; | |||
| 
 | |||
|   activeDid = ""; | |||
|   allContacts: Array<Contact> = []; | |||
|   allMyDids: string[] = []; | |||
|   apiServer = ""; | |||
|   lastAckedOfferToUserProjectsJwtId = ""; | |||
|   newOffersToUserProjects: Array<OfferToPlanSummaryRecord> = []; | |||
|   newOffersToUserProjectsAtEnd = false; | |||
| 
 | |||
|   showOffersDetails = false; | |||
|   showOffersToUserProjectsDetails = false; | |||
|   didInfo = didInfo; | |||
|   displayAmount = displayAmount; | |||
| 
 | |||
|   async created() { | |||
|     try { | |||
|       const settings = await retrieveSettingsForActiveAccount(); | |||
|       this.apiServer = settings.apiServer || ""; | |||
|       this.activeDid = settings.activeDid || ""; | |||
|       this.lastAckedOfferToUserProjectsJwtId = | |||
|         settings.lastAckedOfferToUserProjectsJwtId || ""; | |||
| 
 | |||
|       this.allContacts = await db.contacts.toArray(); | |||
| 
 | |||
|       await accountsDB.open(); | |||
|       const allAccounts = await accountsDB.accounts.toArray(); | |||
|       if (allAccounts.length > 0) { | |||
|         this.allMyDids = allAccounts.map((acc) => acc.did); | |||
|       } | |||
| 
 | |||
|       const offersToUserProjectsData = await getNewOffersToUserProjects( | |||
|         this.axios, | |||
|         this.apiServer, | |||
|         this.activeDid, | |||
|         undefined, | |||
|         undefined, | |||
|       ); | |||
|       this.newOffersToUserProjects = offersToUserProjectsData.data; | |||
|       this.newOffersToUserProjectsAtEnd = !offersToUserProjectsData.hitLimit; | |||
| 
 | |||
|       // eslint-disable-next-line @typescript-eslint/no-explicit-any | |||
|     } catch (err: any) { | |||
|       console.error("Error retrieving settings & contacts:", err); | |||
|       this.$notify( | |||
|         { | |||
|           group: "alert", | |||
|           type: "danger", | |||
|           title: "Error", | |||
|           text: err.message || "There was an error retrieving your activity.", | |||
|         }, | |||
|         5000, | |||
|       ); | |||
|     } | |||
|   } | |||
| 
 | |||
|   async loadMoreOffersToUserProjects() { | |||
|     if (this.newOffersToUserProjectsAtEnd) { | |||
|       return; | |||
|     } | |||
|     const offersToUserProjectsData = await getNewOffersToUserProjects( | |||
|       this.axios, | |||
|       this.apiServer, | |||
|       this.activeDid, | |||
|       undefined, | |||
|       this.newOffersToUserProjects[this.newOffersToUserProjects.length - 1] | |||
|         .jwtId, | |||
|     ); | |||
|     this.newOffersToUserProjects.push(...offersToUserProjectsData.data); | |||
|     this.newOffersToUserProjectsAtEnd = !offersToUserProjectsData.hitLimit; | |||
|   } | |||
| } | |||
| </script> | |||
| @ -0,0 +1,146 @@ | |||
| <template> | |||
|   <QuickNav selected="Home"></QuickNav> | |||
|   <!-- CONTENT --> | |||
|   <section id="Content" class="p-6 pb-24 max-w-3xl mx-auto"> | |||
|     <!-- Breadcrumb --> | |||
|     <div id="ViewBreadcrumb" class="mb-8"> | |||
|       <h1 class="text-lg text-center font-light relative px-7"> | |||
|         <!-- Back --> | |||
|         <fa | |||
|           icon="chevron-left" | |||
|           @click="$router.back()" | |||
|           class="fa-fw text-lg text-center px-2 py-1 absolute -left-2 -top-1" | |||
|         /> | |||
|         Offers to You | |||
|       </h1> | |||
|     </div> | |||
| 
 | |||
|     <InfiniteScroll @reached-bottom="loadMoreOffersToUser"> | |||
|       <ul id="listLatestActivity" class="border-t border-slate-300"> | |||
|         <li | |||
|           v-for="offer in newOffersToUser" | |||
|           :key="offer.jwtId" | |||
|           class="mt-4 relative group" | |||
|         > | |||
|           <div | |||
|             class="border-b border-slate-300 text-orange-400 pb-2 mb-2 font-bold text-sm" | |||
|             v-if="offer.jwtId == lastAckedOfferToUserJwtId" | |||
|           > | |||
|             You've already seen all the following | |||
|           </div> | |||
| 
 | |||
|           <span>{{ | |||
|             didInfo(offer.offeredByDid, activeDid, allMyDids, allContacts) | |||
|           }}</span> | |||
|           offered | |||
|           <span v-if="offer.objectDescription">{{ | |||
|             offer.objectDescription | |||
|           }}</span | |||
|           >{{ offer.objectDescription && offer.amount ? ", and " : "" }} | |||
|           <span v-if="offer.amount">{{ | |||
|             displayAmount(offer.unit, offer.amount) | |||
|           }}</span> | |||
|           <router-link | |||
|             :to="{ path: '/claim/' + encodeURIComponent(offer.jwtId) }" | |||
|             class="text-blue-500" | |||
|           > | |||
|             <fa icon="file-lines" class="pl-2 text-blue-500 cursor-pointer" /> | |||
|           </router-link> | |||
|         </li> | |||
|       </ul> | |||
|     </InfiniteScroll> | |||
|   </section> | |||
| </template> | |||
| 
 | |||
| <script lang="ts"> | |||
| import { Component, Vue } from "vue-facing-decorator"; | |||
| 
 | |||
| import GiftedDialog from "@/components/GiftedDialog.vue"; | |||
| import EntityIcon from "@/components/EntityIcon.vue"; | |||
| import InfiniteScroll from "@/components/InfiniteScroll.vue"; | |||
| import QuickNav from "@/components/QuickNav.vue"; | |||
| import { NotificationIface } from "@/constants/app"; | |||
| import { accountsDB, db, retrieveSettingsForActiveAccount } from "@/db/index"; | |||
| import { Contact } from "@/db/tables/contacts"; | |||
| import { | |||
|   didInfo, | |||
|   displayAmount, | |||
|   getNewOffersToUser, | |||
|   OfferSummaryRecord, | |||
| } from "@/libs/endorserServer"; | |||
| 
 | |||
| @Component({ | |||
|   components: { EntityIcon, GiftedDialog, InfiniteScroll, QuickNav }, | |||
| }) | |||
| export default class RecentOffersToUserView extends Vue { | |||
|   $notify!: (notification: NotificationIface, timeout?: number) => void; | |||
| 
 | |||
|   activeDid = ""; | |||
|   allContacts: Array<Contact> = []; | |||
|   allMyDids: string[] = []; | |||
|   apiServer = ""; | |||
|   lastAckedOfferToUserJwtId = ""; | |||
|   newOffersToUser: Array<OfferSummaryRecord> = []; | |||
|   newOffersToUserAtEnd = false; | |||
| 
 | |||
|   showOffersDetails = false; | |||
|   showOffersToUserProjectsDetails = false; | |||
|   didInfo = didInfo; | |||
|   displayAmount = displayAmount; | |||
| 
 | |||
|   async created() { | |||
|     try { | |||
|       const settings = await retrieveSettingsForActiveAccount(); | |||
|       this.apiServer = settings.apiServer || ""; | |||
|       this.activeDid = settings.activeDid || ""; | |||
|       this.lastAckedOfferToUserJwtId = settings.lastAckedOfferToUserJwtId || ""; | |||
| 
 | |||
|       this.allContacts = await db.contacts.toArray(); | |||
| 
 | |||
|       await accountsDB.open(); | |||
|       const allAccounts = await accountsDB.accounts.toArray(); | |||
|       if (allAccounts.length > 0) { | |||
|         this.allMyDids = allAccounts.map((acc) => acc.did); | |||
|       } | |||
| 
 | |||
|       const offersToUserData = await getNewOffersToUser( | |||
|         this.axios, | |||
|         this.apiServer, | |||
|         this.activeDid, | |||
|         undefined, | |||
|         undefined, | |||
|       ); | |||
|       this.newOffersToUser = offersToUserData.data; | |||
|       this.newOffersToUserAtEnd = !offersToUserData.hitLimit; | |||
| 
 | |||
|       // eslint-disable-next-line @typescript-eslint/no-explicit-any | |||
|     } catch (err: any) { | |||
|       console.error("Error retrieving settings & contacts:", err); | |||
|       this.$notify( | |||
|         { | |||
|           group: "alert", | |||
|           type: "danger", | |||
|           title: "Error", | |||
|           text: err.message || "There was an error retrieving your activity.", | |||
|         }, | |||
|         5000, | |||
|       ); | |||
|     } | |||
|   } | |||
| 
 | |||
|   async loadMoreOffersToUser() { | |||
|     if (this.newOffersToUserAtEnd) { | |||
|       return; | |||
|     } | |||
|     const offersToUserData = await getNewOffersToUser( | |||
|       this.axios, | |||
|       this.apiServer, | |||
|       this.activeDid, | |||
|       undefined, | |||
|       this.newOffersToUser[this.newOffersToUser.length - 1].jwtId, | |||
|     ); | |||
|     this.newOffersToUser.push(...offersToUserData.data); | |||
|     this.newOffersToUserAtEnd = !offersToUserData.hitLimit; | |||
|   } | |||
| } | |||
| </script> | |||
					Loading…
					
					
				
		Reference in new issue