fea/nhat-dat-11042026-merge #1

Closed
minhnhat wants to merge 27 commits from UKSOURCE/cms.hailearning.edu.vn:fea/nhat-dat-11042026-merge into fea/nhat-13042028-merge-kiet-thien
14 changed files with 48 additions and 26 deletions
Showing only changes of commit e7929568dc - Show all commits

Binary file not shown.

View File

@@ -445,14 +445,11 @@ exports.apiGetBlogs = async (req, res) => {
};
exports.api = async (req, res) => {
try {
const docs = await getAllHomeDocs();
let data = docs[0]?.toObject() || {};
// Chỉ dùng doc mới nhất, không merge nhiều docs
const doc = await getHomeDoc();
let data = doc?.toObject() || {};
const baseUrl = `${req.protocol}://${req.get("host")}`;
if (docs.length > 1) {
data.hero = getPreferredHeroData(docs.map((doc) => doc.toObject()));
}
// === Xử lý Blog Preview động ===
const blogPreview = data.blogPreview || {};
let blogs = [];

View File

@@ -349,5 +349,8 @@ const HomeSchema = new Schema(
},
);
// Đảm bảo chỉ có 1 document duy nhất (singleton pattern)
HomeSchema.index({ createdAt: 1 }, { unique: false });
module.exports = mongoose.model("Home", HomeSchema);

View File

@@ -0,0 +1,22 @@
require('dotenv').config();
const mongoose = require('mongoose');
const Home = require('../models/home');
mongoose.connect(process.env.MONGODB_URI).then(async () => {
const docs = await Home.find().sort({ updatedAt: -1 }).lean();
console.log('Total docs:', docs.length);
if (docs.length <= 1) {
console.log('Nothing to clean up.');
return;
}
const keep = docs[0];
const idsToDelete = docs.slice(1).map(d => d._id);
await Home.deleteMany({ _id: { $in: idsToDelete } });
console.log('Kept doc:', keep._id, '| hero.enabled:', keep.hero?.enabled);
console.log('Deleted', idsToDelete.length, 'duplicate docs');
await mongoose.disconnect();
});

View File

@@ -1,4 +1,4 @@
<!-- Achievements Tab -->
<!-- Achievements Tab -->
<div class="tab-pane fade" id="achievements" role="tabpanel">
<div class="row g-4">
<!-- Basic Info -->
@@ -88,7 +88,7 @@
window.homeScrapers.achievements = function () {
const items = [];
const enabled = document.getElementById("achievementEnabled")?.checked !== false;
const enabled = document.getElementById("achievementEnabled")?.checked === true;
document.querySelectorAll('.achievement-item').forEach(el => {
items.push({

View File

@@ -1,4 +1,4 @@
<!-- Blog Preview Tab -->
<!-- Blog Preview Tab -->
<div class="tab-pane fade" id="blogpreview" role="tabpanel">
<div class="row g-4">
<!-- Basic Info -->
@@ -158,7 +158,7 @@
window.homeScrapers.blogPreview = () => {
const selectedIds = [];
const enabled = document.getElementById("blogpreviewEnabled")?.checked !== false;
const enabled = document.getElementById("blogpreviewEnabled")?.checked === true;
document.querySelectorAll('.blog-checkbox:checked').forEach(cb => {
selectedIds.push(cb.value);

View File

@@ -1,4 +1,4 @@
<!-- FAQ Tab -->
<!-- FAQ Tab -->
<div class="tab-pane fade" id="faq" role="tabpanel">
<div class="row g-4">
<!-- Basic Info -->
@@ -139,7 +139,7 @@
window.homeScrapers.faq = () => {
const getVal = (id) => (document.getElementById(id)?.value || "").trim();
const enabled = document.getElementById('faqEnabled')?.checked !== false;
const enabled = document.getElementById('faqEnabled')?.checked === true;
const items = [];
document.querySelectorAll(".faq-item").forEach((el, idx) => {

View File

@@ -1,4 +1,4 @@
<!-- Hero Tab -->
<!-- Hero Tab -->
<div class="tab-pane fade show active" id="hero" role="tabpanel">
<div class="row g-4">
<div class="col-md-12">
@@ -203,7 +203,7 @@
const getVal = (id) => (document.getElementById(id)?.value || "").trim();
const backgroundImage = getVal("heroBackgroundImage");
const enabled = document.getElementById("heroEnabled")?.checked !== false;
const enabled = document.getElementById("heroEnabled")?.checked === true;
const slides = [];
const slideEls = document.querySelectorAll(".hero-slide-item");

View File

@@ -1,4 +1,4 @@
<!-- Partners Tab -->
<!-- Partners Tab -->
<div class="tab-pane fade" id="partners" role="tabpanel">
<div class="row g-4">
<!-- Visa Consultancy Awards -->
@@ -120,7 +120,7 @@
window.homeScrapers.partners = function () {
const visaItems = [];
const enabled = document.getElementById('partnersEnabled')?.checked !== false;
const enabled = document.getElementById('partnersEnabled')?.checked === true;
document.querySelectorAll('.visa-item').forEach(el => {
visaItems.push({

View File

@@ -1,4 +1,4 @@
<!-- Testimonials Tab -->
<!-- Testimonials Tab -->
<div class="tab-pane fade" id="testimonials" role="tabpanel">
<div class="row g-4">
<!-- Basic Info -->
@@ -135,7 +135,7 @@
window.homeScrapers.testimonials = () => {
const getVal = (id) => (document.getElementById(id)?.value || "").trim();
const enabled = document.getElementById("testimonialEnabled")?.checked !== false;
const enabled = document.getElementById("testimonialEnabled")?.checked === true;
const items = [];
document.querySelectorAll(".testimonial-item").forEach((el, idx) => {

View File

@@ -1,4 +1,4 @@
<!-- Video Gallery Tab -->
<!-- Video Gallery Tab -->
<div class="tab-pane fade" id="videogallery" role="tabpanel">
<div class="row g-4">
<div class="col-md-12">
@@ -64,7 +64,7 @@
window.homeScrapers.videoGallery = () => {
const getVal = (id) => (document.getElementById(id)?.value || "").trim();
const enabled = document.getElementById("videoGalleryEnabled")?.checked !== false;
const enabled = document.getElementById("videoGalleryEnabled")?.checked === true;
return {
heading: getVal("videoGalleryHeading"),
videoUrl: getVal("videoGalleryVideoUrl"),

View File

@@ -1,4 +1,4 @@
<!-- Visa Countries Tab -->
<!-- Visa Countries Tab -->
<div class="tab-pane fade" id="visacountries" role="tabpanel">
<div class="row g-4">
<!-- Basic Info -->
@@ -135,7 +135,7 @@
window.homeScrapers.visaCountries = () => {
const getVal = (id) => (document.getElementById(id)?.value || "").trim();
const enabled = document.getElementById("visaCountriesEnabled")?.checked !== false
const enabled = document.getElementById("visaCountriesEnabled")?.checked === true
const visaTypesRaw = getVal("visaCountriesVisaTypes_0");
const visaTypes = visaTypesRaw ? visaTypesRaw.split(",").map((s) => s.trim()).filter(Boolean) : [];

View File

@@ -1,4 +1,4 @@
<!-- Visa Solutions Tab -->
<!-- Visa Solutions Tab -->
<div class="tab-pane fade" id="visasolutions" role="tabpanel">
<div class="row g-4">
<!-- Basic Info -->
@@ -100,7 +100,7 @@
window.homeScrapers.visaSolutions = () => {
const getVal = (id) => (document.getElementById(id)?.value || "").trim();
const enabled = document.getElementById("visaSolutionsEnabled")?.checked !== false;
const enabled = document.getElementById("visaSolutionsEnabled")?.checked === true;
const items = [];
document.querySelectorAll(".visa-solution-item").forEach((el, idx) => {

View File

@@ -1,4 +1,4 @@
<!-- Why Choose Us Tab -->
<!-- Why Choose Us Tab -->
<div class="tab-pane fade" id="whychooseus" role="tabpanel">
<div class="row g-4">
<!-- Basic Info -->
@@ -206,7 +206,7 @@
window.homeScrapers = window.homeScrapers || {};
window.homeScrapers.whyChooseUs = () => {
const getVal = (id) => (document.getElementById(id)?.value || "").trim();
const enabled = document.getElementById("whyChooseUsEnabled")?.checked !== false;
const enabled = document.getElementById("whyChooseUsEnabled")?.checked === true;
// Collect items
const items = [];