const {addBaseUrlToImages} = require("../utils/imageHelper"); const About = require("../models/about"); const AboutUs = require("../models/aboutUs"); // -------------------- 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")); } 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")); } await AboutUs.findByIdAndUpdate(currentData._id, updatedData, { new: true, }); 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")); } } 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); if (!aboutUs) { req.flash("error_msg", "About Us record not found"); return res.redirect("/admin/about-us"); } 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); if (!aboutUs) { return res.status(404).json({error: "About Us record not found"}); } const processedData = addBaseUrlToImages(aboutUs.toObject()); res.json(processedData); } catch (err) { console.error("Preview error:", err); res.status(500).json({error: "Error loading preview data"}); } };