Convert backends to Firebase and combine projects
This commit is contained in:
205
RIT-EVENT-MANAGEMENT--main/utils/pdfGenerator.ts
Normal file
205
RIT-EVENT-MANAGEMENT--main/utils/pdfGenerator.ts
Normal file
@@ -0,0 +1,205 @@
|
||||
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`);
|
||||
};
|
||||
Reference in New Issue
Block a user