import { jsPDF } from 'jspdf'; import autoTable from 'jspdf-autotable'; import { Event } from '../types'; export const generateEventDetailsPDF = (event: Event) => { const doc = new jsPDF(); // Set fonts and colors doc.setFont('helvetica'); // --- Header Section --- doc.setFillColor(0, 74, 153); // #004a99 doc.rect(0, 0, 210, 40, 'F'); doc.setTextColor(255, 255, 255); doc.setFontSize(22); doc.setFont('helvetica', 'bold'); doc.text('RAJALAKSHMI INSTITUTE OF TECHNOLOGY', 105, 18, { align: 'center' }); doc.setFontSize(14); doc.setFont('helvetica', 'normal'); doc.text('OFFICIAL EVENT PROPOSAL & VERIFICATION DOCUMENT', 105, 28, { align: 'center' }); // --- Basic Information --- let startY = 50; doc.setTextColor(0, 0, 0); const addSectionTitle = (title: string, yPos: number) => { doc.setFontSize(14); doc.setFont('helvetica', 'bold'); doc.setTextColor(0, 74, 153); doc.text(title, 14, yPos); doc.setDrawColor(0, 74, 153); doc.setLineWidth(0.5); doc.line(14, yPos + 2, 196, yPos + 2); doc.setTextColor(0, 0, 0); return yPos + 10; }; startY = addSectionTitle('1. General Overview', startY); doc.setFontSize(10); doc.setFont('helvetica', 'bold'); const basicInfo = [ ['Event Title:', event.title.toUpperCase()], ['Category & Domain:', `${event.category} - ${event.domain || 'N/A'}`], ['Conducting Dept:', event.conducting_dept || 'General'], ['Coordinator:', event.coordinator || 'N/A'], ['Club / Entity:', event.club || 'N/A'], ['Participant Type:', event.participantType || 'Internal'], ['Creation Date:', event.request_by_faculty ? new Date(event.request_by_faculty).toLocaleString() : 'N/A'] ]; basicInfo.forEach((info, idx) => { doc.setFont('helvetica', 'bold'); doc.text(info[0], 14, startY + (idx * 7)); doc.setFont('helvetica', 'normal'); doc.text(info[1], 55, startY + (idx * 7)); }); startY += (basicInfo.length * 7) + 10; // --- Operational Logistics --- startY = addSectionTitle('2. Operational Logistics', startY); const eventTime = event.schedule && event.schedule.length > 0 ? `${event.schedule[0].start_time} - ${event.schedule[0].end_time}` : 'N/A'; const logisticsInfo = [ ['Date & Time:', `${event.date} at ${eventTime}`], ['Duration:', `${event.durationDays || 1} Day(s)`], ['Venue:', event.location || 'N/A'], ['Event Format:', event.isTeamEvent ? `Team Play (Max ${event.teamSizeLimit || 1} members)` : 'Solo Participation'], ['Registration Deadline:', event.registrationDeadline ? new Date(event.registrationDeadline).toLocaleString() : 'N/A'], ['Global Capacity:', event.maxParticipants ? `${event.maxParticipants} Seats` : 'Unlimited'] ]; logisticsInfo.forEach((info, idx) => { doc.setFont('helvetica', 'bold'); doc.text(info[0], 14, startY + (idx * 7)); doc.setFont('helvetica', 'normal'); doc.text(info[1], 55, startY + (idx * 7)); }); startY += (logisticsInfo.length * 7) + 10; // --- Detailed Summary --- startY = addSectionTitle('3. Detailed Summary', startY); doc.setFont('helvetica', 'normal'); doc.setFontSize(10); const splitSummary = doc.splitTextToSize(event.event_summary || 'No detailed summary provided for this event.', 180); doc.text(splitSummary, 14, startY); startY += (splitSummary.length * 5) + 10; // --- Schedule & Resource Persons --- if (startY > 230) { doc.addPage(); startY = 20; } if (event.schedule && event.schedule.length > 0) { startY = addSectionTitle('4. Schedule & Resource Persons', startY); const scheduleData = event.schedule.map(slot => [ `Day ${slot.day_idx} - Batch ${slot.batch_idx}`, `${slot.date} (${slot.start_time} - ${slot.end_time})`, slot.resource_person ? `${slot.resource_person.name}\n${slot.resource_person.dept || ''} ${slot.resource_person.college_name || ''}` : 'N/A', slot.resource_person ? `${slot.resource_person.email}\n${slot.resource_person.phone}` : 'N/A' ]); autoTable(doc, { startY: startY, head: [['Session', 'Timing', 'Resource Person', 'Contact']], body: scheduleData, theme: 'grid', headStyles: { fillColor: [0, 74, 153] }, styles: { fontSize: 9 } }); startY = (doc as any).lastAutoTable.finalY + 15; } // --- Department Quotas --- if (startY > 230) { doc.addPage(); startY = 20; } if (event.deptLimits && Object.keys(event.deptLimits).length > 0) { startY = addSectionTitle('5. Department Seat Quotas', startY); const quotaData = Object.entries(event.deptLimits).map(([dept, maxSeats]) => { const current = event.currentDeptCounts?.[dept] || 0; return [dept, `${current} Enrolled`, `${maxSeats} Limit`]; }); autoTable(doc, { startY: startY, head: [['Department', 'Current Enrollment', 'Max Seats Allocated']], body: quotaData, theme: 'grid', headStyles: { fillColor: [249, 115, 22] }, // Orange theme for quotas styles: { fontSize: 9 } }); startY = (doc as any).lastAutoTable.finalY + 15; } // --- Financial Projections --- if (startY > 230) { doc.addPage(); startY = 20; } startY = addSectionTitle('6. Financial Projections', startY); const financeData = [ ['Refreshment Expenses', `Rs. ${event.refreshment_expense || 0}`], ['Transportation Expenses', `Rs. ${event.transportation_expense || 0}`], ['Session Coverage Fees', `Rs. ${(event as any).session_coverage_fee || 0}`], ['Total Projected Budget', `Rs. ${event.total_expense || 0}`] ]; autoTable(doc, { startY: startY, body: financeData, theme: 'plain', styles: { fontSize: 10, cellPadding: 3 }, columnStyles: { 0: { fontStyle: 'bold' }, 1: { halign: 'right' } }, didParseCell: function(data) { if (data.row.index === 3) { data.cell.styles.fontStyle = 'bold'; data.cell.styles.textColor = [16, 185, 129]; // Emerald 500 } } }); startY = (doc as any).lastAutoTable.finalY + 15; // --- Footer / Verification Box --- if (startY > 250) { doc.addPage(); startY = 20; } doc.setDrawColor(0, 0, 0); doc.setLineWidth(0.2); doc.rect(14, startY, 182, 35); doc.setFontSize(9); doc.setFont('helvetica', 'italic'); doc.text('This is a system generated event verification document.', 105, startY + 6, { align: 'center' }); doc.setFont('helvetica', 'bold'); doc.setFontSize(10); doc.text(`Status: ${event.verificationStatus || 'PENDING'}`, 20, startY + 18); doc.setFontSize(8); doc.text(`Generated on: ${new Date().toLocaleString()}`, 20, startY + 28); doc.text('Rajalakshmi Institute of Technology - Events Hub', 130, startY + 28); // Save PDF doc.save(`${event.title.replace(/\s+/g, '_')}_Verification_Report.pdf`); };