feat(about): sync FE-BE data and image upload

This commit is contained in:
2026-02-06 01:58:56 +07:00
parent fb8676879d
commit 8232a36e71
16 changed files with 1096 additions and 2821 deletions

View File

@@ -1,64 +0,0 @@
const mongoose = require('mongoose');
const aboutSchema = new mongoose.Schema({
banner: {
image: String,
title: String,
text: String
},
about: {
title: String,
paragraphs: [String],
list_items: [String],
button: {
text: String,
url: String
},
image: String,
quote: {
mark_image: String,
title: String,
text: String,
author: String
}
},
values: {
background_image: String,
items: [{
icon: String,
title: String,
text: String
}]
},
education: {
images: {
student1: String,
student2: String
},
subtitle: String,
title: String,
text: String
},
advantages: {
title: String,
items: [{
number: String,
title: String,
text: String
}]
},
academic_board: {
title: String,
members: [{
image: String,
title: String,
name: String,
color: String
}]
},
updatedAt: Date
}, {
timestamps: true
});
module.exports = mongoose.model('About', aboutSchema);

View File

@@ -2,87 +2,105 @@ const mongoose = require("mongoose");
const aboutUsSchema = new mongoose.Schema(
{
// Hero section
hero: {
title: String,
breadcrumb: [String],
backgroundImage: String,
},
// Introduction section with nested services
introduction: {
subtitle: String,
title: String,
intro: {
subheading: String,
heading: String,
description: String,
mainImage: String,
services: [
{
title: String,
description: String,
},
],
image: String,
},
// Statistics with nested items
statistics: {
mission: {
subheading: String,
heading: String,
description: String,
images: {
main: String,
secondary: String,
bgShape: String,
planeShape: String,
topShape: String,
globeShape: String,
},
items: [
{
number: String,
description: String,
},
new mongoose.Schema(
{
icon: String,
label: String,
description: String,
},
{ _id: false }
),
],
features: [String],
ctaButton: {
label: String,
href: String,
},
},
// Accommodation section with nested features
accommodation: {
subtitle: String,
title: String,
features: {
backgroundImage: String,
subheading: String,
heading: String,
description: String,
features: [
{
title: String,
description: String,
icon: String,
},
],
},
// Activities section with nested gallery
activities: {
subtitle: String,
title: String,
description: String,
gallery: [
{
image: String,
title: String,
description: String,
},
],
},
// Newsletter
newsletter: {
imagePath: String,
title: String,
description: String,
buttonText: String,
},
// Events with nested items
events: {
title: String,
image: String,
items: [
{
imageUrl: String,
date: String,
title: String,
description: String,
age: String,
},
new mongoose.Schema(
{
icon: String,
title: String,
description: String,
},
{ _id: false }
),
],
ctaButton: {
label: String,
href: String,
},
},
news: {
subheading: String,
heading: String,
ctaButton: {
label: String,
href: String,
},
items: [
new mongoose.Schema(
{
title: String,
category: String,
date: String,
comments: Number,
author: {
name: String,
avatar: String,
},
link: String,
thumbnail: String,
},
{ _id: false }
),
],
},
},
{timestamps: true}
{
timestamps: true,
collection: "aboutus",
}
);
// Static method để đảm bảo luôn chỉ có 1 bản ghi duy nhất (Singleton)
aboutUsSchema.statics.getSingle = async function () {
let doc = await this.findOne();
if (!doc) {
doc = await this.create({});
}
return doc;
};
module.exports = mongoose.model("AboutUs", aboutUsSchema);