You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
190 lines
5.7 KiB
190 lines
5.7 KiB
<template>
|
|
<section id="Content">
|
|
<div v-if="claimData">
|
|
<canvas ref="claimCanvas"></canvas>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { Component, Vue } from "vue-facing-decorator";
|
|
import { nextTick } from "vue";
|
|
import QRCode from "qrcode";
|
|
|
|
import { APP_SERVER, NotificationIface } from "../constants/app";
|
|
import { db, retrieveSettingsForActiveAccount } from "../db/index";
|
|
import * as endorserServer from "../libs/endorserServer";
|
|
|
|
@Component
|
|
export default class ClaimReportCertificateView extends Vue {
|
|
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
|
|
|
activeDid = "";
|
|
allMyDids: Array<string> = [];
|
|
apiServer = "";
|
|
claimId = "";
|
|
claimData = null;
|
|
|
|
endorserServer = endorserServer;
|
|
|
|
async created() {
|
|
const settings = await retrieveSettingsForActiveAccount();
|
|
this.activeDid = settings.activeDid || "";
|
|
this.apiServer = settings.apiServer || "";
|
|
const pathParams = window.location.pathname.substring(
|
|
"/claim-cert/".length,
|
|
);
|
|
this.claimId = pathParams;
|
|
await this.fetchClaim();
|
|
}
|
|
|
|
async fetchClaim() {
|
|
try {
|
|
const response = await fetch(
|
|
`${this.apiServer}/api/claim/${this.claimId}`,
|
|
);
|
|
if (response.ok) {
|
|
this.claimData = await response.json();
|
|
await nextTick(); // Wait for the DOM to update
|
|
if (this.claimData) {
|
|
this.drawCanvas(this.claimData);
|
|
}
|
|
} else {
|
|
throw new Error(`Error fetching claim: ${response.statusText}`);
|
|
}
|
|
} catch (error) {
|
|
console.error("Failed to load claim:", error);
|
|
this.$notify({
|
|
group: "alert",
|
|
type: "danger",
|
|
title: "Error",
|
|
text: "There was a problem loading the claim.",
|
|
});
|
|
}
|
|
}
|
|
|
|
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;
|
|
const CANVAS_HEIGHT = 850;
|
|
|
|
// size to approximate portrait of 8.5"x11"
|
|
canvas.width = CANVAS_WIDTH;
|
|
canvas.height = CANVAS_HEIGHT;
|
|
const ctx = canvas.getContext("2d");
|
|
if (ctx) {
|
|
// Load the background image
|
|
const backgroundImage = new Image();
|
|
backgroundImage.src = "/img/background/cert-frame-2.jpg";
|
|
backgroundImage.onload = async () => {
|
|
// Draw the background image
|
|
ctx.drawImage(backgroundImage, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
|
|
|
|
// Set font and styles
|
|
ctx.fillStyle = "black";
|
|
|
|
// Draw claim type
|
|
ctx.font = "bold 20px Arial";
|
|
const claimTypeText =
|
|
this.endorserServer.capitalizeAndInsertSpacesBeforeCaps(
|
|
claimData.claimType || "",
|
|
);
|
|
const claimTypeWidth = ctx.measureText(claimTypeText).width;
|
|
ctx.fillText(
|
|
claimTypeText,
|
|
(CANVAS_WIDTH - claimTypeWidth) / 2, // Center horizontally
|
|
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 =
|
|
claimData.claim.name || claimData.claim.description;
|
|
if (descriptionText) {
|
|
const descriptionLine =
|
|
descriptionText.length > 50
|
|
? descriptionText.substring(0, 75) + "..."
|
|
: descriptionText;
|
|
ctx.font = "14px Arial";
|
|
const descriptionWidth = ctx.measureText(descriptionLine).width;
|
|
ctx.fillText(
|
|
descriptionLine,
|
|
(CANVAS_WIDTH - descriptionWidth) / 2,
|
|
CANVAS_HEIGHT * 0.45,
|
|
);
|
|
}
|
|
|
|
// 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.7);
|
|
ctx.fillText(
|
|
"via EndorserSearch.com",
|
|
CANVAS_WIDTH * 0.3,
|
|
CANVAS_HEIGHT * 0.73,
|
|
);
|
|
|
|
// Generate and draw QR code
|
|
const qrCodeCanvas = document.createElement("canvas");
|
|
await QRCode.toCanvas(
|
|
qrCodeCanvas,
|
|
APP_SERVER + "/claim/" + this.claimId,
|
|
{
|
|
width: 150,
|
|
color: { light: "#0000" /* Transparent background */ },
|
|
},
|
|
);
|
|
ctx.drawImage(qrCodeCanvas, CANVAS_WIDTH * 0.6, CANVAS_HEIGHT * 0.55);
|
|
};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
canvas {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
</style>
|
|
|