+
${escapeHtml(certificate.studentName)}
+
${escapeHtml(certificate.courseName)}
+
+
+
${escapeHtml(certificate.studentName)}
+
+ has successfully completed the course
+ ${escapeHtml(certificate.courseName)}
+ with a final grade of ${gradeDisplay}
+ ${certificate.remarks ? `
"${escapeHtml(certificate.remarks)}"` : ''}
+
+
+
+
+ Digital Signature: ${escapeHtml(certificate.digitalSignature)}
+
+ ` : ''}
+ `;
+}
+
+// Get grade display text
+function getGradeDisplay(grade) {
+ const gradeMap = {
+ 0: 'A (Excellent)',
+ 1: 'B (Good)',
+ 2: 'C (Satisfactory)',
+ 3: 'D (Poor)',
+ 4: 'F (Fail)'
+ };
+
+ return gradeMap[grade] || grade.toString();
+}
+
+// Close certificate viewer
+function closeCertificateViewer() {
+ certificateViewerModal.classList.add('hidden');
+ currentCertificate = null;
+}
+
+// Print certificate
+function printCertificate() {
+ if (!currentCertificate) return;
+ window.print();
+}
+
+// Download certificate as PDF
+function downloadCertificate() {
+ if (!currentCertificate) return;
+
+ // For now, use print dialog
+ // In a production app, you'd generate a proper PDF using a library like jsPDF
+ showSuccess('Please use the print dialog to save as PDF');
+ printCertificate();
+}
+
+// Reset search form
+function resetSearchForm() {
+ searchStudentName.value = '';
+ searchCertificateNumber.value = '';
+ hideSearchResults();
+ searchEmpty.classList.add('hidden');
+}
+
+// Hide search results
+function hideSearchResults() {
+ searchResultsContainer.classList.add('hidden');
+ certificatesGrid.innerHTML = '';
+}
+
+// Show/hide loading overlay
+function showLoading(show) {
+ if (show) {
+ searchLoading.classList.remove('hidden');
+ } else {
+ searchLoading.classList.add('hidden');
+ }
+}
+
+// Show success message
+function showSuccess(message) {
+ const successModal = document.getElementById('success-modal');
+ const successMessage = document.getElementById('success-message');
+ successMessage.textContent = message;
+ successModal.classList.remove('hidden');
+}
+
+// Show error message
+function showError(message) {
+ const errorModal = document.getElementById('error-modal');
+ const errorMessage = document.getElementById('error-message');
+ errorMessage.textContent = message;
+ errorModal.classList.remove('hidden');
+}
+
+// Close modal
+function closeModal(modalId) {
+ const modal = document.getElementById(modalId);
+ modal.classList.add('hidden');
+}
+
+// Escape HTML to prevent XSS
+function escapeHtml(text) {
+ const div = document.createElement('div');
+ div.textContent = text;
+ return div.innerHTML;
+}
From 4583b10da4ce51eb00ea4aae3bb8fdbed96cfb73 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 23 Dec 2025 05:42:52 +0000
Subject: [PATCH 4/4] Fix CSS grade class mismatch and add thread-safety to
certificate number generation
Co-authored-by: Hemavathi15sg <224925058+Hemavathi15sg@users.noreply.github.com>
---
.../Services/CertificateService.cs | 18 ++++++++++++++----
frontend/certificates.js | 15 ++++++++++++++-
2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/api/CourseRegistration.Application/Services/CertificateService.cs b/api/CourseRegistration.Application/Services/CertificateService.cs
index 55013f4..a80afee 100644
--- a/api/CourseRegistration.Application/Services/CertificateService.cs
+++ b/api/CourseRegistration.Application/Services/CertificateService.cs
@@ -10,6 +10,9 @@ namespace CourseRegistration.Application.Services;
///