[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:
Kemas M. Aryadary Rasyad
2026-07-03 15:03:17 +07:00
parent 5dec77862c
commit 508ffe5f84
29 changed files with 782 additions and 607 deletions
+7 -10
View File
@@ -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(