3 changed files with 748 additions and 45 deletions
			
			
		@ -0,0 +1,624 @@ | 
				
			|||
<template> | 
				
			|||
  <QuickNav /> | 
				
			|||
  <TopMessage /> | 
				
			|||
 | 
				
			|||
  <!-- CONTENT --> | 
				
			|||
  <section id="Content" class="p-6 pb-24 max-w-3xl mx-auto"> | 
				
			|||
    <!-- Back --> | 
				
			|||
    <div | 
				
			|||
      v-if="!hideBackButton" | 
				
			|||
      class="text-lg text-center font-light relative px-7" | 
				
			|||
    > | 
				
			|||
      <h1 | 
				
			|||
        class="text-lg text-center px-2 py-1 absolute -left-2 -top-1" | 
				
			|||
        @click="cancelBack()" | 
				
			|||
      > | 
				
			|||
        <fa icon="chevron-left" class="fa-fw"></fa> | 
				
			|||
      </h1> | 
				
			|||
    </div> | 
				
			|||
 | 
				
			|||
    <!-- Heading --> | 
				
			|||
    <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 | 
				
			|||
        {{ | 
				
			|||
          offeredToProject | 
				
			|||
            ? projectName | 
				
			|||
            : offeredToRecipient | 
				
			|||
              ? recipientName | 
				
			|||
              : "someone unidentified" | 
				
			|||
        }}</span | 
				
			|||
      > | 
				
			|||
    </h1> | 
				
			|||
    <textarea | 
				
			|||
      class="block w-full rounded border border-slate-400 mb-2 px-3 py-2" | 
				
			|||
      placeholder="What was offered" | 
				
			|||
      v-model="description" | 
				
			|||
    /> | 
				
			|||
    <div class="flex flex-row justify-center"> | 
				
			|||
      <span | 
				
			|||
        class="rounded-l border border-r-0 border-slate-400 bg-slate-200 text-center text-blue-500 px-2 py-2 w-20" | 
				
			|||
        @click="changeUnitCode()" | 
				
			|||
      > | 
				
			|||
        {{ libsUtil.UNIT_SHORT[unitCode] || unitCode }} | 
				
			|||
      </span> | 
				
			|||
      <div | 
				
			|||
        class="border border-r-0 border-slate-400 bg-slate-200 px-4 py-2" | 
				
			|||
        @click="amountInput === '0' ? null : decrement()" | 
				
			|||
      > | 
				
			|||
        <fa icon="chevron-left" /> | 
				
			|||
      </div> | 
				
			|||
      <input | 
				
			|||
        type="number" | 
				
			|||
        class="border border-r-0 border-slate-400 px-2 py-2 text-center w-20" | 
				
			|||
        v-model="amountInput" | 
				
			|||
      /> | 
				
			|||
      <div | 
				
			|||
        class="rounded-r border border-slate-400 bg-slate-200 px-4 py-2" | 
				
			|||
        @click="increment()" | 
				
			|||
      > | 
				
			|||
        <fa icon="chevron-right" /> | 
				
			|||
      </div> | 
				
			|||
    </div> | 
				
			|||
 | 
				
			|||
    <div class="h-7 mt-4 flex"> | 
				
			|||
      <input | 
				
			|||
        v-if="projectId && !offeredToRecipient" | 
				
			|||
        type="checkbox" | 
				
			|||
        class="h-6 w-6 mr-2" | 
				
			|||
        v-model="offeredToProject" | 
				
			|||
      /> | 
				
			|||
      <fa | 
				
			|||
        v-else | 
				
			|||
        icon="square" | 
				
			|||
        class="bg-slate-500 text-slate-500 h-5 w-5 px-0.5 py-0.5 mr-2 rounded" | 
				
			|||
        @click="notifyUserOfProject()" | 
				
			|||
      /> | 
				
			|||
      <label class="text-sm mt-1"> | 
				
			|||
        {{ | 
				
			|||
          projectId | 
				
			|||
            ? "This was given to " + projectName | 
				
			|||
            : "No project was chosen" | 
				
			|||
        }} | 
				
			|||
      </label> | 
				
			|||
    </div> | 
				
			|||
 | 
				
			|||
    <div class="h-7 mt-4 flex"> | 
				
			|||
      <input | 
				
			|||
        v-if="recipientDid && !offeredToProject" | 
				
			|||
        type="checkbox" | 
				
			|||
        class="h-6 w-6 mr-2" | 
				
			|||
        v-model="offeredToRecipient" | 
				
			|||
      /> | 
				
			|||
      <fa | 
				
			|||
        v-else | 
				
			|||
        icon="square" | 
				
			|||
        class="bg-slate-500 text-slate-500 h-5 w-5 px-0.5 py-0.5 mr-2 rounded" | 
				
			|||
        @click="notifyUserOfRecipient()" | 
				
			|||
      /> | 
				
			|||
      <label class="text-sm mt-1"> | 
				
			|||
        {{ | 
				
			|||
          recipientDid | 
				
			|||
            ? "This was given to " + recipientName | 
				
			|||
            : "No recipient was chosen." | 
				
			|||
        }} | 
				
			|||
      </label> | 
				
			|||
    </div> | 
				
			|||
 | 
				
			|||
    <div class="mt-4 flex"> | 
				
			|||
      <router-link | 
				
			|||
        :to="{ | 
				
			|||
          name: 'claim-add-raw', | 
				
			|||
          query: { | 
				
			|||
            claim: constructOfferParam(), | 
				
			|||
          }, | 
				
			|||
        }" | 
				
			|||
        class="text-blue-500" | 
				
			|||
      > | 
				
			|||
        Edit & Submit Raw | 
				
			|||
      </router-link> | 
				
			|||
    </div> | 
				
			|||
 | 
				
			|||
    <p class="text-center mb-2 mt-6 italic"> | 
				
			|||
      Sign & Send to publish to the world | 
				
			|||
      <fa | 
				
			|||
        icon="circle-info" | 
				
			|||
        class="pl-2 text-blue-500 cursor-pointer" | 
				
			|||
        @click="explainData()" | 
				
			|||
      /> | 
				
			|||
    </p> | 
				
			|||
    <div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> | 
				
			|||
      <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" | 
				
			|||
      > | 
				
			|||
        Cancel | 
				
			|||
      </button> | 
				
			|||
    </div> | 
				
			|||
  </section> | 
				
			|||
