Refactor: remove unused APIs, controllers, models and data files. Update: icon picker all system, Dashboard, Main UI more respone, Change: Logo, favicon.

This commit is contained in:
2026-04-23 18:44:37 +07:00
parent 8ce6cf3c7e
commit 4ba3eb4a82
48 changed files with 438 additions and 14850 deletions
-194
View File
@@ -1,194 +0,0 @@
const mongoose = require("mongoose");
const activitySchema = new mongoose.Schema(
{
// Hero section for activity page header (supports Activities and Booking variants)
hero: {
titleActivities: {
type: String,
trim: true,
default: ''
},
titleBooking: {
type: String,
trim: true,
default: ''
},
bannerImageActivities: {
type: String,
trim: true,
default: ''
},
bannerImageBooking: {
type: String,
trim: true,
default: ''
},
},
name: {
type: String,
required: true,
trim: true,
},
price: {
type: Number,
required: true,
min: 0,
},
priceText: {
type: String,
trim: true,
},
season: [
{
type: String,
enum: ["spring", "summer", "autumn", "winter"],
},
],
age: {
type: [Number],
validate: {
validator: function (v) {
return v.length === 2 && v[0] <= v[1];
},
message: "Age must be an array of [minAge, maxAge]",
},
},
locations: [
{
type: String,
trim: true,
},
],
image: {
type: String,
trim: true,
},
link: {
type: String,
trim: true,
},
// Global filters document (single document in Activity collection)
filters: [
{
label: { type: String, required: true, trim: true },
value: { type: String, required: true, trim: true },
items: [
{
value: { type: String, required: true },
label: { type: String, required: true },
},
],
order: { type: Number, default: 0 },
},
],
program: {
type: String,
trim: true,
},
rating: {
type: Number,
min: 1,
max: 5,
default: 4,
},
isActive: {
type: Boolean,
default: true,
},
order: {
type: Number,
default: 0,
},
// marker for the single document that stores global filters
isFiltersDoc: {
type: Boolean,
default: false,
},
// Rich camp details from camp-detail field in activities.json
campDetail: {
type: mongoose.Schema.Types.Mixed,
default: {},
},
// Booking sessions - các đợt booking với thông số riêng
bookingSessions: [
{
sessionId: { type: String, required: true },
startDate: { type: Date, required: true },
endDate: { type: Date, required: true },
overnightStays: { type: Number, required: true, default: 14 },
// Spots theo giới tính
totalMaleSpots: { type: Number, default: 25 },
totalFemaleSpots: { type: Number, default: 25 },
bookedMaleSpots: { type: Number, default: 0 },
bookedFemaleSpots: { type: Number, default: 0 },
price: { type: Number },
isActive: { type: Boolean, default: true },
// Danh sách booking cho session này
bookingList: [
{
address: { type: String, required: true },
agreeNewsletter: { type: Boolean, default: false },
agreeTerms: { type: Boolean, required: true },
city: { type: String, required: true },
country: { type: String, required: true },
dietaryRestrictions: {
type: String,
enum: ['none', 'vegetarian', 'vegan', 'halal', 'kosher', 'gluten-free', 'other'],
default: 'none'
},
email: {
type: String,
required: true,
lowercase: true,
trim: true
},
emergencyContact: { type: String, required: true },
emergencyPhone: { type: String, required: true },
medicalConditions: { type: String, default: '' },
numberOfParticipants: { type: Number, required: true, min: 1 },
parentFirstName: { type: String, required: true, trim: true },
parentLastName: { type: String, required: true, trim: true },
participantBirthDate: { type: Date, required: true },
participantFirstName: { type: String, required: true, trim: true },
participantGender: {
type: String,
enum: ['male', 'female', 'other'],
required: true
},
participantLastName: { type: String, required: true, trim: true },
phone: { type: String, required: true },
postalCode: { type: String, required: true },
sessionDate: { type: String, required: true }, // sessionId reference
specialRequests: { type: String, default: '' },
// Thêm các trường quản lý
bookingStatus: {
type: String,
enum: ['pending', 'confirmed', 'cancelled', 'completed'],
default: 'pending'
},
paymentStatus: {
type: String,
enum: ['pending', 'partial', 'paid', 'refunded'],
default: 'pending'
},
totalAmount: { type: Number, default: 0 },
paidAmount: { type: Number, default: 0 },
bookingDate: { type: Date, default: Date.now },
confirmationCode: { type: String, unique: true },
adminNotes: { type: String, default: '' }
}
]
}
],
},
{timestamps: true}
);
// Add index for better query performance
activitySchema.index({name: 1});
activitySchema.index({isActive: 1, order: 1});
activitySchema.index({season: 1});
activitySchema.index({locations: 1});
module.exports = mongoose.model("Activity", activitySchema);
-302
View File
@@ -1,302 +0,0 @@
const mongoose = require("mongoose");
// Schema cho content items
const contentItemSchema = new mongoose.Schema(
{
type: {
type: String,
enum: ["paragraph", "section", "list", "note", "embed", "header"],
required: true,
},
text: {
type: String,
trim: true,
default: "",
},
title: {
type: String,
trim: true,
default: "",
},
content: {
type: String,
trim: true,
default: "",
},
items: {
type: [String],
default: [],
},
level: {
type: Number,
default: 2,
},
// Embed/video fields
embed: {
type: String,
trim: true,
default: ''
},
url: {
type: String,
trim: true,
default: ''
},
source: {
type: String,
trim: true,
default: ''
},
videoId: {
type: String,
trim: true,
default: ''
},
caption: {
type: String,
trim: true,
default: ''
},
width: {
type: Number,
default: 0
},
height: {
type: Number,
default: 0
},
},
{ _id: false }
);
// Schema cho overlay style
const overlayStyleSchema = new mongoose.Schema(
{
backgroundColor: {
type: String,
trim: true,
default: "rgba(0, 0, 0, 0)",
},
},
{ _id: false }
);
// Schema cho hero section
const heroSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
trim: true,
default: "Insurance & Travel Cancellation Guarantee",
},
subtitle: {
type: String,
trim: true,
default: "Comprehensive coverage for your peace of mind",
},
backgroundImage: {
type: String,
trim: true,
default: "/uploads/banner/b13.jpg",
},
sectionClass: {
type: String,
trim: true,
default: "uk-section-default uk-section-overlap uk-preserve-color uk-light uk-position-relative",
},
backgroundClasses: {
type: String,
trim: true,
default: "uk-background-norepeat uk-background-cover uk-background-top-center uk-section uk-section-xlarge",
},
overlayStyle: {
type: overlayStyleSchema,
default: () => ({ backgroundColor: "rgba(0, 0, 0, 0)" }),
},
titleClass: {
type: String,
trim: true,
default: "text-white text-[5vw] uk-text-center",
},
subtitleClass: {
type: String,
trim: true,
default: "uk-panel font-[Raleway] italic text-[1.5vw] uk-margin uk-text-center",
},
enableScrollspy: {
type: Boolean,
default: true,
},
},
{ _id: false }
);
// Schema cho page section
const pageSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
trim: true,
default: "Insurance & Travel Information",
},
divider: {
type: Boolean,
default: true,
},
sectionClass: {
type: String,
trim: true,
default: "uk-section-default uk-section-overlap uk-section",
},
titleClass: {
type: String,
trim: true,
default: "text-[2.5vw] text-[#292c3d] uk-text-left@m uk-text-center",
},
dividerClass: {
type: String,
trim: true,
default: "uk-divider-small uk-text-left@m uk-text-center",
},
},
{ _id: false }
);
// Schema cho content section
const contentSchema = new mongoose.Schema(
{
sectionClass: {
type: String,
trim: true,
default: "uk-section-muted uk-section-overlap uk-section",
},
textClass: {
type: String,
trim: true,
default: "uk-panel uk-margin text-[1vw]",
},
content: {
type: [contentItemSchema],
default: [],
},
},
{ _id: false }
);
// Main Insurance Schema - CẤU TRÚC MỚI
const insuranceSchema = new mongoose.Schema(
{
name: {
type: String,
default: "default",
unique: true,
},
// 3 PHẦN CHÍNH
hero: {
type: heroSchema,
required: true,
},
page: {
type: pageSchema,
required: true,
},
content: {
type: contentSchema,
required: true,
},
language: {
type: String,
default: "en",
},
version: {
type: String,
default: "2.0.0",
},
isActive: {
type: Boolean,
default: true,
},
migratedFromOldStructure: {
type: Boolean,
default: false,
},
},
{
timestamps: true,
}
);
// Static method: Lấy insurance default
insuranceSchema.statics.getDefault = async function(language = "en") {
try {
let insurance = await this.findOne({ name: "default", language: language });
if (!insurance) {
// Tạo default data nếu chưa có
insurance = await this.create({
name: "default",
language: language,
hero: {
title: "Insurance & Travel Cancellation Guarantee",
subtitle: "Comprehensive coverage for your peace of mind",
backgroundImage: "/uploads/banner/b13.jpg",
},
page: {
title: "Insurance & Travel Information",
divider: true,
},
content: {
content: []
}
});
}
return insurance;
} catch (error) {
console.error("Error in getDefault:", error);
throw error;
}
};
// Method để get insurance data
insuranceSchema.methods.getInsuranceData = function() {
return this.toObject();
};
// Migration method - chỉ hỗ trợ cấu trúc mới
insuranceSchema.statics.migrateFromJson = async function(jsonData, language = "en") {
try {
console.log('Migrating insurance from JSON...');
// Xóa document cũ nếu có
await this.deleteOne({ name: "default", language: language });
// Sử dụng dữ liệu từ JSON trực tiếp
const processedData = {
name: "default",
language: language,
version: "2.0.0",
isActive: true,
hero: jsonData.hero,
page: jsonData.page,
content: jsonData.content
};
// Tạo document mới
const newInsurance = await this.create(processedData);
const contentItems = jsonData.content?.content || [];
console.log(`Insurance data migrated successfully for language: ${language}`);
console.log(`Total content items: ${contentItems.length}`);
return newInsurance;
} catch (error) {
console.error("Error migrating insurance data to new structure:", error);
throw error;
}
};
const Insurance = mongoose.model("Insurance", insuranceSchema);
module.exports = Insurance;
-76
View File
@@ -1,76 +0,0 @@
const mongoose = require("mongoose");
// Schema cho hero section
const safetySchema = new mongoose.Schema(
{
//hero section
hero: {
banner: String,
title: String,
},
//approach section
approach: {
badge: String,
title:String,
description:String,
imgs:{
img1:String,
img2:String
},
stats:{
count:String,
label:String,
avatars:[String]
},
features:[
{text:String}
],
cards: [
{
title: String,
content: String,
},
],
},
//philosophy section
philosophy: {
title: String,
subtitle: String,
cards: [
{
title: String,
content: String,
author: {
avt: String,
name: String,
role: String,
rating: String,
},
},
],
},
//security section
security: {
title: String,
subtitle: String,
cards: [
{
title: String,
content: String,
author: {
avt: String,
name: String,
role: String,
rating: String,
},
},
],
},
},
{ timestamps: true }
);
module.exports = mongoose.model("Safety", safetySchema);
-519
View File
@@ -1,519 +0,0 @@
// models/terms.js
const mongoose = require("mongoose");
// Schema cho content items
const contentItemSchema = new mongoose.Schema(
{
type: {
type: String,
enum: ["paragraph", "section", "header", "list", "cancellation_table", "cancellation_section", "note", "embed", "image"],
required: true,
},
text: {
type: String,
trim: true,
default: "",
},
// Header level (h2, h3, h4, h5, h6)
level: {
type: Number,
min: 1,
max: 6,
default: 2,
},
title: {
type: String,
trim: true,
default: "",
},
content: {
type: String,
trim: true,
default: "",
},
subsections: {
type: [mongoose.Schema.Types.Mixed], // Recursive reference
default: [],
},
items: {
type: [String],
default: [],
},
// List style (for list type)
style: {
type: String,
enum: ["ordered", "unordered"],
default: "unordered",
},
// Embed/video fields (optional)
embed: {
type: String,
trim: true,
default: ''
},
url: {
type: String,
trim: true,
default: ''
},
source: {
type: String,
trim: true,
default: ''
},
videoId: {
type: String,
trim: true,
default: ''
},
caption: {
type: String,
trim: true,
default: ''
},
width: {
type: Number,
default: 0
},
height: {
type: Number,
default: 0
},
},
{ _id: false }
);
// Schema cho overlay style
const overlayStyleSchema = new mongoose.Schema(
{
backgroundColor: {
type: String,
trim: true,
default: "rgba(0, 0, 0, 0)",
},
},
{ _id: false }
);
// Schema cho hero section - CẤU TRÚC MỚI
const heroSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
trim: true,
default: "Frequently Asked Questions",
},
backgroundImage: {
type: String,
trim: true,
default: "/uploads/terms/faqimage.jpg",
},
sectionClass: {
type: String,
trim: true,
default: "uk-section-default uk-section-overlap uk-preserve-color uk-light uk-position-relative",
},
backgroundClasses: {
type: String,
trim: true,
default: "uk-background-norepeat uk-background-cover uk-background-top-center uk-section uk-section-xlarge",
},
overlayStyle: {
type: overlayStyleSchema,
default: () => ({ backgroundColor: "rgba(0, 0, 0, 0)" }),
},
titleClass: {
type: String,
trim: true,
default: "text-white text-[5vw] uk-text-center",
},
enableScrollspy: {
type: Boolean,
default: true,
},
},
{ _id: false }
);
// Schema cho page section - CẤU TRÚC MỚI
const pageSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
trim: true,
default: "Terms & Conditions Go and Grow Camp e.K.",
},
divider: {
type: Boolean,
default: true,
},
sectionClass: {
type: String,
trim: true,
default: "uk-section-default uk-section-overlap uk-section",
},
titleClass: {
type: String,
trim: true,
default: "text-[2.5vw] text-[#292c3d] uk-text-left@m uk-text-center",
},
dividerClass: {
type: String,
trim: true,
default: "uk-divider-small uk-text-left@m uk-text-center",
},
},
{ _id: false }
);
// Schema cho content section - CẤU TRÚC MỚI
const contentSchema = new mongoose.Schema(
{
sectionClass: {
type: String,
trim: true,
default: "uk-section-muted uk-section-overlap uk-section",
},
textClass: {
type: String,
trim: true,
default: "uk-panel uk-margin text-[1vw]",
},
content: {
type: [contentItemSchema],
default: [],
},
},
{ _id: false }
);
// Main Terms Schema - CẤU TRÚC MỚI
const termsSchema = new mongoose.Schema(
{
name: {
type: String,
default: "default",
unique: true,
},
// CHỈ CÒN 3 PHẦN CHÍNH
hero: {
type: heroSchema,
required: true,
},
page: {
type: pageSchema,
required: true,
},
content: {
type: contentSchema,
required: true,
},
language: {
type: String,
default: "en",
},
version: {
type: String,
default: "2.0.0", // Tăng version vì cấu trúc thay đổi
},
isActive: {
type: Boolean,
default: true,
},
migratedFromOldStructure: {
type: Boolean,
default: false,
},
},
{
timestamps: true,
}
);
// Static method: Lấy terms default - CẬP NHẬT THEO CẤU TRÚC MỚI
termsSchema.statics.getDefault = async function(language = "en") {
try {
let terms = await this.findOne({ name: "default", language: language });
if (!terms) {
// Tạo terms mặc định theo cấu trúc mới
terms = new this({
name: "default",
language: language,
hero: {
title: "Frequently Asked Questions",
subtitle: "Our Terms & Conditions",
backgroundImage: "/uploads/terms/faqimage.jpg",
sectionClass: "uk-section-default uk-section-overlap uk-preserve-color uk-light uk-position-relative",
backgroundClasses: "uk-background-norepeat uk-background-cover uk-background-top-center uk-section uk-section-xlarge",
overlayStyle: {
backgroundColor: "rgba(0, 0, 0, 0)"
},
titleClass: "text-white text-[5vw] uk-text-center",
subtitleClass: "uk-panel font-[Raleway] italic text-[1.5vw] uk-margin uk-text-center",
enableScrollspy: true
},
page: {
title: "Terms & Conditions Go and Grow Camp e.K.",
divider: true,
sectionClass: "uk-section-default uk-section-overlap uk-section",
titleClass: "text-[2.5vw] text-[#292c3d] uk-text-left@m uk-text-center",
dividerClass: "uk-divider-small uk-text-left@m uk-text-center"
},
content: {
sectionClass: "uk-section-muted uk-section-overlap uk-section",
textClass: "uk-panel uk-margin text-[1vw]",
content: [
{
type: "paragraph",
text: "This is an English translation of the original and legally binding German document \"Allgemeine Geschäftsbedingungen Go and Grow Camp e.K.\", which can be viewed at <a href=\"https://www.campadventure.de/de/infos/agb\" target=\"_self\">https://www.campadventure.de/de/infos/agb</a>. This translation is for your information only and is not legally binding."
},
{
type: "paragraph",
text: "<strong>Go and Grow Camp e.K. is the tour operator for individuals, for camps in Germany, England and Northern Ireland.</strong>"
},
{
type: "paragraph",
text: "GUARANTEE: All participants are protected in accordance with the legal regulations governing tour operators in Germany. As per §651, any payments made towards the travel price are insured against insolvency by tourVers."
}
]
},
version: "2.0.0",
isActive: true,
migratedFromOldStructure: false
});
await terms.save();
console.log(`Created default terms for language: ${language} (new structure)`);
}
return terms;
} catch (error) {
console.error("Error in getDefault:", error);
throw error;
}
};
// Method để get terms data
termsSchema.methods.getTermsData = function() {
return this.toObject();
};
// Migration method từ JSON CŨ sang cấu trúc MỚI
termsSchema.statics.migrateFromJson = async function(jsonData, language = "en") {
try {
console.log('Migrating from JSON to new structure...');
// Xóa document cũ nếu có
await this.deleteOne({ name: "default", language: language });
// Chuyển đổi từ cấu trúc cũ sang mới
const processedData = {
name: "default",
language: language,
version: "2.0.0",
isActive: true,
migratedFromOldStructure: true,
hero: {
title: jsonData.hero?.title || "Go and Grow Camp",
subtitle: jsonData.hero?.subtitle || "Our Terms & Conditions",
backgroundImage: jsonData.hero?.backgroundImage || "/uploads/terms/faqimage.jpg",
sectionClass: "uk-section-default uk-section-overlap uk-preserve-color uk-light uk-position-relative",
backgroundClasses: "uk-background-norepeat uk-background-cover uk-background-top-center uk-section uk-section-xlarge",
overlayStyle: {
backgroundColor: jsonData.hero?.overlayColor || "rgba(0, 0, 0, 0)"
},
titleClass: "text-white text-[5vw] uk-text-center",
subtitleClass: "uk-panel font-[Raleway] italic text-[1.5vw] uk-margin uk-text-center",
enableScrollspy: jsonData.hero?.enableScrollspy || true
},
page: {
title: jsonData.termsHeader?.title || "Terms & Conditions Go and Grow Camp e.K.",
divider: jsonData.termsHeader?.divider !== false,
sectionClass: jsonData.termsHeader?.sectionClass || "uk-section-default uk-section-overlap uk-section",
titleClass: jsonData.termsHeader?.titleClass || "text-[2.5vw] text-[#292c3d] uk-text-left@m uk-text-center",
dividerClass: jsonData.termsHeader?.dividerClass || "uk-divider-small uk-text-left@m uk-text-center"
},
content: {
sectionClass: jsonData.layout?.termsSectionClass || "uk-section-muted uk-section-overlap uk-section",
textClass: jsonData.layout?.textContentClass || "uk-panel uk-margin text-[1vw]",
content: []
}
};
// Chuyển đổi sections cũ sang content mới
const contentItems = [];
// Thêm disclaimer đầu tiên nếu có
if (jsonData.disclaimer?.text) {
contentItems.push({
type: "paragraph",
text: jsonData.disclaimer.text
});
}
if (jsonData.disclaimer?.importantNote) {
contentItems.push({
type: "paragraph",
text: `<strong>${jsonData.disclaimer.importantNote}</strong>`
});
}
if (jsonData.disclaimer?.legalNote) {
contentItems.push({
type: "paragraph",
text: jsonData.disclaimer.legalNote
});
}
// Thêm disclaimer note
if (jsonData.disclaimer?.note) {
contentItems.push({
type: "paragraph",
text: jsonData.disclaimer.note
});
}
// Thêm các sections
if (jsonData.sections && Array.isArray(jsonData.sections)) {
jsonData.sections.forEach(section => {
if (section.title && section.content) {
const contentItem = {
type: "section",
title: section.title,
content: section.content
};
// Thêm subsections nếu có
if (section.subsections && section.subsections.length > 0) {
contentItem.subsections = section.subsections.map(sub => ({
type: "note",
text: sub.content || sub
}));
}
// Thêm cancellation fees nếu có
if (section.fees) {
contentItem.subsections = contentItem.subsections || [];
// Individual fees
if (section.fees.individual && section.fees.individual.length > 0) {
contentItem.subsections.push({
type: "cancellation_table",
title: "Standard Cancellation Fees",
items: section.fees.individual.map(fee => `${fee.period} ${fee.fee}`)
});
}
// School group fees
if (section.fees.schoolGroups && section.fees.schoolGroups.fees) {
contentItem.subsections.push({
type: "cancellation_section",
title: "Cancellation policy for school groups:",
items: [
section.fees.schoolGroups.freeCorrection,
...section.fees.schoolGroups.fees.map(fee => `${fee.period}: ${fee.fee}`)
]
});
}
// Fee note
if (section.fees.note) {
contentItem.subsections.push({
type: "note",
text: section.fees.note
});
}
}
contentItems.push(contentItem);
}
});
}
// Thêm footer note nếu có
if (jsonData.footerNote?.text) {
contentItems.push({
type: "paragraph",
text: jsonData.footerNote.text
});
}
// Gán content items đã chuyển đổi
processedData.content.content = contentItems;
// Tạo document mới
const newTerms = await this.create(processedData);
console.log(`Terms data migrated to new structure for language: ${language}`);
console.log(`Total content items: ${contentItems.length}`);
return newTerms;
} catch (error) {
console.error("Error migrating terms data to new structure:", error);
throw error;
}
};
// Migration method từ cấu trúc MỚI sang cấu trúc MỚI (dành cho JSON mới)
termsSchema.statics.migrateFromNewJson = async function(jsonData, language = "en") {
try {
console.log('Migrating from new JSON structure...');
// Xóa document cũ nếu có
await this.deleteOne({ name: "default", language: language });
// Tạo document mới với cấu trúc mới
const newTerms = await this.create({
name: "default",
language: language,
version: "2.0.0",
isActive: true,
migratedFromOldStructure: false,
hero: {
title: jsonData.hero?.title || "Go and Grow Camp",
subtitle: jsonData.hero?.subtitle || "Our Terms & Conditions",
backgroundImage: jsonData.hero?.backgroundImage || "/uploads/terms/faqimage.jpg",
sectionClass: jsonData.hero?.sectionClass || "uk-section-default uk-section-overlap uk-preserve-color uk-light uk-position-relative",
backgroundClasses: jsonData.hero?.backgroundClasses || "uk-background-norepeat uk-background-cover uk-background-top-center uk-section uk-section-xlarge",
overlayStyle: jsonData.hero?.overlayStyle || { backgroundColor: "rgba(0, 0, 0, 0)" },
titleClass: jsonData.hero?.titleClass || "text-white text-[5vw] uk-text-center",
subtitleClass: jsonData.hero?.subtitleClass || "uk-panel font-[Raleway] italic text-[1.5vw] uk-margin uk-text-center",
enableScrollspy: jsonData.hero?.enableScrollspy !== undefined ? jsonData.hero.enableScrollspy : true
},
page: {
title: jsonData.page?.title || "Terms & Conditions Go and Grow Camp e.K.",
divider: jsonData.page?.divider !== undefined ? jsonData.page.divider : true,
sectionClass: jsonData.page?.sectionClass || "uk-section-default uk-section-overlap uk-section",
titleClass: jsonData.page?.titleClass || "text-[2.5vw] text-[#292c3d] uk-text-left@m uk-text-center",
dividerClass: jsonData.page?.dividerClass || "uk-divider-small uk-text-left@m uk-text-center"
},
content: {
sectionClass: jsonData.content?.sectionClass || "uk-section-muted uk-section-overlap uk-section",
textClass: jsonData.content?.textClass || "uk-panel uk-margin text-[1vw]",
content: jsonData.content?.content || []
}
});
console.log(`Terms data created with new structure for language: ${language}`);
console.log(`Hero title: ${newTerms.hero.title}`);
console.log(`Page title: ${newTerms.page.title}`);
console.log(`Content items: ${newTerms.content.content.length}`);
return newTerms;
} catch (error) {
console.error("Error creating terms data from new structure:", error);
throw error;
}
};
const Terms = mongoose.model("Terms", termsSchema);
module.exports = Terms;
-45
View File
@@ -1,45 +0,0 @@
const mongoose = require("mongoose");
const travelSchema = new mongoose.Schema(
{
page: {
title: {
type: String,
default: "Travel Information",
},
description: {
type: String,
default: "",
},
year: {
type: String,
default: "",
},
metadata: {
title: String,
description: String,
},
},
hero: {
title: {
type: String,
default: "Travel Information",
},
backgroundImage: {
type: String,
default: "",
},
},
content: {
type: mongoose.Schema.Types.Mixed,
default: { blocks: [] },
},
enableScrollspy: {
type: Boolean,
default: false,
},
},
{ timestamps: true }
);
module.exports = mongoose.model("Travel", travelSchema);