add screens for the shortcuts for the BVC group (doesn't submit yet)

This commit is contained in:
2024-02-24 18:38:11 -07:00
parent 6aab1ff49d
commit 866dcb3a2a
10 changed files with 667 additions and 14 deletions

View File

@@ -50,9 +50,9 @@ export interface GenericVerifiableCredential {
export interface GenericServerRecord extends GenericVerifiableCredential {
handleId?: string;
id?: string;
issuedAt?: string;
issuer?: string;
id: string;
issuedAt: string;
issuer: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
claim: Record<any, any>;
claimType?: string;
@@ -61,6 +61,9 @@ export const BLANK_GENERIC_SERVER_RECORD: GenericServerRecord = {
"@context": SCHEMA_ORG_CONTEXT,
"@type": "",
claim: {},
id: "",
issuedAt: "",
issuer: "",
};
export interface GiveServerRecord {
@@ -579,6 +582,182 @@ export async function createAndSubmitClaim(
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const isAccept = (claim: Record<any, any>) => {
return (
claim &&
claim["@context"] === SCHEMA_ORG_CONTEXT &&
claim["@type"] === "AcceptAction"
);
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const isOffer = (claim: Record<any, any>) => {
return (
claim &&
claim["@context"] === SCHEMA_ORG_CONTEXT &&
claim["@type"] === "Offer"
);
};
export function currencyShortWordForCode(unitCode: string, single: boolean) {
return unitCode === "HUR" ? (single ? "hour" : "hours") : unitCode;
}
export function displayAmount(code: string, amt: number) {
return "" + amt + " " + currencyShortWordForCode(code, amt === 1);
}
// insert a space before any capital letters except the initial letter
// (and capitalize initial letter, just in case)
export const capitalizeAndInsertSpacesBeforeCaps = (text: string) => {
return !text
? ""
: text[0].toUpperCase() + text.substr(1).replace(/([A-Z])/g, " $1");
};
/**
return readable summary of claim, or something generic
similar code is also contained in endorser-mobile
**/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const claimSummary = (claim: Record<any, any>) => {
if (!claim) {
// to differentiate from "something" above
return "something";
}
if (claim.claim) {
// probably a Verified Credential
// eslint-disable-next-line @typescript-eslint/no-explicit-any
claim = claim.claim as Record<any, any>;
}
if (Array.isArray(claim)) {
if (claim.length === 1) {
claim = claim[0];
} else {
return "multiple claims";
}
}
const type = claim["@type"];
if (!type) {
return "a claim";
} else {
let typeExpl = capitalizeAndInsertSpacesBeforeCaps(type);
if (typeExpl === "Person") {
typeExpl += " claim";
}
return "a " + typeExpl;
}
};
/**
return readable description of claim if possible, as a past-tense action
identifiers is a list of objects with a 'did' field, each representing the user
contacts is a list of objects with a 'did' field for others and a 'name' field for their name
similar code is also contained in endorser-mobile
**/
export const claimSpecialDescription = (
record: GenericServerRecord,
activeDid: string,
identifiers: Array<string>,
contacts: Array<Contact>,
) => {
let claim = record.claim;
if (claim.claim) {
// it's probably a Verified Credential
claim = claim.claim;
}
const issuer = didInfo(record.issuer, activeDid, identifiers, contacts);
const type = claim["@type"] || "UnknownType";
if (type === "AgreeAction") {
return issuer + " agreed with " + claimSummary(claim.object);
} else if (isAccept(claim)) {
return issuer + " accepted " + claimSummary(claim.object);
} else if (type === "GiveAction") {
// agent.did is for legacy data, before March 2023
const giver = claim.agent?.identifier || claim.agent?.did;
const giverInfo = didInfo(giver, activeDid, identifiers, contacts);
let gaveAmount = claim.object?.amountOfThisGood
? displayAmount(claim.object.unitCode, claim.object.amountOfThisGood)
: "";
if (claim.description) {
if (gaveAmount) {
gaveAmount = gaveAmount + ", and also: ";
}
gaveAmount = gaveAmount + claim.description;
}
if (!gaveAmount) {
gaveAmount = "something not described";
}
// recipient.did is for legacy data, before March 2023
const gaveRecipientId = claim.recipient?.identifier || claim.recipient?.did;
const gaveRecipientInfo = gaveRecipientId
? " to " + didInfo(gaveRecipientId, activeDid, identifiers, contacts)
: "";
return giverInfo + " gave" + gaveRecipientInfo + ": " + gaveAmount;
} else if (type === "JoinAction") {
// agent.did is for legacy data, before March 2023
const agent = claim.agent?.identifier || claim.agent?.did;
const contactInfo = didInfo(agent, activeDid, identifiers, contacts);
let eventOrganizer =
claim.event && claim.event.organizer && claim.event.organizer.name;
eventOrganizer = eventOrganizer || "";
let eventName = claim.event && claim.event.name;
eventName = eventName ? " " + eventName : "";
let fullEvent = eventOrganizer + eventName;
fullEvent = fullEvent ? " attended the " + fullEvent : "";
let eventDate = claim.event && claim.event.startTime;
eventDate = eventDate ? " at " + eventDate : "";
return contactInfo + fullEvent + eventDate;
} else if (isOffer(claim)) {
const offerer = claim.offeredBy?.identifier;
const contactInfo = didInfo(offerer, activeDid, identifiers, contacts);
let offering = "";
if (claim.includesObject) {
offering +=
" " +
displayAmount(
claim.includesObject.unitCode,
claim.includesObject.amountOfThisGood,
);
}
if (claim.itemOffered?.description) {
offering += ", saying: " + claim.itemOffered?.description;
}
// recipient.did is for legacy data, before March 2023
const offerRecipientId =
claim.recipient?.identifier || claim.recipient?.did;
const offerRecipientInfo = offerRecipientId
? " to " + didInfo(offerRecipientId, activeDid, identifiers, contacts)
: "";
return contactInfo + " offered" + offering + offerRecipientInfo;
} else if (type === "PlanAction") {
const claimer = claim.agent?.identifier || record.issuer;
const claimerInfo = didInfo(claimer, activeDid, identifiers, contacts);
return claimerInfo + " announced a project: " + claim.name;
} else if (type === "Tenure") {
// party.did is for legacy data, before March 2023
const claimer = claim.party?.identifier || claim.party?.did;
const contactInfo = didInfo(claimer, activeDid, identifiers, contacts);
const polygon = claim.spatialUnit?.geo?.polygon || "";
return (
contactInfo +
" possesses [" +
polygon.substring(0, polygon.indexOf(" ")) +
"...]"
);
} else {
return issuer + " declared " + claimSummary(claim as GenericServerRecord);
}
};
// from https://stackoverflow.com/a/175787/845494
//
export function isNumeric(str: string): boolean {