forked from UKSOURCE/cms.lams
Refactor Homepage, About, Footer (Controller,Model, View, Data), Update: Dashboard, Delete old file
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
const About = require("../models/about");
|
||||
const { addBaseUrlToImages } = require("../utils/imageHelper");
|
||||
|
||||
// Helpers
|
||||
const getAboutDoc = async () => About.findOne().sort({ updatedAt: -1 });
|
||||
const getAboutData = async () => (await getAboutDoc())?.toObject() || {};
|
||||
|
||||
const getDefaultAboutData = () => ({
|
||||
hero: {
|
||||
badge: "",
|
||||
title: "",
|
||||
description: "",
|
||||
studentCount: "",
|
||||
image: "",
|
||||
imageAlt: "",
|
||||
coreValues: [],
|
||||
},
|
||||
leadership: {
|
||||
heading: "",
|
||||
description: "",
|
||||
members: [],
|
||||
},
|
||||
learningModel: {
|
||||
heading: "",
|
||||
description: "",
|
||||
async: {
|
||||
title: "",
|
||||
description: "",
|
||||
features: [],
|
||||
},
|
||||
sync: {
|
||||
title: "",
|
||||
description: "",
|
||||
features: [],
|
||||
},
|
||||
},
|
||||
accreditation: {
|
||||
heading: "",
|
||||
description: "",
|
||||
badges: [],
|
||||
stats: [],
|
||||
},
|
||||
successStories: {
|
||||
heading: "",
|
||||
description: "",
|
||||
stories: [],
|
||||
},
|
||||
cta: {
|
||||
heading: "",
|
||||
description: "",
|
||||
primaryButton: { label: "", href: "" },
|
||||
secondaryButton: { label: "", href: "" },
|
||||
},
|
||||
});
|
||||
|
||||
// Admin: render management view with data from MongoDB
|
||||
exports.index = async (req, res) => {
|
||||
try {
|
||||
let data = await getAboutData();
|
||||
const defaults = getDefaultAboutData();
|
||||
|
||||
// Merge defaults for any missing sections
|
||||
const sections = Object.keys(defaults);
|
||||
sections.forEach((s) => {
|
||||
data[s] = data[s] || defaults[s];
|
||||
});
|
||||
|
||||
return res.render("admin/about/index", {
|
||||
layout: "layouts/main",
|
||||
title: "About Management",
|
||||
data,
|
||||
currentPath: req.path,
|
||||
user: req.session.user,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("About index error:", err);
|
||||
req.flash("error_msg", "Error loading about data");
|
||||
return req.session.save(() => res.redirect("/admin/dashboard"));
|
||||
}
|
||||
};
|
||||
|
||||
// Admin: parse req.body sections and save to MongoDB
|
||||
exports.update = async (req, res) => {
|
||||
try {
|
||||
const sections = [
|
||||
"hero",
|
||||
"leadership",
|
||||
"learningModel",
|
||||
"accreditation",
|
||||
"successStories",
|
||||
"cta",
|
||||
];
|
||||
|
||||
let doc = await getAboutDoc();
|
||||
|
||||
if (!doc) {
|
||||
doc = new About({});
|
||||
}
|
||||
|
||||
let hasChanges = false;
|
||||
|
||||
for (const section of sections) {
|
||||
if (req.body[section]) {
|
||||
try {
|
||||
const payload = JSON.parse(req.body[section]);
|
||||
doc[section] = payload;
|
||||
doc.markModified(section);
|
||||
hasChanges = true;
|
||||
} catch (e) {
|
||||
console.error(`Invalid JSON for ${section}:`, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasChanges) {
|
||||
req.flash("info_msg", "No changes were made");
|
||||
return req.session.save(() => res.redirect("/admin/about-us"));
|
||||
}
|
||||
|
||||
await doc.save();
|
||||
|
||||
req.flash("success_msg", "About page configuration has been updated!");
|
||||
return req.session.save(() => res.redirect("/admin/about-us"));
|
||||
} catch (err) {
|
||||
console.error("About update error:", err);
|
||||
req.flash("error_msg", `Update error: ${err.message}`);
|
||||
return req.session.save(() => res.redirect("/admin/about-us"));
|
||||
}
|
||||
};
|
||||
|
||||
// Recursively prepend BACKEND_URL to any relative /uploads/... paths in an object
|
||||
function resolveImageUrls(obj, baseUrl) {
|
||||
if (!obj || typeof obj !== "object") return obj;
|
||||
if (Array.isArray(obj)) return obj.map((item) => resolveImageUrls(item, baseUrl));
|
||||
const result = {};
|
||||
for (const [key, val] of Object.entries(obj)) {
|
||||
if (typeof val === "string" && val.startsWith("/uploads/")) {
|
||||
result[key] = `${baseUrl}${val}`;
|
||||
} else {
|
||||
result[key] = resolveImageUrls(val, baseUrl);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Public API: return JSON data for frontend
|
||||
exports.api = async (req, res) => {
|
||||
try {
|
||||
let data = await getAboutData();
|
||||
if (!data || Object.keys(data).length === 0) {
|
||||
data = getDefaultAboutData();
|
||||
}
|
||||
const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get("host")}`;
|
||||
return res.json(resolveImageUrls(data, baseUrl));
|
||||
} catch (err) {
|
||||
console.error("About API error:", err);
|
||||
return res.status(500).json({ error: "Error loading about data" });
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user