Browse Source

refine claim certificate view

split_build_process
Trent Larson 1 month ago
parent
commit
6d1681cb07
  1. 10
      src/libs/endorserServer.ts
  2. 75
      src/views/ClaimCertificateView.vue
  3. 48
      src/views/ClaimView.vue

10
src/libs/endorserServer.ts

@ -476,6 +476,16 @@ export function didInfo(
return didInfoForContact(did, activeDid, contact, allMyDids).displayName;
}
/**
* return text description without any references to "you" as user
*/
export function didInfoForCertificate(
did: string | undefined,
contacts: Contact[],
): string {
return didInfoForContact(did, undefined, contactForDid(did, contacts), []).displayName;
}
let passkeyAccessToken: string = "";
let passkeyTokenExpirationEpochSeconds: number = 0;

75
src/views/ClaimCertificateView.vue

@ -21,8 +21,8 @@ import { Component, Vue } from "vue-facing-decorator";
import { nextTick } from "vue";
import QRCode from "qrcode";
import { NotificationIface } from "@/constants/app";
import { retrieveSettingsForActiveAccount } from "@/db/index";
import { APP_SERVER, NotificationIface } from "@/constants/app";
import { db, retrieveSettingsForActiveAccount } from "@/db/index";
import * as endorserServer from "@/libs/endorserServer";
@Component
@ -56,7 +56,9 @@ export default class ClaimViewCertificate extends Vue {
if (response.ok) {
this.claimData = await response.json();
await nextTick(); // Wait for the DOM to update
this.drawCanvas();
if (this.claimData) {
this.drawCanvas(this.claimData);
}
} else {
throw new Error(`Error fetching claim: ${response.statusText}`);
}
@ -71,7 +73,12 @@ export default class ClaimViewCertificate extends Vue {
}
}
drawCanvas() {
async drawCanvas(
claimData: endorserServer.GenericCredWrapper<endorserServer.GenericVerifiableCredential>,
) {
await db.open();
const allContacts = await db.contacts.toArray();
const canvas = this.$refs.claimCanvas as HTMLCanvasElement;
if (canvas) {
const CANVAS_WIDTH = 1100;
@ -96,21 +103,43 @@ export default class ClaimViewCertificate extends Vue {
ctx.font = "bold 20px Arial";
const claimTypeText =
this.endorserServer.capitalizeAndInsertSpacesBeforeCaps(
this.claimData.claimType,
claimData.claimType || "",
);
const claimTypeWidth = ctx.measureText(claimTypeText).width;
ctx.fillText(
claimTypeText,
(CANVAS_WIDTH - claimTypeWidth) / 2, // Center horizontally
CANVAS_HEIGHT * 0.35,
CANVAS_HEIGHT * 0.33,
);
if (claimData.claim.agent) {
const presentedText = "Presented to ";
ctx.font = "14px Arial";
const presentedWidth = ctx.measureText(presentedText).width;
ctx.fillText(
presentedText,
(CANVAS_WIDTH - presentedWidth) / 2, // Center horizontally
CANVAS_HEIGHT * 0.37,
);
const agentText = endorserServer.didInfoForCertificate(
claimData.claim.agent,
allContacts,
);
ctx.font = "bold 20px Arial";
const agentWidth = ctx.measureText(agentText).width;
ctx.fillText(
agentText,
(CANVAS_WIDTH - agentWidth) / 2, // Center horizontally
CANVAS_HEIGHT * 0.4,
);
}
const descriptionText =
this.claimData.claim.description || this.claimData.claim.name;
claimData.claim.name || claimData.claim.description;
if (descriptionText) {
const descriptionLine =
descriptionText.length > 50
? descriptionText.substring(0, 47) + "..."
? descriptionText.substring(0, 85) + "..."
: descriptionText;
ctx.font = "14px Arial";
const descriptionWidth = ctx.measureText(descriptionLine).width;
@ -121,26 +150,38 @@ export default class ClaimViewCertificate extends Vue {
);
}
// Draw claim issuer & recipient
if (claimData.issuer) {
ctx.font = "14px Arial";
const issuerText =
"Issued by " +
endorserServer.didInfoForCertificate(
claimData.issuer,
allContacts,
);
ctx.fillText(issuerText, CANVAS_WIDTH * 0.3, CANVAS_HEIGHT * 0.6);
}
// Draw claim ID
ctx.font = "14px Arial";
ctx.fillText(this.claimId, CANVAS_WIDTH * 0.3, CANVAS_HEIGHT * 0.62);
ctx.fillText(this.claimId, CANVAS_WIDTH * 0.3, CANVAS_HEIGHT * 0.7);
ctx.fillText(
"via EndorserSearch.com",
CANVAS_WIDTH * 0.3,
CANVAS_HEIGHT * 0.65,
CANVAS_HEIGHT * 0.73,
);
// Generate and draw QR code
const qrCodeCanvas = document.createElement("canvas");
await QRCode.toCanvas(qrCodeCanvas, window.location.href, {
width: 150,
color: { light: "#0000" /* Transparent background */ },
});
ctx.drawImage(
await QRCode.toCanvas(
qrCodeCanvas,
CANVAS_WIDTH * 0.57,
CANVAS_HEIGHT * 0.55,
APP_SERVER + "/claim/" + this.claimId,
{
width: 150,
color: { light: "#0000" /* Transparent background */ },
},
);
ctx.drawImage(qrCodeCanvas, CANVAS_WIDTH * 0.6, CANVAS_HEIGHT * 0.55);
};
}
}

48
src/views/ClaimView.vue

@ -20,24 +20,36 @@
<div class="bg-slate-100 rounded-md overflow-hidden px-4 py-3 mb-4">
<div class="block flex gap-4 overflow-hidden">
<div class="overflow-hidden">
<h2 class="text-md font-bold">
{{ capitalizeAndInsertSpacesBeforeCaps(veriClaim.claimType) }}
<button
v-if="
['GiveAction', 'Offer', 'PlanAction'].includes(
veriClaim.claimType as string,
) && veriClaim.issuer === activeDid
// a PlanAction agent also could edit one of those,
// but rather than add more Plan-specific logic to detect the agent
// we'll let them click the Project link and edit from there
"
@click="onClickEditClaim"
title="Edit"
data-testId="editClaimButton"
>
<fa icon="pen" class="text-sm text-blue-500 ml-2 mb-1" />
</button>
</h2>
<div class="flex justify-between">
<h2 class="text-md font-bold">
{{ capitalizeAndInsertSpacesBeforeCaps(veriClaim.claimType) }}
<button
v-if="
['GiveAction', 'Offer', 'PlanAction'].includes(
veriClaim.claimType as string,
) && veriClaim.issuer === activeDid
// a PlanAction agent also could edit one of those,
// but rather than add more Plan-specific logic to detect the agent
// we'll let them click the Project link and edit from there
"
@click="onClickEditClaim"
title="Edit"
data-testId="editClaimButton"
>
<fa icon="pen" class="text-sm text-blue-500 ml-2 mb-1" />
</button>
</h2>
<!--
<div>
<router-link
:to="'/claim-cert/' + encodeURIComponent(veriClaim.id)"
class="text-blue-500 mt-2"
>
<fa icon="square" class="text-white bg-yellow-500 p-1" />
</router-link>
</div>
-->
</div>
<div class="text-sm">
<div data-testId="description">
<fa icon="message" class="fa-fw text-slate-400" />

Loading…
Cancel
Save