microtecflix/src/components/CertificateView.tsx

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>
);
}