first commit

This commit is contained in:
r2xrzh9q2z-lab
2026-02-02 11:07:09 +07:00
commit d1b931d547
286 changed files with 53992 additions and 0 deletions

222
models/faq.js Normal file
View File

@@ -0,0 +1,222 @@
const mongoose = require('mongoose');
const faqItemSchema = new mongoose.Schema({
title: {
type: String,
required: true
},
description: {
type: String,
required: true
}
}, { _id: true });
const faqSectionSchema = new mongoose.Schema({
id: {
type: String,
required: true
},
title: {
type: String,
required: true
},
faqs: [faqItemSchema]
}, { _id: true });
const sidebarNavSchema = new mongoose.Schema({
id: {
type: String,
required: true
},
label: {
type: String,
required: true
}
});
const heroSchema = new mongoose.Schema({
title: String,
backgroundImage: String,
overlayColor: String,
sectionClass: String,
titleClass: String,
enableScrollspy: Boolean,
backgroundPosition: String
});
const contactBoxSchema = new mongoose.Schema({
title: String,
phone: {
icon: String,
text: String
},
email: {
icon: String,
text: String
}
});
const videoSchema = new mongoose.Schema({
url: String,
title: String
});
const faqSchema = new mongoose.Schema({
name: {
type: String,
default: 'default',
},
hero: heroSchema,
sidebarNav: [sidebarNavSchema],
contactBox: contactBoxSchema,
faqSections: [faqSectionSchema],
video: videoSchema
}, {
timestamps: true
});
// Virtual property để tính tổng số FAQ items
faqSchema.virtual('totalFaqs').get(function() {
return this.faqSections.reduce((total, section) => {
return total + (section.faqs ? section.faqs.length : 0);
}, 0);
});
// Static method: Lấy FAQ mặc định
faqSchema.statics.getDefault = async function() {
let faq = await this.findOne({ name: 'default' });
// Nếu không có, tạo mới
if (!faq) {
faq = new this({
name: 'default',
hero: {
title: 'Frequently Asked Questions',
backgroundImage: 'yootheme/cache/18/faqs_header_new.jpg',
overlayColor: 'rgba(0, 0, 0, 0)',
sectionClass: 'uk-section-secondary uk-section-overlap uk-preserve-color uk-light',
titleClass: 'uk-heading-large uk-text-center !text-[5vw]',
enableScrollspy: true,
backgroundPosition: 'top-center'
},
sidebarNav: [
{ id: 'general-information', label: 'General Information' }
],
contactBox: {
title: 'Let\'s plan your perfect nature escape',
phone: { icon: 'phone', text: '+(123)-456-789' },
email: { icon: 'email', text: 'hello@ggcamp.org' }
},
faqSections: [
{
id: 'general-information',
title: 'General Information',
faqs: [
{
title: 'Sample FAQ Question',
description: 'This is a sample FAQ answer. Please update with your actual content.'
}
]
}
]
});
await faq.save();
}
return faq;
};
// Static method: Import từ JSON
faqSchema.statics.importFromJson = async function(data) {
let faq = await this.findOne({ name: 'default' });
// Đảm bảo có name
const faqData = {
name: 'default',
...data
};
if (!faq) {
faq = new this(faqData);
} else {
// Update các trường
Object.keys(faqData).forEach(key => {
faq[key] = faqData[key];
});
}
await faq.save();
return faq;
};
// Method: Thêm FAQ vào section
faqSchema.methods.addFaqToSection = async function(sectionId, faqItem) {
const section = this.faqSections.find(s => s.id === sectionId);
if (!section) {
throw new Error(`Section with id ${sectionId} not found`);
}
section.faqs.push(faqItem);
await this.save();
return this;
};
// Method: Update FAQ item
faqSchema.methods.updateFaqItem = async function(sectionId, faqId, updates) {
const section = this.faqSections.find(s => s.id === sectionId);
if (!section) {
throw new Error(`Section with id ${sectionId} not found`);
}
const faqItem = section.faqs.id(faqId);
if (!faqItem) {
throw new Error(`FAQ item with id ${faqId} not found in section ${sectionId}`);
}
if (updates.title !== undefined) faqItem.title = updates.title;
if (updates.description !== undefined) faqItem.description = updates.description;
await this.save();
return this;
};
// Method: Delete FAQ item
faqSchema.methods.deleteFaqItem = async function(sectionId, faqId) {
const section = this.faqSections.find(s => s.id === sectionId);
if (!section) {
throw new Error(`Section with id ${sectionId} not found`);
}
const faqItem = section.faqs.id(faqId);
if (!faqItem) {
throw new Error(`FAQ item with id ${faqId} not found in section ${sectionId}`);
}
section.faqs.pull(faqId);
await this.save();
return this;
};
// Method: Update FAQ section
faqSchema.methods.updateFaqSection = async function(sectionId, updates) {
const section = this.faqSections.find(s => s.id === sectionId);
if (!section) {
throw new Error(`Section with id ${sectionId} not found`);
}
if (updates.title !== undefined) section.title = updates.title;
await this.save();
return this;
};
const FAQ = mongoose.model('FAQ', faqSchema);
module.exports = FAQ;