import { Button } from '@/components/ui/button'; import { Card } from '@/components/ui/card'; import { Label } from '@/components/ui/label'; import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group'; import { CoursePlayerProps } from '@/types/page'; import { usePage } from '@inertiajs/react'; import { format, parseISO } from 'date-fns'; import { de } from 'date-fns/locale'; import jsPDF from 'jspdf'; import { Award, Calendar, Download, FileImage, FileText } from 'lucide-react'; import { useRef, useState } from 'react'; import { toast } from 'sonner'; const Certificate = () => { const { props } = usePage(); const { translate } = props; const { frontend } = translate; const courseName = props.course.title; const studentName = props.auth.user.name; const completionDate = props.watchHistory?.completion_date ? format(parseISO(props.watchHistory.completion_date), 'dd. MMMM yyyy', { locale: de }) : ''; const [downloadFormat, setDownloadFormat] = useState('png'); const certificateRef = useRef(null); const dimensions = { width: 900, height: 600 }; // Standard const handleDownloadCertificate = () => { if (!certificateRef.current) return; if (downloadFormat === 'pdf') { downloadAsPDF(); } else { downloadAsPNG(); } }; const downloadAsPNG = () => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); if (!ctx) return; canvas.width = dimensions.width; canvas.height = dimensions.height; drawCertificate(ctx, dimensions); canvas.toBlob((blob) => { if (!blob) return; const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${studentName}_${courseName}_Zertifikat.png`; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); toast.success(frontend.png_certificate_saved); }, 'image/png'); }; const downloadAsPDF = () => { const isLandscape = dimensions.width > dimensions.height; // Create PDF with proper dimensions const pdf = new jsPDF({ orientation: isLandscape ? 'landscape' : 'portrait', unit: 'px', format: [dimensions.width, dimensions.height], }); // Create canvas for drawing const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); if (!ctx) return; canvas.width = dimensions.width; canvas.height = dimensions.height; // Draw certificate on canvas drawCertificate(ctx, dimensions); // Convert canvas to image and add to PDF const imgData = canvas.toDataURL('image/png'); pdf.addImage(imgData, 'PNG', 0, 0, dimensions.width, dimensions.height); // Save the PDF pdf.save(`${studentName}_${courseName}_Zertifikat.pdf`); toast.success(frontend.pdf_certificate_saved); }; // Helper function to wrap text const wrapText = (ctx: CanvasRenderingContext2D, text: string, x: number, y: number, maxWidth: number, lineHeight: number) => { const words = text.split(' '); let line = ''; let testLine = ''; const lines = []; // Split text into lines for (let n = 0; n < words.length; n++) { testLine += `${words[n]} `; const metrics = ctx.measureText(testLine); const testWidth = metrics.width; if (testWidth > maxWidth && n > 0) { lines.push({ text: line.trim(), width: ctx.measureText(line).width }); testLine = `${words[n]} `; line = `${words[n]} `; } else { line = testLine; } } lines.push({ text: line.trim(), width: ctx.measureText(line).width }); // Draw text let currentY = y; lines.forEach((lineObj) => { ctx.fillText(lineObj.text, x, currentY); currentY += lineHeight; }); return currentY; }; const drawCertificate = (ctx: CanvasRenderingContext2D, dimensions: { width: number; height: number }) => { // Create gradient background const gradient = ctx.createLinearGradient(0, 0, dimensions.width, dimensions.height); gradient.addColorStop(0, '#dbeafe'); gradient.addColorStop(1, '#e0e7ff'); ctx.fillStyle = gradient; ctx.fillRect(0, 0, dimensions.width, dimensions.height); // Add decorative border ctx.strokeStyle = '#f59e0b'; ctx.lineWidth = 8; ctx.strokeRect(20, 20, dimensions.width - 40, dimensions.height - 40); // Inner border ctx.strokeStyle = '#3730a3'; ctx.lineWidth = 2; ctx.strokeRect(40, 40, dimensions.width - 80, dimensions.height - 80); // Set text styles ctx.fillStyle = '#1f2937'; ctx.textAlign = 'center'; // Title ctx.font = 'bold 42px serif'; ctx.fillText(frontend.certificate_of_completion, dimensions.width / 2, 120); // Decorative line under title ctx.strokeStyle = '#f59e0b'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(dimensions.width / 2 - 150, 140); ctx.lineTo(dimensions.width / 2 + 150, 140); ctx.stroke(); // Certificate description text with wrapping ctx.font = '22px serif'; ctx.fillStyle = '#4b5563'; ctx.textAlign = 'center'; const descriptionText = frontend.certificate_description; const lineHeight = 30; // Adjust this value based on your font size const maxWidth = dimensions.width - 100; // 50px padding on each side // Draw wrapped text and get the Y position after the last line const lastY = wrapText(ctx, descriptionText, dimensions.width / 2, 190, maxWidth, lineHeight); // Student name with underline ctx.font = 'bold 36px serif'; ctx.fillStyle = '#3730a3'; ctx.fillText(studentName, dimensions.width / 2, 310); // Underline for student name const nameWidth = ctx.measureText(studentName).width; ctx.strokeStyle = '#f59e0b'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo((dimensions.width - nameWidth) / 2 - 20, 330); ctx.lineTo((dimensions.width + nameWidth) / 2 + 20, 330); ctx.stroke(); // "has successfully completed the course" ctx.font = '22px serif'; ctx.fillStyle = '#4b5563'; ctx.fillText(frontend.has_successfully_completed, dimensions.width / 2, 380); // Course name ctx.font = 'bold 28px serif'; ctx.fillStyle = '#3730a3'; ctx.fillText(courseName, dimensions.width / 2, 430); // Completion date ctx.font = '18px serif'; ctx.fillStyle = '#6b7280'; ctx.fillText(frontend.completed_on.replace(':date', completionDate), dimensions.width / 2, 490); // Footer ctx.font = '16px serif'; ctx.fillStyle = '#9ca3af'; ctx.fillText(frontend.authorized_certificate, dimensions.width / 2, dimensions.height - 60); }; return (

{frontend.course_certificate_download}

{frontend.download_official_certificate}

{/* Inner decorative border */}

{frontend.certificate_of_completion}

{frontend.certificate_description}

{studentName || 'Student Name'}

{frontend.has_successfully_completed}

{courseName || 'Course Name'}

{frontend.completed_on.replace(':date', completionDate || 'Date')}

{frontend.authorized_certificate}

); }; export default Certificate;