Updated server.js with necessary changes
This commit is contained in:
137
server.js
137
server.js
@@ -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;
|
||||||
@@ -208,11 +209,12 @@ 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,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user