186 lines
6.4 KiB
JavaScript
186 lines
6.4 KiB
JavaScript
//server.js
|
|
|
|
require("dotenv").config();
|
|
const express = require("express");
|
|
const mongoose = require("mongoose");
|
|
const bodyParser = require("body-parser");
|
|
const cors = require("cors");
|
|
const nodemailer = require("nodemailer");
|
|
const multer = require("multer");
|
|
const path = require("path");
|
|
const moment = require("moment");
|
|
|
|
const app = express();
|
|
app.use(cors());
|
|
app.use(bodyParser.json());
|
|
app.use(bodyParser.urlencoded({ extended: true }));
|
|
app.use("/uploads", express.static("uploads"));
|
|
|
|
// Multer setup for file uploads
|
|
const storage = multer.diskStorage({
|
|
destination: "uploads/",
|
|
filename: (req, file, cb) => {
|
|
cb(null, Date.now() + path.extname(file.originalname));
|
|
},
|
|
});
|
|
const upload = multer({ storage });
|
|
|
|
// MongoDB connection
|
|
mongoose
|
|
.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true })
|
|
.then(() => console.log("Connected to MongoDB"))
|
|
.catch((err) => console.error("MongoDB Connection Error:", err));
|
|
|
|
// Meeting Schema
|
|
const meetingSchema = new mongoose.Schema({
|
|
program: String,
|
|
department: String,
|
|
subject: String,
|
|
body: String,
|
|
agenda: [String],
|
|
date: String,
|
|
startTime: String,
|
|
endTime: String,
|
|
recipients: [String],
|
|
attachments: [{ filename: String, path: String }],
|
|
});
|
|
const Meeting = mongoose.model("Meeting", meetingSchema);
|
|
|
|
app.get("/api/meetings", async (req, res) => {
|
|
try {
|
|
const meetings = await Meeting.find(); // Fetching all meetings
|
|
|
|
// Format agenda in HTML for each meeting
|
|
const formattedMeetings = meetings.map((meeting) => {
|
|
const formattedAgenda = meeting.agenda
|
|
? meeting.agenda.map((item, index) => `<li>${index + 1}. ${item}</li>`).join("")
|
|
: "<li>No agenda provided</li>";
|
|
return { ...meeting.toObject(), formattedAgenda }; // Add formatted agenda to each meeting
|
|
});
|
|
|
|
res.json(formattedMeetings); // Send formatted meetings
|
|
} catch (error) {
|
|
console.error("Error fetching meetings:", error);
|
|
res.status(500).json({ error: "Error fetching meetings" });
|
|
}
|
|
});
|
|
|
|
// API to send email
|
|
app.post("/api/send-email", upload.array("attachments"), async (req, res) => {
|
|
try {
|
|
const { program, department, subject, body, agenda, date, startTime, endTime, recipients } = req.body;
|
|
const files = req.files;
|
|
|
|
console.log({ program, department, subject, body, agenda, date, startTime, endTime, recipients, files });
|
|
|
|
if (!program || !department || !subject || !body || !date || !startTime || !endTime || !recipients) {
|
|
return res.status(400).json({ error: "All fields are required!" });
|
|
}
|
|
|
|
// Check for meeting conflicts
|
|
const conflict = await Meeting.findOne({
|
|
date,
|
|
startTime: { $lt: endTime },
|
|
endTime: { $gt: startTime },
|
|
});
|
|
|
|
if (conflict) {
|
|
// Return the details of the conflicting meeting
|
|
const conflictDetails = {
|
|
department: conflict.department,
|
|
date: conflict.date,
|
|
startTime: conflict.startTime,
|
|
endTime: conflict.endTime,
|
|
recipients: conflict.recipients,
|
|
subject: conflict.subject,
|
|
};
|
|
|
|
return res.status(409).json({
|
|
error: "Meeting conflict detected! Please choose a different time.",
|
|
conflictDetails
|
|
});
|
|
}
|
|
|
|
// Format date and time properly
|
|
const formattedDate = moment(date, "YYYY-MM-DD").format("dddd, MMMM Do YYYY");
|
|
const formattedStartTime = moment(startTime, "HH:mm").format("hh:mm A");
|
|
const formattedEndTime = moment(endTime, "HH:mm").format("hh:mm A");
|
|
|
|
// Format Google Calendar event link
|
|
const formattedStart = moment(`${date} ${startTime}`, "YYYY-MM-DD HH:mm").utc().format("YYYYMMDDTHHmmss[Z]");
|
|
const formattedEnd = moment(`${date} ${endTime}`, "YYYY-MM-DD HH:mm").utc().format("YYYYMMDDTHHmmss[Z]");
|
|
const zoomLink = "https://us05web.zoom.us/j/2655616202?pwd=S3d6RjVPNnhmQ3AzTlZsRC9GYmNHQT09";
|
|
const calendarLink = `https://calendar.google.com/calendar/render?action=TEMPLATE&text=${encodeURIComponent(
|
|
subject
|
|
)}&details=${encodeURIComponent(`${body}\nJoin Zoom Meeting: ${zoomLink}`)}&dates=${formattedStart}/${formattedEnd}`;
|
|
|
|
// Format agenda into pointwise list
|
|
const formattedAgenda = agenda
|
|
? agenda.map((item, index) => `<li>${index + 1}. ${item}</li>`).join("")
|
|
: "<li>No agenda provided</li>";
|
|
|
|
// Store meeting in DB
|
|
const newMeeting = new Meeting({
|
|
program,
|
|
department,
|
|
subject,
|
|
body,
|
|
agenda,
|
|
date,
|
|
startTime,
|
|
endTime,
|
|
recipients,
|
|
attachments: files.map((file) => ({ filename: file.filename, path: file.path })),
|
|
});
|
|
await newMeeting.save();
|
|
|
|
// Email transporter
|
|
const transporter = nodemailer.createTransport({
|
|
service: "gmail",
|
|
auth: {
|
|
user: process.env.EMAIL,
|
|
pass: process.env.EMAIL_PASSWORD,
|
|
},
|
|
});
|
|
|
|
// Email options
|
|
const mailOptions = {
|
|
from: process.env.EMAIL,
|
|
to: recipients,
|
|
subject,
|
|
html: `
|
|
<p><strong>Respected Board Members,</strong></p>
|
|
<p><strong>Greetings from Somaiya Vidyavihar University !!</strong></p>
|
|
<p><strong>We are glad to invite you to the Board of Studies meeting: </strong></p>
|
|
<p>${body}</p>
|
|
<p><strong>Program:</strong> ${program}</p>
|
|
<p><strong>Department:</strong> ${department}</p>
|
|
<p><strong>Date:</strong> ${formattedDate}</p>
|
|
<p><strong>Time:</strong> ${formattedStartTime} - ${formattedEndTime}</p>
|
|
<p><strong>Zoom Meeting Details:</strong></p>
|
|
<p><strong>Meeting ID: </strong>265 561 6202</p>
|
|
<p><strong>Meeting Password: </strong>123456</p>
|
|
<p><strong>Zoom Meeting Link: </strong><a href="https://us05web.zoom.us/j/2655616202?pwd=S3d6RjVPNnhmQ3AzTlZsRC9GYmNHQT09" target="_blank">Join the Meeting</a></p>
|
|
<p><strong>Agenda:</strong></p>
|
|
<ul>${formattedAgenda}</ul>
|
|
<p><a href="${calendarLink}">📅 Click here to add this event to Google Calendar</a></p>
|
|
`,
|
|
attachments: files.map((file) => ({
|
|
filename: file.filename,
|
|
path: file.path,
|
|
})),
|
|
};
|
|
|
|
// Send email
|
|
await transporter.sendMail(mailOptions);
|
|
res.status(200).json({ message: "Email sent successfully!", calendarLink });
|
|
} catch (error) {
|
|
console.error("Error sending email:", error);
|
|
res.status(500).json({ error: "Error sending email" });
|
|
}
|
|
});
|
|
|
|
// Start server
|
|
const PORT = process.env.PORT || 5000;
|
|
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
|