Files
Event-Management-System/RIT-EVENT-MANAGEMENT--main/utils/pdfGenerator.ts

206 lines
6.8 KiB
TypeScript

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