</template> | 
				
			|||
 | 
				
			|||
<script lang="ts"> | 
				
			|||
import { Component, Vue } from "vue-facing-decorator"; | 
				
			|||
import { Router } from "vue-router"; | 
				
			|||
 | 
				
			|||
import QuickNav from "@/components/QuickNav.vue"; | 
				
			|||
import TopMessage from "@/components/TopMessage.vue"; | 
				
			|||
import { NotificationIface } from "@/constants/app"; | 
				
			|||
import { accountsDB, db } from "@/db/index"; | 
				
			|||
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings"; | 
				
			|||
import { | 
				
			|||
  createAndSubmitOffer, | 
				
			|||
  didInfo, | 
				
			|||
  editAndSubmitOffer, | 
				
			|||
  GenericCredWrapper, | 
				
			|||
  getPlanFromCache, | 
				
			|||
  hydrateOffer, | 
				
			|||
  OfferVerifiableCredential, | 
				
			|||
} from "@/libs/endorserServer"; | 
				
			|||
import * as libsUtil from "@/libs/util"; | 
				
			|||
import { Contact } from "@/db/tables/contacts"; | 
				
			|||
 | 
				
			|||
@Component({ | 
				
			|||
  components: { | 
				
			|||
    QuickNav, | 
				
			|||
    TopMessage, | 
				
			|||
  }, | 
				
			|||
}) | 
				
			|||
export default class OfferDetails extends Vue { | 
				
			|||
  $notify!: (notification: NotificationIface, timeout?: number) => void; | 
				
			|||
 | 
				
			|||
  activeDid = ""; | 
				
			|||
  apiServer = ""; | 
				
			|||
 | 
				
			|||
  amountInput = "0"; | 
				
