Refactor Homepage, About, Footer (Controller,Model, View, Data), Update: Dashboard, Delete old file

This commit is contained in:
2026-04-22 15:30:09 +07:00
parent cb5e4b0ceb
commit 3ede974215
67 changed files with 3003 additions and 14780 deletions
+58 -169
View File
@@ -1,213 +1,102 @@
const mongoose = require("mongoose");
// Schema cho menu links
const menuLinkSchema = new mongoose.Schema(
const { Schema } = mongoose;
// Brand
const LogoSchema = new Schema(
{
label: {
type: String,
required: true,
trim: true,
},
href: {
type: String,
required: true,
trim: true,
},
order: {
type: Number,
required: false,
default: 0,
},
image: { type: String, default: "" },
href: { type: String, default: "/" },
},
{ _id: false },
);
// Schema cho social links
const socialLinkSchema = new mongoose.Schema(
const SocialItemSchema = new Schema(
{
icon: {
type: String,
required: true,
trim: true,
},
href: {
type: String,
required: true,
trim: true,
},
icon: { type: String, default: "" },
href: { type: String, default: "#" },
},
{ _id: false },
);
// Schema cho phone
const phoneSchema = new mongoose.Schema(
const BrandSchema = new Schema(
{
display: {
type: String,
required: false,
trim: true,
default: "",
},
href: {
type: String,
required: false,
trim: true,
default: "",
},
logo: { type: LogoSchema, default: () => ({}) },
description: { type: String, default: "" },
social: { type: [SocialItemSchema], default: [] },
},
{ _id: false },
);
// Schema cho logo
const logoSchema = new mongoose.Schema(
// Explore
const ExploreLinkSchema = new Schema(
{
src: {
type: String,
required: false,
trim: true,
default: "",
},
alt: {
type: String,
required: false,
trim: true,
default: "",
},
href: {
type: String,
required: false,
trim: true,
default: "/",
},
label: { type: String, default: "" },
href: { type: String, default: "#" },
},
{ _id: false },
);
// Schema cho copyright
const copyrightSchema = new mongoose.Schema(
const ExploreSchema = new Schema(
{
text: {
type: String,
required: false,
trim: true,
default: "Copyright©",
},
brand: {
type: String,
required: false,
trim: true,
default: "",
},
rights: {
type: String,
required: false,
trim: true,
default: "All Rights Reserved.",
},
heading: { type: String, default: "" },
links: { type: [ExploreLinkSchema], default: [] },
},
{ _id: false },
);
// Schema cho top section
const topSchema = new mongoose.Schema(
// Contact
const ContactSchema = new Schema(
{
bgImage: {
type: String,
required: false,
trim: true,
default: "",
},
phone: {
type: phoneSchema,
default: () => ({ display: "", href: "" }),
},
address: {
type: String,
required: false,
trim: true,
default: "",
},
logo: {
type: logoSchema,
default: () => ({ src: "", alt: "", href: "/" }),
},
menuLinks: {
type: [menuLinkSchema],
default: [],
},
socialLinks: {
type: [socialLinkSchema],
default: [],
},
heading: { type: String, default: "" },
address: { type: String, default: "" },
phone: { type: String, default: "" },
email: { type: String, default: "" },
},
{ _id: false },
);
// Schema cho bottom section
const bottomSchema = new mongoose.Schema(
// Newsletter
const NewsletterSchema = new Schema(
{
copyright: {
type: copyrightSchema,
default: () => ({ text: "Copyright©", brand: "", rights: "All Rights Reserved." }),
},
menuLinks: {
type: [menuLinkSchema],
default: [],
},
heading: { type: String, default: "" },
description: { type: String, default: "" },
placeholder: { type: String, default: "" },
buttonText: { type: String, default: "" },
},
{ _id: false },
);
// Main Footer Schema - khớp 100% với footer.json
const footerSchema = new mongoose.Schema(
// Bottom
const BottomLinkSchema = new Schema(
{
top: {
type: topSchema,
default: () => ({
bgImage: "",
phone: { display: "", href: "" },
address: "",
logo: { src: "", alt: "", href: "/" },
menuLinks: [],
socialLinks: [],
}),
},
bottom: {
type: bottomSchema,
default: () => ({
copyright: { text: "Copyright©", brand: "", rights: "All Rights Reserved." },
menuLinks: [],
}),
},
label: { type: String, default: "" },
href: { type: String, default: "#" },
},
{ _id: false },
);
const BottomSchema = new Schema(
{
copyright: { type: String, default: "" },
links: { type: [BottomLinkSchema], default: [] },
},
{ _id: false },
);
// Root
const FooterSchema = new Schema(
{
brand: { type: BrandSchema, default: () => ({}) },
explore: { type: ExploreSchema, default: () => ({}) },
contact: { type: ContactSchema, default: () => ({}) },
newsletter: { type: NewsletterSchema, default: () => ({}) },
bottom: { type: BottomSchema, default: () => ({}) },
},
{
timestamps: true,
strict: false,
},
);
// Static method để lấy hoặc tạo footer duy nhất
footerSchema.statics.getSingle = async function () {
let footer = await this.findOne();
if (!footer) {
footer = await this.create({});
}
return footer;
};
// Migration method để import từ JSON hiện tại
footerSchema.statics.migrateFromJson = async function (jsonData) {
try {
// Xóa tất cả documents hiện có
await this.deleteMany({});
// Tạo document mới
const footer = await this.create(jsonData);
console.log("Footer data migrated successfully");
return footer;
} catch (error) {
console.error("Error migrating footer data:", error);
throw error;
}
};
module.exports = mongoose.model("Footer", footerSchema);
module.exports = mongoose.model("Footer", FooterSchema);