forked from UKSOURCE/cms.hailearning.edu.vn
Align home hero API and CMS hero editor
This commit is contained in:
@@ -10,6 +10,7 @@ const AUDIT_ACTIONS = require("../constants/auditAction");
|
||||
|
||||
// Các hàm hỗ trợ
|
||||
const getHomeDoc = async () => Home.findOne().sort({ updatedAt: -1 });
|
||||
const getAllHomeDocs = async () => Home.find().sort({ updatedAt: -1 });
|
||||
const getHomeData = async () => (await getHomeDoc())?.toObject() || {};
|
||||
const getOrCreateHomeDoc = async () => {
|
||||
let doc = await getHomeDoc();
|
||||
@@ -21,6 +22,77 @@ const getOrCreateHomeDoc = async () => {
|
||||
return doc;
|
||||
};
|
||||
|
||||
const hasMeaningfulValue = (value) =>
|
||||
typeof value === "string" && value.trim().length > 0;
|
||||
|
||||
const getMeaningfulHeroSlides = (hero = {}) => {
|
||||
if (!Array.isArray(hero.slides)) return [];
|
||||
|
||||
return hero.slides.filter((slide = {}) => {
|
||||
return (
|
||||
hasMeaningfulValue(slide.title) ||
|
||||
hasMeaningfulValue(slide.subtitle) ||
|
||||
hasMeaningfulValue(slide.description) ||
|
||||
hasMeaningfulValue(slide.heroImage) ||
|
||||
hasMeaningfulValue(slide.videoUrl) ||
|
||||
hasMeaningfulValue(slide.primaryButton?.label) ||
|
||||
hasMeaningfulValue(slide.primaryButton?.href) ||
|
||||
hasMeaningfulValue(slide.secondaryButton?.label) ||
|
||||
hasMeaningfulValue(slide.secondaryButton?.href)
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const scoreHeroSlides = (slides = []) =>
|
||||
slides.reduce((score, slide = {}) => {
|
||||
return (
|
||||
score +
|
||||
(slide.title || "").trim().length * 3 +
|
||||
(slide.subtitle || "").trim().length +
|
||||
(slide.description || "").trim().length * 2 +
|
||||
(slide.primaryButton?.label || "").trim().length +
|
||||
(slide.primaryButton?.href || "").trim().length +
|
||||
(slide.secondaryButton?.label || "").trim().length +
|
||||
(slide.secondaryButton?.href || "").trim().length +
|
||||
(hasMeaningfulValue(slide.heroImage) ? 20 : 0) +
|
||||
(hasMeaningfulValue(slide.videoUrl) ? 12 : 0)
|
||||
);
|
||||
}, 0);
|
||||
|
||||
const scoreHeroData = (hero = {}) => {
|
||||
const slides = getMeaningfulHeroSlides(hero);
|
||||
|
||||
if (slides.length > 0) {
|
||||
return scoreHeroSlides(slides) + slides.length * 30;
|
||||
}
|
||||
|
||||
return (
|
||||
(hero.title || "").trim().length * 3 +
|
||||
(hero.subtitle || "").trim().length +
|
||||
(hero.description || "").trim().length * 2 +
|
||||
(hero.primaryButton?.label || "").trim().length +
|
||||
(hero.primaryButton?.href || "").trim().length +
|
||||
(hero.secondaryButton?.label || "").trim().length +
|
||||
(hero.secondaryButton?.href || "").trim().length +
|
||||
(hasMeaningfulValue(hero.heroImage) ? 20 : 0) +
|
||||
(hasMeaningfulValue(hero.videoUrl) ? 12 : 0)
|
||||
);
|
||||
};
|
||||
|
||||
const getPreferredHeroData = (docs = []) => {
|
||||
const heroes = docs
|
||||
.map((doc) => doc?.hero)
|
||||
.filter(Boolean);
|
||||
|
||||
if (!heroes.length) return {};
|
||||
|
||||
return heroes.reduce((bestHero, currentHero) => {
|
||||
return scoreHeroData(currentHero) > scoreHeroData(bestHero)
|
||||
? currentHero
|
||||
: bestHero;
|
||||
}, heroes[0]);
|
||||
};
|
||||
|
||||
const normalizeStoredImagePath = (imagePath) => {
|
||||
if (!imagePath || typeof imagePath !== "string") return "";
|
||||
|
||||
@@ -373,9 +445,14 @@ exports.apiGetBlogs = async (req, res) => {
|
||||
};
|
||||
exports.api = async (req, res) => {
|
||||
try {
|
||||
let data = await getHomeData();
|
||||
const docs = await getAllHomeDocs();
|
||||
let data = docs[0]?.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 = [];
|
||||
|
||||
Reference in New Issue
Block a user