Updated server.js with necessary changes

This commit is contained in:
2026-01-05 15:58:55 +05:30
parent a22d683c55
commit 7635bd3b3f

145
server.js
View File

@@ -1,10 +1,11 @@
const express = require("express"); const express = require("express");
require('dotenv').config();
const cors = require("cors"); const cors = require("cors");
const nodemailer = require("nodemailer"); const nodemailer = require("nodemailer");
const multer = require("multer"); const multer = require("multer");
const fs = require("fs"); const fs = require('fs/promises'); // change this line
const path = require("path"); const path = require("path");
const { v4: uuid } = require('uuid');
const app = express(); const app = express();
const PORT = 8000; const PORT = 8000;
@@ -18,32 +19,28 @@ app.use("/uploads", express.static(path.join(__dirname, "uploads")));
app.use("/applications", express.static(path.join(__dirname, "applications"))); app.use("/applications", express.static(path.join(__dirname, "applications")));
app.use("/gallery-media", express.static(path.join(__dirname, "gallery-media"))); app.use("/gallery-media", express.static(path.join(__dirname, "gallery-media")));
const loadData = (filePath) => { const loadData = async (filePath) => {
if (!fs.existsSync(filePath)) return [];
const data = fs.readFileSync(filePath, "utf-8");
try { try {
await fs.access(filePath); // check if file exists
const data = await fs.readFile(filePath, "utf-8");
return JSON.parse(data); return JSON.parse(data);
} catch { } catch {
return []; return [];
} }
}; };
const saveData = (filePath, data) => { const saveData = async (filePath, data) => {
fs.writeFileSync(filePath, JSON.stringify(data, null, 2)); await fs.writeFile(filePath, JSON.stringify(data, null, 2));
}; };
// ====================== GALLERY API ====================== // // ====================== GALLERY API ====================== //
const galleryStorage = multer.diskStorage({ const galleryStorage = multer.diskStorage({
destination: (req, file, cb) => { destination: async (req, file, cb) => {
const dir = "./gallery-media"; const dir = "./gallery-media";
if (!fs.existsSync(dir)) fs.mkdirSync(dir); fs.mkdir(dir, { recursive: true }) // async, safe
cb(null, dir); cb(null, dir);
}, },
filename: (req, file, cb) => {
const uniqueName = Date.now() + "-" + file.originalname;
cb(null, uniqueName);
},
}); });
const uploadGallery = multer({ const uploadGallery = multer({
@@ -63,8 +60,8 @@ const uploadGallery = multer({
}); });
// Get all gallery items with filtering by category // Get all gallery items with filtering by category
app.get("/api/gallery", (req, res) => { app.get("/api/gallery", async (req, res) => {
const items = loadData(GALLERY_DATA_FILE); const items = await loadData(GALLERY_DATA_FILE);
if (req.query.category) { if (req.query.category) {
const filtered = items.filter(item => item.category === req.query.category); const filtered = items.filter(item => item.category === req.query.category);
@@ -74,8 +71,9 @@ app.get("/api/gallery", (req, res) => {
res.json(items); res.json(items);
}); });
// Add new gallery item // Add new gallery item
app.post("/api/gallery", uploadGallery.single("media"), (req, res) => { app.post("/api/gallery", uploadGallery.single("media"), async (req, res) => {
const { category, caption, date } = req.body; const { category, caption, date } = req.body;
const mediaFile = req.file; const mediaFile = req.file;
@@ -86,7 +84,7 @@ app.post("/api/gallery", uploadGallery.single("media"), (req, res) => {
const mediaType = mediaFile.mimetype.startsWith("video") ? "video" : "image"; const mediaType = mediaFile.mimetype.startsWith("video") ? "video" : "image";
const newItem = { const newItem = {
id: Date.now(), id: uuid(),
category, category,
caption: caption || "", caption: caption || "",
date: date || "", date: date || "",
@@ -95,20 +93,22 @@ app.post("/api/gallery", uploadGallery.single("media"), (req, res) => {
createdAt: new Date().toISOString() createdAt: new Date().toISOString()
}; };
const items = loadData(GALLERY_DATA_FILE); const items = await loadData(GALLERY_DATA_FILE); // ✅ now safe
items.push(newItem); items.push(newItem);
saveData(GALLERY_DATA_FILE, items); await saveData(GALLERY_DATA_FILE, items); // also await
res.status(201).json({ message: "Gallery item added successfully", item: newItem }); res.status(201).json({ message: "Gallery item added successfully", item: newItem });
}); });
// Update gallery item // Update gallery item
app.put("/api/gallery/:id", uploadGallery.single("media"), (req, res) => { app.put("/api/gallery/:id", uploadGallery.single("media"), async (req, res) => {
const itemId = parseInt(req.params.id); const itemId = req.params.id;
const { category, caption, date } = req.body; const { category, caption, date } = req.body;
const mediaFile = req.file; const mediaFile = req.file;
let items = loadData(GALLERY_DATA_FILE); let items = await loadData(GALLERY_DATA_FILE);
const itemIndex = items.findIndex(item => item.id === itemId); const itemIndex = items.findIndex(item => item.id === itemId);
if (itemIndex === -1) { if (itemIndex === -1) {
@@ -120,11 +120,10 @@ app.put("/api/gallery/:id", uploadGallery.single("media"), (req, res) => {
let mediaUrl = existingItem.url; let mediaUrl = existingItem.url;
if (mediaFile) { if (mediaFile) {
// Delete old media file
const oldFilename = existingItem.url.split("/").pop(); const oldFilename = existingItem.url.split("/").pop();
const oldPath = path.join(__dirname, "gallery-media", oldFilename); const oldPath = path.join(__dirname, "gallery-media", oldFilename);
if (fs.existsSync(oldPath)) { if (await fs.stat(oldPath).catch(() => false)) {
fs.unlinkSync(oldPath); await fs.unlink(oldPath);
} }
mediaType = mediaFile.mimetype.startsWith("video") ? "video" : "image"; mediaType = mediaFile.mimetype.startsWith("video") ? "video" : "image";
@@ -141,33 +140,35 @@ app.put("/api/gallery/:id", uploadGallery.single("media"), (req, res) => {
updatedAt: new Date().toISOString() updatedAt: new Date().toISOString()
}; };
saveData(GALLERY_DATA_FILE, items); await saveData(GALLERY_DATA_FILE, items);
res.json({ message: "Gallery item updated successfully", item: items[itemIndex] }); res.json({ message: "Gallery item updated successfully", item: items[itemIndex] });
}); });
// Delete gallery item // Delete gallery item
app.delete("/api/gallery/:id", (req, res) => { app.delete("/api/gallery/:id", async (req, res) => {
const itemId = parseInt(req.params.id); const itemId = parseInt(req.params.id);
const items = loadData(GALLERY_DATA_FILE); const items = await loadData(GALLERY_DATA_FILE);
const itemIndex = items.findIndex(item => item.id === itemId); const itemIndex = items.findIndex(item => item.id === itemId);
if (itemIndex === -1) { if (itemIndex === -1) {
return res.status(404).json({ error: "Gallery item not found" }); return res.status(404).json({ error: "Gallery item not found" });
} }
// Delete associated media file
const filename = items[itemIndex].url.split("/").pop(); const filename = items[itemIndex].url.split("/").pop();
const filePath = path.join(__dirname, "gallery-media", filename); const filePath = path.join(__dirname, "gallery-media", filename);
if (fs.existsSync(filePath)) { if (await fs.stat(filePath).catch(() => false)) {
fs.unlinkSync(filePath); await fs.unlink(filePath);
} }
items.splice(itemIndex, 1); items.splice(itemIndex, 1);
saveData(GALLERY_DATA_FILE, items); await saveData(GALLERY_DATA_FILE, items);
res.json({ message: "Gallery item deleted successfully" }); res.json({ message: "Gallery item deleted successfully" });
}); });
// ========= CONTACT FORM ========= // // ========= CONTACT FORM ========= //
app.post("/contact", async (req, res) => { app.post("/contact", async (req, res) => {
const { name, email, contact, message } = req.body; const { name, email, contact, message } = req.body;
@@ -206,12 +207,13 @@ app.post("/contact", async (req, res) => {
} }
const transporter = nodemailer.createTransport({ const transporter = nodemailer.createTransport({
service: "gmail", service: "gmail",
auth: { auth: {
user: emailUser, user: process.env.EMAIL_USER,
pass: emailPass, pass: process.env.EMAIL_PASS,
}, },
}); });
// Verify connection configuration // Verify connection configuration
await transporter.verify(); await transporter.verify();
@@ -278,7 +280,7 @@ app.post("/contact", async (req, res) => {
const storage = multer.diskStorage({ const storage = multer.diskStorage({
destination: (req, file, cb) => { destination: (req, file, cb) => {
const dir = "./uploads"; const dir = "./uploads";
if (!fs.existsSync(dir)) fs.mkdirSync(dir); fs.mkdir(dir, { recursive: true }) // creates dir if not exists
cb(null, dir); cb(null, dir);
}, },
filename: (req, file, cb) => { filename: (req, file, cb) => {
@@ -288,21 +290,22 @@ const storage = multer.diskStorage({
}); });
const upload = multer({ storage }); const upload = multer({ storage });
const loadProjects = () => { const loadProjects = async () => {
if (!fs.existsSync(DATA_FILE)) return [];
const data = fs.readFileSync(DATA_FILE, "utf-8");
try { try {
await fs.access(DATA_FILE);
const data = await fs.readFile(DATA_FILE, "utf-8");
return JSON.parse(data); return JSON.parse(data);
} catch { } catch {
return []; return [];
} }
}; };
const saveProjects = (projects) => { const saveProjects = async (projects) => {
fs.writeFileSync(DATA_FILE, JSON.stringify(projects, null, 2)); await fs.writeFile(DATA_FILE, JSON.stringify(projects, null, 2));
}; };
app.post("/api/projects", upload.single("image"), (req, res) => {
app.post("/api/projects", upload.single("image"), async (req, res) => {
const { sector } = req.body; const { sector } = req.body;
const image = req.file ? `/uploads/${req.file.filename}` : ""; const image = req.file ? `/uploads/${req.file.filename}` : "";
@@ -310,26 +313,23 @@ app.post("/api/projects", upload.single("image"), (req, res) => {
return res.status(400).json({ error: "Sector and image are required" }); return res.status(400).json({ error: "Sector and image are required" });
} }
const newProject = { const newProject = { id: uuid(), sector, image };
id: Date.now(),
sector,
image,
};
const projects = loadProjects(); const projects = await loadProjects(); // ✅ await
projects.push(newProject); projects.push(newProject);
saveProjects(projects); await saveProjects(projects); // ✅ await
res.status(201).json({ message: "Project added successfully", project: newProject }); res.status(201).json({ message: "Project added successfully", project: newProject });
}); });
app.get("/api/projects", (req, res) => {
const projects = loadProjects(); app.get("/api/projects", async (req, res) => {
const projects = await loadProjects(); // ✅ await
res.json(projects); res.json(projects);
}); });
app.post("/api/projects/update/:id", upload.single("image"), (req, res) => { app.post("/api/projects/update/:id", upload.single("image"), (req, res) => {
const projectId = parseInt(req.params.id); const projectId = req.params.id;
const { sector } = req.body; const { sector } = req.body;
let projects = loadProjects(); let projects = loadProjects();
@@ -370,7 +370,7 @@ app.delete("/api/projects/:id", (req, res) => {
const applicationStorage = multer.diskStorage({ const applicationStorage = multer.diskStorage({
destination: (req, file, cb) => { destination: (req, file, cb) => {
const dir = "./applications"; const dir = "./applications";
if (!fs.existsSync(dir)) fs.mkdirSync(dir); fs.mkdir(dir, { recursive: true }) // creates dir if not exists
cb(null, dir); cb(null, dir);
}, },
filename: (req, file, cb) => { filename: (req, file, cb) => {
@@ -406,8 +406,8 @@ app.post("/send-application", uploadApplication.single("resume"), async (req, re
const transporter = nodemailer.createTransport({ const transporter = nodemailer.createTransport({
service: "gmail", service: "gmail",
auth: { auth: {
user: "laxmibamnale2002@gmail.com", user: process.env.EMAIL_USER,
pass: "smqcwjwdsuiywrse", pass: process.env.EMAIL_PASS,
}, },
}); });
@@ -461,26 +461,26 @@ Laxmi Civil Engineering Services Pvt. Ltd.`,
// ========= ENHANCED JOB POSTINGS API ========= // // ========= ENHANCED JOB POSTINGS API ========= //
const loadJobs = () => { const loadJobs = async () => {
if (!fs.existsSync(JOBS_DATA_FILE)) return [];
const data = fs.readFileSync(JOBS_DATA_FILE, "utf-8");
try { try {
await fs.access(JOBS_DATA_FILE);
const data = await fs.readFile(JOBS_DATA_FILE, "utf-8");
return JSON.parse(data); return JSON.parse(data);
} catch { } catch {
return []; return [];
} }
}; };
const saveJobs = (jobs) => { const saveJobs = async (jobs) => {
fs.writeFileSync(JOBS_DATA_FILE, JSON.stringify(jobs, null, 2)); await fs.writeFile(JOBS_DATA_FILE, JSON.stringify(jobs, null, 2));
}; };
// Get all jobs with automatic status updates // Get all jobs with automatic status updates
app.get("/api/jobs", (req, res) => { app.get("/api/jobs", async (req, res) => {
let jobs = loadJobs(); let jobs = await loadJobs(); // ✅ await
const currentDate = new Date(); const currentDate = new Date();
// Update job statuses based on closing date
jobs = jobs.map(job => { jobs = jobs.map(job => {
if (job.closingDate && new Date(job.closingDate) < currentDate) { if (job.closingDate && new Date(job.closingDate) < currentDate) {
return { ...job, isActive: false }; return { ...job, isActive: false };
@@ -488,12 +488,11 @@ app.get("/api/jobs", (req, res) => {
return job; return job;
}); });
// Save updated statuses if any changed await saveJobs(jobs); // ✅ await
saveJobs(jobs);
res.json(jobs); res.json(jobs);
}); });
// Create new job posting with enhanced fields // Create new job posting with enhanced fields
app.post("/api/jobs", (req, res) => { app.post("/api/jobs", (req, res) => {
const { const {
@@ -526,7 +525,7 @@ app.post("/api/jobs", (req, res) => {
const jobs = loadJobs(); const jobs = loadJobs();
const newJob = { const newJob = {
id: Date.now(), id: uuid(),
positionName, positionName,
qualification, qualification,
experience, experience,
@@ -648,7 +647,7 @@ app.delete("/api/jobs/:id", (req, res) => {
const careerStorage = multer.diskStorage({ const careerStorage = multer.diskStorage({
destination: (req, file, cb) => { destination: (req, file, cb) => {
const dir = "./career-applications"; const dir = "./career-applications";
if (!fs.existsSync(dir)) fs.mkdirSync(dir); fs.mkdir(dir, { recursive: true }) // creates dir if not exists
cb(null, dir); cb(null, dir);
}, },
filename: (req, file, cb) => { filename: (req, file, cb) => {
@@ -683,8 +682,8 @@ app.post('/api/careers/contact', uploadCareer.single('resume'), async (req, res)
const transporter = nodemailer.createTransport({ const transporter = nodemailer.createTransport({
service: "gmail", service: "gmail",
auth: { auth: {
user: "laxmibamnale2002@gmail.com", user: process.env.EMAIL_USER,
pass: "smqcwjwdsuiywrse", pass: process.env.EMAIL_PASS,
}, },
}); });