Spaces:
Sleeping
Sleeping
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Certificate of Completion</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> | |
<link href="https://fonts.googleapis.com/css2?family=Great+Vibes&family=Playfair+Display:wght@700&family=Open+Sans&display=swap" rel="stylesheet"> | |
<style> | |
body { | |
font-family: 'Open Sans', sans-serif; | |
background: linear-gradient(135deg, #f0f2f5 0%, #e0e7ef 100%); | |
min-height: 100vh; | |
display: flex; | |
flex-direction: column; | |
align-items: center; | |
justify-content: center; | |
padding: 20px; | |
position: relative; | |
} | |
.certificate-container { | |
background: rgba(255, 255, 255, 0.95); | |
border-radius: 24px; | |
box-shadow: 0 10px 30px rgba(0,0,0,0.15); | |
max-width: 900px; | |
width: 100%; | |
margin-bottom: 30px; | |
border: 10px double #FFD700; | |
overflow: hidden; | |
position: relative; | |
} | |
.certificate { | |
padding: 60px 40px 40px 40px; | |
position: relative; | |
background: linear-gradient(135deg, #fdfdfd 0%, #f3f9ff 100%); | |
} | |
.logo-container { | |
width: 100px; | |
height: 100px; | |
margin: 0 auto 30px auto; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
border-radius: 20px; | |
background: #fff; | |
box-shadow: 0 4px 16px rgba(0,0,0,0.08); | |
position: relative; | |
} | |
.logo-container img { | |
width: 90px; | |
height: auto; | |
border-radius: 12px; | |
} | |
.certificate-title { | |
font-family: 'Playfair Display', serif; | |
font-size: 3em; | |
color: #1d3557; | |
margin-bottom: 10px; | |
text-transform: uppercase; | |
letter-spacing: 2px; | |
} | |
.certificate-subtitle { | |
font-size: 1.2em; | |
color: #444; | |
margin-bottom: 30px; | |
} | |
.certificate-body { | |
text-align: center; | |
margin: 40px 0 30px 0; | |
} | |
.certificate-name-label { | |
font-size: 1.1em; | |
color: #6c757d; | |
margin-bottom: 10px; | |
font-weight: 600; | |
} | |
.certificate-name { | |
font-family: 'Great Vibes', cursive; | |
font-size: 3.2em; | |
color: #0d6efd; | |
margin-bottom: 20px; | |
line-height: 1.2; | |
text-shadow: 2px 2px 6px rgba(0, 0, 0, 0.10); | |
} | |
.certificate-text { | |
font-size: 1.1em; | |
color: #495057; | |
line-height: 1.7; | |
margin: 0 auto 20px auto; | |
max-width: 700px; | |
} | |
.certificate-points { | |
font-size: 1.3em; | |
color: #0a9396; | |
font-weight: 700; | |
margin-top: 15px; | |
} | |
.certificate-footer { | |
width: 100%; | |
display: flex; | |
justify-content: space-between; | |
margin-top: 40px; | |
font-size: 1em; | |
color: #555; | |
} | |
.certificate-signature { | |
width: 40%; | |
text-align: center; | |
} | |
.certificate-signature p { | |
margin-top: 40px; | |
border-top: 2px solid #000; | |
padding-top: 8px; | |
font-weight: 600; | |
} | |
.certificate-id { | |
font-size: 0.95em; | |
color: #888; | |
text-align: center; | |
margin-top: 30px; | |
font-family: 'SF Mono', 'Monaco', 'Inconsolata', monospace; | |
padding: 10px 20px; | |
background: #f8f9fa; | |
border-radius: 10px; | |
border: 1px solid #eee; | |
display: inline-block; | |
} | |
.download-btn { | |
background: linear-gradient(135deg, #00b4d8 0%, #0077b6 100%); | |
color: white; | |
border: none; | |
padding: 16px 32px; | |
border-radius: 50px; | |
font-size: 1.1em; | |
font-weight: 600; | |
cursor: pointer; | |
transition: all 0.3s ease; | |
box-shadow: 0 8px 32px rgba(0, 180, 216, 0.15); | |
margin: 30px auto 0 auto; | |
display: block; | |
letter-spacing: 0.5px; | |
} | |
.download-btn:hover { | |
background: linear-gradient(135deg, #0077b6 0%, #00b4d8 100%); | |
transform: translateY(-2px) scale(1.01); | |
box-shadow: 0 12px 32px rgba(0, 180, 216, 0.22); | |
} | |
@media (max-width: 700px) { | |
.certificate { | |
padding: 30px 10px; | |
} | |
.certificate-footer { | |
flex-direction: column; | |
gap: 20px; | |
} | |
} | |
@media print { | |
body { | |
background: white; | |
padding: 0; | |
} | |
.download-btn { | |
display: none ; | |
} | |
.certificate-container { | |
box-shadow: none; | |
max-width: none; | |
width: 100%; | |
background: white; | |
border: none; | |
} | |
.certificate { | |
background: white; | |
} | |
} | |
</style> | |
</head> | |
<body> | |
<div class="certificate-container" id="certificate"> | |
<div class="certificate"> | |
<div class="logo-container"> | |
<img src="/static/WhatsApp Image 2025-09-18 at 18.33.55_105edc80.jpg" alt="Logo"> | |
</div> | |
<h1 class="certificate-title">Certificate of Completion</h1> | |
<p class="certificate-subtitle">This certifies that</p> | |
<div class="certificate-body"> | |
<div class="certificate-name-label">Name:</div> | |
<div class="certificate-name" id="recipientName">{{ username }}</div> | |
<div class="certificate-name-label">has successfully completed the course</div> | |
<div class="certificate-text"> | |
for demonstrating outstanding dedication and mastering the principles of Rainwater Harvesting | |
through the <strong>Raindrop Quest: Harvest Hero</strong> learning program. | |
</div> | |
<div class="certificate-points">Total Points Earned: <span id="points">{{ total_points }}</span></div> | |
</div> | |
<div class="certificate-footer"> | |
<div class="certificate-signature"> | |
<p>Date: <span id="issueDate">{{ 'today' | date('%B %d, %Y') }}</span></p> | |
</div> | |
<div class="certificate-signature"> | |
<p>Instructor: HydroHero Academy</p> | |
</div> | |
</div> | |
<div class="certificate-id"> | |
Certificate ID: RWH-2025-<span id="certId">001234</span> | |
</div> | |
</div> | |
</div> | |
<button class="download-btn" onclick="downloadPDF()"> | |
📥 Download Certificate | |
</button> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> | |
<script> | |
// Function to generate random certificate ID | |
function generateCertId() { | |
return Math.random().toString(36).substr(2, 6).toUpperCase(); | |
} | |
// Set current date | |
function setDate() { | |
const currentDate = new Date(); | |
const options = { month: 'short', year: 'numeric' }; | |
document.getElementById('issueDate').textContent = currentDate.toLocaleDateString('en-US', options); | |
} | |
// Set certificate ID | |
function setCertId() { | |
document.getElementById('certId').textContent = generateCertId(); | |
} | |
// Function to download certificate as PDF | |
async function downloadPDF() { | |
const certificate = document.getElementById('certificate'); | |
const downloadBtn = document.querySelector('.download-btn'); | |
downloadBtn.style.display = 'none'; | |
try { | |
const canvas = await html2canvas(certificate, { | |
scale: 3, | |
useCORS: true, | |
backgroundColor: '#ffffff', | |
width: certificate.offsetWidth, | |
height: certificate.offsetHeight, | |
logging: false | |
}); | |
const { jsPDF } = window.jspdf; | |
const pdf = new jsPDF({ | |
orientation: 'landscape', | |
unit: 'mm', | |
format: 'a4' | |
}); | |
const imgWidth = 297; | |
const imgHeight = (canvas.height * imgWidth) / canvas.width; | |
const yPosition = (210 - imgHeight) / 2; | |
pdf.addImage( | |
canvas.toDataURL('image/png', 1.0), | |
'PNG', | |
0, | |
yPosition, | |
imgWidth, | |
imgHeight | |
); | |
const recipientName = document.getElementById('recipientName').textContent; | |
const fileName = `Certificate_${recipientName.replace(/\s+/g, '_')}_Rainwater_Harvesting.pdf`; | |
pdf.save(fileName); | |
} catch (error) { | |
alert('Error generating PDF. Please try again.'); | |
} finally { | |
downloadBtn.style.display = 'block'; | |
} | |
} | |
// Initialize on load | |
document.addEventListener('DOMContentLoaded', function() { | |
setDate(); | |
setCertId(); | |
}); | |
</script> | |
</body> | |
</html> | |