diff --git a/client/src/Pages/courseConsolidated.jsx b/client/src/Pages/courseConsolidated.jsx index 5fbcc54..3a6e90f 100644 --- a/client/src/Pages/courseConsolidated.jsx +++ b/client/src/Pages/courseConsolidated.jsx @@ -79,6 +79,247 @@ const CourseConsolidated = () => { } }; + // const generateAppointmentPDFs = async (courseData, courseName) => { + // const maroon = [128, 0, 0]; + // const roles = [ + // { key: "oralPracticalTeachers", role: "Oral/Practical Teacher" }, + // { key: "assessmentTeachers", role: "Assessment Teacher" }, + // { key: "reassessmentTeachers", role: "Reassessment Teacher" }, + // { key: "paperSettingTeachers", role: "Paper Setter" }, + // { key: "moderationTeachers", role: "Moderator" }, + // { key: "pwdPaperSettingTeachers", role: "PwD Paper Setter" }, + // ]; + + // // ✅ NEW: Group appointments by Faculty ID + // const facultyMap = {}; + + // for (const { key, role } of roles) { + // if (!courseData[key] || courseData[key].length === 0) continue; + + // for (const teacher of courseData[key]) { + // if (!facultyMap[teacher.facultyId]) { + // facultyMap[teacher.facultyId] = { + // facultyName: teacher.facultyName, + // email: await fetchFacultyEmail(teacher.facultyId), + // appointments: [], + // }; + // } + // facultyMap[teacher.facultyId].appointments.push({ + // role, + // teacher, + // }); + // } + // } + + // // ✅ NEW: For each Faculty, generate PDFs & send one email + // for (const facultyId in facultyMap) { + // const faculty = facultyMap[facultyId]; + // const pdfBlobs = []; + + // for (const appointment of faculty.appointments) { + // const { role } = appointment; + + // const doc = new jsPDF(); + + // // Add Logo and Title (your original PDF content) + // const logoUrl = "/logo.png"; + // const loadImage = async (url) => { + // const response = await fetch(url); + // const blob = await response.blob(); + // return new Promise((resolve, reject) => { + // const reader = new FileReader(); + // reader.onload = () => resolve(reader.result); + // reader.onerror = (error) => reject(error); + // reader.readAsDataURL(blob); + // }); + // }; + + // try { + // const logoBase64 = await loadImage(logoUrl); + // doc.addImage(logoBase64, "PNG", 10, 10, 40, 40); + // } catch (error) { + // console.error("Failed to load logo:", error); + // } + + // doc.setFont("times", "normal"); + // doc.text(`Date: ${new Date().toLocaleDateString()}`, 150, 20); + // doc.text("CONFIDENTIAL", 10, 60); + // doc.text(`LETTER OF APPOINTMENT AS ${role.toUpperCase()}`, 105, 70, { align: "center" }); + + // autoTable(doc, { + // head: [["Name", "Affiliation", "Appointment Role", "Email"]], + // body: [[faculty.facultyName, "K. J. Somaiya School of Engineering", role, faculty.email]], + // startY: 80, + // theme: "grid", + // headStyles: { fillColor: maroon, textColor: [255, 255, 255] }, + // }); + + // autoTable(doc, { + // body: [ + // ["Programme:", courseData.courseName], + // ["Exam Category:", "Regular Examination"], + // ["Exam Type:", courseData.examType], + // ["Exam Season:", "Second Half - Winter Examination 2023"], + // ["Year:", courseData.year], + // ["Semester:", courseData.semester], + // ["Course Name:", courseName], + // ["Course Code:", courseData.courseCode], + // ], + // startY: doc.previousAutoTable.finalY + 10, + // theme: "grid", + // }); + + // const pdfBlob = doc.output("blob"); + // pdfBlobs.push({ blob: pdfBlob, filename: `${courseName}-${role}.pdf` }); + // } + + // // ✅ NEW: Send ONE email with ALL PDFs to the Faculty + // try { + // const formData = new FormData(); + + // pdfBlobs.forEach(({ blob, filename }) => { + // formData.append("pdfFiles", blob, filename); // note 'pdfFiles' is plural + // }); + + // formData.append("recipientEmail", faculty.email); + // formData.append("facultyName", faculty.facultyName); + // formData.append("courseName", courseName); + + // const emailResponse = await sendEmail(formData, "bulk-pdf"); + // toast.success(`✅ Email sent successfully to ${faculty.email}`); + // console.log("Response:", emailResponse); + // } catch (error) { + // toast.error(`❌ Error sending email to ${faculty.email}: ${error.message}`); + // console.error(error); + // } + // } + // }; + + // const generateAppointmentPDFs = async (courseData, courseName) => { + // const maroon = [128, 0, 0]; + // const roles = [ + // { key: "oralPracticalTeachers", role: "Oral/Practical Teacher" }, + // { key: "assessmentTeachers", role: "Assessment Teacher" }, + // { key: "reassessmentTeachers", role: "Reassessment Teacher" }, + // { key: "paperSettingTeachers", role: "Paper Setter" }, + // { key: "moderationTeachers", role: "Moderator" }, + // { key: "pwdPaperSettingTeachers", role: "PwD Paper Setter" }, + // ]; + + // // Group appointments by Faculty ID and by role + // const facultyMap = {}; + // const roleFaculties = {}; // Store faculties by role + + // for (const { key, role } of roles) { + // if (!courseData[key] || courseData[key].length === 0) continue; + + // for (const teacher of courseData[key]) { + // if (!facultyMap[teacher.facultyId]) { + // facultyMap[teacher.facultyId] = { + // facultyName: teacher.facultyName, + // email: await fetchFacultyEmail(teacher.facultyId), + // appointments: [], + // }; + // } + // facultyMap[teacher.facultyId].appointments.push({ role, teacher }); + + // // Add faculty to the role-specific list + // if (!roleFaculties[role]) roleFaculties[role] = []; + // roleFaculties[role].push(teacher.facultyName); + // } + // } + + // // Generate PDF for each faculty + // for (const facultyId in facultyMap) { + // const faculty = facultyMap[facultyId]; + // const pdfBlobs = []; + + // for (const appointment of faculty.appointments) { + // const { role } = appointment; + + // const doc = new jsPDF(); + // const logoUrl = "/logo.png"; + // const loadImage = async (url) => { + // const response = await fetch(url); + // const blob = await response.blob(); + // return new Promise((resolve, reject) => { + // const reader = new FileReader(); + // reader.onload = () => resolve(reader.result); + // reader.onerror = (error) => reject(error); + // reader.readAsDataURL(blob); + // }); + // }; + + // try { + // const logoBase64 = await loadImage(logoUrl); + // doc.addImage(logoBase64, "PNG", 10, 10, 40, 40); + // } catch (error) { + // console.error("Failed to load logo:", error); + // } + + // doc.setFont("times", "normal"); + // doc.text(`Date: ${new Date().toLocaleDateString()}`, 150, 20); + // doc.text("CONFIDENTIAL", 10, 60); + // doc.text(`LETTER OF APPOINTMENT AS ${role.toUpperCase()}`, 105, 70, { align: "center" }); + + // // Include other faculties performing the same role + // const otherFaculties = roleFaculties[role].filter( + // (name) => name !== faculty.facultyName + // ); + // doc.text( + // `Other faculties performing the same role: ${otherFaculties.join(", ")}`, + // 10, + // 90 + // ); + + // autoTable(doc, { + // head: [["Name", "Affiliation", "Appointment Role", "Email"]], + // body: [[faculty.facultyName, "K. J. Somaiya School of Engineering", role, faculty.email]], + // startY: 100, + // theme: "grid", + // headStyles: { fillColor: maroon, textColor: [255, 255, 255] }, + // }); + + // autoTable(doc, { + // body: [ + // ["Programme:", courseData.courseName], + // ["Exam Category:", "Regular Examination"], + // ["Exam Type:", courseData.examType], + // ["Exam Season:", "Second Half - Winter Examination 2023"], + // ["Year:", courseData.year], + // ["Semester:", courseData.semester], + // ["Course Name:", courseName], + // ["Course Code:", courseData.courseCode], + // ], + // startY: doc.previousAutoTable.finalY + 10, + // theme: "grid", + // }); + + // const pdfBlob = doc.output("blob"); + // pdfBlobs.push({ blob: pdfBlob, filename: `${courseName}-${role}.pdf` }); + // } + + // // Send ONE email with ALL PDFs to the Faculty + // try { + // const formData = new FormData(); + // pdfBlobs.forEach(({ blob, filename }) => { + // formData.append("pdfFiles", blob, filename); + // }); + + // formData.append("recipientEmail", faculty.email); + // formData.append("facultyName", faculty.facultyName); + // formData.append("courseName", courseName); + + // const emailResponse = await sendEmail(formData, "bulk-pdf"); + // toast.success(`✅ Email sent successfully to ${faculty.email}`); + // console.log("Response:", emailResponse); + // } catch (error) { + // toast.error(`❌ Error sending email to ${faculty.email}: ${error.message}`); + // console.error(error); + // } + // } + // }; + const generateAppointmentPDFs = async (courseData, courseName) => { const maroon = [128, 0, 0]; const roles = [ @@ -90,8 +331,9 @@ const CourseConsolidated = () => { { key: "pwdPaperSettingTeachers", role: "PwD Paper Setter" }, ]; - // ✅ NEW: Group appointments by Faculty ID + // Group appointments by Faculty ID and by role const facultyMap = {}; + const roleFaculties = {}; // Store faculties by role for (const { key, role } of roles) { if (!courseData[key] || courseData[key].length === 0) continue; @@ -104,14 +346,15 @@ const CourseConsolidated = () => { appointments: [], }; } - facultyMap[teacher.facultyId].appointments.push({ - role, - teacher, - }); + facultyMap[teacher.facultyId].appointments.push({ role, teacher }); + + // Add faculty to the role-specific list + if (!roleFaculties[role]) roleFaculties[role] = []; + roleFaculties[role].push(teacher.facultyName); } } - // ✅ NEW: For each Faculty, generate PDFs & send one email + // Generate PDF for each faculty for (const facultyId in facultyMap) { const faculty = facultyMap[facultyId]; const pdfBlobs = []; @@ -120,8 +363,6 @@ const CourseConsolidated = () => { const { role } = appointment; const doc = new jsPDF(); - - // Add Logo and Title (your original PDF content) const logoUrl = "/logo.png"; const loadImage = async (url) => { const response = await fetch(url); @@ -146,10 +387,14 @@ const CourseConsolidated = () => { doc.text("CONFIDENTIAL", 10, 60); doc.text(`LETTER OF APPOINTMENT AS ${role.toUpperCase()}`, 105, 70, { align: "center" }); + // Include all faculties performing the same role in the same list + const allFacultiesInRole = roleFaculties[role].join(", "); + doc.text(`Faculties performing the same role: ${allFacultiesInRole}`, 10, 90); + autoTable(doc, { head: [["Name", "Affiliation", "Appointment Role", "Email"]], body: [[faculty.facultyName, "K. J. Somaiya School of Engineering", role, faculty.email]], - startY: 80, + startY: 100, theme: "grid", headStyles: { fillColor: maroon, textColor: [255, 255, 255] }, }); @@ -173,12 +418,11 @@ const CourseConsolidated = () => { pdfBlobs.push({ blob: pdfBlob, filename: `${courseName}-${role}.pdf` }); } - // ✅ NEW: Send ONE email with ALL PDFs to the Faculty + // Send ONE email with ALL PDFs to the Faculty try { const formData = new FormData(); - pdfBlobs.forEach(({ blob, filename }) => { - formData.append("pdfFiles", blob, filename); // note 'pdfFiles' is plural + formData.append("pdfFiles", blob, filename); }); formData.append("recipientEmail", faculty.email); diff --git a/server/routes/emailRoutes.js b/server/routes/emailRoutes.js index dfa193c..c1506bb 100644 --- a/server/routes/emailRoutes.js +++ b/server/routes/emailRoutes.js @@ -5,6 +5,7 @@ const multer = require("multer"); const router = express.Router(); // Multer setup remains intact + const storage = multer.diskStorage({ destination: function (req, file, cb) { cb(null, "./"); // Customize directory if needed