certificate
import React, { useState, useEffect } from 'react';
// --- FontAwesome Icons (as components for clarity) ---
const Icon = ({ classes }) => <i className={classes}></i>;
// --- Reusable Components ---
const Section = ({ id, children, className = '' }) => (
<section id={id} className={`py-10 md:py-20 ${className}`}>
<div className="container mx-auto px-4 sm:px-6">{children}</div>
</section>
);
const SectionTitle = ({ title, subtitle }) => (
<div className="text-center mb-12">
<h2 className="text-3xl md:text-4xl font-bold text-white">{title}</h2>
<p className="text-gray-400 mt-4 max-w-2xl mx-auto">{subtitle}</p>
</div>
);
// --- Certificate Generation Component ---
const CreateCertificate = () => {
const [recipient, setRecipient] = useState('Ujjwal Kumar');
const [course, setCourse] = useState('Software Engineer Intern');
const [issuer, setIssuer] = useState('Debashish Kumar');
const [issuerTitle, setIssuerTitle] = useState('Founder & CEO');
const [company, setCompany] = useState('YUGA YATRA RETAIL (OPC) PRIVATE LIMITED');
const [date, setDate] = useState('30th June to 30th August, 2025');
const [internId, setInternId] = useState('280400113');
const handleDownload = () => {
const certificateElement = document.getElementById('certificate-template');
if (window.html2canvas && window.jspdf) {
window.html2canvas(certificateElement, {
scale: 3,
useCORS: true,
backgroundColor: null, // Ensure transparent background is handled correctly
}).then(canvas => {
const imgData = canvas.toDataURL('image/png', 1.0);
const { jsPDF } = window.jspdf;
const pdf = new jsPDF({
orientation: 'landscape',
unit: 'px',
format: [canvas.width, canvas.height]
});
pdf.addImage(imgData, 'PNG', 0, 0, canvas.width, canvas.height);
pdf.save(`${recipient}-certificate.pdf`);
}).catch(err => {
console.error("Error generating PDF:", err);
});
} else {
console.error('PDF generation libraries not loaded. Please ensure you have an internet connection and try again.');
}
};
return (
<Section id="create" className="bg-gray-900 min-h-screen flex items-center">
<div>
<SectionTitle title="Professional Certificate Generator" subtitle="Fill in the details below to create and download a professional certificate instantly." />
<div className="grid lg:grid-cols-2 gap-8 lg:gap-12 items-start">
{/* Form */}
<div className="bg-gray-800 p-8 rounded-xl border border-gray-700 shadow-lg">
<h3 className="text-2xl font-bold text-white mb-6">Certificate Details</h3>
<form className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-300 mb-1">Recipient Name</label>
<input type="text" value={recipient} onChange={e => setRecipient(e.target.value)} className="w-full bg-gray-700 border border-gray-600 rounded-lg p-2.5 text-gray-200 focus:ring-2 focus:ring-blue-500"/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-1">Issuing Company / Institution</label>
<input type="text" value={company} onChange={e => setCompany(e.target.value)} className="w-full bg-gray-700 border border-gray-600 rounded-lg p-2.5 text-gray-200 focus:ring-2 focus:ring-blue-500"/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-1">Course / Internship Title</label>
<input type="text" value={course} onChange={e => setCourse(e.target.value)} className="w-full bg-gray-700 border border-gray-600 rounded-lg p-2.5 text-gray-200 focus:ring-2 focus:ring-blue-500"/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-1">Completion Period</label>
<input type="text" value={date} onChange={e => setDate(e.target.value)} className="w-full bg-gray-700 border border-gray-600 rounded-lg p-2.5 text-gray-200 focus:ring-2 focus:ring-blue-500"/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-1">Issuer Name (Signature)</label>
<input type="text" value={issuer} onChange={e => setIssuer(e.target.value)} className="w-full bg-gray-700 border border-gray-600 rounded-lg p-2.5 text-gray-200 focus:ring-2 focus:ring-blue-500" style={{fontFamily: "'Caveat', cursive"}}/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-1">Issuer Title</label>
<input type="text" value={issuerTitle} onChange={e => setIssuerTitle(e.target.value)} className="w-full bg-gray-700 border border-gray-600 rounded-lg p-2.5 text-gray-200 focus:ring-2 focus:ring-blue-500"/>
</div>
<div>
<label className="block text-sm font-medium text-gray-300 mb-1">Intern ID / Certificate ID</label>
<input type="text" value={internId} onChange={e => setInternId(e.target.value)} className="w-full bg-gray-700 border border-gray-600 rounded-lg p-2.5 text-gray-200 focus:ring-2 focus:ring-blue-500"/>
</div>
<div className="pt-4">
<button type="button" onClick={handleDownload} className="w-full bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-8 rounded-lg text-lg transition-all duration-300 ease-in-out hover:scale-105 shadow-lg">
<Icon classes="fas fa-download mr-2" />
Generate & Download PDF
</button>
</div>
</form>
</div>
{/* Preview */}
<div className="p-2 bg-gray-800 rounded-lg shadow-2xl">
<div id="certificate-template" className="bg-white text-[#0D47A1] p-8 md:p-12 aspect-[1.414] w-full" style={{ fontFamily: "'Times New Roman', Times, serif", border: '10px solid #0D47A1', position: 'relative' }}>
<div className="absolute top-4 left-4 right-4 bottom-4 border-2 border-[#E6B800]"></div>
<div className="absolute top-6 left-6 right-6 bottom-6 border border-[#0D47A1]"></div>
<div className="relative z-10 flex flex-col h-full text-center">
<div className="flex justify-between items-start">
<div></div>
<div className="text-2xl" style={{color: '#E6B800'}}><span>⚜</span></div>
<div className="w-20 h-20 border-2 border-gray-400 rounded-full flex items-center justify-center text-sm font-bold text-gray-500 bg-gray-100">LOGO</div>
</div>
<h1 className="text-4xl font-bold uppercase mt-2">Certificate</h1>
<h2 className="text-2xl font-semibold uppercase">Of Internship</h2>
<div className="flex-grow flex flex-col justify-center my-4">
<p className="text-lg mt-4 text-gray-700">THIS CERTIFICATE IS PROUDLY PRESENTED TO</p>
<h3 className="text-4xl lg:text-5xl font-bold my-2 break-words" style={{ fontFamily: "'Garamond', serif" }}>{recipient || 'Recipient Name'}</h3>
<p className="text-base my-4 mx-auto max-w-2xl text-gray-600 break-words">
We are happy to certify that Mr. {recipient || '[Recipient Name]'} has completed his Internship as a "{course || '[Course/Internship Title]'}" from {date || '[Date Range]'}. We appreciate his work and contributions.
</p>
</div>
<div className="flex justify-between items-center mt-auto pt-2">
<div className="text-left w-1/3 min-w-0">
<p className="text-2xl break-words" style={{ fontFamily: "'Caveat', cursive" }}>{issuer || 'Issuer Name'}</p>
<hr className="border-gray-800 my-1" />
<p className="font-bold break-words">{issuer || 'Issuer Name'}</p>
<p className="text-sm break-words">{issuerTitle || 'Issuer Title'}</p>
</div>
<div className="w-1/3 flex justify-center">
<svg className="w-20 h-20 text-yellow-500" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="48" fill="#FFC107" stroke="#B8860B" strokeWidth="2"/>
<circle cx="50" cy="50" r="40" fill="none" stroke="#B8860B" strokeWidth="2"/>
<text x="50" y="55" fontFamily="serif" fontSize="12" fill="#8B4513" textAnchor="middle" fontWeight="bold">OFFICIAL</text>
<text x="50" y="68" fontFamily="serif" fontSize="12" fill="#8B4513" textAnchor="middle" fontWeight="bold">SEAL</text>
<path d="M20 50 A 30 30 0 0 1 80 50" fill="none" stroke="#B8860B" strokeWidth="1"/>
<path d="M25 40 A 30 30 0 0 1 75 40" fill="none" stroke="#B8860B" strokeWidth="1"/>
</svg>
</div>
<div className="text-right w-1/3 min-w-0">
<p className="break-words">Intern ID: {internId || '[Certificate ID]'}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</Section>
);
};
// --- Main App Component ---
export default function App() {
useEffect(() => {
const scripts = [
{ src: 'https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js', id: 'html2canvas' },
{ src: 'https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js', id: 'jspdf' }
];
// Add Google Fonts for cursive/signature font
const fontLink = document.createElement('link');
fontLink.href = "https://fonts.googleapis.com/css2?family=Caveat&display=swap";
fontLink.rel = "stylesheet";
document.head.appendChild(fontLink);
scripts.forEach(scriptInfo => {
if (!document.getElementById(scriptInfo.id)) {
const script = document.createElement('script');
script.id = scriptInfo.id;
script.src = scriptInfo.src;
script.async = false;
document.body.appendChild(script);
}
});
}, []);
return (
<>
{/* Global styles */}
<style>{`
body {
font-family: 'Inter', sans-serif;
background-color: #111827;
color: #e5e7eb;
}
`}</style>
<main>
<CreateCertificate />
</main>
</>
);
}
Comments
Post a Comment