[UNTEST] CERTIFICATE GENERATION AND BACKEND ENDPOINT IMPLEMENTATION ON CERTIFICATES (CLAIM, GENERATE, FETCH DATA)
- Updated AddInternsModal to allow selection of interns via dropdown instead of email input. - Introduced CertResultTable component for displaying certificate results with search and pagination. - Modified CreateProjectDialog to accept an onSuccess callback for better project creation handling. - Integrated certificate generation functionality in EligibleInternTable with improved error handling. - Enhanced HomeMentorProject and MentorProjectCard to dynamically display project icons and statuses. - Refactored SidebarMentor to improve active route detection. - Added utility functions for certificate preview and download in Certificates.ts. - Removed unused DownloadImagetoDevice utility and related hooks. - Implemented useProjectsByRole hook for fetching projects based on user role. - Updated types for certificates and projects to reflect recent changes in the data structure.
This commit is contained in:
@@ -1,11 +1,5 @@
|
||||
import api from "../../lib/api";
|
||||
|
||||
// ── Konstanta posisi nama di template ─────────────────────────────────────────
|
||||
const NAME_Y_RATIO = 0.55; // posisi Y = 55% dari tinggi canvas
|
||||
const NAME_FONT_SIZE = 48; // px
|
||||
const NAME_FONT_FAMILY = "Georgia, serif";
|
||||
const NAME_COLOR = "#1a1a1a";
|
||||
|
||||
// src/utils/certificateGenerator.ts
|
||||
export function resolveImageUrl(path: string): string {
|
||||
if (!path) return "";
|
||||
@@ -31,7 +25,10 @@ export function loadImage(src: string): Promise<HTMLImageElement> {
|
||||
// ── Generate satu sertifikat sebagai Blob ─────────────────────────────────────
|
||||
export async function generateCertificate(
|
||||
templateUrl: string,
|
||||
internName: string
|
||||
internName: string,
|
||||
projectName: string,
|
||||
uuid: string,
|
||||
barcodeUrl: string
|
||||
): Promise<Blob> {
|
||||
const img = await loadImage(templateUrl);
|
||||
|
||||
@@ -43,11 +40,11 @@ export async function generateCertificate(
|
||||
ctx.drawImage(img, 0, 0);
|
||||
|
||||
// Tulis nama di tengah horizontal, posisi Y dari konstanta
|
||||
ctx.font = `bold ${NAME_FONT_SIZE}px ${NAME_FONT_FAMILY}`;
|
||||
ctx.fillStyle = NAME_COLOR;
|
||||
ctx.font = `bold 48px Georgia, serif`;
|
||||
ctx.fillStyle = "#800000";
|
||||
ctx.textAlign = "center";
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.fillText(internName, canvas.width / 2, canvas.height * NAME_Y_RATIO);
|
||||
ctx.fillText(internName, canvas.width / 2, canvas.height * 0.55);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
canvas.toBlob(
|
||||
|
||||
Reference in New Issue
Block a user