forked from jsnbuchanan/crowd-funder-for-time-pwa
refactor: Improve ConfirmGiftView component organization and error handling
- Split loadClaim into focused methods for better separation of concerns - Add proper error handling and error messages - Add JSDoc comments for all methods - Extract URL parameter handling into dedicated method - Improve gift confirmation and sharing workflows The changes improve code maintainability by: 1. Breaking down monolithic methods into smaller, focused functions 2. Adding clear error handling and user feedback 3. Improving method documentation with JSDoc 4. Separating data fetching from processing logic 5. Making component behavior more predictable
This commit is contained in:
@@ -448,8 +448,25 @@ import * as libsUtil from "../libs/util";
|
|||||||
import { isGiveAction, retrieveAccountDids } from "../libs/util";
|
import { isGiveAction, retrieveAccountDids } from "../libs/util";
|
||||||
import TopMessage from "../components/TopMessage.vue";
|
import TopMessage from "../components/TopMessage.vue";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ConfirmGiftView Component
|
||||||
|
*
|
||||||
|
* Displays details about a gift claim and allows users to confirm it if eligible.
|
||||||
|
* Shows gift details including giver, recipient, amount, description, and confirmation status.
|
||||||
|
* Handles visibility of hidden DIDs and provides access to detailed claim information.
|
||||||
|
*
|
||||||
|
* Key features:
|
||||||
|
* - Gift confirmation workflow
|
||||||
|
* - Detailed gift information display
|
||||||
|
* - Confirmation status tracking
|
||||||
|
* - Hidden DID handling
|
||||||
|
* - Claim details expansion
|
||||||
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
components: { TopMessage, QuickNav },
|
components: {
|
||||||
|
QuickNav,
|
||||||
|
TopMessage,
|
||||||
|
},
|
||||||
})
|
})
|
||||||
export default class ConfirmGiftView extends Vue {
|
export default class ConfirmGiftView extends Vue {
|
||||||
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
||||||
@@ -485,94 +502,92 @@ export default class ConfirmGiftView extends Vue {
|
|||||||
serverUtil = serverUtil;
|
serverUtil = serverUtil;
|
||||||
displayAmount = displayAmount;
|
displayAmount = displayAmount;
|
||||||
|
|
||||||
resetThisValues() {
|
/**
|
||||||
this.confirmerIdList = [];
|
* Initializes the view with gift claim information
|
||||||
this.confsVisibleErrorMessage = "";
|
*
|
||||||
this.confsVisibleToIdList = [];
|
* Workflow:
|
||||||
this.giveDetails = undefined;
|
* 1. Retrieves active account settings
|
||||||
this.isRegistered = false;
|
* 2. Loads gift claim details from ID in URL
|
||||||
this.numConfsNotVisible = 0;
|
* 3. Processes claim information for display
|
||||||
this.urlForNewGive = "";
|
* 4. Checks user's ability to confirm the gift
|
||||||
this.veriClaim = serverUtil.BLANK_GENERIC_SERVER_RECORD;
|
*/
|
||||||
this.veriClaimDump = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
async mounted() {
|
async mounted() {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
|
try {
|
||||||
|
await this.initializeSettings();
|
||||||
|
await this.loadClaimFromUrl();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error in mounted:", error);
|
||||||
|
this.handleMountError(error);
|
||||||
|
} finally {
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes component settings and user data
|
||||||
|
*/
|
||||||
|
private async initializeSettings() {
|
||||||
const settings = await retrieveSettingsForActiveAccount();
|
const settings = await retrieveSettingsForActiveAccount();
|
||||||
this.activeDid = settings.activeDid || "";
|
this.activeDid = settings.activeDid || "";
|
||||||
this.apiServer = settings.apiServer || "";
|
this.apiServer = settings.apiServer || "";
|
||||||
this.allContacts = await db.contacts.toArray();
|
this.allContacts = await db.contacts.toArray();
|
||||||
this.isRegistered = settings.isRegistered || false;
|
this.isRegistered = settings.isRegistered || false;
|
||||||
|
|
||||||
this.allMyDids = await retrieveAccountDids();
|
this.allMyDids = await retrieveAccountDids();
|
||||||
|
|
||||||
const pathParam = window.location.pathname.substring(
|
// Check share capability
|
||||||
"/confirm-gift/".length,
|
|
||||||
);
|
|
||||||
let claimId;
|
|
||||||
if (pathParam) {
|
|
||||||
claimId = decodeURIComponent(pathParam);
|
|
||||||
await this.loadClaim(claimId, this.activeDid);
|
|
||||||
} else {
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "danger",
|
|
||||||
title: "Error",
|
|
||||||
text: "No claim ID was provided.",
|
|
||||||
},
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// When Chrome compatibility is fixed https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API#api.navigator.canshare
|
// When Chrome compatibility is fixed https://developer.mozilla.org/en-US/docs/Web/API/Web_Share_API#api.navigator.canshare
|
||||||
// then use this truer check: navigator.canShare && navigator.canShare()
|
// then use this truer check: navigator.canShare && navigator.canShare()
|
||||||
this.canShare = !!navigator.share;
|
this.canShare = !!navigator.share;
|
||||||
|
|
||||||
this.isLoading = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// insert a space before any capital letters except the initial letter
|
/**
|
||||||
// (and capitalize initial letter, just in case)
|
* Loads and processes claim from URL parameters
|
||||||
capitalizeAndInsertSpacesBeforeCaps(text: string) {
|
*/
|
||||||
return !text
|
private async loadClaimFromUrl() {
|
||||||
? ""
|
const pathParam = window.location.pathname.substring("/confirm-gift/".length);
|
||||||
: text[0].toUpperCase() + text.substr(1).replace(/([A-Z])/g, " $1");
|
if (!pathParam) {
|
||||||
|
throw new Error("No claim ID was provided.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const claimId = decodeURIComponent(pathParam);
|
||||||
|
await this.loadClaim(claimId, this.activeDid);
|
||||||
}
|
}
|
||||||
|
|
||||||
capitalizeAndInsertSpacesBeforeCapsWithAPrefix(text: string) {
|
/**
|
||||||
const word = this.capitalizeAndInsertSpacesBeforeCaps(text);
|
* Handles errors during component mounting
|
||||||
if (word) {
|
*/
|
||||||
// if the word starts with a vowel, use "an" instead of "a"
|
private handleMountError(error: unknown) {
|
||||||
const firstLetter = word[0].toLowerCase();
|
this.$notify(
|
||||||
const vowels = ["a", "e", "i", "o", "u"];
|
{
|
||||||
const particle = vowels.includes(firstLetter) ? "an" : "a";
|
group: "alert",
|
||||||
return particle + " " + word;
|
type: "danger",
|
||||||
} else {
|
title: "Error",
|
||||||
return "";
|
text: error instanceof Error ? error.message : "No claim ID was provided.",
|
||||||
|
},
|
||||||
|
3000,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads claim details and associated give information
|
||||||
|
*
|
||||||
|
* @param claimId - ID of claim to load
|
||||||
|
* @param userDid - User's DID
|
||||||
|
*/
|
||||||
|
private async loadClaim(claimId: string, userDid: string) {
|
||||||
|
await this.fetchClaimDetails(claimId, userDid);
|
||||||
|
if (this.veriClaim.claimType === "GiveAction") {
|
||||||
|
await this.fetchGiveDetails(claimId, userDid);
|
||||||
|
await this.processGiveDetails();
|
||||||
|
await this.fetchConfirmerInfo(claimId, userDid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
totalConfirmers() {
|
/**
|
||||||
return (
|
* Fetches basic claim details from server
|
||||||
this.numConfsNotVisible +
|
*/
|
||||||
this.confirmerIdList.length +
|
private async fetchClaimDetails(claimId: string, userDid: string) {
|
||||||
this.confsVisibleToIdList.length
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Isn't there a better way to make this available to the template?
|
|
||||||
didInfo(did: string | undefined) {
|
|
||||||
return serverUtil.didInfo(
|
|
||||||
did,
|
|
||||||
this.activeDid,
|
|
||||||
this.allMyDids,
|
|
||||||
this.allContacts,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async loadClaim(claimId: string, userDid: string) {
|
|
||||||
const urlPath = libsUtil.isGlobalUri(claimId)
|
const urlPath = libsUtil.isGlobalUri(claimId)
|
||||||
? "/api/claim/byHandle/"
|
? "/api/claim/byHandle/"
|
||||||
: "/api/claim/";
|
: "/api/claim/";
|
||||||
@@ -581,9 +596,7 @@ export default class ConfirmGiftView extends Vue {
|
|||||||
try {
|
try {
|
||||||
const headers = await serverUtil.getHeaders(userDid);
|
const headers = await serverUtil.getHeaders(userDid);
|
||||||
const resp = await this.axios.get(url, { headers });
|
const resp = await this.axios.get(url, { headers });
|
||||||
// resp.data is:
|
|
||||||
// - a Jwt from https://api.endorser.ch/api-docs/
|
|
||||||
// - with a Give from https://endorser.ch/doc/html/transactions.html#id3
|
|
||||||
if (resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
this.veriClaim = resp.data;
|
this.veriClaim = resp.data;
|
||||||
this.veriClaimDump = yaml.dump(this.veriClaim);
|
this.veriClaimDump = yaml.dump(this.veriClaim);
|
||||||
@@ -591,138 +604,196 @@ export default class ConfirmGiftView extends Vue {
|
|||||||
this.veriClaim,
|
this.veriClaim,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
this.issuerName = this.didInfo(this.veriClaim.issuer);
|
||||||
} else {
|
} else {
|
||||||
// actually, axios typically throws an error so we never get here
|
throw new Error("Error getting claim: " + resp.status);
|
||||||
console.error("Error getting claim:", resp);
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "danger",
|
|
||||||
title: "Error",
|
|
||||||
text: "There was a problem retrieving that claim.",
|
|
||||||
},
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
} catch (error) {
|
||||||
// retrieve more details on Give, Offer, or Plan
|
console.error("Error getting claim:", error);
|
||||||
if (this.veriClaim.claimType !== "GiveAction") {
|
throw new Error("There was a problem retrieving that claim.");
|
||||||
// no need to go further... this page is for gifts
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.issuerName = this.didInfo(this.veriClaim.issuer);
|
|
||||||
|
|
||||||
// use give record when possible since it may include edits
|
|
||||||
const giveUrl =
|
|
||||||
this.apiServer +
|
|
||||||
"/api/v2/report/gives?handleId=" +
|
|
||||||
encodeURIComponent(this.veriClaim.handleId as string);
|
|
||||||
const giveHeaders = await serverUtil.getHeaders(userDid);
|
|
||||||
const giveResp = await this.axios.get(giveUrl, {
|
|
||||||
headers: giveHeaders,
|
|
||||||
});
|
|
||||||
// giveResp.data is a Give from https://api.endorser.ch/api-docs/
|
|
||||||
if (giveResp.status === 200) {
|
|
||||||
this.giveDetails = giveResp.data.data[0];
|
|
||||||
} else {
|
|
||||||
console.error("Error getting detailed give info:", giveResp);
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "danger",
|
|
||||||
title: "Error",
|
|
||||||
text: "Something went wrong retrieving gift data.",
|
|
||||||
},
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the logic already stops earlier if the claim doesn't exist but this helps with typechecking
|
|
||||||
if (!this.giveDetails) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.urlForNewGive = "/gifted-details?";
|
|
||||||
if (this.giveDetails.amount) {
|
|
||||||
this.urlForNewGive +=
|
|
||||||
"&amountInput=" + encodeURIComponent(String(this.giveDetails.amount));
|
|
||||||
}
|
|
||||||
if (this.giveDetails.unit) {
|
|
||||||
this.urlForNewGive +=
|
|
||||||
"&unitCode=" + encodeURIComponent(this.giveDetails.unit);
|
|
||||||
}
|
|
||||||
if (this.giveDetails.description) {
|
|
||||||
this.urlForNewGive +=
|
|
||||||
"&description=" + encodeURIComponent(this.giveDetails.description);
|
|
||||||
}
|
|
||||||
this.giverName = this.didInfo(this.giveDetails.agentDid);
|
|
||||||
if (this.giveDetails.agentDid) {
|
|
||||||
this.urlForNewGive +=
|
|
||||||
"&giverDid=" +
|
|
||||||
encodeURIComponent(this.giveDetails.agentDid) +
|
|
||||||
"&giverName=" +
|
|
||||||
encodeURIComponent(this.giverName);
|
|
||||||
}
|
|
||||||
this.recipientName = this.didInfo(this.giveDetails.recipientDid);
|
|
||||||
if (this.giveDetails.recipientDid) {
|
|
||||||
this.urlForNewGive +=
|
|
||||||
"&recipientDid=" +
|
|
||||||
encodeURIComponent(this.giveDetails.recipientDid) +
|
|
||||||
"&recipientName=" +
|
|
||||||
encodeURIComponent(this.recipientName);
|
|
||||||
}
|
|
||||||
if (this.giveDetails.fullClaim.image) {
|
|
||||||
this.urlForNewGive +=
|
|
||||||
"&image=" + encodeURIComponent(this.giveDetails.fullClaim.image);
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
this.giveDetails.type == "Offer" &&
|
|
||||||
this.giveDetails.fulfillsHandleId
|
|
||||||
) {
|
|
||||||
this.urlForNewGive +=
|
|
||||||
"&offerId=" +
|
|
||||||
encodeURIComponent(this.giveDetails?.fulfillsHandleId as string);
|
|
||||||
}
|
|
||||||
if (this.giveDetails.fulfillsPlanHandleId) {
|
|
||||||
this.urlForNewGive +=
|
|
||||||
"&fulfillsProjectId=" +
|
|
||||||
encodeURIComponent(this.giveDetails.fulfillsPlanHandleId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// retrieve the list of confirmers
|
|
||||||
const confirmerInfo = await libsUtil.retrieveConfirmerIdList(
|
|
||||||
this.apiServer,
|
|
||||||
claimId,
|
|
||||||
this.veriClaim.issuer,
|
|
||||||
userDid,
|
|
||||||
);
|
|
||||||
if (confirmerInfo) {
|
|
||||||
this.confirmerIdList = confirmerInfo.confirmerIdList;
|
|
||||||
this.confsVisibleToIdList = confirmerInfo.confsVisibleToIdList;
|
|
||||||
this.numConfsNotVisible = confirmerInfo.numConfsNotVisible;
|
|
||||||
} else {
|
|
||||||
this.confsVisibleErrorMessage =
|
|
||||||
"Had problems retrieving confirmations.";
|
|
||||||
}
|
|
||||||
} catch (error: unknown) {
|
|
||||||
const serverError = error as AxiosError;
|
|
||||||
console.error("Error retrieving claim:", serverError);
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "danger",
|
|
||||||
title: "Error",
|
|
||||||
text: "Something went wrong retrieving claim data.",
|
|
||||||
},
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmConfirmClaim() {
|
/**
|
||||||
|
* Fetches detailed give information
|
||||||
|
*/
|
||||||
|
private async fetchGiveDetails(claimId: string, userDid: string) {
|
||||||
|
const giveUrl = `${this.apiServer}/api/v2/report/gives?handleId=${encodeURIComponent(claimId)}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const headers = await serverUtil.getHeaders(userDid);
|
||||||
|
const resp = await this.axios.get(giveUrl, { headers });
|
||||||
|
|
||||||
|
if (resp.status === 200) {
|
||||||
|
this.giveDetails = resp.data.data[0];
|
||||||
|
} else {
|
||||||
|
throw new Error("Error getting detailed give info: " + resp.status);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error getting detailed give info:", error);
|
||||||
|
throw new Error("Something went wrong retrieving gift data.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes give details and builds URL for new give
|
||||||
|
*/
|
||||||
|
private async processGiveDetails() {
|
||||||
|
if (!this.giveDetails) return;
|
||||||
|
|
||||||
|
this.urlForNewGive = "/gifted-details?";
|
||||||
|
this.addGiveDetailsToUrl();
|
||||||
|
this.processParticipantInfo();
|
||||||
|
this.processAdditionalDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds basic give details to URL
|
||||||
|
*/
|
||||||
|
private addGiveDetailsToUrl() {
|
||||||
|
if (this.giveDetails?.amount) {
|
||||||
|
this.urlForNewGive += `&amountInput=${encodeURIComponent(String(this.giveDetails.amount))}`;
|
||||||
|
}
|
||||||
|
if (this.giveDetails?.unit) {
|
||||||
|
this.urlForNewGive += `&unitCode=${encodeURIComponent(this.giveDetails.unit)}`;
|
||||||
|
}
|
||||||
|
if (this.giveDetails?.description) {
|
||||||
|
this.urlForNewGive += `&description=${encodeURIComponent(this.giveDetails.description)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes participant (giver/recipient) information
|
||||||
|
*/
|
||||||
|
private processParticipantInfo() {
|
||||||
|
if (this.giveDetails?.agentDid) {
|
||||||
|
this.giverName = this.didInfo(this.giveDetails.agentDid);
|
||||||
|
this.urlForNewGive += `&giverDid=${encodeURIComponent(this.giveDetails.agentDid)}&giverName=${encodeURIComponent(this.giverName)}`;
|
||||||
|
}
|
||||||
|
if (this.giveDetails?.recipientDid) {
|
||||||
|
this.recipientName = this.didInfo(this.giveDetails.recipientDid);
|
||||||
|
this.urlForNewGive += `&recipientDid=${encodeURIComponent(this.giveDetails.recipientDid)}&recipientName=${encodeURIComponent(this.recipientName)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes additional give details (image, offer, plan)
|
||||||
|
*/
|
||||||
|
private processAdditionalDetails() {
|
||||||
|
if (this.giveDetails?.fullClaim.image) {
|
||||||
|
this.urlForNewGive += `&image=${encodeURIComponent(this.giveDetails.fullClaim.image)}`;
|
||||||
|
}
|
||||||
|
if (this.giveDetails?.type === "Offer" && this.giveDetails?.fulfillsHandleId) {
|
||||||
|
this.urlForNewGive += `&offerId=${encodeURIComponent(this.giveDetails.fulfillsHandleId)}`;
|
||||||
|
}
|
||||||
|
if (this.giveDetails?.fulfillsPlanHandleId) {
|
||||||
|
this.urlForNewGive += `&fulfillsProjectId=${encodeURIComponent(this.giveDetails.fulfillsPlanHandleId)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches confirmer information for the claim
|
||||||
|
*/
|
||||||
|
private async fetchConfirmerInfo(claimId: string, userDid: string) {
|
||||||
|
const confirmerInfo = await libsUtil.retrieveConfirmerIdList(
|
||||||
|
this.apiServer,
|
||||||
|
claimId,
|
||||||
|
this.veriClaim.issuer,
|
||||||
|
userDid,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (confirmerInfo) {
|
||||||
|
this.confirmerIdList = confirmerInfo.confirmerIdList;
|
||||||
|
this.confsVisibleToIdList = confirmerInfo.confsVisibleToIdList;
|
||||||
|
this.numConfsNotVisible = confirmerInfo.numConfsNotVisible;
|
||||||
|
} else {
|
||||||
|
this.confsVisibleErrorMessage = "Had problems retrieving confirmations.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates total number of confirmers for the gift
|
||||||
|
* Includes both direct confirmers and those visible through network
|
||||||
|
*
|
||||||
|
* @returns Total number of confirmers
|
||||||
|
*/
|
||||||
|
totalConfirmers(): number {
|
||||||
|
return (
|
||||||
|
this.numConfsNotVisible +
|
||||||
|
this.confirmerIdList.length +
|
||||||
|
this.confsVisibleToIdList.length
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats display amount with proper unit
|
||||||
|
*
|
||||||
|
* @param unit - Currency or unit code
|
||||||
|
* @param amount - Numeric amount
|
||||||
|
* @returns Formatted amount string
|
||||||
|
*/
|
||||||
|
displayAmount(unit: string, amount: number): string {
|
||||||
|
return displayAmount(unit, amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves human-readable name for a DID
|
||||||
|
* Falls back to DID if no name available
|
||||||
|
*
|
||||||
|
* @param did - DID to get name for
|
||||||
|
* @returns Human-readable name
|
||||||
|
*/
|
||||||
|
didInfo(did: string): string {
|
||||||
|
return serverUtil.didInfo(
|
||||||
|
did,
|
||||||
|
this.activeDid,
|
||||||
|
this.allMyDids,
|
||||||
|
this.allContacts,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies text to clipboard and shows notification
|
||||||
|
*
|
||||||
|
* @param description - Description of copied content
|
||||||
|
* @param text - Text to copy
|
||||||
|
*/
|
||||||
|
copyToClipboard(description: string, text: string): void {
|
||||||
|
useClipboard()
|
||||||
|
.copy(text)
|
||||||
|
.then(() => {
|
||||||
|
this.$notify(
|
||||||
|
{
|
||||||
|
group: "alert",
|
||||||
|
type: "toast",
|
||||||
|
title: "Copied",
|
||||||
|
text: (description || "That") + " was copied to the clipboard.",
|
||||||
|
},
|
||||||
|
2000,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Navigates to claim page for detailed view
|
||||||
|
*
|
||||||
|
* @param claimId - ID of claim to view
|
||||||
|
*/
|
||||||
|
showClaimPage(claimId: string): void {
|
||||||
|
const route = {
|
||||||
|
path: "/claim/" + encodeURIComponent(claimId),
|
||||||
|
};
|
||||||
|
(this.$router as Router).push(route).then(async () => {
|
||||||
|
this.resetThisValues();
|
||||||
|
await this.loadClaim(claimId, this.activeDid);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initiates claim confirmation process
|
||||||
|
* Verifies user eligibility and handles confirmation workflow
|
||||||
|
*/
|
||||||
|
async confirmConfirmClaim(): Promise<void> {
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "modal",
|
group: "modal",
|
||||||
@@ -737,80 +808,11 @@ export default class ConfirmGiftView extends Vue {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// similar code is found in ProjectViewView
|
/**
|
||||||
async confirmClaim() {
|
* Notifies user why they cannot confirm the gift
|
||||||
// similar logic is found in endorser-mobile
|
* Explains requirements or restrictions preventing confirmation
|
||||||
const goodClaim = serverUtil.removeSchemaContext(
|
*/
|
||||||
serverUtil.removeVisibleToDids(
|
notifyWhyCannotConfirm(): void {
|
||||||
serverUtil.addLastClaimOrHandleAsIdIfMissing(
|
|
||||||
this.veriClaim.claim,
|
|
||||||
this.veriClaim.id,
|
|
||||||
this.veriClaim.handleId,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
const confirmationClaim: GenericVerifiableCredential = {
|
|
||||||
"@context": "https://schema.org",
|
|
||||||
"@type": "AgreeAction",
|
|
||||||
object: goodClaim,
|
|
||||||
};
|
|
||||||
const result = await serverUtil.createAndSubmitClaim(
|
|
||||||
confirmationClaim,
|
|
||||||
this.activeDid,
|
|
||||||
this.apiServer,
|
|
||||||
this.axios,
|
|
||||||
);
|
|
||||||
if (result.type === "success") {
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "success",
|
|
||||||
title: "Success",
|
|
||||||
text: "Confirmation submitted.",
|
|
||||||
},
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
console.error("Got error submitting the confirmation:", result);
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "danger",
|
|
||||||
title: "Error",
|
|
||||||
text: "There was a problem submitting the confirmation.",
|
|
||||||
},
|
|
||||||
5000,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showClaimPage(claimId: string) {
|
|
||||||
const route = {
|
|
||||||
path: "/claim/" + encodeURIComponent(claimId),
|
|
||||||
};
|
|
||||||
(this.$router as Router).push(route).then(async () => {
|
|
||||||
this.resetThisValues();
|
|
||||||
await this.loadClaim(claimId, this.activeDid);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
copyToClipboard(name: string, text: string) {
|
|
||||||
useClipboard()
|
|
||||||
.copy(text)
|
|
||||||
.then(() => {
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "toast",
|
|
||||||
title: "Copied",
|
|
||||||
text: (name || "That") + " was copied to the clipboard.",
|
|
||||||
},
|
|
||||||
2000,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyWhyCannotConfirm() {
|
|
||||||
libsUtil.notifyWhyCannotConfirm(
|
libsUtil.notifyWhyCannotConfirm(
|
||||||
this.$notify,
|
this.$notify,
|
||||||
this.isRegistered,
|
this.isRegistered,
|
||||||
@@ -821,71 +823,35 @@ export default class ConfirmGiftView extends Vue {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyWhyCannotConfirmBak() {
|
/**
|
||||||
if (!this.isRegistered) {
|
* Formats type string for display by adding spaces before capitals
|
||||||
this.$notify(
|
* Optionally adds a prefix
|
||||||
{
|
*
|
||||||
group: "alert",
|
* @param text - Text to format
|
||||||
type: "info",
|
* @param prefix - Optional prefix to add
|
||||||
title: "Not Registered",
|
* @returns Formatted string
|
||||||
text: "Someone needs to register you before you can contribute.",
|
*/
|
||||||
},
|
capitalizeAndInsertSpacesBeforeCapsWithAPrefix(
|
||||||
3000,
|
text: string,
|
||||||
);
|
prefix?: string
|
||||||
} else if (!isGiveAction(this.veriClaim)) {
|
): string {
|
||||||
this.$notify(
|
const word = this.capitalizeAndInsertSpacesBeforeCaps(text);
|
||||||
{
|
if (word) {
|
||||||
group: "alert",
|
// if the word starts with a vowel, use "an" instead of "a"
|
||||||
type: "info",
|
const firstLetter = word[0].toLowerCase();
|
||||||
title: "Not A Give",
|
const vowels = ["a", "e", "i", "o", "u"];
|
||||||
text: "This is not a giving action to confirm.",
|
const particle = vowels.includes(firstLetter) ? "an" : "a";
|
||||||
},
|
return particle + " " + word;
|
||||||
3000,
|
|
||||||
);
|
|
||||||
} else if (this.confirmerIdList.includes(this.activeDid)) {
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "info",
|
|
||||||
title: "Already Confirmed",
|
|
||||||
text: "You already confirmed this claim.",
|
|
||||||
},
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
} else if (this.giveDetails?.issuerDid == this.activeDid) {
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "info",
|
|
||||||
title: "Cannot Confirm",
|
|
||||||
text: "You cannot confirm this because you issued this claim.",
|
|
||||||
},
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
} else if (serverUtil.containsHiddenDid(this.giveDetails?.fullClaim)) {
|
|
||||||
this.$notify(
|
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "info",
|
|
||||||
title: "Cannot Confirm",
|
|
||||||
text: "You cannot confirm this because some people are hidden.",
|
|
||||||
},
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
this.$notify(
|
return "";
|
||||||
{
|
|
||||||
group: "alert",
|
|
||||||
type: "info",
|
|
||||||
title: "Cannot Confirm",
|
|
||||||
text: "You cannot confirm this claim. There are no other details, but we can help more if you contact us and send us screenshots.",
|
|
||||||
},
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickShareClaim() {
|
/**
|
||||||
|
* Initiates sharing of claim information
|
||||||
|
* Handles share functionality based on platform capabilities
|
||||||
|
*/
|
||||||
|
async onClickShareClaim(): Promise<void> {
|
||||||
this.copyToClipboard("A link to this page", this.windowLocation);
|
this.copyToClipboard("A link to this page", this.windowLocation);
|
||||||
window.navigator.share({
|
window.navigator.share({
|
||||||
title: "Help Connect Me",
|
title: "Help Connect Me",
|
||||||
@@ -893,5 +859,23 @@ export default class ConfirmGiftView extends Vue {
|
|||||||
url: this.windowLocation,
|
url: this.windowLocation,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resetThisValues() {
|
||||||
|
this.confirmerIdList = [];
|
||||||
|
this.confsVisibleErrorMessage = "";
|
||||||
|
this.confsVisibleToIdList = [];
|
||||||
|
this.giveDetails = undefined;
|
||||||
|
this.isRegistered = false;
|
||||||
|
this.numConfsNotVisible = 0;
|
||||||
|
this.urlForNewGive = "";
|
||||||
|
this.veriClaim = serverUtil.BLANK_GENERIC_SERVER_RECORD;
|
||||||
|
this.veriClaimDump = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
capitalizeAndInsertSpacesBeforeCaps(text: string) {
|
||||||
|
return !text
|
||||||
|
? ""
|
||||||
|
: text[0].toUpperCase() + text.substr(1).replace(/([A-Z])/g, " $1");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user