forked from CSI-KJSCE/appointment_to_examiner
Merge branch 'main' of https://github.com/hk151109/appointment_to_examiner
This commit is contained in:
@@ -80,6 +80,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 = [
|
||||
@@ -91,8 +332,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 faculty IDs by role
|
||||
|
||||
for (const { key, role } of roles) {
|
||||
if (!courseData[key] || courseData[key].length === 0) continue;
|
||||
@@ -105,14 +347,15 @@ const CourseConsolidated = () => {
|
||||
appointments: [],
|
||||
};
|
||||
}
|
||||
facultyMap[teacher.facultyId].appointments.push({
|
||||
role,
|
||||
teacher,
|
||||
});
|
||||
facultyMap[teacher.facultyId].appointments.push({ role, teacher });
|
||||
|
||||
// Add facultyId to the role-specific list
|
||||
if (!roleFaculties[role]) roleFaculties[role] = [];
|
||||
roleFaculties[role].push(teacher.facultyId); // Store facultyId instead of 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 = [];
|
||||
@@ -121,8 +364,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);
|
||||
@@ -147,10 +388,21 @@ 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 inside the table
|
||||
const roleFacultyDetails = roleFaculties[role].map((facultyId) => {
|
||||
const facultyDetail = facultyMap[facultyId]; // Access by facultyId
|
||||
return [
|
||||
facultyDetail.facultyName,
|
||||
"K. J. Somaiya School of Engineering",
|
||||
role,
|
||||
facultyDetail.email,
|
||||
];
|
||||
});
|
||||
|
||||
autoTable(doc, {
|
||||
head: [["Name", "Affiliation", "Appointment Role", "Email"]],
|
||||
body: [[faculty.facultyName, "K. J. Somaiya School of Engineering", role, faculty.email]],
|
||||
startY: 80,
|
||||
body: roleFacultyDetails, // Mapping through all faculties in the role
|
||||
startY: 100,
|
||||
theme: "grid",
|
||||
headStyles: { fillColor: maroon, textColor: [255, 255, 255] },
|
||||
});
|
||||
@@ -174,12 +426,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);
|
||||
@@ -198,6 +449,7 @@ const CourseConsolidated = () => {
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<Navbar />
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user