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

388 lines
8.9 KiB
JavaScript

const mongoose = require("mongoose");
// Schema cho hero section
const heroSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
trim: true,
},
backgroundImage: {
type: String,
trim: true,
default: "",
},
overlayColor: {
type: String,
trim: true,
default: "rgba(0, 0, 0, 0)",
},
sectionClass: {
type: String,
trim: true,
default: "",
},
titleClass: {
type: String,
trim: true,
default: "",
},
enableScrollspy: {
type: Boolean,
default: false,
},
backgroundPosition: {
type: String,
trim: true,
default: "center",
},
},
{ _id: false }
);
// Schema cho contact card
const contactCardSchema = new mongoose.Schema(
{
type: {
type: String,
required: true,
trim: true,
enum: [
"phone",
"email",
"location",
"hours",
"website",
"social",
"custom",
],
},
title: {
type: String,
required: true,
trim: true,
},
content: {
type: [String],
default: [],
},
iconType: {
type: String,
required: false,
trim: true,
default: "",
},
iconSource: {
type: String,
required: false,
trim: true,
enum: ["fontawesome", "image"],
default: "fontawesome",
},
},
{ _id: false }
);
// Schema cho map coordinates
const coordinatesSchema = new mongoose.Schema(
{
lat: {
type: Number,
required: true,
},
lng: {
type: Number,
required: true,
},
},
{ _id: false }
);
// Schema cho tile layer
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 }
);
// Schema cho map
const mapSchema = new mongoose.Schema(
{
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 }
);
// Schema cho form field
const formFieldSchema = new mongoose.Schema(
{
name: {
type: String,
required: true,
trim: true,
},
type: {
type: String,
required: true,
trim: true,
enum: ["text", "email", "tel", "textarea", "programme"],
},
placeholder: {
type: String,
trim: true,
default: "",
},
required: {
type: Boolean,
default: false,
},
programmeName: {
type: String,
trim: true,
default: "",
},
},
{ _id: false }
);
// Schema cho submit button
const submitButtonSchema = new mongoose.Schema(
{
text: {
type: String,
required: true,
trim: true,
},
},
{ _id: false }
);
// Schema cho form
const formSchema = new mongoose.Schema(
{
sectionLabel: {
type: String,
trim: true,
default: "",
},
heading: {
type: String,
trim: true,
default: "",
},
fields: {
type: [formFieldSchema],
default: [],
},
submitButton: {
type: submitButtonSchema,
required: true,
},
},
{ _id: false }
);
// Main Contact Schema
const contactSchema = new mongoose.Schema(
{
name: {
type: String,
default: "default",
unique: true,
},
hero: {
type: heroSchema,
required: true,
},
contactCards: {
type: [contactCardSchema],
default: [],
},
map: {
type: mapSchema,
required: true,
},
form: {
type: formSchema,
required: true,
},
},
{
timestamps: true,
}
);
// Mapping iconType cũ sang Font Awesome icon mới
const iconTypeMapping = {
phone: "fas fa-phone",
email: "fas fa-envelope",
location: "fas fa-map-marker-alt",
clock: "fas fa-clock",
hours: "fas fa-clock",
};
// Tạo migration script để import dữ liệu từ contact-data.json
contactSchema.statics.migrateFromJson = async function (jsonData) {
try {
// Kiểm tra xem đã có contact mặc định chưa
const existingContact = await this.findOne({ name: "default" });
// Xử lý và chuẩn hóa dữ liệu từ JSON
const processedData = {
hero: {
title: jsonData.hero?.title || "Contact Us",
backgroundImage: jsonData.hero?.backgroundImage || "",
overlayColor: jsonData.hero?.overlayColor || "rgba(0, 0, 0, 0)",
sectionClass: jsonData.hero?.sectionClass || "",
titleClass: jsonData.hero?.titleClass || "",
enableScrollspy: jsonData.hero?.enableScrollspy || false,
backgroundPosition: jsonData.hero?.backgroundPosition || "center",
},
contactCards: (jsonData.contactCards || []).map((card) => {
let iconType = card.iconType || "";
let iconSource = card.iconSource;
// Nếu không có iconSource, tự động detect từ iconType
if (!iconSource) {
// Nếu iconType là image path (bắt đầu bằng /uploads/ hoặc http)
if (
iconType.startsWith("/uploads/") ||
iconType.startsWith("http://") ||
iconType.startsWith("https://")
) {
iconSource = "image";
} else {
// Nếu iconType là string cũ (phone, email, location, clock)
iconSource = "fontawesome";
// Map iconType cũ sang Font Awesome icon mới
if (iconTypeMapping[iconType]) {
iconType = iconTypeMapping[iconType];
} else if (
iconType &&
!iconType.startsWith("fas ") &&
!iconType.startsWith("fab ")
) {
// Nếu iconType không phải là Font Awesome class hợp lệ, thử map
iconType = iconTypeMapping[iconType] || iconType;
}
}
} else {
// Nếu đã có iconSource nhưng iconType là string cũ, map sang Font Awesome
if (
iconSource === "fontawesome" &&
iconType &&
!iconType.startsWith("fas ") &&
!iconType.startsWith("fab ") &&
iconTypeMapping[iconType]
) {
iconType = iconTypeMapping[iconType];
}
}
return {
type: card.type || "custom",
title: card.title || "",
content: Array.isArray(card.content) ? card.content : [],
iconType: iconType,
iconSource: iconSource || "fontawesome",
};
}),
map: {
coordinates: {
lat: jsonData.map?.coordinates?.lat || 0,
lng: jsonData.map?.coordinates?.lng || 0,
},
zoom: jsonData.map?.zoom || 15,
location: jsonData.map?.location || "",
markerTitle: jsonData.map?.markerTitle || "",
tileLayer: {
url:
jsonData.map?.tileLayer?.url ||
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
attribution: jsonData.map?.tileLayer?.attribution || "",
maxZoom: jsonData.map?.tileLayer?.maxZoom || 18,
minZoom: jsonData.map?.tileLayer?.minZoom || 0,
},
},
form: {
sectionLabel: jsonData.form?.sectionLabel || "",
heading: jsonData.form?.heading || "",
fields: (jsonData.form?.fields || []).map((field) => ({
name: field.name || "",
type: field.type || "text",
placeholder: field.placeholder || "",
required: field.required || false,
programmeName: field.programmeName || "",
})),
submitButton: {
text: jsonData.form?.submitButton?.text || "Send Message",
},
},
};
if (existingContact) {
// Cập nhật contact hiện có với dữ liệu đã xử lý
existingContact.hero = processedData.hero;
existingContact.contactCards = processedData.contactCards;
existingContact.map = processedData.map;
existingContact.form = processedData.form;
await existingContact.save();
console.log("Contact data updated successfully");
return existingContact;
} else {
// Tạo contact mới với dữ liệu đã xử lý
const newContact = await this.create({
name: "default",
...processedData,
});
console.log("Contact data imported successfully");
return newContact;
}
} catch (error) {
console.error("Error migrating contact data:", error);
throw error;
}
};
module.exports = mongoose.model("Contact", contactSchema);