Trent Larson
2 weeks ago
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