Browse Source

allow details on a give for a providing project (so we can attach a picture)

Trent Larson 2 months ago
parent
commit
625acb66f0
  1. 2
      src/components/GiftedDialog.vue
  2. 17
      src/libs/endorserServer.ts
  3. 20
      src/views/ClaimView.vue
  4. 2
      src/views/ConfirmGiftView.vue
  5. 249
      src/views/GiftedDetailsView.vue
  6. 94
      src/views/HomeView.vue
  7. 2
      src/views/QuickActionBvcBeginView.vue
  8. 94
      src/views/QuickActionBvcEndView.vue

2
src/components/GiftedDialog.vue

@ -47,7 +47,7 @@
giverDid: giver?.did, giverDid: giver?.did,
giverName: giver?.name, giverName: giver?.name,
offerId, offerId,
projectId, fulfillsProjectId: projectId,
recipientDid: receiver?.did, recipientDid: receiver?.did,
recipientName: receiver?.name, recipientName: receiver?.name,
unitCode, unitCode,

17
src/libs/endorserServer.ts

@ -91,6 +91,7 @@ export interface GiveSummaryRecord {
issuedAt: string; issuedAt: string;
issuerDid: string; issuerDid: string;
jwtId: string; jwtId: string;
providerPlanHandleId?: string;
recipientDid: string; recipientDid: string;
unit: string; unit: string;
} }
@ -530,7 +531,7 @@ const planCache: LRUCache<string, PlanSummaryRecord> = new LRUCache({
* @param apiServer * @param apiServer
*/ */
export async function getPlanFromCache( export async function getPlanFromCache(
handleId: string, handleId: string | undefined,
axios: Axios, axios: Axios,
apiServer: string, apiServer: string,
requesterDid?: string, requesterDid?: string,
@ -593,7 +594,7 @@ export function hydrateGive(
fulfillsOfferHandleId?: string, fulfillsOfferHandleId?: string,
isTrade: boolean = false, isTrade: boolean = false,
imageUrl?: string, imageUrl?: string,
providers?: Array<GenericVerifiableCredential>, // typically @type & identifier providerPlanHandleId?: string,
lastClaimId?: string, lastClaimId?: string,
): GiveVerifiableCredential { ): GiveVerifiableCredential {
// Remember: replace values or erase if it's null // Remember: replace values or erase if it's null
@ -652,7 +653,9 @@ export function hydrateGive(
vcClaim.image = imageUrl || undefined; vcClaim.image = imageUrl || undefined;
vcClaim.provider = providers || undefined; vcClaim.provider = providerPlanHandleId
? [{ "@type": "PlanAction", identifier: providerPlanHandleId }]
: undefined;
return vcClaim; return vcClaim;
} }
@ -678,7 +681,7 @@ export async function createAndSubmitGive(
fulfillsOfferHandleId?: string, fulfillsOfferHandleId?: string,
isTrade: boolean = false, isTrade: boolean = false,
imageUrl?: string, imageUrl?: string,
providers?: Array<GenericVerifiableCredential>, providerPlanHandleId?: string,
): Promise<CreateAndSubmitClaimResult> { ): Promise<CreateAndSubmitClaimResult> {
const vcClaim = hydrateGive( const vcClaim = hydrateGive(
undefined, undefined,
@ -691,7 +694,7 @@ export async function createAndSubmitGive(
fulfillsOfferHandleId, fulfillsOfferHandleId,
isTrade, isTrade,
imageUrl, imageUrl,
providers, providerPlanHandleId,
undefined, undefined,
); );
return createAndSubmitClaim( return createAndSubmitClaim(
@ -724,7 +727,7 @@ export async function editAndSubmitGive(
fulfillsOfferHandleId?: string, fulfillsOfferHandleId?: string,
isTrade: boolean = false, isTrade: boolean = false,
imageUrl?: string, imageUrl?: string,
providers?: Array<GenericVerifiableCredential>, providerPlanHandleId?: string,
): Promise<CreateAndSubmitClaimResult> { ): Promise<CreateAndSubmitClaimResult> {
const vcClaim = hydrateGive( const vcClaim = hydrateGive(
fullClaim.claim, fullClaim.claim,
@ -737,7 +740,7 @@ export async function editAndSubmitGive(
fulfillsOfferHandleId, fulfillsOfferHandleId,
isTrade, isTrade,
imageUrl, imageUrl,
providers, providerPlanHandleId,
fullClaim.id, fullClaim.id,
); );
return createAndSubmitClaim( return createAndSubmitClaim(

20
src/views/ClaimView.vue

@ -86,6 +86,15 @@
</a> </a>
</div> </div>
<div v-if="veriClaim.claimType === 'PlanAction'" class="mt-4">
<router-link
:to="'/project/' + encodeURIComponent(veriClaim.id)"
class="text-blue-500 mt-2"
>
Go to Project page
</router-link>
</div>
<!-- Fullfills Links --> <!-- Fullfills Links -->
<!-- fullfills links for a give --> <!-- fullfills links for a give -->
@ -159,18 +168,13 @@
" "
class="text-blue-500 mt-4 cursor-pointer" class="text-blue-500 mt-4 cursor-pointer"
> >
{{ an activity...
provider.identifier.startsWith("did:")
? "a person..."
: "an activity..."
}}
</a> </a>
</div> </div>
</div> </div>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@ -552,10 +556,11 @@ export default class ClaimView extends Vue {
this.fullClaimDump = ""; this.fullClaimDump = "";
this.fullClaimMessage = ""; this.fullClaimMessage = "";
this.isEditedGlobalId = false; this.isEditedGlobalId = false;
this.isRegistered = false;
this.numConfsNotVisible = 0; this.numConfsNotVisible = 0;
this.providersForGive = [];
this.veriClaim = serverUtil.BLANK_GENERIC_SERVER_RECORD; this.veriClaim = serverUtil.BLANK_GENERIC_SERVER_RECORD;
this.veriClaimDump = ""; this.veriClaimDump = "";
this.veriClaimDidsVisible = {};
} }
async created() { async created() {
@ -672,7 +677,6 @@ export default class ClaimView extends Vue {
this.apiServer + this.apiServer +
"/api/v2/report/providersToGive?handleId=" + "/api/v2/report/providersToGive?handleId=" +
encodeURIComponent(this.veriClaim.handleId as string); encodeURIComponent(this.veriClaim.handleId as string);
console.log("providerUrl:", providerUrl);
const providerHeaders = await serverUtil.getHeaders(userDid); const providerHeaders = await serverUtil.getHeaders(userDid);
const providerResp = await this.axios.get(providerUrl, { const providerResp = await this.axios.get(providerUrl, {
headers: providerHeaders, headers: providerHeaders,

2
src/views/ConfirmGiftView.vue

@ -655,7 +655,7 @@ export default class ClaimView extends Vue {
} }
if (this.giveDetails.fulfillsPlanHandleId) { if (this.giveDetails.fulfillsPlanHandleId) {
this.urlForNewGive += this.urlForNewGive +=
"&projectId=" + "&fulfillsProjectId=" +
encodeURIComponent(this.giveDetails.fulfillsPlanHandleId); encodeURIComponent(this.giveDetails.fulfillsPlanHandleId);
} }

249
src/views/GiftedDetailsView.vue

@ -21,12 +21,22 @@
<h1 class="text-4xl text-center font-light px-4 mb-4">What Was Given</h1> <h1 class="text-4xl text-center font-light px-4 mb-4">What Was Given</h1>
<h1 class="text-xl font-bold text-center mb-4"> <h1 class="text-xl font-bold text-center mb-4">
<span>From {{ giverName || "someone not named" }}</span> <span>
From
{{
providedByProject
? providerProjectName
: providedByGiver
? giverName
: "someone not named"
}}
</span>
<br />
<span> <span>
to to
{{ {{
givenToProject givenToProject
? projectName ? fulfillsProjectName
: givenToRecipient : givenToRecipient
? recipientName ? recipientName
: "someone unidentified" : "someone unidentified"
@ -87,7 +97,29 @@
<div class="h-7 mt-4 flex"> <div class="h-7 mt-4 flex">
<input <input
v-if="projectId && !givenToRecipient" v-if="providerProjectId && !providedByGiver"
type="checkbox"
class="h-6 w-6 mr-2"
v-model="providedByProject"
/>
<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="notifyUserOfProvidingProject()"
/>
<label class="text-sm mt-1">
{{
providerProjectId
? "This was provided by " + providerProjectName
: "This was not provided by a project"
}}
</label>
</div>
<div class="h-7 mt-4 flex">
<input
v-if="fulfillsProjectId && !givenToRecipient"
type="checkbox" type="checkbox"
class="h-6 w-6 mr-2" class="h-6 w-6 mr-2"
v-model="givenToProject" v-model="givenToProject"
@ -96,13 +128,13 @@
v-else v-else
icon="square" icon="square"
class="bg-slate-500 text-slate-500 h-5 w-5 px-0.5 py-0.5 mr-2 rounded" class="bg-slate-500 text-slate-500 h-5 w-5 px-0.5 py-0.5 mr-2 rounded"
@click="notifyUserOfProject()" @click="notifyUserFulfillsProject()"
/> />
<label class="text-sm mt-1"> <label class="text-sm mt-1">
{{ {{
projectId fulfillsProjectId
? "This was given to " + projectName ? "This was given to " + fulfillsProjectName
: "No project was chosen" : "No recipient project was chosen"
}} }}
</label> </label>
</div> </div>
@ -211,8 +243,10 @@ export default class GiftedDetails extends Vue {
amountInput = "0"; amountInput = "0";
description = ""; description = "";
destinationPathAfter = ""; destinationPathAfter = "";
givenToProject = false; fulfillsProjectId = "";
givenToRecipient = false; fulfillsProjectName = "a project";
givenToProject = false; // basically static, based on input; if we allow changing then let's fix things (see below)
givenToRecipient = false; // basically static, based on input; if we allow changing then let's fix things (see below)
giverDid: string | undefined; giverDid: string | undefined;
giverName = ""; giverName = "";
hideBackButton = false; hideBackButton = false;
@ -221,8 +255,10 @@ export default class GiftedDetails extends Vue {
message = ""; message = "";
offerId = ""; offerId = "";
prevCredToEdit?: GenericCredWrapper<GiveVerifiableCredential>; prevCredToEdit?: GenericCredWrapper<GiveVerifiableCredential>;
projectId = ""; providerProjectId = "";
projectName = "a project"; providerProjectName = "a project";
providedByProject = false; // basically static, based on input; if we allow changing then let's fix things (see below)
providedByGiver = false; // basically static, based on input; if we allow changing then let's fix things (see below)
recipientDid = ""; recipientDid = "";
recipientName = ""; recipientName = "";
showGeneralAdvanced = false; showGeneralAdvanced = false;
@ -282,11 +318,31 @@ export default class GiftedDetails extends Vue {
offer?.identifier || offer?.identifier ||
this.offerId) as string; this.offerId) as string;
// find any project ID // find any fulfills project ID
const project = fulfillsArray.find((rec) => rec["@type"] === "PlanAction"); const fulfillsProject = fulfillsArray.find(
this.projectId = ((this.$route as Router).query["projectId"] || (rec) => rec["@type"] === "PlanAction",
project?.identifier || );
this.projectId) as string; // eslint-disable-next-line prettier/prettier
this.fulfillsProjectId =
((this.$route as Router).query["fulfillsProjectId"] ||
fulfillsProject?.identifier ||
this.fulfillsProjectId) as string;
// find any provider project ID
const provider = this.prevCredToEdit?.claim?.provider;
const providerArray = Array.isArray(provider)
? provider
: provider
? [provider]
: [];
const providerProject = providerArray.find(
(rec) => rec["@type"] === "PlanAction",
);
this.providerProjectId = ((this.$route as Router).query[
"providerProjectId"
] ||
providerProject?.identifier ||
this.providerProjectId) as string;
this.recipientDid = ((this.$route as Router).query["recipientDid"] || this.recipientDid = ((this.$route as Router).query["recipientDid"] ||
this.prevCredToEdit?.claim?.recipient?.identifier) as string; this.prevCredToEdit?.claim?.recipient?.identifier) as string;
@ -318,69 +374,70 @@ export default class GiftedDetails extends Vue {
this.imageUrl = (this.$route as Router).query["shareUrl"] as string; this.imageUrl = (this.$route as Router).query["shareUrl"] as string;
} }
try { const settings = await retrieveSettingsForActiveAccount();
const settings = await retrieveSettingsForActiveAccount(); this.apiServer = settings.apiServer || "";
this.apiServer = settings.apiServer || ""; this.activeDid = settings.activeDid || "";
this.activeDid = settings.activeDid || "";
let allContacts: Contact[] = [];
let allContacts: Contact[] = []; let allMyDids: string[] = [];
let allMyDids: string[] = []; if (
if ( (this.giverDid && !this.giverName) ||
(this.giverDid && !this.giverName) || (this.recipientDid && !this.recipientName)
(this.recipientDid && !this.recipientName) ) {
) { allContacts = await db.contacts.toArray();
allContacts = await db.contacts.toArray();
await accountsDB.open();
await accountsDB.open(); const allAccounts = await accountsDB.accounts.toArray();
const allAccounts = await accountsDB.accounts.toArray(); allMyDids = allAccounts.map((acc) => acc.did);
allMyDids = allAccounts.map((acc) => acc.did); if (this.giverDid && !this.giverName) {
if (this.giverDid && !this.giverName) { this.giverName = didInfo(
this.giverName = didInfo( this.giverDid,
this.giverDid, this.activeDid,
this.activeDid, allMyDids,
allMyDids, allContacts,
allContacts, );
);
}
if (this.recipientDid && !this.recipientName) {
this.recipientName = didInfo(
this.recipientDid,
this.activeDid,
allMyDids,
allContacts,
);
}
} }
// these should be functions but something's wrong with the syntax in the <> conditional if (this.recipientDid && !this.recipientName) {
this.givenToProject = !!this.projectId; this.recipientName = didInfo(
this.givenToRecipient = !this.givenToProject && !!this.recipientDid; this.recipientDid,
this.activeDid,
allMyDids,
allContacts,
);
}
}
// these should be functions but something's wrong with the syntax in the <> conditional
this.givenToProject = !!this.fulfillsProjectId;
this.givenToRecipient = !this.givenToProject && !!this.recipientDid;
this.showGeneralAdvanced = !!settings.showGeneralAdvanced; // these should be functions but something's wrong with the syntax in the <> conditional
this.providedByProject = !!this.providerProjectId;
this.providedByGiver = !this.providedByProject && !!this.giverDid;
// eslint-disable-next-line @typescript-eslint/no-explicit-any this.showGeneralAdvanced = !!settings.showGeneralAdvanced;
} catch (err: any) {
console.error("Error retrieving settings from database:", err); if (this.fulfillsProjectId) {
this.$notify( // console.log("Getting project name from cache", this.fulfillsProjectId);
{ const fulfillsProject = await getPlanFromCache(
group: "alert", this.fulfillsProjectId,
type: "danger", this.axios,
title: "Error", this.apiServer,
text: err.message || "There was an error retrieving your settings.", this.activeDid,
},
-1,
); );
this.fulfillsProjectName = fulfillsProject?.name
? `the project "${fulfillsProject.name}"`
: "a project";
} }
if (this.providerProjectId) {
if (this.projectId) { // console.log("Getting project name from cache", this.providerProjectId);
// console.log("Getting project name from cache", this.projectId); const providerProject = await getPlanFromCache(
const project = await getPlanFromCache( this.providerProjectId,
this.projectId,
this.axios, this.axios,
this.apiServer, this.apiServer,
this.activeDid, this.activeDid,
); );
this.projectName = project?.name this.providerProjectName = providerProject?.name
? "the project: " + project.name ? `the project "${providerProject.name}"`
: "a project"; : "a project";
} }
} }
@ -545,8 +602,35 @@ export default class GiftedDetails extends Vue {
await this.recordGive(); await this.recordGive();
} }
notifyUserOfProject() { notifyUserOfProvidingProject() {
if (!this.projectId) { // we're here because they clicked and either there is no provider project or there is a giver chosen
if (!this.providerProjectId) {
this.$notify(
{
group: "alert",
type: "warning",
title: "Error",
text: "To select a project as a provider, you must open this page through a project.",
},
3000,
);
} else {
// no providing project was chosen
this.$notify(
{
group: "alert",
type: "warning",
title: "Error",
text: "You cannot select both a giving project and person.",
},
3000,
);
}
}
notifyUserFulfillsProject() {
// we're here because they clicked and either there is no fulfills project or there is a recipient chosen
if (!this.fulfillsProjectId) {
this.$notify( this.$notify(
{ {
group: "alert", group: "alert",
@ -557,7 +641,7 @@ export default class GiftedDetails extends Vue {
3000, 3000,
); );
} else { } else {
// must be because givenToRecipient is true // no fulfills project was chosen
this.$notify( this.$notify(
{ {
group: "alert", group: "alert",
@ -607,7 +691,9 @@ export default class GiftedDetails extends Vue {
const recipientDid = this.givenToRecipient const recipientDid = this.givenToRecipient
? this.recipientDid ? this.recipientDid
: undefined; : undefined;
const projectId = this.givenToProject ? this.projectId : undefined; const fulfillsProjectId = this.givenToProject
? this.fulfillsProjectId
: undefined;
let result; let result;
if (this.prevCredToEdit) { if (this.prevCredToEdit) {
// don't create from a blank one in case some properties were set from a different interface // don't create from a blank one in case some properties were set from a different interface
@ -621,10 +707,11 @@ export default class GiftedDetails extends Vue {
this.description, this.description,
parseFloat(this.amountInput), parseFloat(this.amountInput),
this.unitCode, this.unitCode,
projectId, fulfillsProjectId,
this.offerId, this.offerId,
this.isTrade, this.isTrade,
this.imageUrl, this.imageUrl,
this.providerProjectId,
); );
} else { } else {
result = await createAndSubmitGive( result = await createAndSubmitGive(
@ -636,11 +723,11 @@ export default class GiftedDetails extends Vue {
this.description, this.description,
parseFloat(this.amountInput), parseFloat(this.amountInput),
this.unitCode, this.unitCode,
projectId, fulfillsProjectId,
this.offerId, this.offerId,
this.isTrade, this.isTrade,
this.imageUrl, this.imageUrl,
[], this.providerProjectId,
); );
} }
@ -697,7 +784,9 @@ export default class GiftedDetails extends Vue {
constructGiveParam() { constructGiveParam() {
const recipientDid = this.givenToRecipient ? this.recipientDid : undefined; const recipientDid = this.givenToRecipient ? this.recipientDid : undefined;
const projectId = this.givenToProject ? this.projectId : undefined; const fulfillsProjectId = this.givenToProject
? this.fulfillsProjectId
: undefined;
const giveClaim = hydrateGive( const giveClaim = hydrateGive(
this.prevCredToEdit?.claim as GiveVerifiableCredential, this.prevCredToEdit?.claim as GiveVerifiableCredential,
this.giverDid, this.giverDid,
@ -705,11 +794,11 @@ export default class GiftedDetails extends Vue {
this.description, this.description,
parseFloat(this.amountInput), parseFloat(this.amountInput),
this.unitCode, this.unitCode,
projectId, fulfillsProjectId,
this.offerId, this.offerId,
this.isTrade, this.isTrade,
this.imageUrl, this.imageUrl,
[], this.providerProjectId,
this.prevCredToEdit?.id as string, this.prevCredToEdit?.id as string,
); );
const claimStr = JSON.stringify(giveClaim); const claimStr = JSON.stringify(giveClaim);

94
src/views/HomeView.vue

@ -282,6 +282,15 @@
> >
<fa icon="hammer" class="text-blue-500" /> <fa icon="hammer" class="text-blue-500" />
</router-link> </router-link>
<router-link
v-if="record.providerPlanHandleId"
:to="
'/project/' +
encodeURIComponent(record.providerPlanHandleId)
"
>
<fa icon="hammer" class="text-blue-500" />
</router-link>
</span> </span>
</div> </div>
<div v-if="record.image" class="flex justify-center"> <div v-if="record.image" class="flex justify-center">
@ -359,6 +368,7 @@ interface GiveRecordWithContactInfo extends GiveSummaryRecord {
profileImageUrl?: string; profileImageUrl?: string;
}; };
image?: string; image?: string;
providerPlanName?: string;
recipientProjectName?: string; recipientProjectName?: string;
receiver: { receiver: {
displayName: string; displayName: string;
@ -554,8 +564,8 @@ export default class HomeView extends Vue {
// This has indeed proven problematic. See loadMoreGives // This has indeed proven problematic. See loadMoreGives
// We should display it immediately and then get the plan later. // We should display it immediately and then get the plan later.
const plan = await getPlanFromCache( const fulfillsPlan = await getPlanFromCache(
record.fulfillsPlanHandleId || "", record.fulfillsPlanHandleId,
this.axios, this.axios,
this.apiServer, this.apiServer,
this.activeDid, this.activeDid,
@ -570,8 +580,13 @@ export default class HomeView extends Vue {
if (!anyMatch && this.isFeedFilteredByNearby) { if (!anyMatch && this.isFeedFilteredByNearby) {
// check if the associated project has a location inside user's search box // check if the associated project has a location inside user's search box
if (record.fulfillsPlanHandleId) { if (record.fulfillsPlanHandleId) {
if (plan?.locLat && plan?.locLon) { if (fulfillsPlan?.locLat && fulfillsPlan?.locLon) {
if (this.latLongInAnySearchBox(plan.locLat, plan.locLon)) { if (
this.latLongInAnySearchBox(
fulfillsPlan.locLat,
fulfillsPlan.locLon,
)
) {
anyMatch = true; anyMatch = true;
} }
} }
@ -581,6 +596,17 @@ export default class HomeView extends Vue {
continue; continue;
} }
// checking for arrays due to legacy data
const provider = Array.isArray(claim.provider)
? claim.provider[0]
: claim.provider;
const providedByPlan = await getPlanFromCache(
provider?.identifier as string,
this.axios,
this.apiServer,
this.activeDid,
);
const newRecord: GiveRecordWithContactInfo = { const newRecord: GiveRecordWithContactInfo = {
...record, ...record,
giver: didInfoForContact( giver: didInfoForContact(
@ -590,7 +616,9 @@ export default class HomeView extends Vue {
this.allMyDids, this.allMyDids,
), ),
image: claim.image, image: claim.image,
recipientProjectName: plan?.name as string, providerPlanHandleId: provider?.identifier as string,
providerPlanName: providedByPlan?.name as string,
recipientProjectName: fulfillsPlan?.name as string,
receiver: didInfoForContact( receiver: didInfoForContact(
recipientDid, recipientDid,
this.activeDid, this.activeDid,
@ -684,46 +712,62 @@ export default class HomeView extends Vue {
} }
/** /**
* Only show giver and/or receiver info first if they're named. * Only show giver and/or receiver info first if they're named in your contacts.
* - If only giver is named, show "... gave" * - If only giver is named, show "... gave"
* - If only receiver is named, show "... received" * - If only receiver is named, show "... received"
*/ */
const giverInfo = giveRecord.giver; const giverInfo = giveRecord.giver;
const recipientInfo = giveRecord.receiver; const recipientInfo = giveRecord.receiver;
// any specific names should be shown first
if (giverInfo.known && recipientInfo.known) { if (giverInfo.known && recipientInfo.known) {
// both giver and recipient are named // both giver and recipient are named
return `${giverInfo.displayName} gave to ${recipientInfo.displayName}: ${gaveAmount}`; return `${giverInfo.displayName} gave to ${recipientInfo.displayName}: ${gaveAmount}`;
} else if (giverInfo.known) { } else if (giverInfo.known) {
// giver is named but recipient is not // giver is known but recipient is not
// show the project name if to one // show the project name if to one
if (giveRecord.recipientProjectName) { if (giveRecord.recipientProjectName) {
// retrieve the project name return `${giverInfo.displayName} gave: ${gaveAmount} (to the project "${giveRecord.recipientProjectName}")`;
return `${giverInfo.displayName} gave: ${gaveAmount} (to the project ${giveRecord.recipientProjectName})`; } else {
// it's not to a project
return `${giverInfo.displayName} gave: ${gaveAmount} (to ${recipientInfo.displayName})`;
} }
// it's not to a project
return `${giverInfo.displayName} gave: ${gaveAmount} (to ${recipientInfo.displayName})`;
} else if (recipientInfo.known) { } else if (recipientInfo.known) {
// recipient is named but giver is not // recipient is known but giver is not
return `${recipientInfo.displayName} received: ${gaveAmount} (from ${giverInfo.displayName})`;
} else {
// neither giver nor recipient are named
// show the project name if to one // show the project name if from one
if (giveRecord.recipientProjectName) { if (giveRecord.providerPlanName) {
// retrieve the project name return `${giverInfo.displayName} received: ${gaveAmount} (from the project "${giveRecord.providerPlanName}")`;
return `${gaveAmount} (to the project ${giveRecord.recipientProjectName})`; } else {
// it's not from a project
return `${recipientInfo.displayName} received: ${gaveAmount} (from ${giverInfo.displayName})`;
} }
} else {
// neither giver nor recipient are named
// it's not to a project // create the part in parens
let peopleInfo; let peopleInfo = "";
if (giverInfo.displayName === recipientInfo.displayName) { if (giveRecord.providerPlanName || giveRecord.recipientProjectName) {
peopleInfo = `between two who are ${giverInfo.displayName}`; if (giveRecord.providerPlanName) {
peopleInfo = `from the project "${giveRecord.providerPlanName}"`;
} else {
peopleInfo = `from ${giverInfo.displayName}`;
}
if (giveRecord.recipientProjectName) {
peopleInfo += ` to the project "${giveRecord.recipientProjectName}"`;
} else {
peopleInfo += ` to ${recipientInfo.displayName}`;
}
} else { } else {
peopleInfo = `from ${giverInfo.displayName} to ${recipientInfo.displayName}`; if (giverInfo.displayName === recipientInfo.displayName) {
peopleInfo = `between two who are ${giverInfo.displayName}`;
} else {
peopleInfo = `from ${giverInfo.displayName} to ${recipientInfo.displayName}`;
}
} }
return gaveAmount + " (" + peopleInfo + ")"; return gaveAmount + " (" + peopleInfo + ")";
} }
} }

2
src/views/QuickActionBvcBeginView.vue

@ -67,6 +67,7 @@
<script lang="ts"> <script lang="ts">
import axios from "axios"; import axios from "axios";
import { DateTime } from "luxon"; import { DateTime } from "luxon";
import { Router } from "vue-router";
import { Component, Vue } from "vue-facing-decorator"; import { Component, Vue } from "vue-facing-decorator";
import QuickNav from "@/components/QuickNav.vue"; import QuickNav from "@/components/QuickNav.vue";
@ -200,6 +201,7 @@ export default class QuickActionBvcBeginView extends Vue {
}, },
3000, 3000,
); );
(this.$router as Router).push({ path: "/quick-action-bvc" });
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any

94
src/views/QuickActionBvcEndView.vue

@ -106,7 +106,8 @@
class="border border-slate-400 h-6 px-2" class="border border-slate-400 h-6 px-2"
/> />
<br /> <br />
(Everyone likes personalized messages! 😁) (Everyone likes personalized messages! 😁 ... and for a pic:
<input type="checkbox" v-model="supplyGiftDetails" />)
</span> </span>
<!-- This is to match input height to avoid shifting when hiding & showing. --> <!-- This is to match input height to avoid shifting when hiding & showing. -->
<span v-else class="h-6">...</span> <span v-else class="h-6">...</span>
@ -179,6 +180,7 @@ export default class QuickActionBvcBeginView extends Vue {
description = "breakfast"; description = "breakfast";
loadingConfirms = true; loadingConfirms = true;
someoneGave = false; someoneGave = false;
supplyGiftDetails = false;
async created() { async created() {
this.loadingConfirms = true; this.loadingConfirms = true;
@ -262,7 +264,9 @@ export default class QuickActionBvcBeginView extends Vue {
async record() { async record() {
try { try {
this.$notify({ group: "alert", type: "toast", title: "Sent..." }, 1000); if (this.claimsToConfirmSelected.length > 0) {
this.$notify({ group: "alert", type: "toast", title: "Sent..." }, 1000);
}
// in parallel, make a confirmation for each selected claim and send them all to the server // in parallel, make a confirmation for each selected claim and send them all to the server
const confirmResults = await Promise.allSettled( const confirmResults = await Promise.allSettled(
@ -304,13 +308,7 @@ export default class QuickActionBvcBeginView extends Vue {
// now send the give for the description // now send the give for the description
let giveSucceeded = false; let giveSucceeded = false;
if (this.someoneGave) { if (this.someoneGave && !this.supplyGiftDetails) {
const providers: Array<GenericVerifiableCredential> = [
{
"@type": "PlanAction",
identifier: BVC_MEETUPS_PROJECT_CLAIM_ID,
},
];
const giveResult = await createAndSubmitGive( const giveResult = await createAndSubmitGive(
axios, axios,
this.apiServer, this.apiServer,
@ -324,7 +322,7 @@ export default class QuickActionBvcBeginView extends Vue {
undefined, undefined,
false, false,
undefined, undefined,
providers, BVC_MEETUPS_PROJECT_CLAIM_ID,
); );
giveSucceeded = giveResult.type === "success"; giveSucceeded = giveResult.type === "success";
if (!giveSucceeded) { if (!giveSucceeded) {
@ -342,29 +340,61 @@ export default class QuickActionBvcBeginView extends Vue {
); );
} }
} }
if (this.someoneGave && this.supplyGiftDetails) {
if (confirmsSucceeded.length > 0 || giveSucceeded) { // we'll give a success message for the confirmations and go to the gifted details page
const confirms = if (confirmsSucceeded.length > 0) {
confirmsSucceeded.length === 1 ? "confirmation" : "confirmations"; const actions =
const actions = confirmsSucceeded.length === 1
confirmsSucceeded.length > 0 && giveSucceeded ? `Your confirmation has been recorded.`
? `Your ${confirms} and that give have been recorded.` : `Your confirmations have been recorded.`;
: giveSucceeded this.$notify(
? "That give has been recorded." {
: "Your " + group: "alert",
confirms + type: "success",
" " + title: "Success",
(confirmsSucceeded.length === 1 ? "has" : "have") + text: actions,
" been recorded."; },
this.$notify( 3000,
{ );
group: "alert", }
type: "success", (this.$router as Router).push({
title: "Success", name: "gifted-details",
text: actions, query: {
description: this.description,
destinationPathAfter: "/",
providerProjectId:
"https://endorser.ch/entity/01J8XW5SE5NJZ34TQCC10FC18B", //BVC_MEETUPS_PROJECT_CLAIM_ID,
recipientDid: this.activeDid,
}, },
3000, });
); } else {
// just go ahead and print a message for all the activity
if (confirmsSucceeded.length > 0 || giveSucceeded) {
const confirms =
confirmsSucceeded.length === 1 ? "confirmation" : "confirmations";
const actions =
confirmsSucceeded.length > 0 && giveSucceeded
? `Your ${confirms} and that give have been recorded.`
: giveSucceeded
? "That give has been recorded."
: "Your " +
confirms +
" " +
(confirmsSucceeded.length === 1 ? "has" : "have") +
" been recorded.";
this.$notify(
{
group: "alert",
type: "success",
title: "Success",
text: actions,
},
3000,
);
(this.$router as Router).push({ path: "/" });
} else {
// errors should have already shown
}
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any

Loading…
Cancel
Save