122 lines
4.9 KiB
TypeScript
122 lines
4.9 KiB
TypeScript
import React, { useRef } from 'react';
|
|
import { Download, Award, ShieldCheck } from 'lucide-react';
|
|
// @ts-ignore
|
|
// html2pdf is loaded globally via CDN in index.html
|
|
|
|
interface CertificateViewProps {
|
|
certificate: {
|
|
id: string;
|
|
courseName: string;
|
|
moduleName?: string | null;
|
|
certificateType: 'COURSE' | 'MODULE';
|
|
unlockedAt: string;
|
|
finalGrade: number | null;
|
|
};
|
|
studentName: string;
|
|
}
|
|
|
|
export default function CertificateView({ certificate, studentName }: CertificateViewProps) {
|
|
const certRef = useRef<HTMLDivElement>(null);
|
|
|
|
const handleDownload = () => {
|
|
if (certRef.current) {
|
|
const opt = {
|
|
margin: 0,
|
|
filename: `Certificado_${certificate.courseName.replace(/\s+/g, '_')}.pdf`,
|
|
image: { type: 'jpeg', quality: 1 },
|
|
html2canvas: { scale: 2, useCORS: true },
|
|
jsPDF: { unit: 'in', format: 'letter', orientation: 'landscape' }
|
|
};
|
|
|
|
// @ts-ignore
|
|
html2pdf().set(opt).from(certRef.current).save();
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
<div className="flex items-center justify-between">
|
|
<h3 className="text-xl font-bold text-white flex items-center gap-2">
|
|
<Award className="w-6 h-6 text-amber-400" />
|
|
<span>Seu Certificado</span>
|
|
</h3>
|
|
<button
|
|
onClick={handleDownload}
|
|
className="glass-btn-primary flex items-center space-x-2 px-4 py-2 rounded-lg text-white font-bold text-sm"
|
|
>
|
|
<Download className="w-4 h-4" />
|
|
<span>Baixar PDF</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div className="overflow-x-auto p-4 bg-zinc-950 rounded-2xl border border-white/5 flex justify-center">
|
|
{/* Certificate Container (Will be converted to PDF) */}
|
|
<div
|
|
ref={certRef}
|
|
className="relative bg-white w-[800px] h-[600px] flex-shrink-0 text-zinc-800 overflow-hidden shadow-2xl"
|
|
style={{ backgroundImage: 'radial-gradient(circle at center, #ffffff 0%, #f3f4f6 100%)' }}
|
|
>
|
|
{/* Decorative Borders */}
|
|
<div className="absolute inset-4 border-2 border-amber-600/20 p-2">
|
|
<div className="absolute inset-0 border border-amber-600/40"></div>
|
|
</div>
|
|
|
|
<div className="absolute top-0 left-0 w-32 h-32 bg-amber-500/10 rounded-br-full"></div>
|
|
<div className="absolute bottom-0 right-0 w-32 h-32 bg-[#E50914]/10 rounded-tl-full"></div>
|
|
|
|
{/* Content */}
|
|
<div className="relative z-10 w-full h-full flex flex-col items-center justify-center p-16 text-center">
|
|
|
|
<div className="mb-6">
|
|
<ShieldCheck className="w-16 h-16 mx-auto text-amber-500" />
|
|
</div>
|
|
|
|
<h1 className="text-4xl font-display font-black text-zinc-900 tracking-widest uppercase mb-2">
|
|
Certificado de Conclusão
|
|
</h1>
|
|
<p className="text-sm font-semibold tracking-[0.2em] text-zinc-500 uppercase mb-10">
|
|
MicrotecFlix - Plataforma de Estudos
|
|
</p>
|
|
|
|
<p className="text-lg text-zinc-600 italic mb-4">Certificamos que</p>
|
|
|
|
<h2 className="text-5xl font-display font-bold text-zinc-900 mb-6 border-b border-amber-500/30 pb-4 px-12 inline-block">
|
|
{studentName}
|
|
</h2>
|
|
|
|
<p className="text-lg text-zinc-600 mb-2">
|
|
concluiu com êxito o {certificate.certificateType === 'COURSE' ? 'curso' : 'módulo'}:
|
|
</p>
|
|
|
|
<h3 className="text-2xl font-bold text-zinc-800 mb-4 max-w-2xl leading-tight">
|
|
{certificate.certificateType === 'COURSE'
|
|
? certificate.courseName
|
|
: `${certificate.moduleName} (${certificate.courseName})`}
|
|
</h3>
|
|
|
|
<div className="mt-8 flex justify-between w-full max-w-lg px-8 border-t border-zinc-200 pt-6">
|
|
<div className="text-center">
|
|
<p className="text-xs text-zinc-400 font-bold uppercase tracking-wider mb-1">Data de Conclusão</p>
|
|
<p className="font-semibold text-zinc-800">{new Date(certificate.unlockedAt).toLocaleDateString('pt-BR')}</p>
|
|
</div>
|
|
|
|
{certificate.finalGrade !== null && (
|
|
<div className="text-center border-l border-zinc-200 pl-8">
|
|
<p className="text-xs text-zinc-400 font-bold uppercase tracking-wider mb-1">Nota Final</p>
|
|
<p className="font-semibold text-zinc-800">{certificate.finalGrade.toFixed(1)} / 10</p>
|
|
</div>
|
|
)}
|
|
|
|
<div className="text-center border-l border-zinc-200 pl-8">
|
|
<p className="text-xs text-zinc-400 font-bold uppercase tracking-wider mb-1">Código de Validação</p>
|
|
<p className="font-mono text-[10px] text-zinc-500">{certificate.id.toUpperCase()}</p>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|