Files
cms.uldp.edu.vn/models/campLocation.js
r2xrzh9q2z-lab d1b931d547 first commit
2026-02-02 11:07:09 +07:00

246 lines
5.0 KiB
JavaScript

const mongoose = require('mongoose');
// Sub-schemas for better organization
const programOptionSchema = new mongoose.Schema({
_comment: String,
href: String,
imageSrc: String,
title: String,
description: String
}, { _id: false });
const locationSchema = new mongoose.Schema({
_comment: String,
id: {
type: Number,
required: true
},
country: String,
title: String,
imageSrc: String,
imageAlt: String,
readMoreLink: String,
imagePosition: {
type: String,
enum: ['left', 'right']
},
cardSize: {
type: String,
enum: ['default', 'large']
},
scrollspyClass: String,
programOptions: [programOptionSchema]
}, { _id: false });
const campMarkerSchema = new mongoose.Schema({
_comment: String,
id: {
type: Number,
required: true
},
lat: {
type: Number,
required: false // Changed to false since coordinates are optional
},
lng: {
type: Number,
required: false // Changed to false since coordinates are optional
},
title: {
type: String,
required: true
},
image: String
}, { _id: false });
const faqItemSchema = new mongoose.Schema({
_comment: String,
question: {
type: String,
required: true
},
answer: {
type: String,
required: true
}
}, { _id: false });
const securityItemSchema = new mongoose.Schema({
_comment: String,
title: {
type: String,
required: true
},
content: {
type: String,
required: true
}
}, { _id: false });
// Map schemas (similar to contact model)
const coordinatesSchema = new mongoose.Schema({
lat: {
type: Number,
required: true
},
lng: {
type: Number,
required: true
}
}, { _id: false });
const tileLayerSchema = new mongoose.Schema({
url: {
type: String,
required: true,
trim: true
},
attribution: {
type: String,
trim: true,
default: ''
},
maxZoom: {
type: Number,
default: 18
},
minZoom: {
type: Number,
default: 0
}
}, { _id: false });
const mapSchema = new mongoose.Schema({
_comment: String,
coordinates: {
type: coordinatesSchema,
required: true
},
zoom: {
type: Number,
default: 15
},
location: {
type: String,
required: true,
trim: true
},
markerTitle: {
type: String,
trim: true,
default: ''
},
tileLayer: {
type: tileLayerSchema,
required: true
}
}, { _id: false });
// Main schema
const campLocationSchema = new mongoose.Schema({
metadata: {
_comment: String,
title: String,
description: String
},
hero: {
_comment: String,
title: String,
backgroundImage: String,
overlayColor: String
},
camps: [campMarkerSchema],
locationsSection: {
_comment: String,
title: String,
readMoreButtonText: {
type: String,
default: 'read more'
}
},
locations: [locationSchema],
intro: {
_comment: String,
content: String
},
map: {
coordinates: {
lat: { type: Number, default: 0 },
lng: { type: Number, default: 0 }
},
zoom: { type: Number, default: 5 },
location: { type: String, default: '' },
markerTitle: { type: String, default: '' },
tileLayer: {
url: { type: String, default: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png' },
attribution: { type: String, default: '' },
maxZoom: { type: Number, default: 18 },
minZoom: { type: Number, default: 0 }
}
},
faqSection: {
_comment: String,
title: String,
buttonText: {
type: String,
default: 'More questions'
},
buttonIcon: {
type: String,
default: 'comments'
},
buttonLink: {
type: String,
default: '/info/faq'
}
},
faq: [faqItemSchema],
welcomeQuote: {
_comment: String,
title: String,
quote: String,
author: String
},
securityConcept: {
_comment: String,
title: String,
introduction: String,
items: [securityItemSchema]
},
updatedAt: Date
}, {
timestamps: true
});
// Indexes for better query performance
campLocationSchema.index({ 'camps.id': 1 });
campLocationSchema.index({ 'locations.id': 1 });
campLocationSchema.index({ 'locations.country': 1 });
// Virtual to get camp by ID
campLocationSchema.virtual('getCampById').get(function() {
return (id) => this.camps.find(camp => camp.id === id);
});
// Virtual to get location by ID
campLocationSchema.virtual('getLocationById').get(function() {
return (id) => this.locations.find(location => location.id === id);
});
// Method to get locations by country
campLocationSchema.methods.getLocationsByCountry = function(country) {
return this.locations.filter(location => location.country === country);
};
// Method to get all countries
campLocationSchema.methods.getAllCountries = function() {
return [...new Set(this.locations.map(location => location.country))];
};
// Static method to get the latest camp location data
campLocationSchema.statics.getLatest = function() {
return this.findOne().sort({ updatedAt: -1 });
};
module.exports = mongoose.model('CampLocation', campLocationSchema);