forked from UKSOURCE/cms.hailearning.edu.vn
246 lines
5.0 KiB
JavaScript
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);
|