			|||
  description = ""; | 
				
			|||
  destinationPathAfter = ""; | 
				
			|||
  offeredToProject = false; | 
				
			|||
  offeredToRecipient = false; | 
				
			|||
  giverDid: string | undefined; | 
				
			|||
  giverName = ""; | 
				
			|||
  hideBackButton = false; | 
				
			|||
  isTrade = false; | 
				
			|||
  message = ""; | 
				
			|||
  offerId = ""; | 
				
			|||
  prevCredToEdit?: GenericCredWrapper<OfferVerifiableCredential>; | 
				
			|||
  projectId = ""; | 
				
			|||
  projectName = "a project"; | 
				
			|||
  recipientDid = ""; | 
				
			|||
  recipientName = ""; | 
				
			|||
  unitCode = "HUR"; | 
				
			|||
  validThroughDate = null; | 
				
			|||
 | 
				
			|||
  libsUtil = libsUtil; | 
				
			|||
 | 
				
			|||
  async mounted() { | 
				
			|||
    try { | 
				
			|||
      this.prevCredToEdit = (this.$route as Router).query["prevCredToEdit"] | 
				
			|||
        ? (JSON.parse( | 
				
			|||
            (this.$route as Router).query["prevCredToEdit"], | 
				
			|||
          ) as GenericCredWrapper<OfferVerifiableCredential>) | 
				
			|||
        : undefined; | 
				
			|||
    } catch (error) { | 
				
			|||
      this.$notify( | 
				
			|||
        { | 
				
			|||
          group: "alert", | 
				
			|||
          type: "danger", | 
				
			|||
          title: "Retrieval Error", | 
				
			|||
          text: "The previous record isn't available for editing. If you submit, you'll create a new record.", | 
				
			|||
        }, | 
				
			|||
        6000, | 
				
			|||
      ); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    const prevAmount = this.prevCredToEdit?.claim?.object?.amountOfThisGood; | 
				
			|||
    this.amountInput = | 
				
			|||
      (this.$route as Router).query["amountInput"] || | 
				
			|||
      (prevAmount ? String(prevAmount) : "") || | 
				
			|||
      this.amountInput; | 
				
			|||
    this.description = | 
				
			|||
      (this.$route as Router).query["description"] || | 
				
			|||
      this.prevCredToEdit?.claim?.description || | 
				
			|||
      this.description; | 
				
			|||
    this.destinationPathAfter = (this.$route as Router).query[ | 
				
			|||
      "destinationPathAfter" | 
				
			|||
    ]; | 
				
			|||
    this.giverDid = ((this.$route as Router).query["giverDid"] || | 
				
			|||
      this.prevCredToEdit?.claim?.agent?.identifier || | 
				
			|||
      this.giverDid) as string; | 
				
			|||
    this.giverName = | 
				
			|||
      ((this.$route as Router).query["giverName"] 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"); | 
				
			|||
    this.projectId = ((this.$route as Router).query["projectId"] || | 
				
			|||
      project?.identifier || | 
				
			|||
      this.projectId) 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; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    try { | 
				
			|||
      await db.open(); | 
				
			|||
      const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings; | 
				
			|||
      this.apiServer = settings?.apiServer || ""; | 
				
			|||
      this.activeDid = settings?.activeDid || ""; | 
				
			|||
 | 
				
			|||
      let allContacts: Contact[] = []; | 
				
			|||
      let allMyDids: string[] = []; | 
				
			|||
      if ( | 
				
			|||
        (this.giverDid && !this.giverName) || | 
				
			|||
        (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, | 
				
			|||
            allMyDids, | 
				
			|||
            allContacts, | 
				
			|||
          ); | 
				
			|||
        } | 
				
			|||
      } | 
				
			|||
      this.offeredToProject = !!this.projectId; | 
				
			|||
      this.offeredToRecipient = !this.offeredToProject && !!this.recipientDid; | 
				
			|||
 | 
				
			|||
      // eslint-disable-next-line @typescript-eslint/no-explicit-any | 
				
			|||
    } catch (err: any) { | 
				
			|||
      console.error("Error retrieving settings from database:", err); | 
				
			|||
      this.$notify( | 
				
			|||
        { | 
				
			|||
          group: "alert", | 
				
			|||
          type: "danger", | 
				
			|||
          title: "Error", | 
				
			|||
          text: err.message || "There was an error retrieving your settings.", | 
				
			|||
        }, | 
				
			|||
        -1, | 
				
			|||
      ); | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    if (this.projectId) { | 
				
			|||
      // console.log("Getting project name from cache", this.projectId); | 
				
			|||
      const project = await getPlanFromCache( | 
				
			|||
        this.projectId, | 
				
			|||
        this.axios, | 
				
			|||
        this.apiServer, | 
				
			|||
        this.activeDid, | 
				
			|||
      ); | 
				
			|||
      this.projectName = project?.name | 
				
			|||
        ? "the project: " + project.name | 
				
			|||
        : "a project"; | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  changeUnitCode() { | 
				
			|||
    const units = Object.keys(this.libsUtil.UNIT_SHORT); | 
				
			|||
    const index = units.indexOf(this.unitCode); | 
				
			|||
    this.unitCode = units[(index + 1) % units.length]; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  increment() { | 
				
			|||
    this.amountInput = `${(parseFloat(this.amountInput) || 0) + 1}`; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  decrement() { | 
				
			|||
    this.amountInput = `${Math.max( | 
				
			|||
      0, | 
				
			|||
      (parseFloat(this.amountInput) || 1) - 1, | 
				
			|||
    )}`; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  cancel() { | 
				
			|||
    if (this.destinationPathAfter) { | 
				
			|||
      (this.$router as Router).push({ path: this.destinationPathAfter }); | 
				
			|||
    } else { | 
				
			|||
      (this.$router as Router).back(); | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  cancelBack() { | 
				
			|||
    (this.$router as Router).back(); | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  async confirm() { | 
				
			|||
    if (!this.activeDid) { | 
				
			|||
      this.$notify( | 
				
			|||
        { | 
				
			|||
          group: "alert", | 
				
			|||
          type: "danger", | 
				
			|||
          title: "Error", | 
				
			|||
          text: "You must select an identifier before you can record a offer.", | 
				
			|||
        }, | 
				
			|||
        2000, | 
				
			|||
      ); | 
				
			|||
      return; | 
				
			|||
    } | 
				
			|||
    if (parseFloat(this.amountInput) < 0) { | 
				
			|||
      this.$notify( | 
				
			|||
        { | 
				
			|||
          group: "alert", | 
				
			|||
          type: "danger", | 
				
			|||
          text: "You may not send a negative number.", | 
				
			|||
          title: "", | 
				
			|||
        }, | 
				
			|||
        2000, | 
				
			|||
      ); | 
				
			|||
      return; | 
				
			|||
    } | 
				
			|||
    if (!this.description && !parseFloat(this.amountInput)) { | 
				
			|||
      this.$notify( | 
				
			|||
        { | 
				
			|||
          group: "alert", | 
				
			|||
          type: "danger", | 
				
			|||
          title: "Error", | 
				
			|||
          text: `You must enter a description or some number of ${ | 
				
			|||
            this.libsUtil.UNIT_LONG[this.unitCode] | 
				
			|||
          }.`, | 
				
			|||
        }, | 
				
			|||
        2000, | 
				
			|||
      ); | 
				
			|||
      return; | 
				
			|||
    } | 
				
			|||
 | 
				
			|||
    this.$notify( | 
				
			|||
      { | 
				
			|||
        group: "alert", | 
				
			|||
        type: "toast", | 
				
			|||
        text: "Recording the give...", | 
				
			|||
        title: "", | 
				
			|||
      }, | 
				
			|||
      1000, | 
				
			|||
    ); | 
				
			|||
 | 
				
			|||
    // this is asynchronous, but we don't need to wait for it to complete | 
				
			|||
    await this.recordOffer(); | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  notifyUserOfProject() { | 
				
			|||
    if (!this.projectId) { | 
				
			|||
      this.$notify( | 
				
			|||
        { | 
				
			|||
          group: "alert", | 
				
			|||
          type: "warning", | 
				
			|||
          title: "Error", | 
				
			|||
          text: "To assign to a project, you must open this dialog through a project.", | 
				
			|||
        }, | 
				
			|||
        3000, | 
				
			|||
      ); | 
				
			|||
    } else { | 
				
			|||
      // must be because offeredToRecipient is true | 
				
			|||
      this.$notify( | 
				
			|||
        { | 
				
			|||
          group: "alert", | 
				
			|||
          type: "warning", | 
				
			|||
          title: "Error", | 
				
			|||
          text: "You cannot assign both to a project and to a recipient.", | 
				
			|||
        }, | 
				
			|||
        3000, | 
				
			|||
      ); | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  notifyUserOfRecipient() { | 
				
			|||
    if (!this.recipientDid) { | 
				
			|||
      this.$notify( | 
				
			|||
        { | 
				
			|||
          group: "alert", | 
				
			|||
          type: "warning", | 
				
			|||
          title: "Error", | 
				
			|||
          text: "To assign to a recipient, you must open this dialog from a contact.", | 
				
			|||
        }, | 
				
			|||
        3000, | 
				
			|||
      ); | 
				
			|||
    } else { | 
				
			|||
      // must be because offeredToProject is true | 
				
			|||
      this.$notify( | 
				
			|||
        { | 
				
			|||
          group: "alert", | 
				
			|||
          type: "warning", | 
				
			|||
          title: "Error", | 
				
			|||
          text: "You cannot assign both to a recipient and to a project.", | 
				
			|||
        }, | 
				
			|||
        3000, | 
				
			|||
      ); | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  /** | 
				
			|||
   * | 
				
			|||
   * @param giverDid may be null | 
				
			|||
   * @param description may be an empty string | 
				
			|||
   * @param amountInput may be 0 | 
				
			|||
   * @param unitCode may be omitted, defaults to "HUR" | 
				
			|||
   */ | 
				
			|||
  public async recordOffer() { | 
				
			|||
    try { | 
				
			|||
      const recipientDid = this.offeredToRecipient | 
				
			|||
        ? this.recipientDid | 
				
			|||
        : undefined; | 
				
			|||
      const projectId = this.offeredToProject ? this.projectId : undefined; | 
				
			|||
      let result; | 
				
			|||
      if (this.prevCredToEdit) { | 
				
			|||
        // don't create from a blank one in case some properties were set from a different interface | 
				
			|||
        result = await editAndSubmitOffer( | 
				
			|||
          this.axios, | 
				
			|||
          this.apiServer, | 
				
			|||
          this.prevCredToEdit, | 
				
			|||
          this.activeDid, | 
				
			|||
          this.description, | 
				
			|||
          parseFloat(this.amountInput), | 
				
			|||
          this.unitCode, | 
				
			|||
          this.validThroughDate, | 
				
			|||
          recipientDid, | 
				
			|||
          projectId, | 
				
			|||
        ); | 
				
			|||
      } else { | 
				
			|||
        result = await createAndSubmitOffer( | 
				
			|||
          this.axios, | 
				
			|||
          this.apiServer, | 
				
			|||
          this.activeDid, | 
				
			|||
          this.description, | 
				
			|||
          parseFloat(this.amountInput), | 
				
			|||
          this.unitCode, | 
				
			|||
          this.validThroughDate, | 
				
			|||
          recipientDid, | 
				
			|||
          projectId, | 
				
			|||
        ); | 
				
			|||
      } | 
				
			|||
 | 
				
			|||
      if (result.type === "error" || this.isCreationError(result.response)) { | 
				
			|||
        const errorMessage = this.getCreationErrorMessage(result); | 
				
			|||
        console.error("Error with give creation result:", result); | 
				
			|||
        this.$notify( | 
				
			|||
          { | 
				
			|||
            group: "alert", | 
				
			|||
            type: "danger", | 
				
			|||
            title: "Error", | 
				
			|||
            text: errorMessage || "There was an error creating the give.", | 
				
			|||
          }, | 
				
			|||
          -1, | 
				
			|||
        ); | 
				
			|||
      } else { | 
				
			|||
        this.$notify( | 
				
			|||
          { | 
				
			|||
            group: "alert", | 
				
			|||
            type: "success", | 
				
			|||
            title: "Success", | 
				
			|||
            text: `That ${this.isTrade ? "trade" : "gift"} was recorded.`, | 
				
			|||
          }, | 
				
			|||
          5000, | 
				
			|||
        ); | 
				
			|||
        localStorage.removeItem("imageUrl"); | 
				
			|||
        if (this.destinationPathAfter) { | 
				
			|||
          (this.$router as Router).push({ path: this.destinationPathAfter }); | 
				
			|||
        } else { | 
				
			|||
          (this.$router as Router).back(); | 
				
			|||
        } | 
				
			|||
      } | 
				
			|||
      // eslint-disable-next-line @typescript-eslint/no-explicit-any | 
				
			|||
    } catch (error: any) { | 
				
			|||
      console.error("Error with give recordation caught:", error); | 
				
			|||
      const errorMessage = | 
				
			|||
        error.userMessage || | 
				
			|||
        error.response?.data?.error?.message || | 
				
			|||
        "There was an error recording the give."; | 
				
			|||
      this.$notify( | 
				
			|||
        { | 
				
			|||
          group: "alert", | 
				
			|||
          type: "danger", | 
				
			|||
          title: "Error", | 
				
			|||
          text: errorMessage, | 
				
			|||
        }, | 
				
			|||
        -1, | 
				
			|||
      ); | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  constructOfferParam() { | 
				
			|||
    const recipientDid = this.offeredToRecipient | 
				
			|||
      ? this.recipientDid | 
				
			|||
      : undefined; | 
				
			|||
    const projectId = this.offeredToProject ? this.projectId : undefined; | 
				
			|||
    const giveClaim = hydrateOffer( | 
				
			|||
      this.prevCredToEdit?.claim as OfferVerifiableCredential, | 
				
			|||
      this.activeDid, | 
				
			|||
      recipientDid, | 
				
			|||
      this.description, | 
				
			|||
      parseFloat(this.amountInput), | 
				
			|||
      this.unitCode, | 
				
			|||
      "", | 
				
			|||
      projectId, | 
				
			|||
      this.validThroughDate, | 
				
			|||
      this.prevCredToEdit?.id as string, | 
				
			|||
    ); | 
				
			|||
    const claimStr = JSON.stringify(giveClaim); | 
				
			|||
    return claimStr; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  // Helper functions for readability | 
				
			|||
 | 
				
			|||
  /** | 
				
			|||
   * @param result response "data" from the server | 
				
			|||
   * @returns true if the result indicates an error | 
				
			|||
   */ | 
				
			|||
  // eslint-disable-next-line @typescript-eslint/no-explicit-any | 
				
			|||
  isCreationError(result: any) { | 
				
			|||
    return result.status !== 201 || result.data?.error; | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  /** | 
				
			|||
   * @param result direct response eg. ErrorResult or SuccessResult (potentially with embedded "data") | 
				
			|||
   * @returns best guess at an error message | 
				
			|||
   */ | 
				
			|||
  // eslint-disable-next-line @typescript-eslint/no-explicit-any | 
				
			|||
  getCreationErrorMessage(result: any) { | 
				
			|||
    return ( | 
				
			|||
      result.error?.userMessage || | 
				
			|||
      result.error?.error || | 
				
			|||
      result.response?.data?.error?.message | 
				
			|||
    ); | 
				
			|||
  } | 
				
			|||
 | 
				
			|||
  explainData() { | 
				
			|||
    this.$notify( | 
				
			|||
      { | 
				
			|||
        group: "alert", | 
				
			|||
        type: "success", | 
				
			|||
        title: "Data Sharing", | 
				
			|||
        text: libsUtil.PRIVACY_MESSAGE, | 
				
			|||
      }, | 
				
			|||
      -1, | 
				
			|||
    ); | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
</script> | 
				
			|||
					Loading…
					
					
				
		Reference in new issue