Initial commit: CMS backend for Old Vine Hotel

- Complete Express.js API server
- MongoDB integration with Mongoose
- Admin authentication and authorization
- Room management (CRUD operations)
- Booking management system
- Guest management
- Payment processing (Stripe integration)
- Content management (pages, blog, gallery)
- Media upload and management
- Integration services (Booking.com, Expedia, Opera PMS, Trip.com)
- Email notifications
- Comprehensive logging and error handling
This commit is contained in:
Talal Sharabi
2026-01-06 12:21:56 +04:00
commit a3308a26e2
48 changed files with 15294 additions and 0 deletions

93
models/GalleryCategory.js Normal file
View File

@@ -0,0 +1,93 @@
const mongoose = require('mongoose');
const galleryCategorySchema = new mongoose.Schema({
// Basic category information
name: {
type: String,
required: true,
trim: true,
unique: true
},
slug: {
type: String,
required: true,
unique: true,
lowercase: true
},
description: {
type: String,
required: false
},
shortDescription: {
type: String,
maxlength: 200
},
// Category images (gallery)
images: [{
url: {
type: String,
required: true
},
alt: {
type: String,
default: ''
},
isPrimary: {
type: Boolean,
default: false
},
order: {
type: Number,
default: 0
}
}],
// Display settings
isActive: {
type: Boolean,
default: true
},
displayOrder: {
type: Number,
default: 0
},
// SEO and metadata
metaTitle: String,
metaDescription: String
}, {
timestamps: true,
toJSON: { virtuals: true },
toObject: { virtuals: true }
});
// Indexes
galleryCategorySchema.index({ slug: 1 });
galleryCategorySchema.index({ isActive: 1, displayOrder: 1 });
// Pre-save middleware to generate slug
galleryCategorySchema.pre('save', function(next) {
if (this.isModified('name') || !this.slug) {
this.slug = this.name
.toLowerCase()
.replace(/[^a-z0-9]/g, '-')
.replace(/-+/g, '-')
.replace(/^-|-$/g, '');
}
next();
});
// Virtual for primary image
galleryCategorySchema.virtual('primaryImage').get(function() {
const primary = this.images.find(img => img.isPrimary);
return primary ? primary.url : (this.images.length > 0 ? this.images[0].url : null);
});
// Virtual for image count
galleryCategorySchema.virtual('imageCount').get(function() {
return this.images.length;
});
module.exports = mongoose.model('GalleryCategory', galleryCategorySchema);