|
|
@ -21,9 +21,8 @@ |
|
|
|
<h1 class="text-4xl text-center font-light px-4 mb-4">What Was Offered</h1> |
|
|
|
|
|
|
|
<h1 class="text-xl font-bold text-center mb-4"> |
|
|
|
<span>From {{ giverName }}</span> |
|
|
|
<span> |
|
|
|
to |
|
|
|
Offer to |
|
|
|
{{ |
|
|
|
offeredToProject |
|
|
|
? projectName |
|
|
@ -36,7 +35,7 @@ |
|
|
|
<textarea |
|
|
|
class="block w-full rounded border border-slate-400 mb-2 px-3 py-2" |
|
|
|
placeholder="What was offered" |
|
|
|
v-model="description" |
|
|
|
v-model="itemDescription" |
|
|
|
/> |
|
|
|
<div class="flex flex-row justify-center"> |
|
|
|
<span |
|
|
@ -64,6 +63,32 @@ |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="flex flex-row mt-2"> |
|
|
|
<span |
|
|
|
class="rounded-l border border-r-0 border-slate-400 bg-slate-200 text-center px-2 py-2" |
|
|
|
> |
|
|
|
Conditions |
|
|
|
</span> |
|
|
|
<textarea |
|
|
|
class="w-full border border-slate-400 px-3 py-2 rounded-r" |
|
|
|
placeholder="Prerequisites, other people to include, etc." |
|
|
|
v-model="conditionDescription" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="flex flex-row mt-2"> |
|
|
|
<span |
|
|
|
class="rounded-l border border-r-0 border-slate-400 bg-slate-200 text-center px-2 py-2" |
|
|
|
> |
|
|
|
{{ validThroughDateInput ? "" : "No" }} Expiration |
|
|
|
</span> |
|
|
|
<input |
|
|
|
v-model="validThroughDateInput" |
|
|
|
type="date" |
|
|
|
class="w-full rounded border border-slate-400 px-3 py-2 rounded-r" |
|
|
|
/> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div class="h-7 mt-4 flex"> |
|
|
|
<input |
|
|
|
v-if="projectId && !offeredToRecipient" |
|
|
@ -131,6 +156,12 @@ |
|
|
|
/> |
|
|
|
</p> |
|
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> |
|
|
|
<button |
|
|
|
class="block w-full text-center text-lg font-bold uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md" |
|
|
|
@click="confirm" |
|
|
|
> |
|
|
|
Sign & Send |
|
|
|
</button> |
|
|
|
<button |
|
|
|
class="block w-full text-center text-md uppercase bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-2 rounded-md" |
|
|
|
@click="cancel" |
|
|
@ -142,6 +173,7 @@ |
|
|
|
</template> |
|
|
|
|
|
|
|
<script lang="ts"> |
|
|
|
import { DateTime } from "luxon"; |
|
|
|
import { Component, Vue } from "vue-facing-decorator"; |
|
|
|
import { Router } from "vue-router"; |
|
|
|
|
|
|
@ -168,21 +200,20 @@ import { Contact } from "@/db/tables/contacts"; |
|
|
|
TopMessage, |
|
|
|
}, |
|
|
|
}) |
|
|
|
export default class OfferDetails extends Vue { |
|
|
|
export default class OfferDetailsView extends Vue { |
|
|
|
$notify!: (notification: NotificationIface, timeout?: number) => void; |
|
|
|
|
|
|
|
activeDid = ""; |
|
|
|
apiServer = ""; |
|
|
|
|
|
|
|
amountInput = "0"; |
|
|
|
description = ""; |
|
|
|
conditionDescription = ""; |
|
|
|
itemDescription = ""; |
|
|
|
destinationPathAfter = ""; |
|
|
|
offeredToProject = false; |
|
|
|
offeredToRecipient = false; |
|
|
|
giverDid: string | undefined; |
|
|
|
giverName = ""; |
|
|
|
offererDid: string | undefined; |
|
|
|
hideBackButton = false; |
|
|
|
isTrade = false; |
|
|
|
message = ""; |
|
|
|
offerId = ""; |
|
|
|
prevCredToEdit?: GenericCredWrapper<OfferVerifiableCredential>; |
|
|
@ -191,7 +222,7 @@ export default class OfferDetails extends Vue { |
|
|
|
recipientDid = ""; |
|
|
|
recipientName = ""; |
|
|
|
unitCode = "HUR"; |
|
|
|
validThroughDate = null; |
|
|
|
validThroughDateInput = ""; |
|
|
|
|
|
|
|
libsUtil = libsUtil; |
|
|
|
|
|
|
@ -214,67 +245,54 @@ export default class OfferDetails extends Vue { |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
const prevAmount = this.prevCredToEdit?.claim?.object?.amountOfThisGood; |
|
|
|
const prevAmount = |
|
|
|
this.prevCredToEdit?.claim?.includesObject?.amountOfThisGood; |
|
|
|
this.amountInput = |
|
|
|
(this.$route as Router).query["amountInput"] || |
|
|
|
(prevAmount ? String(prevAmount) : "") || |
|
|
|
this.amountInput; |
|
|
|
this.description = |
|
|
|
this.unitCode = ((this.$route as Router).query["unitCode"] || |
|
|
|
this.prevCredToEdit?.claim?.includesObject?.unitCode || |
|
|
|
this.unitCode) as string; |
|
|
|
|
|
|
|
this.conditionDescription = |
|
|
|
this.prevCredToEdit?.claim?.description || this.conditionDescription; |
|
|
|
this.itemDescription = |
|
|
|
(this.$route as Router).query["description"] || |
|
|
|
this.prevCredToEdit?.claim?.description || |
|
|
|
this.description; |
|
|
|
this.prevCredToEdit?.claim?.itemOffered?.description || |
|
|
|
this.itemDescription; |
|
|
|
this.destinationPathAfter = (this.$route as Router).query[ |
|
|
|
"destinationPathAfter" |
|
|
|
]; |
|
|
|
this.giverDid = ((this.$route as Router).query["giverDid"] || |
|
|
|
this.offererDid = ((this.$route as Router).query["offererDid"] || |
|
|
|
this.prevCredToEdit?.claim?.agent?.identifier || |
|
|
|
this.giverDid) as string; |
|
|
|
this.giverName = |
|
|
|
((this.$route as Router).query["giverName"] as string) || ""; |
|
|
|
this.offererDid) as string; |
|
|
|
this.hideBackButton = |
|
|
|
(this.$route as Router).query["hideBackButton"] === "true"; |
|
|
|
this.message = ((this.$route as Router).query["message"] as string) || ""; |
|
|
|
// find any offer ID |
|
|
|
const fulfills = this.prevCredToEdit?.claim?.fulfills; |
|
|
|
const fulfillsArray = Array.isArray(fulfills) |
|
|
|
? fulfills |
|
|
|
: fulfills |
|
|
|
? [fulfills] |
|
|
|
: []; |
|
|
|
const offer = fulfillsArray.find((rec) => rec["@type"] === "Offer"); |
|
|
|
this.offerId = ((this.$route as Router).query["offerId"] || |
|
|
|
offer?.identifier || |
|
|
|
this.offerId) as string; |
|
|
|
|
|
|
|
// find any project ID |
|
|
|
const project = fulfillsArray.find((rec) => rec["@type"] === "PlanAction"); |
|
|
|
let project; |
|
|
|
if ( |
|
|
|
this.prevCredToEdit?.claim?.itemOffered?.isPartOf["@type"] === |
|
|
|
"PlanAction" |
|
|
|
) { |
|
|
|
project = this.prevCredToEdit?.claim?.itemOffered?.isPartOf; |
|
|
|
} |
|
|
|
this.projectId = ((this.$route as Router).query["projectId"] || |
|
|
|
project?.identifier || |
|
|
|
this.projectId) as string; |
|
|
|
this.projectName = ((this.$route as Router).query["projectName"] || |
|
|
|
project?.name || |
|
|
|
this.projectName) as string; |
|
|
|
|
|
|
|
this.recipientDid = ((this.$route as Router).query["recipientDid"] || |
|
|
|
this.prevCredToEdit?.claim?.recipient?.identifier) as string; |
|
|
|
this.recipientName = |
|
|
|
((this.$route as Router).query["recipientName"] as string) || ""; |
|
|
|
this.unitCode = ((this.$route as Router).query["unitCode"] || |
|
|
|
this.prevCredToEdit?.claim?.object?.unitCode || |
|
|
|
this.unitCode) as string; |
|
|
|
|
|
|
|
// this is an endpoint for sharing project info to highlight something given |
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/Manifest/share_target |
|
|
|
if ((this.$route as Router).query["shareTitle"]) { |
|
|
|
this.description = |
|
|
|
((this.$route as Router).query["shareTitle"] as string) + |
|
|
|
(this.description ? "\n" + this.description : ""); |
|
|
|
} |
|
|
|
if ((this.$route as Router).query["shareText"]) { |
|
|
|
this.description = |
|
|
|
(this.description ? this.description + "\n" : "") + |
|
|
|
((this.$route as Router).query["shareText"] as string); |
|
|
|
} |
|
|
|
if ((this.$route as Router).query["shareUrl"]) { |
|
|
|
this.imageUrl = (this.$route as Router).query["shareUrl"] as string; |
|
|
|
} |
|
|
|
this.validThroughDateInput = |
|
|
|
this.prevCredToEdit?.claim?.validThrough || this.validThroughDateInput; |
|
|
|
|
|
|
|
try { |
|
|
|
await db.open(); |
|
|
@ -284,24 +302,12 @@ export default class OfferDetails extends Vue { |
|
|
|
|
|
|
|
let allContacts: Contact[] = []; |
|
|
|
let allMyDids: string[] = []; |
|
|
|
if ( |
|
|
|
(this.giverDid && !this.giverName) || |
|
|
|
(this.recipientDid && !this.recipientName) |
|
|
|
) { |
|
|
|
if (this.recipientDid && !this.recipientName) { |
|
|
|
allContacts = await db.contacts.toArray(); |
|
|
|
|
|
|
|
await accountsDB.open(); |
|
|
|
const allAccounts = await accountsDB.accounts.toArray(); |
|
|
|
allMyDids = allAccounts.map((acc) => acc.did); |
|
|
|
if (this.giverDid && !this.giverName) { |
|
|
|
this.giverName = didInfo( |
|
|
|
this.giverDid, |
|
|
|
this.activeDid, |
|
|
|
allMyDids, |
|
|
|
allContacts, |
|
|
|
); |
|
|
|
} |
|
|
|
if (this.recipientDid && !this.recipientName) { |
|
|
|
this.recipientName = didInfo( |
|
|
|
this.recipientDid, |
|
|
|
this.activeDid, |
|
|
@ -309,7 +315,7 @@ export default class OfferDetails extends Vue { |
|
|
|
allContacts, |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
// these should be functions but something's wrong with the syntax in the <> conditional |
|
|
|
this.offeredToProject = !!this.projectId; |
|
|
|
this.offeredToRecipient = !this.offeredToProject && !!this.recipientDid; |
|
|
|
|
|
|
@ -327,7 +333,7 @@ export default class OfferDetails extends Vue { |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
if (this.projectId) { |
|
|
|
if (this.projectId && !this.projectName) { |
|
|
|
// console.log("Getting project name from cache", this.projectId); |
|
|
|
const project = await getPlanFromCache( |
|
|
|
this.projectId, |
|
|
@ -395,7 +401,7 @@ export default class OfferDetails extends Vue { |
|
|
|
); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (!this.description && !parseFloat(this.amountInput)) { |
|
|
|
if (!this.itemDescription && !parseFloat(this.amountInput)) { |
|
|
|
this.$notify( |
|
|
|
{ |
|
|
|
group: "alert", |
|
|
@ -431,7 +437,7 @@ export default class OfferDetails extends Vue { |
|
|
|
group: "alert", |
|
|
|
type: "warning", |
|
|
|
title: "Error", |
|
|
|
text: "To assign to a project, you must open this dialog through a project.", |
|
|
|
text: "To assign to a project, you must open this page through a project.", |
|
|
|
}, |
|
|
|
3000, |
|
|
|
); |
|
|
@ -456,7 +462,7 @@ export default class OfferDetails extends Vue { |
|
|
|
group: "alert", |
|
|
|
type: "warning", |
|
|
|
title: "Error", |
|
|
|
text: "To assign to a recipient, you must open this dialog from a contact.", |
|
|
|
text: "To assign to a recipient, you must open this page from a contact.", |
|
|
|
}, |
|
|
|
3000, |
|
|
|
); |
|
|
@ -476,7 +482,7 @@ export default class OfferDetails extends Vue { |
|
|
|
|
|
|
|
/** |
|
|
|
* |
|
|
|
* @param giverDid may be null |
|
|
|
* @param offererDid may be null |
|
|
|
* @param description may be an empty string |
|
|
|
* @param amountInput may be 0 |
|
|
|
* @param unitCode may be omitted, defaults to "HUR" |
|
|
@ -495,10 +501,11 @@ export default class OfferDetails extends Vue { |
|
|
|
this.apiServer, |
|
|
|
this.prevCredToEdit, |
|
|
|
this.activeDid, |
|
|
|
this.description, |
|
|
|
this.itemDescription, |
|
|
|
parseFloat(this.amountInput), |
|
|
|
this.unitCode, |
|
|
|
this.validThroughDate, |
|
|
|
this.conditionDescription, |
|
|
|
this.validThroughDateInput, |
|
|
|
recipientDid, |
|
|
|
projectId, |
|
|
|
); |
|
|
@ -507,10 +514,11 @@ export default class OfferDetails extends Vue { |
|
|
|
this.axios, |
|
|
|
this.apiServer, |
|
|
|
this.activeDid, |
|
|
|
this.description, |
|
|
|
this.itemDescription, |
|
|
|
parseFloat(this.amountInput), |
|
|
|
this.unitCode, |
|
|
|
this.validThroughDate, |
|
|
|
this.conditionDescription, |
|
|
|
this.validThroughDateInput, |
|
|
|
recipientDid, |
|
|
|
projectId, |
|
|
|
); |
|
|
@ -534,7 +542,7 @@ export default class OfferDetails extends Vue { |
|
|
|
group: "alert", |
|
|
|
type: "success", |
|
|
|
title: "Success", |
|
|
|
text: `That ${this.isTrade ? "trade" : "gift"} was recorded.`, |
|
|
|
text: `That offer was recorded.`, |
|
|
|
}, |
|
|
|
5000, |
|
|
|
); |
|
|
@ -573,12 +581,12 @@ export default class OfferDetails extends Vue { |
|
|
|
this.prevCredToEdit?.claim as OfferVerifiableCredential, |
|
|
|
this.activeDid, |
|
|
|
recipientDid, |
|
|
|
this.description, |
|
|
|
this.itemDescription, |
|
|
|
parseFloat(this.amountInput), |
|
|
|
this.unitCode, |
|
|
|
"", |
|
|
|
this.conditionDescription, |
|
|
|
projectId, |
|
|
|
this.validThroughDate, |
|
|
|
this.validThroughDateInput, |
|
|
|
this.prevCredToEdit?.id as string, |
|
|
|
); |
|
|
|
const claimStr = JSON.stringify(giveClaim); |