Files

191 lines
6.3 KiB
JavaScript

const mongoose = require("mongoose");
// ─────────────────────────────────────────────
// Sub-schemas
// ─────────────────────────────────────────────
const metadataSchema = new mongoose.Schema(
{
title: { type: String, trim: true, default: "" },
description: { type: String, trim: true, default: "" },
keywords: { type: String, trim: true, default: "" },
ogImage: { type: String, trim: true, default: "" },
},
{ _id: false }
);
const heroSchema = new mongoose.Schema(
{
badge: { type: String, trim: true, default: "" },
titleMain: { type: String, trim: true, default: "" },
titleHighlight: { type: String, trim: true, default: "" },
description: { type: String, trim: true, default: "" },
},
{ _id: false }
);
const channelSchema = new mongoose.Schema(
{
icon: { type: String, trim: true, default: "" },
title: { type: String, trim: true, default: "" },
detail: { type: String, trim: true, default: "" },
subDetail: { type: String, trim: true, default: "" },
},
{ _id: false }
);
const supportHourSchema = new mongoose.Schema(
{
day: { type: String, trim: true, default: "" },
time: { type: String, trim: true, default: "" },
},
{ _id: false }
);
const infoCardsSchema = new mongoose.Schema(
{
contactInfo: {
title: { type: String, trim: true, default: "" },
channels: { type: [channelSchema], default: [] },
},
supportHours: {
title: { type: String, trim: true, default: "" },
hours: { type: [supportHourSchema], default: [] },
footer: {
text: { type: String, trim: true, default: "" },
linkText: { type: String, trim: true, default: "" },
linkHref: { type: String, trim: true, default: "" },
},
},
},
{ _id: false }
);
const formOptionSchema = new mongoose.Schema(
{
label: { type: String, trim: true, default: "" },
value: { type: String, trim: true, default: "" },
},
{ _id: false }
);
const simpleFieldSchema = new mongoose.Schema(
{
name: { type: String, trim: true, default: "" },
label: { type: String, trim: true, default: "" },
placeholder: { type: String, trim: true, default: "" },
required: { type: Boolean, default: false },
},
{ _id: false }
);
const inquiryFieldSchema = new mongoose.Schema(
{
name: { type: String, trim: true, default: "" },
label: { type: String, trim: true, default: "" },
placeholder: { type: String, trim: true, default: "" },
required: { type: Boolean, default: true },
options: { type: [formOptionSchema], default: [] },
},
{ _id: false }
);
const formSchema = new mongoose.Schema(
{
heading: { type: String, trim: true, default: "" },
description: { type: String, trim: true, default: "" },
fields: {
firstName: { type: simpleFieldSchema, default: () => ({}) },
lastName: { type: simpleFieldSchema, default: () => ({}) },
email: { type: simpleFieldSchema, default: () => ({}) },
phone: { type: simpleFieldSchema, default: () => ({}) },
inquiryType: { type: inquiryFieldSchema, default: () => ({}) },
message: { type: simpleFieldSchema, default: () => ({}) },
},
submitLabel: { type: String, trim: true, default: "Send Message" },
successMessage: { type: String, trim: true, default: "" },
errorMessage: { type: String, trim: true, default: "" },
},
{ _id: false }
);
const faqItemSchema = new mongoose.Schema(
{
question: { type: String, trim: true, default: "" },
answer: { type: String, trim: true, default: "" },
},
{ _id: false }
);
const faqSchema = new mongoose.Schema(
{
title: { type: String, trim: true, default: "" },
subtitle: { type: String, trim: true, default: "" },
items: { type: [faqItemSchema], default: [] },
},
{ _id: false }
);
const ctaButtonSchema = new mongoose.Schema(
{
label: { type: String, trim: true, default: "" },
href: { type: String, trim: true, default: "" },
},
{ _id: false }
);
const ctaSchema = new mongoose.Schema(
{
title: { type: String, trim: true, default: "" },
description: { type: String, trim: true, default: "" },
primaryButton: { type: ctaButtonSchema, default: () => ({}) },
secondaryButton: { type: ctaButtonSchema, default: () => ({}) },
},
{ _id: false }
);
// ─────────────────────────────────────────────
// Main Contact Schema (slug-based, same pattern
// as StudentSupport / RequestInfo)
// ─────────────────────────────────────────────
const contactSchema = new mongoose.Schema(
{
slug: { type: String, default: "contact", unique: true },
metadata: { type: metadataSchema, default: () => ({}) },
hero: { type: heroSchema, default: () => ({}) },
infoCards: { type: infoCardsSchema, default: () => ({}) },
form: { type: formSchema, default: () => ({}) },
faq: { type: faqSchema, default: () => ({}) },
cta: { type: ctaSchema, default: () => ({}) },
},
{ timestamps: true }
);
// ─────────────────────────────────────────────
// Migration helper (idempotent upsert)
// ─────────────────────────────────────────────
contactSchema.statics.migrateFromJson = async function (jsonData) {
const payload = {
metadata: jsonData.metadata || {},
hero: jsonData.hero || {},
infoCards: jsonData.infoCards || {},
form: jsonData.form || {},
faq: jsonData.faq || {},
cta: jsonData.cta || {},
};
const existing = await this.findOne({ slug: "contact" });
if (existing) {
existing.set(payload);
await existing.save();
console.log("✅ Contact data updated via migration.");
return existing;
} else {
const created = await this.create({ slug: "contact", ...payload });
console.log("✅ Contact data created via migration.");
return created;
}
};
module.exports = mongoose.model("Contact", contactSchema);