forked from UKSOURCE/cms.hailearning.edu.vn
feat(about): sync FE-BE data and image upload
This commit is contained in:
@@ -1,161 +0,0 @@
|
||||
const { addBaseUrlToImages } = require('../utils/imageHelper');
|
||||
const About = require('../models/about');
|
||||
|
||||
// Get about data from MongoDB
|
||||
const getAboutData = async () => {
|
||||
const about = await About.findOne().sort({ updatedAt: -1 });
|
||||
|
||||
// Trả về object rỗng với cấu trúc cơ bản nếu không có dữ liệu
|
||||
if (!about) {
|
||||
return {
|
||||
banner: {
|
||||
image: '',
|
||||
title: '',
|
||||
text: ''
|
||||
},
|
||||
about: {
|
||||
title: '',
|
||||
paragraphs: [],
|
||||
list_items: [],
|
||||
button: {
|
||||
text: '',
|
||||
url: ''
|
||||
},
|
||||
image: '',
|
||||
quote: {
|
||||
mark_image: '',
|
||||
title: '',
|
||||
text: '',
|
||||
author: ''
|
||||
}
|
||||
},
|
||||
values: {
|
||||
background_image: '',
|
||||
items: []
|
||||
},
|
||||
education: {
|
||||
images: {
|
||||
student1: '',
|
||||
student2: ''
|
||||
},
|
||||
subtitle: '',
|
||||
title: '',
|
||||
text: ''
|
||||
},
|
||||
advantages: {
|
||||
title: '',
|
||||
items: []
|
||||
},
|
||||
academic_board: {
|
||||
title: '',
|
||||
members: []
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return about;
|
||||
};
|
||||
|
||||
// Display about management page
|
||||
exports.index = async (req, res) => {
|
||||
try {
|
||||
const data = await getAboutData();
|
||||
res.render('admin/about', {
|
||||
title: 'About Management',
|
||||
data
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
req.flash('error_msg', 'Error loading about data');
|
||||
res.redirect('/admin/dashboard');
|
||||
}
|
||||
};
|
||||
|
||||
// Update about data
|
||||
exports.update = async (req, res) => {
|
||||
try {
|
||||
// Lấy document hiện tại từ MongoDB
|
||||
const currentData = await getAboutData();
|
||||
|
||||
// Danh sách các section cần cập nhật
|
||||
const sections = ['banner', 'about', 'values', 'education', 'advantages', 'academic_board'];
|
||||
const errors = [];
|
||||
let hasChanges = false;
|
||||
|
||||
// Tạo đối tượng dữ liệu mới dựa trên dữ liệu hiện tại
|
||||
const updatedData = { ...currentData.toObject() };
|
||||
|
||||
// Xử lý từng section
|
||||
sections.forEach(section => {
|
||||
try {
|
||||
// Kiểm tra nếu section không được gửi lên
|
||||
if (!req.body[section]) {
|
||||
console.warn(`No data for section: ${section}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse dữ liệu JSON từ form
|
||||
const newSectionData = JSON.parse(req.body[section]);
|
||||
|
||||
// So sánh dữ liệu mới với dữ liệu hiện tại
|
||||
const currentSectionData = currentData[section];
|
||||
const sectionHasChanges = JSON.stringify(newSectionData) !== JSON.stringify(currentSectionData);
|
||||
|
||||
// Nếu có thay đổi, cập nhật vào đối tượng dữ liệu mới
|
||||
if (sectionHasChanges) {
|
||||
updatedData[section] = newSectionData;
|
||||
hasChanges = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error processing section ${section}:`, error);
|
||||
errors.push(`Error processing ${section} data: ${error.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Nếu có lỗi, thông báo và chuyển hướng
|
||||
if (errors.length > 0) {
|
||||
req.flash('error_msg', `Data processing error: ${errors[0]}`);
|
||||
return req.session.save(() => res.redirect('/admin/about'));
|
||||
}
|
||||
|
||||
// Nếu không có thay đổi, thông báo và chuyển hướng
|
||||
if (!hasChanges) {
|
||||
req.flash('info_msg', 'No changes were made');
|
||||
return req.session.save(() => res.redirect('/admin/about'));
|
||||
}
|
||||
|
||||
try {
|
||||
// Cập nhật hoặc tạo mới document trong MongoDB
|
||||
if (currentData._id) {
|
||||
await About.findByIdAndUpdate(currentData._id, updatedData, { new: true });
|
||||
} else {
|
||||
await About.create(updatedData);
|
||||
}
|
||||
|
||||
// Success notification and redirect
|
||||
req.flash('success_msg', 'About data updated successfully');
|
||||
return req.session.save(() => res.redirect('/admin/about'));
|
||||
} catch (dbError) {
|
||||
console.error('Database error:', dbError);
|
||||
req.flash('error_msg', `Database error: ${dbError.message || 'Unknown'}`);
|
||||
return req.session.save(() => res.redirect('/admin/about'));
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Update error:', err);
|
||||
req.flash('error_msg', `Update error: ${err.message || 'Unknown'}`);
|
||||
return req.session.save(() => res.redirect('/admin/about'));
|
||||
}
|
||||
};
|
||||
|
||||
// API to get about data
|
||||
exports.api = async (req, res) => {
|
||||
try {
|
||||
const aboutData = await getAboutData();
|
||||
const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`;
|
||||
const processedData = addBaseUrlToImages(aboutData, baseUrl);
|
||||
res.json(processedData);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
res.status(500).json({ error: 'Error loading about data' });
|
||||
}
|
||||
};
|
||||
@@ -1,363 +1,141 @@
|
||||
const {addBaseUrlToImages} = require("../utils/imageHelper");
|
||||
const About = require("../models/about");
|
||||
const { addBaseUrlToImages } = require("../utils/imageHelper");
|
||||
const AboutUs = require("../models/aboutUs");
|
||||
const jsonHelper = require("../utils/jsonHelper");
|
||||
|
||||
// -------------------- Public (read-only) helpers --------------------
|
||||
// Map stored About document back to the original aboutUs.json shape
|
||||
function transformToAboutUs(doc) {
|
||||
if (!doc) return null;
|
||||
|
||||
const hero = {
|
||||
banner: doc.banner?.image || "",
|
||||
title: doc.banner?.title || "",
|
||||
breadcrumb: doc.banner?.text || "",
|
||||
};
|
||||
|
||||
const stats = Array.isArray(doc.advantages?.items)
|
||||
? doc.advantages.items.map((item) => ({
|
||||
number: item.number || "",
|
||||
description: item.title || "",
|
||||
}))
|
||||
: [];
|
||||
|
||||
const services = Array.isArray(doc.about?.paragraphs)
|
||||
? doc.about.paragraphs.map((p) => ({title: "", description: p}))
|
||||
: [];
|
||||
|
||||
const features = Array.isArray(doc.values?.items)
|
||||
? doc.values.items.map((i) => ({
|
||||
title: i.title || "",
|
||||
description: i.text || "",
|
||||
icon: i.icon || "",
|
||||
}))
|
||||
: [];
|
||||
|
||||
const events = Array.isArray(doc.academic_board?.members)
|
||||
? doc.academic_board.members.map((m) => ({
|
||||
imageUrl: m.image || "",
|
||||
date: "",
|
||||
title: m.title || "",
|
||||
description: "",
|
||||
authorName: m.name || "",
|
||||
authorRole: "",
|
||||
}))
|
||||
: [];
|
||||
|
||||
return {
|
||||
hero,
|
||||
stats,
|
||||
services,
|
||||
features,
|
||||
events,
|
||||
};
|
||||
}
|
||||
|
||||
// Get aboutUs data: prefer AboutUs collection, fallback to transforming About
|
||||
const getAboutUsData = async () => {
|
||||
// Prefer stored AboutUs document
|
||||
const aboutUsDoc = await AboutUs.findOne().sort({updatedAt: -1});
|
||||
if (aboutUsDoc)
|
||||
return aboutUsDoc.toObject ? aboutUsDoc.toObject() : aboutUsDoc;
|
||||
|
||||
// Fallback: transform legacy About document into aboutUs shape
|
||||
const about = await About.findOne().sort({updatedAt: -1});
|
||||
if (!about) return null;
|
||||
return transformToAboutUs(about);
|
||||
};
|
||||
|
||||
// -------------------- Admin (CRUD on AboutUs model) helpers --------------------
|
||||
// Default shape for AboutUs documents (matches data/aboutUs.json)
|
||||
const getDefaultAboutUsData = () => ({
|
||||
hero: {title: "", backgroundImage: ""},
|
||||
introduction: {
|
||||
subtitle: "",
|
||||
title: "",
|
||||
description: "",
|
||||
mainImage: "",
|
||||
services: [],
|
||||
},
|
||||
statistics: {
|
||||
items: [],
|
||||
},
|
||||
accommodation: {
|
||||
subtitle: "",
|
||||
title: "",
|
||||
description: "",
|
||||
features: [],
|
||||
},
|
||||
activities: {
|
||||
subtitle: "",
|
||||
title: "",
|
||||
description: "",
|
||||
gallery: [],
|
||||
},
|
||||
newsletter: {
|
||||
imagePath: "",
|
||||
title: "",
|
||||
description: "",
|
||||
buttonText: "",
|
||||
},
|
||||
events: {
|
||||
title: "",
|
||||
items: [],
|
||||
},
|
||||
});
|
||||
|
||||
// Get latest stored AboutUs document or default (returned as plain object)
|
||||
const getStoredAboutUs = async () => {
|
||||
const aboutUs = await AboutUs.findOne().sort({updatedAt: -1});
|
||||
if (!aboutUs) return getDefaultAboutUsData();
|
||||
return aboutUs.toObject ? aboutUs.toObject() : aboutUs;
|
||||
};
|
||||
|
||||
// -------------------- Public exports --------------------
|
||||
// Public endpoint: return AboutUs JSON (previously rendered HTML)
|
||||
exports.page = async (req, res) => {
|
||||
try {
|
||||
const aboutUsData = await getAboutUsData();
|
||||
const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`;
|
||||
const processed = addBaseUrlToImages(aboutUsData || {}, baseUrl);
|
||||
return res.json(processed);
|
||||
} catch (err) {
|
||||
console.error("aboutUs.page error:", err);
|
||||
return res.status(500).json({ error: "Error loading about-us data" });
|
||||
}
|
||||
};
|
||||
|
||||
// API endpoint to return aboutUs JSON
|
||||
exports.api = async (req, res) => {
|
||||
try {
|
||||
const aboutUsData = await getAboutUsData();
|
||||
const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`;
|
||||
const processed = addBaseUrlToImages(aboutUsData || {}, baseUrl);
|
||||
return res.json(processed);
|
||||
} catch (err) {
|
||||
console.error("aboutUs.api error:", err);
|
||||
return res.status(500).json({error: "Error loading about-us data"});
|
||||
}
|
||||
};
|
||||
|
||||
// API endpoint to return an array of AboutUs records (for frontend listing)
|
||||
exports.apiList = async (req, res) => {
|
||||
try {
|
||||
const docs = await AboutUs.find().sort({ updatedAt: -1 }).lean();
|
||||
const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`;
|
||||
const processed = (docs || []).map((d) => addBaseUrlToImages(d || {}, baseUrl));
|
||||
return res.json(processed);
|
||||
} catch (err) {
|
||||
console.error("aboutUs.apiList error:", err);
|
||||
return res.status(500).json({ error: "Error loading about-us list" });
|
||||
}
|
||||
};
|
||||
|
||||
// -------------------- Admin exports --------------------
|
||||
// Display AboutUs management page
|
||||
exports.index = async (req, res) => {
|
||||
try {
|
||||
const data = await getStoredAboutUs();
|
||||
const items = await AboutUs.find().sort({updatedAt: -1}).limit(10);
|
||||
|
||||
res.render("admin/aboutUs/index", {
|
||||
layout: "layouts/main",
|
||||
title: "About Us Management",
|
||||
data,
|
||||
items,
|
||||
frontendUrl:
|
||||
process.env.FRONTEND_URL || req.protocol + "://" + req.get("host"),
|
||||
currentPath: req.path,
|
||||
user: req.session.user,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
req.flash("error_msg", "Error loading About Us data");
|
||||
res.redirect("/admin/dashboard");
|
||||
}
|
||||
};
|
||||
|
||||
// Display create form
|
||||
exports.createForm = async (req, res) => {
|
||||
try {
|
||||
const data = getDefaultAboutUsData();
|
||||
|
||||
res.render("admin/aboutUs/create", {
|
||||
layout: "layouts/main",
|
||||
title: "Create About Us",
|
||||
data,
|
||||
currentPath: req.path,
|
||||
user: req.session.user,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
req.flash("error_msg", "Error loading create form");
|
||||
res.redirect("/admin/about-us");
|
||||
}
|
||||
};
|
||||
|
||||
// Create new AboutUs record
|
||||
exports.create = async (req, res) => {
|
||||
try {
|
||||
const aboutUsData = {
|
||||
hero: JSON.parse(req.body.hero || "{}"),
|
||||
introduction: JSON.parse(req.body.introduction || "{}"),
|
||||
statistics: JSON.parse(req.body.statistics || "{}"),
|
||||
accommodation: JSON.parse(req.body.accommodation || "{}"),
|
||||
activities: JSON.parse(req.body.activities || "{}"),
|
||||
newsletter: JSON.parse(req.body.newsletter || "{}"),
|
||||
events: JSON.parse(req.body.events || "{}"),
|
||||
};
|
||||
|
||||
const newAboutUs = new AboutUs(aboutUsData);
|
||||
await newAboutUs.save();
|
||||
|
||||
req.flash("success_msg", "About Us created successfully");
|
||||
res.redirect("/admin/about-us");
|
||||
} catch (err) {
|
||||
console.error("Create error:", err);
|
||||
req.flash("error_msg", `Create error: ${err.message || "Unknown"}`);
|
||||
res.redirect("/admin/about-us/create");
|
||||
}
|
||||
};
|
||||
|
||||
// Display edit form
|
||||
exports.editForm = async (req, res) => {
|
||||
try {
|
||||
const aboutUs = await AboutUs.findById(req.params.id);
|
||||
|
||||
if (!aboutUs) {
|
||||
req.flash("error_msg", "About Us record not found");
|
||||
return res.redirect("/admin/about-us");
|
||||
}
|
||||
|
||||
res.render("admin/aboutUs/edit", {
|
||||
layout: "layouts/main",
|
||||
title: "Edit About Us",
|
||||
data: aboutUs.toObject ? aboutUs.toObject() : aboutUs,
|
||||
currentPath: req.path,
|
||||
user: req.session.user,
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
req.flash("error_msg", "Error loading edit form");
|
||||
res.redirect("/admin/about-us");
|
||||
}
|
||||
};
|
||||
|
||||
// Update AboutUs record
|
||||
exports.update = async (req, res) => {
|
||||
try {
|
||||
// Get current data
|
||||
const currentData = await getStoredAboutUs();
|
||||
|
||||
// Parse form data
|
||||
const sections = [
|
||||
"hero",
|
||||
"introduction",
|
||||
"statistics",
|
||||
"accommodation",
|
||||
"activities",
|
||||
"newsletter",
|
||||
"events",
|
||||
];
|
||||
const errors = [];
|
||||
let hasChanges = false;
|
||||
|
||||
// Create updated data object
|
||||
const updatedData = {
|
||||
...(currentData.toObject ? currentData.toObject() : currentData),
|
||||
};
|
||||
|
||||
// Process each section
|
||||
sections.forEach((section) => {
|
||||
try {
|
||||
if (!req.body[section]) {
|
||||
console.warn(`No data for section: ${section}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const newSectionData = JSON.parse(req.body[section]);
|
||||
const currentSectionData = currentData[section];
|
||||
const sectionHasChanges =
|
||||
JSON.stringify(newSectionData) !== JSON.stringify(currentSectionData);
|
||||
|
||||
if (sectionHasChanges) {
|
||||
updatedData[section] = newSectionData;
|
||||
hasChanges = true;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error processing section ${section}:`, error);
|
||||
errors.push(`Error processing ${section} data: ${error.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
if (errors.length > 0) {
|
||||
req.flash("error_msg", `Data processing error: ${errors[0]}`);
|
||||
return req.session.save(() => res.redirect("/admin/about-us"));
|
||||
}
|
||||
|
||||
if (!hasChanges) {
|
||||
req.flash("info_msg", "No changes were made");
|
||||
return req.session.save(() => res.redirect("/admin/about-us"));
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /api/about
|
||||
* Lấy dữ liệu About Us (Public API cho website và CMS load dữ liệu)
|
||||
*/
|
||||
exports.getAbout = async (req, res) => {
|
||||
try {
|
||||
// Only update existing document; do not create a new one here
|
||||
if (!currentData || !currentData._id) {
|
||||
req.flash("error_msg", "No existing About Us record to update. Create one first.");
|
||||
return req.session.save(() => res.redirect("/admin/about-us"));
|
||||
}
|
||||
// Force no-cache headers
|
||||
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
|
||||
res.setHeader('Pragma', 'no-cache');
|
||||
res.setHeader('Expires', '0');
|
||||
|
||||
await AboutUs.findByIdAndUpdate(currentData._id, updatedData, {
|
||||
new: true,
|
||||
});
|
||||
const data = await AboutUs.getSingle();
|
||||
const rawData = data.toObject();
|
||||
|
||||
req.flash("success_msg", "About Us data updated successfully");
|
||||
return req.session.save(() => res.redirect("/admin/about-us"));
|
||||
} catch (dbError) {
|
||||
console.error("Database error:", dbError);
|
||||
req.flash("error_msg", `Database error: ${dbError.message || "Unknown"}`);
|
||||
return req.session.save(() => res.redirect("/admin/about-us"));
|
||||
const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`;
|
||||
const processedData = addBaseUrlToImages(rawData, baseUrl);
|
||||
|
||||
res.json(processedData);
|
||||
} catch (error) {
|
||||
console.error("Error getting about data:", error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: "Failed to get about data"
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Update error:", err);
|
||||
req.flash("error_msg", `Update error: ${err.message || "Unknown"}`);
|
||||
return req.session.save(() => res.redirect("/admin/about-us"));
|
||||
}
|
||||
};
|
||||
|
||||
// Delete AboutUs record
|
||||
exports.delete = async (req, res) => {
|
||||
try {
|
||||
const aboutUs = await AboutUs.findById(req.params.id);
|
||||
/**
|
||||
* PUT /api/about
|
||||
* Cập nhật dữ liệu About Us (Dùng cho AJAX từ CMS)
|
||||
*/
|
||||
exports.updateAbout = async (req, res) => {
|
||||
try {
|
||||
let updateData = req.body;
|
||||
|
||||
if (!aboutUs) {
|
||||
req.flash("error_msg", "About Us record not found");
|
||||
return res.redirect("/admin/about-us");
|
||||
// Nếu dữ liệu gửi qua trường aboutJson (dạng string JSON)
|
||||
if (updateData.aboutJson && typeof updateData.aboutJson === "string") {
|
||||
try {
|
||||
updateData = JSON.parse(updateData.aboutJson);
|
||||
} catch (e) {
|
||||
return res.status(400).json({
|
||||
success: false,
|
||||
message: "Invalid JSON in aboutJson"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const doc = await AboutUs.getSingle();
|
||||
// Use .set() for better handling of nested objects/arrays in Mongoose
|
||||
doc.set(updateData);
|
||||
await doc.save();
|
||||
|
||||
// Fetch fresh data for syncing and returning
|
||||
const finalData = await AboutUs.findOne()
|
||||
.select('-_id -__v -createdAt -updatedAt')
|
||||
.lean();
|
||||
|
||||
// Update about.json file to keep it in sync
|
||||
jsonHelper.writeJsonFile("about", finalData);
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: "About Us updated successfully",
|
||||
data: finalData
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error updating about data:", error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
error: "Failed to update about data: " + error.message
|
||||
});
|
||||
}
|
||||
|
||||
await AboutUs.findByIdAndDelete(req.params.id);
|
||||
|
||||
req.flash("success_msg", "About Us record deleted successfully");
|
||||
res.redirect("/admin/about-us");
|
||||
} catch (err) {
|
||||
console.error("Delete error:", err);
|
||||
req.flash("error_msg", `Delete error: ${err.message || "Unknown"}`);
|
||||
res.redirect("/admin/about-us");
|
||||
}
|
||||
};
|
||||
|
||||
// Preview AboutUs record
|
||||
exports.preview = async (req, res) => {
|
||||
try {
|
||||
const aboutUs = await AboutUs.findById(req.params.id);
|
||||
/**
|
||||
* Render admin page (Dùng cho Admin UI)
|
||||
*/
|
||||
exports.index = async (req, res) => {
|
||||
try {
|
||||
const data = await AboutUs.getSingle();
|
||||
const rawData = data.toObject();
|
||||
|
||||
if (!aboutUs) {
|
||||
return res.status(404).json({error: "About Us record not found"});
|
||||
const activeTab = req.query.activeTab || "hero";
|
||||
res.render("admin/aboutUs/index", {
|
||||
layout: "layouts/main",
|
||||
title: "About Us Management",
|
||||
data: rawData,
|
||||
activeTab,
|
||||
user: req.session.user,
|
||||
currentPath: req.path,
|
||||
frontendUrl: process.env.FRONTEND_URL || 'http://localhost:3000'
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Error in about index:", err);
|
||||
req.flash("error_msg", "Error loading About Us page");
|
||||
res.redirect("/admin/dashboard");
|
||||
}
|
||||
|
||||
const processedData = addBaseUrlToImages(aboutUs.toObject());
|
||||
res.json(processedData);
|
||||
} catch (err) {
|
||||
console.error("Preview error:", err);
|
||||
res.status(500).json({error: "Error loading preview data"});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Update method cho form-based submission (Admin UI - Post fallback)
|
||||
*/
|
||||
exports.update = async (req, res) => {
|
||||
try {
|
||||
let updateData = req.body;
|
||||
if (updateData.aboutJson && typeof updateData.aboutJson === "string") {
|
||||
try {
|
||||
updateData = JSON.parse(updateData.aboutJson);
|
||||
} catch (e) {
|
||||
req.flash("error_msg", "Invalid JSON data");
|
||||
return res.redirect("/admin/about-us");
|
||||
}
|
||||
}
|
||||
|
||||
const doc = await AboutUs.getSingle();
|
||||
doc.set(updateData);
|
||||
await doc.save();
|
||||
|
||||
const finalData = await AboutUs.findOne()
|
||||
.select('-_id -__v -createdAt -updatedAt')
|
||||
.lean();
|
||||
jsonHelper.writeJsonFile("about", finalData);
|
||||
|
||||
req.flash("success_msg", "About Us updated successfully");
|
||||
const activeTab = req.query.activeTab || "hero";
|
||||
res.redirect(`/admin/about-us?activeTab=${activeTab}`);
|
||||
} catch (err) {
|
||||
console.error("Update error:", err);
|
||||
req.flash("error_msg", "Error updating About Us: " + err.message);
|
||||
res.redirect("/admin/about-us");
|
||||
}
|
||||
};
|
||||
|
||||
// Aliases for compatibility
|
||||
exports.api = exports.getAbout;
|
||||
exports.page = exports.getAbout;
|
||||
exports.updateAboutUs = exports.updateAbout;
|
||||
|
||||
Reference in New Issue
Block a user