Trent Larson
2 months ago
7 changed files with 179 additions and 8 deletions
After Width: | Height: | Size: 332 KiB |
@ -0,0 +1,149 @@ |
|||||
|
<template> |
||||
|
<section id="Content"> |
||||
|
<div v-if="claimData"> |
||||
|
<canvas ref="claimCanvas"></canvas> |
||||
|
</div> |
||||
|
</section> |
||||
|
</template> |
||||
|
|
||||
|
<style scoped> |
||||
|
canvas { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
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 * as endorserServer from "@/libs/endorserServer"; |
||||
|
|
||||
|
@Component |
||||
|
export default class ClaimViewCertificate 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 |
||||
|
this.drawCanvas(); |
||||
|
} 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.", |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
drawCanvas() { |
||||
|
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( |
||||
|
this.claimData.claimType, |
||||
|
); |
||||
|
const claimTypeWidth = ctx.measureText(claimTypeText).width; |
||||
|
ctx.fillText( |
||||
|
claimTypeText, |
||||
|
(CANVAS_WIDTH - claimTypeWidth) / 2, // Center horizontally |
||||
|
CANVAS_HEIGHT * 0.35, |
||||
|
); |
||||
|
|
||||
|
const descriptionText = |
||||
|
this.claimData.claim.description || this.claimData.claim.name; |
||||
|
if (descriptionText) { |
||||
|
const descriptionLine = |
||||
|
descriptionText.length > 50 |
||||
|
? descriptionText.substring(0, 47) + "..." |
||||
|
: descriptionText; |
||||
|
ctx.font = "14px Arial"; |
||||
|
const descriptionWidth = ctx.measureText(descriptionLine).width; |
||||
|
ctx.fillText( |
||||
|
descriptionLine, |
||||
|
(CANVAS_WIDTH - descriptionWidth) / 2, |
||||
|
CANVAS_HEIGHT * 0.45, |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// Draw claim ID |
||||
|
ctx.font = "14px Arial"; |
||||
|
ctx.fillText(this.claimId, CANVAS_WIDTH * 0.3, CANVAS_HEIGHT * 0.62); |
||||
|
ctx.fillText( |
||||
|
"via EndorserSearch.com", |
||||
|
CANVAS_WIDTH * 0.3, |
||||
|
CANVAS_HEIGHT * 0.65, |
||||
|
); |
||||
|
|
||||
|
// 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( |
||||
|
qrCodeCanvas, |
||||
|
CANVAS_WIDTH * 0.57, |
||||
|
CANVAS_HEIGHT * 0.55, |
||||
|
); |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
Loading…
Reference in new issue