const { addBaseUrlToImages } = require('../utils/imageHelper'); const Home = require('../models/home'); // -------------------- Helper Functions -------------------- // Get home data from MongoDB const getHomeData = async () => { const home = await Home.findOne().sort({ updatedAt: -1 }).lean(); return home || {}; }; // Get default home data structure const getDefaultHomeData = () => ({ hero: { title: '', description: '', backgroundImage: '', button: { label: 'Book Your Adventure', href: '/booking' }, contactBox: { welcomeText: '', phone: { label: 'Call us', number: '', href: '' }, email: { label: 'Email', address: '', href: '' }, workingHours: { label: 'Working Hours', hours: '' } } }, about: { title: '', subtitle: '', description: '', images: { mainImage1: '', mainImage2: '', avatars: [] }, features: [], quote: '', button: { label: '', href: '' }, stats: { customerCount: 0, customerLabel: '' } }, missionVision: { title: '', subtitle: '', backgroundImage: '', cards: [] }, whyChooseUs: { title: '', subtitle: '', description: '', button: { label: '', href: '' }, features: [], tags: [], cta: { text: '', linkText: '', linkHref: '' } }, activities: { cards: [] }, faq: { title: '', subtitle: '', description: '', image: '', contact: { title: '', info: '' }, questions: [] }, partners: { title: '', subtitle: '', backgroundImage: '', logos: [], cta: { badge: '', text: '', linkText: '', linkHref: '' } }, programs: { title: '', subtitle: '', button: { label: '', href: '' }, card: { pricePrefix: 'from', priceSuffix: 'USD', buttonLabel: 'Camp Detail', buttonHref: '/camp-profiles' }, items: [] }, newsletter: { title: '', subtitle: '', description: '', image: '', decorativeImage: '', button: { label: '', placeholder: '', href: '' } }, latestPosts: { title: '', subtitle: '', searchPlaceholder: '', sidebarTitle: '', blogPosts: [], sidebarPosts: [], featuredCard: { image: '', title: '', description: '' } } }); // -------------------- Admin Exports -------------------- // Display home management page exports.index = async (req, res) => { try { // Fetch Home data let data = await getHomeData(); // If no data exists, use default if (!data || Object.keys(data).length === 0) { data = getDefaultHomeData(); } else { // Merge with defaults to ensure all fields exist const defaultData = getDefaultHomeData(); // Ensure all sections exist with defaults data.hero = data.hero || defaultData.hero; data.about = data.about || defaultData.about; data.missionVision = data.missionVision || defaultData.missionVision; data.whyChooseUs = data.whyChooseUs || defaultData.whyChooseUs; data.activities = data.activities || defaultData.activities; data.faq = data.faq || defaultData.faq; data.partners = data.partners || defaultData.partners; data.programs = data.programs || defaultData.programs; data.newsletter = data.newsletter || defaultData.newsletter; data.latestPosts = data.latestPosts || defaultData.latestPosts; } const frontendUrl = process.env.FRONTEND_URL || 'http://localhost:3000'; res.render('admin/home/index', { layout: 'layouts/main', title: 'Home Management', data, frontendUrl, currentPath: req.path, user: req.session.user }); } catch (err) { console.error('Home index error:', err); req.flash('error_msg', 'Error loading home data'); res.redirect('/admin/dashboard'); } }; // Update home data exports.update = async (req, res) => { try { // Get current data const currentData = await getHomeData(); // Create updated data object const updatedData = { ...(currentData.toObject ? currentData.toObject() : currentData) }; // Update Hero section data (from Welcome tab) if (req.body.heroTitle || req.body.heroDescription || req.body.heroBackgroundImage) { updatedData.hero = { title: req.body.heroTitle || '', description: req.body.heroDescription || '', backgroundImage: req.body.heroBackgroundImage || '', button: { label: req.body.heroButtonLabel || 'Book Your Adventure', href: req.body.heroButtonHref || '/booking' }, contactBox: { welcomeText: req.body.heroContactWelcome || '', phone: { label: 'Call us', number: req.body.heroContactPhone || '', href: req.body.heroContactPhone ? `tel:${req.body.heroContactPhone}` : '' }, email: { label: 'Email', address: req.body.heroContactEmail || '', href: req.body.heroContactEmail ? `mailto:${req.body.heroContactEmail}` : '' }, workingHours: { label: 'Working Hours', hours: req.body.heroContactHours || '' } } }; } // Update Why Choose Us section if (req.body.whyChooseUsTitle || req.body.whyChooseUsSubtitle) { updatedData.whyChooseUs = { ...(updatedData.whyChooseUs || {}), title: req.body.whyChooseUsTitle || '', subtitle: req.body.whyChooseUsSubtitle || '', description: req.body.whyChooseUsDescription || '', button: { label: req.body.whyChooseUsButtonLabel || '', href: req.body.whyChooseUsButtonHref || '' }, features: updatedData.whyChooseUs?.features || [], tags: updatedData.whyChooseUs?.tags || [], cta: updatedData.whyChooseUs?.cta || { text: '', linkText: '', linkHref: '' } }; } // Handle Home sections (new camp structure only) const sections = ['hero', 'about', 'missionVision', 'whyChooseUs', 'activities', 'faq', 'partners', 'programs', 'newsletter', 'latestPosts']; const errors = []; let hasChanges = false; // Process each section for (const section of sections) { try { if (!req.body[section]) { console.warn(`No data for section: ${section}`); continue; } // Parse JSON data from form const newSectionData = JSON.parse(req.body[section]); // Check for changes 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}`); } } // Handle errors if (errors.length > 0) { req.flash('error_msg', `Data processing error: ${errors[0]}`); return req.session.save(() => res.redirect('/admin/home')); } // Check if there are changes if (!hasChanges) { req.flash('info_msg', 'No changes were made'); return req.session.save(() => res.redirect('/admin/home')); } // Update or create document try { if (currentData._id) { await Home.findByIdAndUpdate(currentData._id, updatedData, { new: true }); } else { await Home.create(updatedData); } req.flash('success_msg', 'Home data updated successfully'); return req.session.save(() => res.redirect('/admin/home')); } catch (dbError) { console.error('Database error:', dbError); req.flash('error_msg', `Database error: ${dbError.message || 'Unknown'}`); return req.session.save(() => res.redirect('/admin/home')); } } catch (err) { console.error('Update error:', err); req.flash('error_msg', `Update error: ${err.message || 'Unknown'}`); return req.session.save(() => res.redirect('/admin/home')); } }; // -------------------- Public API Exports -------------------- // API to get home data for frontend exports.api = async (req, res) => { try { const homeData = await getHomeData(); const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`; const processedData = addBaseUrlToImages(homeData, baseUrl); res.json(processedData); } catch (err) { console.error('Home API error:', err); res.status(500).json({ error: 'Error loading home data' }); } }; // API to get hero data for frontend exports.apiHero = async (req, res) => { try { const homeData = await getHomeData(); const heroData = homeData?.hero; if (!heroData) { return res.status(404).json({ error: 'Hero data not found', data: null }); } const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`; const processedData = addBaseUrlToImages(heroData, baseUrl); res.json(processedData); } catch (err) { console.error('Hero API error:', err); res.status(500).json({ error: 'Error loading hero data' }); } };