Files
uldp-degree-mangement-system/controllers/campLocationController.js
r2xrzh9q2z-lab d1b931d547 first commit
2026-02-02 11:07:09 +07:00

323 lines
10 KiB
JavaScript

const { addBaseUrlToImages } = require('../utils/imageHelper');
const CampLocation = require('../models/campLocation');
// -------------------- Public (read-only) helpers --------------------
// Get camp location data from MongoDB
const getCampLocationData = async () => {
const campLocation = await CampLocation.findOne().sort({ updatedAt: -1 });
if (!campLocation) return null;
return campLocation.toObject ? campLocation.toObject() : campLocation;
};
// -------------------- Admin (CRUD on CampLocation model) helpers --------------------
// Default shape for CampLocation documents
const getDefaultCampLocationData = () => ({
metadata: { title: '', description: '', keywords: '' },
hero: { title: '', subtitle: '', backgroundImage: '' },
camps: [],
locations: [],
locationsSection: { title: '', description: '' },
intro: { title: '', description: '' },
map: {
coordinates: { lat: 0, lng: 0 },
zoom: 15,
location: '',
markerTitle: '',
tileLayer: {
url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '',
maxZoom: 18,
minZoom: 0
}
},
faq: [],
faqSection: { title: '', description: '' },
welcomeQuote: { text: '', author: '' },
securityConcept: { title: '', description: '', items: [] }
});
// Get latest stored CampLocation document or default
const getStoredCampLocation = async () => {
const campLocation = await CampLocation.findOne().sort({ updatedAt: -1 });
if (!campLocation) return getDefaultCampLocationData();
return campLocation.toObject ? campLocation.toObject() : campLocation;
};
// -------------------- Public exports --------------------
// API endpoint to return camp location JSON
exports.api = async (req, res) => {
try {
const campLocationData = await getCampLocationData();
const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`;
const processed = addBaseUrlToImages(campLocationData || {}, baseUrl);
return res.json(processed);
} catch (err) {
console.error('campLocation.api error:', err);
return res.status(500).json({ error: 'Error loading camp location data' });
}
};
// API endpoint to return an array of CampLocation records (for frontend listing)
exports.apiList = async (req, res) => {
try {
const docs = await CampLocation.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('campLocation.apiList error:', err);
return res.status(500).json({ error: 'Error loading camp location list' });
}
};
// -------------------- Admin exports --------------------
// Display camp location management page
exports.index = async (req, res) => {
try {
// Set cache control headers to prevent caching
res.set({
'Cache-Control': 'no-store, no-cache, must-revalidate, private',
'Pragma': 'no-cache',
'Expires': '0'
});
const data = await getStoredCampLocation();
const items = await CampLocation.find().sort({ updatedAt: -1 }).limit(10);
res.render('admin/campLocation/index', {
layout: 'layouts/main',
title: 'Camp Location 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 camp location data');
res.redirect('/admin/dashboard');
}
};
// Display create form
exports.createForm = async (req, res) => {
try {
const data = getDefaultCampLocationData();
res.render('admin/campLocation/create', {
layout: 'layouts/main',
title: 'Create Camp Location',
data,
currentPath: req.path,
user: req.session.user
});
} catch (err) {
console.error(err);
req.flash('error_msg', 'Error loading create form');
res.redirect('/admin/camp-location');
}
};
// Create new CampLocation record
exports.create = async (req, res) => {
try {
const campLocationData = {
metadata: JSON.parse(req.body.metadata || '{}'),
hero: JSON.parse(req.body.hero || '{}'),
camps: JSON.parse(req.body.camps || '[]'),
locations: JSON.parse(req.body.locations || '[]'),
locationsSection: JSON.parse(req.body.locationsSection || '{}'),
intro: JSON.parse(req.body.intro || '{}'),
map: JSON.parse(req.body.map || '{}'),
faq: JSON.parse(req.body.faq || '[]'),
faqSection: JSON.parse(req.body.faqSection || '{}'),
welcomeQuote: JSON.parse(req.body.welcomeQuote || '{}'),
securityConcept: JSON.parse(req.body.securityConcept || '{}')
};
const newCampLocation = new CampLocation(campLocationData);
await newCampLocation.save();
req.flash('success_msg', 'Camp Location created successfully');
res.redirect('/admin/camp-location');
} catch (err) {
console.error('Create error:', err);
req.flash('error_msg', `Create error: ${err.message || 'Unknown'}`);
res.redirect('/admin/camp-location/create');
}
};
// Display edit form
exports.editForm = async (req, res) => {
try {
const campLocation = await CampLocation.findById(req.params.id);
if (!campLocation) {
req.flash('error_msg', 'Camp Location record not found');
return res.redirect('/admin/camp-location');
}
res.render('admin/campLocation/edit', {
layout: 'layouts/main',
title: 'Edit Camp Location',
data: campLocation.toObject ? campLocation.toObject() : campLocation,
currentPath: req.path,
user: req.session.user
});
} catch (err) {
console.error(err);
req.flash('error_msg', 'Error loading edit form');
res.redirect('/admin/camp-location');
}
};
// Update CampLocation record
exports.update = async (req, res) => {
try {
// Get current data
const currentData = await getStoredCampLocation();
// List of sections to update
const sections = [
'metadata',
'hero',
'camps',
'locations',
'locationsSection',
'intro',
'map',
'faq',
'faqSection',
'welcomeQuote',
'securityConcept'
];
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/camp-location'));
}
if (!hasChanges) {
req.flash('info_msg', 'No changes were made');
return req.session.save(() => res.redirect('/admin/camp-location'));
}
try {
// Only update existing document; do not create a new one here
if (!currentData || !currentData._id) {
req.flash('error_msg', 'No existing Camp Location record to update. Create one first.');
return req.session.save(() => res.redirect('/admin/camp-location'));
}
// Update document and ensure it's saved to MongoDB
const updatedDoc = await CampLocation.findByIdAndUpdate(
currentData._id,
updatedData,
{
new: true,
runValidators: true,
useFindAndModify: false
}
);
// Verify the update was successful
if (!updatedDoc) {
throw new Error('Failed to update document');
}
// Force a save to ensure MongoDB commits the changes
await updatedDoc.save();
console.log('✓ Camp location updated successfully in MongoDB');
console.log('✓ Document ID:', updatedDoc._id);
console.log('✓ Updated at:', updatedDoc.updatedAt);
req.flash('success_msg', 'Camp location data updated successfully');
// Redirect back to the same page with cache-busting parameter to force refresh
const timestamp = Date.now();
return req.session.save(() => res.redirect(`/admin/camp-location?updated=${timestamp}`));
} catch (dbError) {
console.error('Database error:', dbError);
req.flash('error_msg', `Database error: ${dbError.message || 'Unknown'}`);
return req.session.save(() => res.redirect('/admin/camp-location'));
}
} catch (err) {
console.error('Update error:', err);
req.flash('error_msg', `Update error: ${err.message || 'Unknown'}`);
return req.session.save(() => res.redirect('/admin/camp-location'));
}
};
// Delete CampLocation record
exports.delete = async (req, res) => {
try {
const campLocation = await CampLocation.findById(req.params.id);
if (!campLocation) {
req.flash('error_msg', 'Camp Location record not found');
return res.redirect('/admin/camp-location');
}
await CampLocation.findByIdAndDelete(req.params.id);
req.flash('success_msg', 'Camp Location record deleted successfully');
res.redirect('/admin/camp-location');
} catch (err) {
console.error('Delete error:', err);
req.flash('error_msg', `Delete error: ${err.message || 'Unknown'}`);
res.redirect('/admin/camp-location');
}
};
// Preview CampLocation record
exports.preview = async (req, res) => {
try {
const campLocation = await CampLocation.findById(req.params.id);
if (!campLocation) {
return res.status(404).json({ error: 'Camp Location record not found' });
}
const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`;
const processedData = addBaseUrlToImages(
campLocation.toObject ? campLocation.toObject() : campLocation,
baseUrl
);
res.json(processedData);
} catch (err) {
console.error('Preview error:', err);
res.status(500).json({ error: 'Error loading preview data' });
}
};