Merge pull request 'refactor(about): remove blog section and decouple from blog module' (#33) from feat/huy-07022026-remove-blog-section-from-about into main

Reviewed-on: UKSOURCE/cms.hailearning.edu.vn#33
This commit is contained in:
2026-02-08 05:12:00 +00:00
37 changed files with 438 additions and 249 deletions

View File

@@ -1,5 +1,6 @@
const { addBaseUrlToImages } = require("../utils/imageHelper"); const { addBaseUrlToImages } = require("../utils/imageHelper");
const AboutUs = require("../models/aboutUs"); const AboutUs = require("../models/aboutUs");
const Blog = require("../models/blog");
const jsonHelper = require("../utils/jsonHelper"); const jsonHelper = require("../utils/jsonHelper");
/** /**
@@ -9,14 +10,59 @@ const jsonHelper = require("../utils/jsonHelper");
exports.getAbout = async (req, res) => { exports.getAbout = async (req, res) => {
try { try {
// Force no-cache headers // Force no-cache headers
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate'); res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
res.setHeader('Pragma', 'no-cache'); res.setHeader("Pragma", "no-cache");
res.setHeader('Expires', '0'); res.setHeader("Expires", "0");
const data = await AboutUs.getSingle(); const data = await AboutUs.getSingle();
const rawData = data.toObject(); const rawData = data.toObject();
const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get('host')}`; // === Dynamic Blog News Section ===
const news = rawData.news || {};
let blogs = [];
// Nếu có chọn blog cụ thể
if (news.selectedBlogIds && news.selectedBlogIds.length > 0) {
blogs = await Blog.find({
_id: { $in: news.selectedBlogIds },
status: "published",
}).lean();
// Sắp xếp theo thứ tự đã chọn trong selectedBlogIds
blogs.sort((a, b) => {
return news.selectedBlogIds.indexOf(a._id.toString()) - news.selectedBlogIds.indexOf(b._id.toString());
});
}
// Nếu không chọn hoặc chọn nhưng không đủ, lấy thêm 3 bài mới nhất
if (blogs.length === 0) {
blogs = await Blog.find({ status: "published" }).sort({ createdAt: -1 }).limit(3).lean();
}
// Map dữ liệu blog sang format mà frontend mong đợi
news.items = blogs.map((blog) => ({
title: blog.title,
category: blog.category && blog.category[0] ? blog.category[0] : "Visa",
date:
blog.publishedAt ||
new Date(blog.createdAt).toLocaleDateString("en-GB", {
day: "numeric",
month: "long",
year: "numeric",
}),
comments: blog.commentsCount || 0,
author: {
name: blog.author || "Admin",
avatar: "/assets/img/home-1/news/client.png", // Default avatar
},
link: `/blog/${blog.slug}`,
thumbnail: blog.featuredImage,
}));
rawData.news = news;
// ===============================
const baseUrl = process.env.BACKEND_URL || `${req.protocol}://${req.get("host")}`;
const processedData = addBaseUrlToImages(rawData, baseUrl); const processedData = addBaseUrlToImages(rawData, baseUrl);
res.json(processedData); res.json(processedData);
@@ -24,7 +70,7 @@ exports.getAbout = async (req, res) => {
console.error("Error getting about data:", error); console.error("Error getting about data:", error);
res.status(500).json({ res.status(500).json({
success: false, success: false,
error: "Failed to get about data" error: "Failed to get about data",
}); });
} }
}; };
@@ -44,7 +90,7 @@ exports.updateAbout = async (req, res) => {
} catch (e) { } catch (e) {
return res.status(400).json({ return res.status(400).json({
success: false, success: false,
message: "Invalid JSON in aboutJson" message: "Invalid JSON in aboutJson",
}); });
} }
} }
@@ -55,9 +101,7 @@ exports.updateAbout = async (req, res) => {
await doc.save(); await doc.save();
// Fetch fresh data for syncing and returning // Fetch fresh data for syncing and returning
const finalData = await AboutUs.findOne() const finalData = await AboutUs.findOne().select("-_id -__v -createdAt -updatedAt").lean();
.select('-_id -__v -createdAt -updatedAt')
.lean();
// Update about.json file to keep it in sync // Update about.json file to keep it in sync
jsonHelper.writeJsonFile("about", finalData); jsonHelper.writeJsonFile("about", finalData);
@@ -65,13 +109,13 @@ exports.updateAbout = async (req, res) => {
res.json({ res.json({
success: true, success: true,
message: "About Us updated successfully", message: "About Us updated successfully",
data: finalData data: finalData,
}); });
} catch (error) { } catch (error) {
console.error("Error updating about data:", error); console.error("Error updating about data:", error);
res.status(500).json({ res.status(500).json({
success: false, success: false,
error: "Failed to update about data: " + error.message error: "Failed to update about data: " + error.message,
}); });
} }
}; };
@@ -84,15 +128,20 @@ exports.index = async (req, res) => {
const data = await AboutUs.getSingle(); const data = await AboutUs.getSingle();
const rawData = data.toObject(); const rawData = data.toObject();
// Lấy tất cả blog để chọn trong CMS
const allBlogs = await Blog.find({ status: "published" }).sort({ createdAt: -1 }).lean();
const activeTab = req.query.activeTab || "hero"; const activeTab = req.query.activeTab || "hero";
res.render("admin/aboutUs/index", { res.render("admin/aboutUs/index", {
layout: "layouts/main", layout: "layouts/main",
title: "About Us Management", title: "About Us Management",
data: rawData, data: rawData,
allBlogs,
activeTab, activeTab,
user: req.session.user, user: req.session.user,
currentPath: req.path, currentPath: req.path,
frontendUrl: process.env.FRONTEND_URL || 'http://localhost:3000' frontendUrl: process.env.FRONTEND_URL || "http://localhost:3000",
backendUrl: process.env.BACKEND_URL || "http://localhost:3001",
}); });
} catch (err) { } catch (err) {
console.error("Error in about index:", err); console.error("Error in about index:", err);
@@ -120,9 +169,7 @@ exports.update = async (req, res) => {
doc.set(updateData); doc.set(updateData);
await doc.save(); await doc.save();
const finalData = await AboutUs.findOne() const finalData = await AboutUs.findOne().select("-_id -__v -createdAt -updatedAt").lean();
.select('-_id -__v -createdAt -updatedAt')
.lean();
jsonHelper.writeJsonFile("about", finalData); jsonHelper.writeJsonFile("about", finalData);
req.flash("success_msg", "About Us updated successfully"); req.flash("success_msg", "About Us updated successfully");

View File

@@ -11,15 +11,15 @@
"subheading": "Company Intro", "subheading": "Company Intro",
"heading": "Building Pathways to Your Immigration Success", "heading": "Building Pathways to Your Immigration Success",
"description": "We provide expert guidance, personalized solutions, and transparent processes to help you achieve your immigration goals. Our dedicated team ensures a smooth journey, building pathways to your international success.", "description": "We provide expert guidance, personalized solutions, and transparent processes to help you achieve your immigration goals. Our dedicated team ensures a smooth journey, building pathways to your international success.",
"image": "http://localhost:3001/uploads/about/intro.jpg" "image": "/uploads/about/businessman.jpg"
}, },
"mission": { "mission": {
"subheading": "About Our Consultancy", "subheading": "About Our Consultancy",
"heading": "Turning Study Abroad Dreams Into Reality", "heading": "Turning Study Abroad Dreams Into Reality",
"description": "We guide students with expert visa consulting, ensuring a smooth process from application to approval, turning study abroad aspirations into life-changing opportunities for a brighter future.", "description": "We guide students with expert visa consulting, ensuring a smooth process from application to approval, turning study abroad aspirations into life-changing opportunities for a brighter future.",
"images": { "images": {
"main": "/assets/img/home-1/about/about-1.jpg", "main": "/uploads/about/375x419.jpg",
"secondary": "/assets/img/home-1/about/about-02.jpg", "secondary": "/uploads/about/375x419.jpg",
"bgShape": "/assets/img/home-1/about/Vector.png", "bgShape": "/assets/img/home-1/about/Vector.png",
"planeShape": "/assets/img/home-1/about/plane.png", "planeShape": "/assets/img/home-1/about/plane.png",
"topShape": "/assets/img/home-1/about/shape.png", "topShape": "/assets/img/home-1/about/shape.png",
@@ -51,7 +51,7 @@
"subheading": "Your Travel Made Easy", "subheading": "Your Travel Made Easy",
"heading": "Smooth Visa Journey Guaranteed", "heading": "Smooth Visa Journey Guaranteed",
"description": "We provide expert guidance for every visa application, ensuring smooth processing, personalized support, and reliable assistance", "description": "We provide expert guidance for every visa application, ensuring smooth processing, personalized support, and reliable assistance",
"image": "/assets/img/home-2/feature/02.png", "image": "/uploads/about/686x906.jpg",
"items": [ "items": [
{ {
"icon": "/assets/img/home-2/icon/01.png", "icon": "/assets/img/home-2/icon/01.png",
@@ -81,43 +81,11 @@
"label": "view all articles", "label": "view all articles",
"href": "/blog" "href": "/blog"
}, },
"items": [ "selectedBlogIds": [
{ "69857d6c6d04fed459107944",
"title": "Step-by-Step Guide to Applying for a Student Visa", "69857d6c6d04fed459107942",
"category": "Student Visa", "69857d6c6d04fed459107940"
"date": "20 August ,2025", ],
"comments": 8, "items": []
"author": {
"name": "Sohel",
"avatar": "/assets/img/home-1/news/client.png"
},
"link": "/blog/step-by-step-guide-student-visa",
"thumbnail": "/assets/img/home-1/news/news-1.jpg"
},
{
"title": "Tips to Prepare Financial Documents for Visa Approval",
"category": "IELTS / TOEFL",
"date": "20 August ,2025",
"comments": 8,
"author": {
"name": "Sohel",
"avatar": "/assets/img/home-1/news/client.png"
},
"link": "/blog/financial-documents-visa-approval",
"thumbnail": "/assets/img/home-1/news/news-2.jpg"
},
{
"title": "Post-Arrival Guide What Every Student Should Know",
"category": "Study Abroad",
"date": "20 August ,2025",
"comments": 8,
"author": {
"name": "Sohel",
"avatar": "/assets/img/home-1/news/client.png"
},
"link": "/blog/post-arrival-guide-students",
"thumbnail": "/assets/img/home-1/news/news-3.jpg"
}
]
} }
} }

View File

@@ -32,7 +32,7 @@ const aboutUsSchema = new mongoose.Schema(
label: String, label: String,
description: String, description: String,
}, },
{ _id: false } { _id: false },
), ),
], ],
features: [String], features: [String],
@@ -54,7 +54,7 @@ const aboutUsSchema = new mongoose.Schema(
title: String, title: String,
description: String, description: String,
}, },
{ _id: false } { _id: false },
), ),
], ],
ctaButton: { ctaButton: {
@@ -69,6 +69,8 @@ const aboutUsSchema = new mongoose.Schema(
label: String, label: String,
href: String, href: String,
}, },
selectedBlogIds: [{ type: mongoose.Schema.Types.ObjectId, ref: "Blog" }],
// Deprecated: items field kept for backward compatibility during migration
items: [ items: [
new mongoose.Schema( new mongoose.Schema(
{ {
@@ -83,7 +85,7 @@ const aboutUsSchema = new mongoose.Schema(
link: String, link: String,
thumbnail: String, thumbnail: String,
}, },
{ _id: false } { _id: false },
), ),
], ],
}, },
@@ -91,7 +93,7 @@ const aboutUsSchema = new mongoose.Schema(
{ {
timestamps: true, timestamps: true,
collection: "aboutus", collection: "aboutus",
} },
); );
// Static method để đảm bảo luôn chỉ có 1 bản ghi duy nhất (Singleton) // Static method để đảm bảo luôn chỉ có 1 bản ghi duy nhất (Singleton)

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 KiB

BIN
public/uploads/about/01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,10 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_405_45874)">
<path d="M13.1588 19.7266C12.6081 19.8683 12.0306 19.9436 11.4356 19.9436C10.2384 19.9436 9.11249 19.6386 8.13126 19.1021C8.17106 17.5984 9.16284 16.9599 10.9394 18.1623C11.7528 18.7129 12.8715 16.9469 13.1588 19.7266ZM13.8425 19.5117C14.1554 19.3952 14.4576 19.2566 14.7471 19.0979L14.7202 18.7269C14.6219 17.369 14.7801 17.0202 13.8554 15.9021C13.4081 15.3614 12.7436 14.5168 13.0721 13.7709C13.3284 13.1892 13.9607 13.0774 14.5195 12.9916C14.8212 12.9452 15.2974 12.8857 15.5554 12.7153C15.8156 12.5434 15.8096 12.2072 15.7796 11.9277C15.7514 11.6653 15.5964 11.4945 15.4021 11.3304C15.0712 11.0511 14.6836 10.832 14.3447 10.5526C13.0131 9.45442 13.1151 8.03448 13.7154 6.53875L13.717 6.53486C13.0028 6.28464 12.2352 6.14809 11.4356 6.14809C10.4291 6.14809 9.47301 6.36386 8.61084 6.75132L8.64716 6.86786C8.91777 7.73575 9.79874 7.77995 10.5699 7.77395C10.975 7.77081 11.5223 7.71807 11.9076 7.82036C12.3068 7.92634 12.6021 8.22803 12.6203 8.653C12.6343 8.97798 12.4722 9.27259 12.286 9.52656C11.6961 10.3314 11.8082 11.2096 12.0235 12.1204C12.1221 12.5378 12.266 13.021 12.2561 13.4495C12.2403 14.1285 11.8208 14.5759 11.1477 14.6683C10.5743 14.747 10.1864 14.3864 9.88706 13.9539C9.84046 13.8866 9.73452 13.7165 9.64068 13.5884C9.57904 13.7017 9.51402 13.8349 9.47479 13.899C9.20404 14.3406 8.80537 14.6145 8.26645 14.5624C7.95918 14.5327 7.69729 14.4122 7.45846 14.2208C7.41346 14.1848 7.36284 14.1358 7.31287 14.0897C7.30279 14.0979 7.2906 14.1085 7.28071 14.1186C7.29341 14.2072 7.36973 14.3896 7.39565 14.4528C7.51766 14.7505 7.63649 15.0316 7.71552 15.3457C7.98313 16.4092 7.68834 17.3647 7.09457 18.2611L7.03232 18.3551C7.1706 18.4699 7.31343 18.5794 7.46048 18.6833C7.55971 17.9567 7.89206 17.268 8.61435 16.968C9.53099 16.5872 10.563 17.0602 11.3245 17.5739C11.3896 17.5793 11.5585 17.5342 11.6135 17.52C11.8905 17.4485 12.1454 17.3822 12.4362 17.4101C13.4758 17.5103 13.7397 18.6395 13.8425 19.5117ZM23.0616 2.7152L21.4076 0.606387C21.1902 0.329121 20.77 0.329121 20.5526 0.606387L18.8986 2.7152C18.7585 2.89384 18.8853 3.15451 19.1123 3.15451H19.9689V13.0458C19.9689 17.7588 16.1486 21.5791 11.4356 21.5791C6.72262 21.5791 2.90235 17.7588 2.90235 13.0458C2.90235 8.33284 6.72266 4.51257 11.4356 4.51257C13.7921 4.51257 15.9254 5.4677 17.4696 7.01186V4.38395C15.7594 3.19032 13.6793 2.49015 11.4356 2.49015C5.60605 2.49015 0.879883 7.21628 0.879883 13.0459C0.879883 18.8755 5.6061 23.6016 11.4356 23.6016C17.2652 23.6016 21.9913 18.8755 21.9913 13.0459V3.15456H22.8479C23.0746 3.15456 23.2018 2.89384 23.0616 2.7152ZM7.97591 7.0772C5.92016 8.27139 4.53787 10.4972 4.53787 13.0458C4.53787 14.9251 5.28941 16.6289 6.50835 17.8729C8.1643 15.3729 5.7674 14.42 6.88541 13.5311C7.63677 12.9338 7.67127 13.7986 8.33404 13.8626C9.04288 13.9311 8.94023 12.7144 9.6532 12.7662C10.2659 12.8107 10.4894 14.049 11.0521 13.9718C12.5248 13.7696 10.1229 11.2886 11.7189 9.11096C12.8573 7.55771 8.77874 9.65181 7.97591 7.0772ZM18.3334 13.0458C18.3334 10.2849 16.7112 7.90276 14.368 6.80064C12.8853 10.4949 16.2779 9.98101 16.4787 11.8527C16.8122 14.9609 11.8994 12.4343 14.3971 15.454C15.4796 16.7627 15.3216 17.2965 15.4215 18.6761C17.1835 17.4264 18.3334 15.3704 18.3334 13.0458Z" fill="#0048B4"/>
</g>
<defs>
<clipPath id="clip0_405_45874">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
public/uploads/about/02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 KiB

View File

@@ -0,0 +1,18 @@
<svg width="159" height="48" viewBox="0 0 159 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M41.3036 18.9806C41.604 18.9074 41.9089 18.8663 42.2184 18.8572C42.5279 18.8389 42.8237 18.8297 43.1059 18.8297C43.3699 18.8297 43.6839 18.8526 44.048 18.8983C44.4213 18.9349 44.7489 19.0034 45.0311 19.104L45.195 19.3372L40.0337 37.7143C39.5513 37.7692 39.0142 37.8057 38.4226 37.824C37.8309 37.8514 37.2665 37.8652 36.7295 37.8652C35.9466 37.8652 35.3322 37.7372 34.8862 37.4812C34.4401 37.2252 34.1124 36.7223 33.9031 35.9726L29.3016 19.3509C29.6749 19.1863 30.0708 19.0446 30.4895 18.9257C30.9174 18.8069 31.3589 18.7474 31.814 18.7474C32.433 18.7474 32.9154 18.912 33.2613 19.2412C33.6072 19.5703 33.8712 20.096 34.0533 20.8183L36.2516 28.9097C36.3972 29.4309 36.5337 29.9749 36.6612 30.5417C36.7886 31.0994 36.907 31.6617 37.0162 32.2286C37.1254 32.7863 37.2256 33.3303 37.3166 33.8606C37.3439 34.0069 37.3757 34.0983 37.4122 34.1349C37.4577 34.1714 37.5214 34.1897 37.6033 34.1897L41.3036 18.9806Z" fill="black"/>
<path d="M48.0401 18.9806C48.3678 18.9166 48.732 18.8754 49.1325 18.8572C49.5421 18.8389 49.8743 18.8297 50.1292 18.8297C50.4114 18.8297 50.7437 18.8389 51.126 18.8572C51.5174 18.8754 51.8815 18.9166 52.2183 18.9806V37.7143C51.8815 37.7783 51.5174 37.8194 51.126 37.8377C50.7437 37.856 50.4114 37.8652 50.1292 37.8652C49.8743 37.8652 49.5421 37.856 49.1325 37.8377C48.732 37.8194 48.3678 37.7783 48.0401 37.7143V18.9806Z" fill="black"/>
<path d="M55.2672 36.0823C55.3218 35.488 55.5039 34.9029 55.8134 34.3269C56.132 33.7509 56.4915 33.2892 56.892 32.9417C57.6658 33.408 58.5396 33.824 59.5136 34.1897C60.4876 34.5554 61.4571 34.7383 62.4219 34.7383C63.2594 34.7383 63.8693 34.5417 64.2516 34.1486C64.6339 33.7463 64.8251 33.3029 64.8251 32.8183C64.8251 32.4709 64.7113 32.1052 64.4837 31.7212C64.2652 31.328 63.7691 30.9714 62.9954 30.6514L59.7048 29.2663C58.576 28.7909 57.643 28.16 56.9057 27.3737C56.1775 26.5874 55.8134 25.5452 55.8134 24.2469C55.8134 23.1223 56.1047 22.1349 56.6872 21.2846C57.2698 20.4343 58.0572 19.7714 59.0494 19.296C60.0507 18.8206 61.1658 18.5829 62.3946 18.5829C63.669 18.5829 64.866 18.7474 65.9857 19.0766C67.1053 19.4057 68.0201 19.7577 68.7301 20.1326C68.6937 20.7269 68.5481 21.3074 68.2932 21.8743C68.0383 22.432 67.7106 22.8983 67.3101 23.2732C66.6092 22.9349 65.799 22.6286 64.8797 22.3543C63.9603 22.08 63.1365 21.9429 62.4083 21.9429C61.5981 21.9429 61.0065 22.1303 60.6333 22.5052C60.2691 22.88 60.0871 23.2777 60.0871 23.6983C60.0871 24.0823 60.2145 24.4206 60.4694 24.7132C60.7334 24.9966 61.1703 25.2663 61.7802 25.5223L65.1254 26.9212C65.9902 27.2777 66.7275 27.7257 67.3374 28.2652C67.9564 28.7954 68.4252 29.4034 68.7438 30.0892C69.0715 30.7657 69.2353 31.5017 69.2353 32.2972C69.2353 33.3943 68.9713 34.3817 68.4434 35.2594C67.9245 36.1372 67.1371 36.832 66.0812 37.344C65.0344 37.856 63.7191 38.112 62.1352 38.112C61.0247 38.112 59.8504 37.9383 58.6125 37.5909C57.3836 37.2343 56.2685 36.7314 55.2672 36.0823Z" fill="black"/>
<path d="M76.7523 18.9806C77.0891 18.9349 77.4896 18.8983 77.9539 18.8709C78.4181 18.8434 78.8232 18.8297 79.1691 18.8297C79.5059 18.8297 79.9064 18.8434 80.3706 18.8709C80.844 18.8983 81.2445 18.944 81.5722 19.008L87.4844 37.44C87.1931 37.6046 86.8199 37.728 86.3648 37.8103C85.9096 37.9017 85.4818 37.9474 85.0813 37.9474C84.4259 37.9474 83.9116 37.7966 83.5384 37.4949C83.1652 37.184 82.8511 36.5806 82.5963 35.6846L80.5072 28.3749C80.2887 27.5977 80.0384 26.7017 79.7562 25.6869C79.4831 24.672 79.2374 23.7212 79.0189 22.8343H78.855C78.7185 23.5749 78.5182 24.4252 78.2543 25.3852C77.9994 26.336 77.7673 27.168 77.5579 27.8812L74.6359 37.7417C74.3811 37.8057 74.1034 37.8469 73.803 37.8652C73.5027 37.8834 73.1932 37.8926 72.8746 37.8926C72.556 37.8926 72.201 37.8697 71.8095 37.824C71.4181 37.7783 71.0995 37.7097 70.8538 37.6183L70.7036 37.3989L76.7523 18.9806ZM76.9981 33.7097C76.8707 33.7097 76.7159 33.7097 76.5339 33.7097C76.3518 33.7006 76.1697 33.696 75.9877 33.696C75.8147 33.6869 75.6645 33.6823 75.5371 33.6823H73.3661L74.6496 30.4046H76.5475C76.6749 30.4046 76.8251 30.4046 76.9981 30.4046C77.171 30.3954 77.344 30.3909 77.5169 30.3909C77.6899 30.3817 77.8355 30.3772 77.9539 30.3772H80.0429C80.1704 30.3772 80.3206 30.3817 80.4935 30.3909C80.6665 30.3909 80.8394 30.3954 81.0124 30.4046C81.1853 30.4046 81.3355 30.4046 81.463 30.4046H83.4292L84.4805 33.6823H82.3232C82.1957 33.6823 82.041 33.6869 81.8589 33.696C81.6769 33.696 81.4948 33.7006 81.3128 33.7097C81.1398 33.7097 80.9896 33.7097 80.8622 33.7097H76.9981Z" fill="black"/>
<path d="M88.069 19.2274C88.3876 19.0903 88.7426 18.976 89.134 18.8846C89.5254 18.7932 89.9077 18.7474 90.2809 18.7474C91.0092 18.7474 91.5371 18.9074 91.8648 19.2274C92.2016 19.5383 92.4383 20.1417 92.5748 21.0377L93.8037 28.4297C93.9038 29.0057 94.004 29.632 94.1041 30.3086C94.2042 30.9852 94.2952 31.6389 94.3772 32.2697C94.4682 32.8914 94.5365 33.4217 94.582 33.8606C94.6002 34.0343 94.6229 34.1394 94.6502 34.176C94.6867 34.2034 94.7504 34.2172 94.8414 34.2172L97.2036 19.3509C97.6132 19.2777 98.0592 19.2274 98.5417 19.2C99.0241 19.1634 99.4656 19.1452 99.8661 19.1452C100.294 19.1452 100.745 19.1634 101.218 19.2C101.7 19.2274 102.137 19.2777 102.529 19.3509L104.713 33.8606C104.741 34.0343 104.772 34.1394 104.809 34.176C104.854 34.2034 104.918 34.2172 105 34.2172C105.055 33.7052 105.127 33.1109 105.218 32.4343C105.31 31.7577 105.41 31.0629 105.519 30.3497C105.628 29.6366 105.733 28.9829 105.833 28.3886L107.458 18.9806C107.767 18.9166 108.086 18.8754 108.414 18.8572C108.741 18.8389 109.046 18.8297 109.328 18.8297C109.647 18.8297 109.984 18.8526 110.339 18.8983C110.694 18.944 111.012 19.0126 111.295 19.104L111.499 19.3509L107.84 37.6869C107.367 37.7417 106.789 37.7829 106.106 37.8103C105.432 37.8469 104.823 37.8652 104.276 37.8652C103.657 37.8652 103.111 37.76 102.638 37.5497C102.165 37.3394 101.864 36.8137 101.737 35.9726L100.754 29.8423C100.59 28.7909 100.43 27.6846 100.276 26.5234C100.13 25.3623 100.012 24.3292 99.9207 23.424H99.7159C99.6067 24.3292 99.4701 25.3623 99.3063 26.5234C99.1424 27.6754 98.9695 28.7817 98.7874 29.8423L97.4766 37.6869C96.976 37.7417 96.4071 37.7829 95.7699 37.8103C95.1418 37.8469 94.5456 37.8652 93.9812 37.8652C93.3167 37.8652 92.7478 37.76 92.2744 37.5497C91.8102 37.3394 91.4962 36.8092 91.3323 35.9589L88.069 19.2274Z" fill="black"/>
<path d="M118.115 18.9806C118.451 18.9349 118.852 18.8983 119.316 18.8709C119.78 18.8434 120.185 18.8297 120.531 18.8297C120.868 18.8297 121.269 18.8434 121.733 18.8709C122.206 18.8983 122.607 18.944 122.934 19.008L128.847 37.44C128.555 37.6046 128.182 37.728 127.727 37.8103C127.272 37.9017 126.844 37.9474 126.444 37.9474C125.788 37.9474 125.274 37.7966 124.901 37.4949C124.527 37.184 124.213 36.5806 123.958 35.6846L121.869 28.3749C121.651 27.5977 121.401 26.7017 121.118 25.6869C120.845 24.672 120.6 23.7212 120.381 22.8343H120.217C120.081 23.5749 119.88 24.4252 119.617 25.3852C119.362 26.336 119.13 27.168 118.92 27.8812L115.998 37.7417C115.743 37.8057 115.466 37.8469 115.165 37.8652C114.865 37.8834 114.555 37.8926 114.237 37.8926C113.918 37.8926 113.563 37.8697 113.172 37.824C112.78 37.7783 112.462 37.7097 112.216 37.6183L112.066 37.3989L118.115 18.9806ZM118.36 33.7097C118.233 33.7097 118.078 33.7097 117.896 33.7097C117.714 33.7006 117.532 33.696 117.35 33.696C117.177 33.6869 117.027 33.6823 116.899 33.6823H114.728L116.012 30.4046H117.91C118.037 30.4046 118.187 30.4046 118.36 30.4046C118.533 30.3954 118.706 30.3909 118.879 30.3909C119.052 30.3817 119.198 30.3772 119.316 30.3772H121.405C121.533 30.3772 121.683 30.3817 121.856 30.3909C122.029 30.3909 122.202 30.3954 122.375 30.4046C122.548 30.4046 122.698 30.4046 122.825 30.4046H124.791L125.843 33.6823H123.685C123.558 33.6823 123.403 33.6869 123.221 33.696C123.039 33.696 122.857 33.7006 122.675 33.7097C122.502 33.7097 122.352 33.7097 122.224 33.7097H118.36Z" fill="black"/>
<path d="M133.41 29.4172H137.588V37.7143C137.251 37.7783 136.892 37.8194 136.51 37.8377C136.136 37.856 135.809 37.8652 135.526 37.8652C135.272 37.8652 134.939 37.856 134.53 37.8377C134.12 37.8194 133.747 37.7783 133.41 37.7143V29.4172ZM138.954 18.9806C139.245 18.9166 139.532 18.8754 139.814 18.8572C140.096 18.8389 140.374 18.8297 140.647 18.8297C141.002 18.8297 141.361 18.8526 141.725 18.8983C142.09 18.944 142.413 19.0172 142.695 19.1177L142.859 19.3509L137.37 32.448H133.683L128.14 19.4743C128.513 19.264 128.922 19.0949 129.369 18.9669C129.815 18.8297 130.256 18.7612 130.693 18.7612C131.285 18.7612 131.74 18.8937 132.058 19.1589C132.377 19.424 132.655 19.8537 132.891 20.448L134.311 23.9863C134.53 24.5532 134.744 25.1612 134.953 25.8103C135.162 26.4594 135.358 27.1406 135.54 27.8537H135.69C135.809 27.4057 135.941 26.9486 136.086 26.4823C136.232 26.016 136.382 25.5589 136.537 25.1109C136.701 24.6629 136.86 24.2423 137.015 23.8492L138.954 18.9806Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.9978 43.3281C20.5208 32.8971 19.5204 21.9194 15.1533 12.1223C23.8314 8.6219 33.1615 7.04718 42.5022 7.50735C42.9362 8.94698 43.3244 10.3982 43.667 11.8579L52.0194 13.536H26.0885V48L24.9804 43.2663C22.6597 43.4062 20.329 43.4278 17.9978 43.3281Z" fill="#E13833"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.6248 38.3511C16.4941 29.4258 12.9019 20.9574 7.20915 13.925C14.6893 8.28785 23.296 4.34155 32.437 2.35731C33.2346 3.64812 33.9906 4.96162 34.7036 6.29676C27.8434 6.78015 21.0798 8.33535 14.6725 10.9201L13.4273 11.422L13.9753 12.6516C17.5633 20.7015 18.8148 29.6527 17.6248 38.3511Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.8945 37.5263C12.4621 29.6575 6.98999 22.8108 0 17.7315C5.77315 10.3418 13.0689 4.29249 21.3877 0C22.4075 0.960982 23.3973 1.94993 24.3567 2.9658C17.8737 5.22498 11.7596 8.48472 6.24812 12.6389L4.91621 13.6421L5.9665 14.9398C11.251 21.4667 14.663 29.2764 15.8945 37.5263Z" fill="#E13833"/>
<path d="M106.782 37.571C108.845 36.9354 111.436 36.0416 113.189 35.1346C110.17 36.4323 109.294 34.9161 109.188 34.3865C108.114 35.1346 107.105 35.8563 106.242 36.4786C105.675 36.8891 106.116 37.7763 106.782 37.571Z" fill="black"/>
<path d="M132.938 27.1765L141.27 20.3638C141.27 20.3638 138.6 22.8002 138.534 24.0317C138.237 24.3826 132.938 27.1765 132.938 27.1765Z" fill="black"/>
<path d="M132.964 25.1771C132.964 25.1771 139.048 21.0458 140.683 19.5098C138.646 21.0259 137.908 20.8736 137.38 20.6551C134.23 23.8596 132.964 25.1771 132.964 25.1771Z" fill="black"/>
<path d="M121.106 34.9095C121.106 34.9095 126.84 31.5528 128.442 30.4405C127.862 30.8775 126.893 32.1222 126.834 32.9432L121.106 34.9095Z" fill="black"/>
<path d="M152.133 21.6416C151.724 19.0265 151.328 16.5503 150.926 13.9682C150.676 14.1735 150.471 14.339 150.274 14.5045C148.791 15.7956 147.149 16.8284 145.304 17.5236C144.677 17.7553 144.111 17.7487 143.524 17.3779C142.39 16.6562 141.223 15.9876 140.07 15.2924C140.498 14.7296 140.979 14.5376 141.639 14.6171C142.548 14.723 143.471 14.7495 144.387 14.7561C144.664 14.7561 145.007 14.6568 145.218 14.478C148.428 11.7503 151.618 9.00272 154.809 6.24852C155.685 5.49376 156.7 5.11638 157.847 5.14286C158.843 5.16272 159.258 5.79831 158.836 6.70534C158.619 7.17541 158.263 7.61238 157.88 7.96328C156.944 8.82397 155.969 9.63169 154.993 10.446C154.723 10.6711 154.585 10.9029 154.558 11.2736C154.347 13.9947 154.09 16.7092 153.892 19.4303C153.846 20.0328 153.649 20.4764 153.148 20.814C152.818 21.0325 152.541 21.304 152.133 21.6416Z" fill="black"/>
<path d="M143.32 10.2275C144.064 9.57872 144.585 8.75114 145.785 8.92989C146.991 9.11527 148.224 9.12189 149.45 9.20796C149.549 9.21458 149.654 9.23445 149.858 9.26093C148.949 10.0289 148.118 10.7373 147.274 11.4325C147.195 11.4987 147.037 11.5384 146.938 11.5053C145.818 11.1544 144.704 10.7903 143.59 10.4196C143.504 10.4063 143.445 10.3269 143.32 10.2275Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

View File

@@ -0,0 +1,18 @@
<svg width="159" height="48" viewBox="0 0 159 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M41.3036 18.9806C41.604 18.9074 41.9089 18.8663 42.2184 18.8572C42.5279 18.8389 42.8237 18.8297 43.1059 18.8297C43.3699 18.8297 43.6839 18.8526 44.048 18.8983C44.4212 18.9349 44.7489 19.0034 45.0311 19.104L45.195 19.3372L40.0337 37.7143C39.5513 37.7692 39.0142 37.8057 38.4226 37.824C37.8309 37.8514 37.2665 37.8652 36.7295 37.8652C35.9466 37.8652 35.3322 37.7372 34.8862 37.4812C34.4401 37.2252 34.1124 36.7223 33.9031 35.9726L29.3016 19.3509C29.6749 19.1863 30.0708 19.0446 30.4895 18.9257C30.9174 18.8069 31.3589 18.7474 31.814 18.7474C32.433 18.7474 32.9154 18.912 33.2613 19.2411C33.6072 19.5703 33.8712 20.096 34.0533 20.8183L36.2516 28.9097C36.3972 29.4309 36.5337 29.9749 36.6612 30.5417C36.7886 31.0994 36.907 31.6617 37.0162 32.2286C37.1254 32.7863 37.2256 33.3303 37.3166 33.8606C37.3439 34.0069 37.3757 34.0983 37.4122 34.1349C37.4577 34.1714 37.5214 34.1897 37.6033 34.1897L41.3036 18.9806Z" fill="white"/>
<path d="M48.0401 18.9806C48.3678 18.9166 48.732 18.8754 49.1325 18.8572C49.5421 18.8389 49.8743 18.8297 50.1292 18.8297C50.4114 18.8297 50.7437 18.8389 51.126 18.8572C51.5174 18.8754 51.8815 18.9166 52.2183 18.9806V37.7143C51.8815 37.7783 51.5174 37.8194 51.126 37.8377C50.7437 37.856 50.4114 37.8652 50.1292 37.8652C49.8743 37.8652 49.5421 37.856 49.1325 37.8377C48.732 37.8194 48.3678 37.7783 48.0401 37.7143V18.9806Z" fill="white"/>
<path d="M55.2672 36.0823C55.3218 35.488 55.5039 34.9029 55.8134 34.3269C56.132 33.7509 56.4915 33.2892 56.892 32.9417C57.6658 33.408 58.5396 33.824 59.5136 34.1897C60.4876 34.5554 61.4571 34.7383 62.4219 34.7383C63.2594 34.7383 63.8693 34.5417 64.2516 34.1486C64.6339 33.7463 64.8251 33.3029 64.8251 32.8183C64.8251 32.4709 64.7113 32.1052 64.4837 31.7212C64.2652 31.328 63.7691 30.9714 62.9954 30.6514L59.7048 29.2663C58.576 28.7909 57.643 28.16 56.9057 27.3737C56.1775 26.5874 55.8134 25.5452 55.8134 24.2469C55.8134 23.1223 56.1047 22.1349 56.6872 21.2846C57.2698 20.4343 58.0572 19.7714 59.0494 19.296C60.0507 18.8206 61.1658 18.5829 62.3946 18.5829C63.669 18.5829 64.866 18.7474 65.9857 19.0766C67.1053 19.4057 68.0201 19.7577 68.7301 20.1326C68.6937 20.7269 68.5481 21.3074 68.2932 21.8743C68.0383 22.432 67.7106 22.8983 67.3101 23.2732C66.6092 22.9349 65.799 22.6286 64.8797 22.3543C63.9603 22.08 63.1365 21.9429 62.4083 21.9429C61.5981 21.9429 61.0065 22.1303 60.6333 22.5052C60.2691 22.88 60.0871 23.2777 60.0871 23.6983C60.0871 24.0823 60.2145 24.4206 60.4694 24.7132C60.7334 24.9966 61.1703 25.2663 61.7802 25.5223L65.1255 26.9212C65.9902 27.2777 66.7275 27.7257 67.3374 28.2652C67.9564 28.7954 68.4252 29.4034 68.7438 30.0892C69.0715 30.7657 69.2353 31.5017 69.2353 32.2972C69.2353 33.3943 68.9713 34.3817 68.4434 35.2594C67.9245 36.1372 67.1371 36.832 66.0812 37.344C65.0344 37.856 63.7191 38.112 62.1352 38.112C61.0247 38.112 59.8504 37.9383 58.6124 37.5909C57.3836 37.2343 56.2685 36.7314 55.2672 36.0823Z" fill="white"/>
<path d="M76.7523 18.9806C77.0891 18.9349 77.4896 18.8983 77.9539 18.8709C78.4181 18.8434 78.8232 18.8297 79.1691 18.8297C79.5059 18.8297 79.9064 18.8434 80.3707 18.8709C80.844 18.8983 81.2445 18.944 81.5722 19.008L87.4844 37.44C87.1931 37.6046 86.8199 37.728 86.3648 37.8103C85.9096 37.9017 85.4818 37.9474 85.0813 37.9474C84.4259 37.9474 83.9116 37.7966 83.5384 37.4949C83.1652 37.184 82.8511 36.5806 82.5963 35.6846L80.5072 28.3749C80.2887 27.5977 80.0384 26.7017 79.7562 25.6869C79.4831 24.672 79.2374 23.7212 79.0189 22.8343H78.855C78.7185 23.5749 78.5182 24.4252 78.2543 25.3852C77.9994 26.336 77.7673 27.168 77.5579 27.8812L74.6359 37.7417C74.3811 37.8057 74.1034 37.8469 73.803 37.8652C73.5026 37.8834 73.1932 37.8926 72.8746 37.8926C72.556 37.8926 72.201 37.8697 71.8095 37.824C71.4181 37.7783 71.0995 37.7097 70.8538 37.6183L70.7036 37.3989L76.7523 18.9806ZM76.9981 33.7097C76.8707 33.7097 76.7159 33.7097 76.5339 33.7097C76.3518 33.7006 76.1697 33.696 75.9877 33.696C75.8147 33.6869 75.6645 33.6823 75.5371 33.6823H73.3661L74.6496 30.4046H76.5475C76.6749 30.4046 76.8251 30.4046 76.9981 30.4046C77.171 30.3954 77.344 30.3909 77.5169 30.3909C77.6899 30.3817 77.8355 30.3772 77.9539 30.3772H80.0429C80.1704 30.3772 80.3206 30.3817 80.4935 30.3909C80.6665 30.3909 80.8394 30.3954 81.0124 30.4046C81.1853 30.4046 81.3355 30.4046 81.463 30.4046H83.4292L84.4805 33.6823H82.3232C82.1957 33.6823 82.041 33.6869 81.8589 33.696C81.6769 33.696 81.4948 33.7006 81.3128 33.7097C81.1398 33.7097 80.9896 33.7097 80.8622 33.7097H76.9981Z" fill="white"/>
<path d="M88.069 19.2274C88.3876 19.0903 88.7426 18.976 89.134 18.8846C89.5254 18.7932 89.9077 18.7474 90.2809 18.7474C91.0092 18.7474 91.5371 18.9074 91.8648 19.2274C92.2016 19.5383 92.4383 20.1417 92.5748 21.0377L93.8037 28.4297C93.9038 29.0057 94.004 29.632 94.1041 30.3086C94.2042 30.9852 94.2952 31.6389 94.3772 32.2697C94.4682 32.8914 94.5365 33.4217 94.582 33.8606C94.6002 34.0343 94.6229 34.1394 94.6502 34.176C94.6867 34.2034 94.7504 34.2172 94.8414 34.2172L97.2036 19.3509C97.6132 19.2777 98.0592 19.2274 98.5417 19.2C99.0241 19.1634 99.4656 19.1452 99.8661 19.1452C100.294 19.1452 100.745 19.1634 101.218 19.2C101.7 19.2274 102.137 19.2777 102.529 19.3509L104.713 33.8606C104.741 34.0343 104.772 34.1394 104.809 34.176C104.854 34.2034 104.918 34.2172 105 34.2172C105.055 33.7052 105.127 33.1109 105.218 32.4343C105.31 31.7577 105.41 31.0629 105.519 30.3497C105.628 29.6366 105.733 28.9829 105.833 28.3886L107.458 18.9806C107.767 18.9166 108.086 18.8754 108.414 18.8572C108.741 18.8389 109.046 18.8297 109.328 18.8297C109.647 18.8297 109.984 18.8526 110.339 18.8983C110.694 18.944 111.012 19.0126 111.295 19.104L111.499 19.3509L107.84 37.6869C107.367 37.7417 106.789 37.7829 106.106 37.8103C105.432 37.8469 104.823 37.8652 104.276 37.8652C103.657 37.8652 103.111 37.76 102.638 37.5497C102.165 37.3394 101.864 36.8137 101.737 35.9726L100.754 29.8423C100.59 28.7909 100.43 27.6846 100.276 26.5234C100.13 25.3623 100.012 24.3292 99.9207 23.424H99.7159C99.6067 24.3292 99.4701 25.3623 99.3063 26.5234C99.1424 27.6754 98.9695 28.7817 98.7874 29.8423L97.4766 37.6869C96.976 37.7417 96.4071 37.7829 95.7699 37.8103C95.1418 37.8469 94.5456 37.8652 93.9812 37.8652C93.3167 37.8652 92.7478 37.76 92.2744 37.5497C91.8102 37.3394 91.4962 36.8092 91.3323 35.9589L88.069 19.2274Z" fill="white"/>
<path d="M118.115 18.9806C118.451 18.9349 118.852 18.8983 119.316 18.8709C119.78 18.8434 120.185 18.8297 120.531 18.8297C120.868 18.8297 121.269 18.8434 121.733 18.8709C122.206 18.8983 122.607 18.944 122.934 19.008L128.847 37.44C128.555 37.6046 128.182 37.728 127.727 37.8103C127.272 37.9017 126.844 37.9474 126.444 37.9474C125.788 37.9474 125.274 37.7966 124.901 37.4949C124.527 37.184 124.213 36.5806 123.958 35.6846L121.869 28.3749C121.651 27.5977 121.401 26.7017 121.118 25.6869C120.845 24.672 120.6 23.7212 120.381 22.8343H120.217C120.081 23.5749 119.88 24.4252 119.617 25.3852C119.362 26.336 119.13 27.168 118.92 27.8812L115.998 37.7417C115.743 37.8057 115.466 37.8469 115.165 37.8652C114.865 37.8834 114.555 37.8926 114.237 37.8926C113.918 37.8926 113.563 37.8697 113.172 37.824C112.78 37.7783 112.462 37.7097 112.216 37.6183L112.066 37.3989L118.115 18.9806ZM118.36 33.7097C118.233 33.7097 118.078 33.7097 117.896 33.7097C117.714 33.7006 117.532 33.696 117.35 33.696C117.177 33.6869 117.027 33.6823 116.899 33.6823H114.728L116.012 30.4046H117.91C118.037 30.4046 118.187 30.4046 118.36 30.4046C118.533 30.3954 118.706 30.3909 118.879 30.3909C119.052 30.3817 119.198 30.3772 119.316 30.3772H121.405C121.533 30.3772 121.683 30.3817 121.856 30.3909C122.029 30.3909 122.202 30.3954 122.375 30.4046C122.548 30.4046 122.698 30.4046 122.825 30.4046H124.791L125.843 33.6823H123.685C123.558 33.6823 123.403 33.6869 123.221 33.696C123.039 33.696 122.857 33.7006 122.675 33.7097C122.502 33.7097 122.352 33.7097 122.224 33.7097H118.36Z" fill="white"/>
<path d="M133.41 29.4172H137.588V37.7143C137.251 37.7783 136.892 37.8194 136.51 37.8377C136.136 37.856 135.809 37.8652 135.526 37.8652C135.272 37.8652 134.939 37.856 134.53 37.8377C134.12 37.8194 133.747 37.7783 133.41 37.7143V29.4172ZM138.954 18.9806C139.245 18.9166 139.532 18.8754 139.814 18.8572C140.096 18.8389 140.374 18.8297 140.647 18.8297C141.002 18.8297 141.361 18.8526 141.725 18.8983C142.09 18.944 142.413 19.0172 142.695 19.1177L142.859 19.3509L137.37 32.448H133.683L128.14 19.4743C128.513 19.264 128.922 19.0949 129.368 18.9669C129.815 18.8297 130.256 18.7612 130.693 18.7612C131.285 18.7612 131.74 18.8937 132.058 19.1589C132.377 19.424 132.655 19.8537 132.891 20.448L134.311 23.9863C134.53 24.5532 134.744 25.1612 134.953 25.8103C135.162 26.4594 135.358 27.1406 135.54 27.8537H135.69C135.809 27.4057 135.941 26.9486 136.086 26.4823C136.232 26.016 136.382 25.5589 136.537 25.1109C136.701 24.6629 136.86 24.2423 137.015 23.8492L138.954 18.9806Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.9978 43.3281C20.5208 32.8971 19.5204 21.9194 15.1533 12.1223C23.8314 8.6219 33.1615 7.04718 42.5022 7.50735C42.9362 8.94698 43.3244 10.3982 43.667 11.8579L52.0194 13.536H26.0885V48L24.9804 43.2663C22.6597 43.4062 20.329 43.4278 17.9978 43.3281Z" fill="#E13833"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.6248 38.3511C16.4941 29.4258 12.9019 20.9574 7.20915 13.925C14.6893 8.28785 23.296 4.34155 32.437 2.35731C33.2346 3.64812 33.9906 4.96162 34.7036 6.29676C27.8434 6.78015 21.0798 8.33535 14.6725 10.9201L13.4273 11.422L13.9753 12.6516C17.5633 20.7015 18.8148 29.6527 17.6248 38.3511Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.8945 37.5263C12.4621 29.6575 6.98999 22.8108 0 17.7315C5.77315 10.3418 13.0689 4.29249 21.3877 0C22.4075 0.960982 23.3973 1.94993 24.3567 2.9658C17.8737 5.22498 11.7596 8.48472 6.24812 12.6389L4.91621 13.6421L5.9665 14.9398C11.251 21.4667 14.663 29.2764 15.8945 37.5263Z" fill="#E13833"/>
<path d="M106.782 37.571C108.845 36.9354 111.436 36.0416 113.189 35.1346C110.17 36.4323 109.294 34.9161 109.188 34.3865C108.114 35.1346 107.105 35.8563 106.242 36.4786C105.675 36.8891 106.116 37.7763 106.782 37.571Z" fill="white"/>
<path d="M132.938 27.1765L141.27 20.3638C141.27 20.3638 138.6 22.8002 138.534 24.0317C138.237 24.3826 132.938 27.1765 132.938 27.1765Z" fill="white"/>
<path d="M132.964 25.1771C132.964 25.1771 139.048 21.0458 140.683 19.5098C138.646 21.0259 137.908 20.8736 137.38 20.6551C134.23 23.8596 132.964 25.1771 132.964 25.1771Z" fill="white"/>
<path d="M121.106 34.9095C121.106 34.9095 126.84 31.5528 128.442 30.4405C127.862 30.8775 126.893 32.1222 126.834 32.9432L121.106 34.9095Z" fill="white"/>
<path d="M152.133 21.6416C151.724 19.0265 151.328 16.5503 150.926 13.9682C150.676 14.1735 150.471 14.339 150.274 14.5045C148.791 15.7956 147.149 16.8284 145.304 17.5236C144.677 17.7553 144.111 17.7487 143.524 17.3779C142.39 16.6562 141.223 15.9876 140.07 15.2924C140.498 14.7296 140.979 14.5376 141.639 14.6171C142.548 14.723 143.471 14.7495 144.387 14.7561C144.664 14.7561 145.007 14.6568 145.218 14.478C148.428 11.7503 151.618 9.00272 154.809 6.24852C155.685 5.49376 156.701 5.11638 157.847 5.14286C158.843 5.16272 159.258 5.79831 158.836 6.70534C158.619 7.17541 158.263 7.61238 157.88 7.96328C156.944 8.82397 155.969 9.63169 154.993 10.446C154.723 10.6711 154.585 10.9029 154.558 11.2736C154.347 13.9947 154.09 16.7092 153.892 19.4303C153.846 20.0328 153.649 20.4764 153.148 20.814C152.818 21.0325 152.541 21.304 152.133 21.6416Z" fill="white"/>
<path d="M143.32 10.2275C144.064 9.57872 144.585 8.75114 145.785 8.92989C146.991 9.11527 148.224 9.12189 149.45 9.20796C149.549 9.21458 149.654 9.23445 149.858 9.26093C148.949 10.0289 148.118 10.7373 147.274 11.4325C147.195 11.4987 147.037 11.5384 146.938 11.5053C145.818 11.1544 144.704 10.7903 143.59 10.4196C143.504 10.4063 143.445 10.3269 143.32 10.2275Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

View File

@@ -0,0 +1,18 @@
<svg width="159" height="48" viewBox="0 0 159 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M41.3036 18.9806C41.604 18.9074 41.9089 18.8663 42.2184 18.8572C42.5279 18.8389 42.8237 18.8297 43.1059 18.8297C43.3699 18.8297 43.6839 18.8526 44.048 18.8983C44.4212 18.9349 44.7489 19.0034 45.0311 19.104L45.195 19.3372L40.0337 37.7143C39.5513 37.7692 39.0142 37.8057 38.4226 37.824C37.8309 37.8514 37.2665 37.8652 36.7295 37.8652C35.9466 37.8652 35.3322 37.7372 34.8862 37.4812C34.4401 37.2252 34.1124 36.7223 33.9031 35.9726L29.3016 19.3509C29.6749 19.1863 30.0708 19.0446 30.4895 18.9257C30.9174 18.8069 31.3589 18.7474 31.814 18.7474C32.433 18.7474 32.9154 18.912 33.2613 19.2411C33.6072 19.5703 33.8712 20.096 34.0533 20.8183L36.2516 28.9097C36.3972 29.4309 36.5337 29.9749 36.6612 30.5417C36.7886 31.0994 36.907 31.6617 37.0162 32.2286C37.1254 32.7863 37.2256 33.3303 37.3166 33.8606C37.3439 34.0069 37.3757 34.0983 37.4122 34.1349C37.4577 34.1714 37.5214 34.1897 37.6033 34.1897L41.3036 18.9806Z" fill="white"/>
<path d="M48.0401 18.9806C48.3678 18.9166 48.732 18.8754 49.1325 18.8572C49.5421 18.8389 49.8743 18.8297 50.1292 18.8297C50.4114 18.8297 50.7437 18.8389 51.126 18.8572C51.5174 18.8754 51.8815 18.9166 52.2183 18.9806V37.7143C51.8815 37.7783 51.5174 37.8194 51.126 37.8377C50.7437 37.856 50.4114 37.8652 50.1292 37.8652C49.8743 37.8652 49.5421 37.856 49.1325 37.8377C48.732 37.8194 48.3678 37.7783 48.0401 37.7143V18.9806Z" fill="white"/>
<path d="M55.2672 36.0823C55.3218 35.488 55.5039 34.9029 55.8134 34.3269C56.132 33.7509 56.4915 33.2892 56.892 32.9417C57.6658 33.408 58.5396 33.824 59.5136 34.1897C60.4876 34.5554 61.4571 34.7383 62.4219 34.7383C63.2594 34.7383 63.8693 34.5417 64.2516 34.1486C64.6339 33.7463 64.8251 33.3029 64.8251 32.8183C64.8251 32.4709 64.7113 32.1052 64.4837 31.7212C64.2652 31.328 63.7691 30.9714 62.9954 30.6514L59.7048 29.2663C58.576 28.7909 57.643 28.16 56.9057 27.3737C56.1775 26.5874 55.8134 25.5452 55.8134 24.2469C55.8134 23.1223 56.1047 22.1349 56.6872 21.2846C57.2698 20.4343 58.0572 19.7714 59.0494 19.296C60.0507 18.8206 61.1658 18.5829 62.3946 18.5829C63.669 18.5829 64.866 18.7474 65.9857 19.0766C67.1053 19.4057 68.0201 19.7577 68.7301 20.1326C68.6937 20.7269 68.5481 21.3074 68.2932 21.8743C68.0383 22.432 67.7106 22.8983 67.3101 23.2732C66.6092 22.9349 65.799 22.6286 64.8797 22.3543C63.9603 22.08 63.1365 21.9429 62.4083 21.9429C61.5981 21.9429 61.0065 22.1303 60.6333 22.5052C60.2691 22.88 60.0871 23.2777 60.0871 23.6983C60.0871 24.0823 60.2145 24.4206 60.4694 24.7132C60.7334 24.9966 61.1703 25.2663 61.7802 25.5223L65.1255 26.9212C65.9902 27.2777 66.7275 27.7257 67.3374 28.2652C67.9564 28.7954 68.4252 29.4034 68.7438 30.0892C69.0715 30.7657 69.2353 31.5017 69.2353 32.2972C69.2353 33.3943 68.9713 34.3817 68.4434 35.2594C67.9245 36.1372 67.1371 36.832 66.0812 37.344C65.0344 37.856 63.7191 38.112 62.1352 38.112C61.0247 38.112 59.8504 37.9383 58.6124 37.5909C57.3836 37.2343 56.2685 36.7314 55.2672 36.0823Z" fill="white"/>
<path d="M76.7523 18.9806C77.0891 18.9349 77.4896 18.8983 77.9539 18.8709C78.4181 18.8434 78.8232 18.8297 79.1691 18.8297C79.5059 18.8297 79.9064 18.8434 80.3707 18.8709C80.844 18.8983 81.2445 18.944 81.5722 19.008L87.4844 37.44C87.1931 37.6046 86.8199 37.728 86.3648 37.8103C85.9096 37.9017 85.4818 37.9474 85.0813 37.9474C84.4259 37.9474 83.9116 37.7966 83.5384 37.4949C83.1652 37.184 82.8511 36.5806 82.5963 35.6846L80.5072 28.3749C80.2887 27.5977 80.0384 26.7017 79.7562 25.6869C79.4831 24.672 79.2374 23.7212 79.0189 22.8343H78.855C78.7185 23.5749 78.5182 24.4252 78.2543 25.3852C77.9994 26.336 77.7673 27.168 77.5579 27.8812L74.6359 37.7417C74.3811 37.8057 74.1034 37.8469 73.803 37.8652C73.5026 37.8834 73.1932 37.8926 72.8746 37.8926C72.556 37.8926 72.201 37.8697 71.8095 37.824C71.4181 37.7783 71.0995 37.7097 70.8538 37.6183L70.7036 37.3989L76.7523 18.9806ZM76.9981 33.7097C76.8707 33.7097 76.7159 33.7097 76.5339 33.7097C76.3518 33.7006 76.1697 33.696 75.9877 33.696C75.8147 33.6869 75.6645 33.6823 75.5371 33.6823H73.3661L74.6496 30.4046H76.5475C76.6749 30.4046 76.8251 30.4046 76.9981 30.4046C77.171 30.3954 77.344 30.3909 77.5169 30.3909C77.6899 30.3817 77.8355 30.3772 77.9539 30.3772H80.0429C80.1704 30.3772 80.3206 30.3817 80.4935 30.3909C80.6665 30.3909 80.8394 30.3954 81.0124 30.4046C81.1853 30.4046 81.3355 30.4046 81.463 30.4046H83.4292L84.4805 33.6823H82.3232C82.1957 33.6823 82.041 33.6869 81.8589 33.696C81.6769 33.696 81.4948 33.7006 81.3128 33.7097C81.1398 33.7097 80.9896 33.7097 80.8622 33.7097H76.9981Z" fill="white"/>
<path d="M88.069 19.2274C88.3876 19.0903 88.7426 18.976 89.134 18.8846C89.5254 18.7932 89.9077 18.7474 90.2809 18.7474C91.0092 18.7474 91.5371 18.9074 91.8648 19.2274C92.2016 19.5383 92.4383 20.1417 92.5748 21.0377L93.8037 28.4297C93.9038 29.0057 94.004 29.632 94.1041 30.3086C94.2042 30.9852 94.2952 31.6389 94.3772 32.2697C94.4682 32.8914 94.5365 33.4217 94.582 33.8606C94.6002 34.0343 94.6229 34.1394 94.6502 34.176C94.6867 34.2034 94.7504 34.2172 94.8414 34.2172L97.2036 19.3509C97.6132 19.2777 98.0592 19.2274 98.5417 19.2C99.0241 19.1634 99.4656 19.1452 99.8661 19.1452C100.294 19.1452 100.745 19.1634 101.218 19.2C101.7 19.2274 102.137 19.2777 102.529 19.3509L104.713 33.8606C104.741 34.0343 104.772 34.1394 104.809 34.176C104.854 34.2034 104.918 34.2172 105 34.2172C105.055 33.7052 105.127 33.1109 105.218 32.4343C105.31 31.7577 105.41 31.0629 105.519 30.3497C105.628 29.6366 105.733 28.9829 105.833 28.3886L107.458 18.9806C107.767 18.9166 108.086 18.8754 108.414 18.8572C108.741 18.8389 109.046 18.8297 109.328 18.8297C109.647 18.8297 109.984 18.8526 110.339 18.8983C110.694 18.944 111.012 19.0126 111.295 19.104L111.499 19.3509L107.84 37.6869C107.367 37.7417 106.789 37.7829 106.106 37.8103C105.432 37.8469 104.823 37.8652 104.276 37.8652C103.657 37.8652 103.111 37.76 102.638 37.5497C102.165 37.3394 101.864 36.8137 101.737 35.9726L100.754 29.8423C100.59 28.7909 100.43 27.6846 100.276 26.5234C100.13 25.3623 100.012 24.3292 99.9207 23.424H99.7159C99.6067 24.3292 99.4701 25.3623 99.3063 26.5234C99.1424 27.6754 98.9695 28.7817 98.7874 29.8423L97.4766 37.6869C96.976 37.7417 96.4071 37.7829 95.7699 37.8103C95.1418 37.8469 94.5456 37.8652 93.9812 37.8652C93.3167 37.8652 92.7478 37.76 92.2744 37.5497C91.8102 37.3394 91.4962 36.8092 91.3323 35.9589L88.069 19.2274Z" fill="white"/>
<path d="M118.115 18.9806C118.451 18.9349 118.852 18.8983 119.316 18.8709C119.78 18.8434 120.185 18.8297 120.531 18.8297C120.868 18.8297 121.269 18.8434 121.733 18.8709C122.206 18.8983 122.607 18.944 122.934 19.008L128.847 37.44C128.555 37.6046 128.182 37.728 127.727 37.8103C127.272 37.9017 126.844 37.9474 126.444 37.9474C125.788 37.9474 125.274 37.7966 124.901 37.4949C124.527 37.184 124.213 36.5806 123.958 35.6846L121.869 28.3749C121.651 27.5977 121.401 26.7017 121.118 25.6869C120.845 24.672 120.6 23.7212 120.381 22.8343H120.217C120.081 23.5749 119.88 24.4252 119.617 25.3852C119.362 26.336 119.13 27.168 118.92 27.8812L115.998 37.7417C115.743 37.8057 115.466 37.8469 115.165 37.8652C114.865 37.8834 114.555 37.8926 114.237 37.8926C113.918 37.8926 113.563 37.8697 113.172 37.824C112.78 37.7783 112.462 37.7097 112.216 37.6183L112.066 37.3989L118.115 18.9806ZM118.36 33.7097C118.233 33.7097 118.078 33.7097 117.896 33.7097C117.714 33.7006 117.532 33.696 117.35 33.696C117.177 33.6869 117.027 33.6823 116.899 33.6823H114.728L116.012 30.4046H117.91C118.037 30.4046 118.187 30.4046 118.36 30.4046C118.533 30.3954 118.706 30.3909 118.879 30.3909C119.052 30.3817 119.198 30.3772 119.316 30.3772H121.405C121.533 30.3772 121.683 30.3817 121.856 30.3909C122.029 30.3909 122.202 30.3954 122.375 30.4046C122.548 30.4046 122.698 30.4046 122.825 30.4046H124.791L125.843 33.6823H123.685C123.558 33.6823 123.403 33.6869 123.221 33.696C123.039 33.696 122.857 33.7006 122.675 33.7097C122.502 33.7097 122.352 33.7097 122.224 33.7097H118.36Z" fill="white"/>
<path d="M133.41 29.4172H137.588V37.7143C137.251 37.7783 136.892 37.8194 136.51 37.8377C136.136 37.856 135.809 37.8652 135.526 37.8652C135.272 37.8652 134.939 37.856 134.53 37.8377C134.12 37.8194 133.747 37.7783 133.41 37.7143V29.4172ZM138.954 18.9806C139.245 18.9166 139.532 18.8754 139.814 18.8572C140.096 18.8389 140.374 18.8297 140.647 18.8297C141.002 18.8297 141.361 18.8526 141.725 18.8983C142.09 18.944 142.413 19.0172 142.695 19.1177L142.859 19.3509L137.37 32.448H133.683L128.14 19.4743C128.513 19.264 128.922 19.0949 129.368 18.9669C129.815 18.8297 130.256 18.7612 130.693 18.7612C131.285 18.7612 131.74 18.8937 132.058 19.1589C132.377 19.424 132.655 19.8537 132.891 20.448L134.311 23.9863C134.53 24.5532 134.744 25.1612 134.953 25.8103C135.162 26.4594 135.358 27.1406 135.54 27.8537H135.69C135.809 27.4057 135.941 26.9486 136.086 26.4823C136.232 26.016 136.382 25.5589 136.537 25.1109C136.701 24.6629 136.86 24.2423 137.015 23.8492L138.954 18.9806Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.9978 43.3281C20.5208 32.8971 19.5204 21.9194 15.1533 12.1223C23.8314 8.6219 33.1615 7.04718 42.5022 7.50735C42.9362 8.94698 43.3244 10.3982 43.667 11.8579L52.0194 13.536H26.0885V48L24.9804 43.2663C22.6597 43.4062 20.329 43.4278 17.9978 43.3281Z" fill="#E13833"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.6248 38.3511C16.4941 29.4258 12.9019 20.9574 7.20915 13.925C14.6893 8.28785 23.296 4.34155 32.437 2.35731C33.2346 3.64812 33.9906 4.96162 34.7036 6.29676C27.8434 6.78015 21.0798 8.33535 14.6725 10.9201L13.4273 11.422L13.9753 12.6516C17.5633 20.7015 18.8148 29.6527 17.6248 38.3511Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.8945 37.5263C12.4621 29.6575 6.98999 22.8108 0 17.7315C5.77315 10.3418 13.0689 4.29249 21.3877 0C22.4075 0.960982 23.3973 1.94993 24.3567 2.9658C17.8737 5.22498 11.7596 8.48472 6.24812 12.6389L4.91621 13.6421L5.9665 14.9398C11.251 21.4667 14.663 29.2764 15.8945 37.5263Z" fill="#E13833"/>
<path d="M106.782 37.571C108.845 36.9354 111.436 36.0416 113.189 35.1346C110.17 36.4323 109.294 34.9161 109.188 34.3865C108.114 35.1346 107.105 35.8563 106.242 36.4786C105.675 36.8891 106.116 37.7763 106.782 37.571Z" fill="white"/>
<path d="M132.938 27.1765L141.27 20.3638C141.27 20.3638 138.6 22.8002 138.534 24.0317C138.237 24.3826 132.938 27.1765 132.938 27.1765Z" fill="white"/>
<path d="M132.964 25.1771C132.964 25.1771 139.048 21.0458 140.683 19.5098C138.646 21.0259 137.908 20.8736 137.38 20.6551C134.23 23.8596 132.964 25.1771 132.964 25.1771Z" fill="white"/>
<path d="M121.106 34.9095C121.106 34.9095 126.84 31.5528 128.442 30.4405C127.862 30.8775 126.893 32.1222 126.834 32.9432L121.106 34.9095Z" fill="white"/>
<path d="M152.133 21.6416C151.724 19.0265 151.328 16.5503 150.926 13.9682C150.676 14.1735 150.471 14.339 150.274 14.5045C148.791 15.7956 147.149 16.8284 145.304 17.5236C144.677 17.7553 144.111 17.7487 143.524 17.3779C142.39 16.6562 141.223 15.9876 140.07 15.2924C140.498 14.7296 140.979 14.5376 141.639 14.6171C142.548 14.723 143.471 14.7495 144.387 14.7561C144.664 14.7561 145.007 14.6568 145.218 14.478C148.428 11.7503 151.618 9.00272 154.809 6.24852C155.685 5.49376 156.701 5.11638 157.847 5.14286C158.843 5.16272 159.258 5.79831 158.836 6.70534C158.619 7.17541 158.263 7.61238 157.88 7.96328C156.944 8.82397 155.969 9.63169 154.993 10.446C154.723 10.6711 154.585 10.9029 154.558 11.2736C154.347 13.9947 154.09 16.7092 153.892 19.4303C153.846 20.0328 153.649 20.4764 153.148 20.814C152.818 21.0325 152.541 21.304 152.133 21.6416Z" fill="white"/>
<path d="M143.32 10.2275C144.064 9.57872 144.585 8.75114 145.785 8.92989C146.991 9.11527 148.224 9.12189 149.45 9.20796C149.549 9.21458 149.654 9.23445 149.858 9.26093C148.949 10.0289 148.118 10.7373 147.274 11.4325C147.195 11.4987 147.037 11.5384 146.938 11.5053C145.818 11.1544 144.704 10.7903 143.59 10.4196C143.504 10.4063 143.445 10.3269 143.32 10.2275Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,99 @@
/**
* Migration: Convert About News static items to dynamic Blog selection
* Date: 2026-02-07
*
* This migration:
* 1. Adds selectedBlogIds field to About news section
* 2. Keeps existing items for backward compatibility
* 3. Does NOT delete old data (safe migration)
*/
const mongoose = require("mongoose");
require("dotenv").config();
const MONGODB_URI = process.env.MONGODB_URI || "mongodb://localhost:27017/SIMS";
async function up() {
try {
await mongoose.connect(MONGODB_URI);
console.log("✓ Connected to MongoDB");
const AboutUs = mongoose.model("AboutUs", new mongoose.Schema({}, { strict: false }));
const doc = await AboutUs.findOne();
if (!doc) {
console.log("⚠ No About Us document found. Skipping migration.");
return;
}
// Check if already migrated
if (doc.news && doc.news.selectedBlogIds !== undefined) {
console.log("✓ Migration already applied. Skipping.");
return;
}
// Add selectedBlogIds field (empty array by default)
if (!doc.news) {
doc.news = {};
}
doc.news.selectedBlogIds = [];
// Keep existing items for backward compatibility
// Admin can manually select blogs after migration
await doc.save();
console.log("✓ Migration completed successfully");
console.log(" - Added selectedBlogIds field to About news section");
console.log(" - Existing items preserved for backward compatibility");
console.log(" - Admin can now select blogs from Blog Management");
} catch (error) {
console.error("✗ Migration failed:", error);
throw error;
}
}
async function down() {
try {
await mongoose.connect(MONGODB_URI);
console.log("✓ Connected to MongoDB");
const AboutUs = mongoose.model("AboutUs", new mongoose.Schema({}, { strict: false }));
const doc = await AboutUs.findOne();
if (!doc || !doc.news) {
console.log("⚠ No About Us document found. Skipping rollback.");
return;
}
// Remove selectedBlogIds field
if (doc.news.selectedBlogIds !== undefined) {
delete doc.news.selectedBlogIds;
await doc.save();
console.log("✓ Rollback completed - selectedBlogIds removed");
} else {
console.log("✓ Nothing to rollback");
}
} catch (error) {
console.error("✗ Rollback failed:", error);
throw error;
}
}
// Run migration
if (require.main === module) {
up()
.then(() => {
console.log("\n✓ Migration script completed");
process.exit(0);
})
.catch((error) => {
console.error("\n✗ Migration script failed:", error);
process.exit(1);
});
}
module.exports = { up, down };

View File

@@ -281,36 +281,65 @@
<!-- News Tab --> <!-- News Tab -->
<div class="tab-pane fade <%= locals.activeTab === 'news' ? 'show active' : '' %>" id="news" role="tabpanel"> <div class="tab-pane fade <%= locals.activeTab === 'news' ? 'show active' : '' %>" id="news" role="tabpanel">
<div class="card border shadow-sm"> <div class="card border shadow-sm">
<div class="card-header bg-white"> <div class="card-header bg-white d-flex justify-content-between align-items-center">
<h6 class="mb-0"><i class="fas fa-newspaper me-2"></i>News Section</h6> <h6 class="mb-0"><i class="fas fa-newspaper me-2"></i>News Section (Blog Preview)</h6>
<span class="badge bg-info text-dark">System will automatically fetch the 3 latest posts if no specific blog is selected.</span>
</div> </div>
<div class="card-body p-4"> <div class="card-body p-4">
<div class="row g-3 mb-4"> <div class="row g-3 mb-4">
<div class="col-md-6"> <div class="col-md-6">
<label class="form-label">Subheading</label> <label class="form-label fw-medium">Subheading</label>
<input type="text" class="form-control" id="newsSubheading" value="<%= data.news?.subheading || '' %>"> <input type="text" class="form-control" id="newsSubheading" value="<%= data.news?.subheading || '' %>" placeholder="e.g., Visa Tips & Guides">
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<label class="form-label">Heading</label> <label class="form-label fw-medium">Heading</label>
<input type="text" class="form-control" id="newsHeading" value="<%= data.news?.heading || '' %>"> <input type="text" class="form-control" id="newsHeading" value="<%= data.news?.heading || '' %>" placeholder="e.g., Latest Insights & Updates">
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<label class="form-label">CTA Button Label</label> <label class="form-label fw-medium">CTA Button Label</label>
<input type="text" class="form-control" id="newsCtaLabel" value="<%= data.news?.ctaButton?.label || '' %>"> <input type="text" class="form-control" id="newsCtaLabel" value="<%= data.news?.ctaButton?.label || '' %>" placeholder="e.g., View All Articles">
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<label class="form-label">CTA Button Link</label> <label class="form-label fw-medium">CTA Button Link</label>
<input type="text" class="form-control" id="newsCtaHref" value="<%= data.news?.ctaButton?.href || '' %>"> <input type="text" class="form-control" id="newsCtaHref" value="<%= data.news?.ctaButton?.href || '' %>" placeholder="/blog">
</div> </div>
</div> </div>
<div class="d-flex justify-content-between align-items-center mb-3"> <div class="col-md-12 mt-4">
<h6 class="mb-0">News Articles</h6> <label class="form-label fw-bold"><i class="fas fa-check-square me-2"></i>Select Featured Blogs (Direct from Blog Module)</label>
<button type="button" class="btn btn-outline-primary btn-sm" onclick="addNewsItem()"> <p class="text-muted small mb-3">Select blog posts to display on About page. If none are selected, the system will use the 3 latest posts.</p>
<i class="fas fa-plus me-1"></i>Add Article <div class="row g-3 blog-selector-container" style="max-height: 400px; overflow-y: auto; border: 1px solid #eee; padding: 15px; border-radius: 8px;">
</button> <% if (allBlogs && allBlogs.length > 0) { %>
<% allBlogs.forEach(blog => {
const isSelected = data.news?.selectedBlogIds && data.news.selectedBlogIds.some(id => id.toString() === blog._id.toString());
%>
<div class="col-md-4">
<div class="card h-100 blog-select-card <%= isSelected ? 'border-primary bg-light' : '' %>" onclick="toggleAboutBlogSelection(this, '<%= blog._id %>')" style="cursor: pointer; transition: all 0.2s;">
<div class="position-absolute top-0 end-0 m-2">
<div class="form-check">
<input class="form-check-input about-blog-checkbox" type="checkbox" value="<%= blog._id %>" <%= isSelected ? 'checked' : '' %> onclick="event.stopPropagation(); handleAboutCheckboxChange(this)">
</div>
</div>
<img src="<%= blog.featuredImage ? (blog.featuredImage.startsWith('http') ? blog.featuredImage : backendUrl + blog.featuredImage) : '/assets/img/placeholder.jpg' %>" class="card-img-top" style="height: 210px; object-fit: cover;">
<div class="card-body p-2">
<h6 class="card-title small fw-bold mb-1" title="<%= blog.title %>" style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; height: 2.6em; line-height: 1.3em;">
<%= blog.title %>
</h6>
<p class="card-text tiny text-muted mb-0">
<%= blog.publishedAt ? new Date(blog.publishedAt).toLocaleDateString('vi-VN') : '' %>
</p>
</div>
</div>
</div>
<% }) %>
<% } else { %>
<div class="col-12 text-center py-4">
<p class="text-muted">No published blogs found. Please create some blogs first.</p>
<a href="/admin/blog/create" class="btn btn-sm btn-outline-primary">Create Blog</a>
</div>
<% } %>
</div>
</div> </div>
<div id="newsItemsContainer"></div>
</div> </div>
</div> </div>
</div> </div>
@@ -638,7 +667,16 @@
document.getElementById('newsHeading').value = news.heading || ''; document.getElementById('newsHeading').value = news.heading || '';
document.getElementById('newsCtaLabel').value = news.ctaButton?.label || ''; document.getElementById('newsCtaLabel').value = news.ctaButton?.label || '';
document.getElementById('newsCtaHref').value = news.ctaButton?.href || ''; document.getElementById('newsCtaHref').value = news.ctaButton?.href || '';
populateNewsItems(news.items || []);
// Update blog selection checkboxes
document.querySelectorAll('.about-blog-checkbox').forEach(cb => {
const isSelected = news.selectedBlogIds && news.selectedBlogIds.some(id => id.toString() === cb.value);
cb.checked = isSelected;
const card = cb.closest('.blog-select-card');
if (card) {
handleAboutCheckboxUpdate(card, isSelected);
}
});
} }
function updateImagePreview(inputId, imagePath) { function updateImagePreview(inputId, imagePath) {
@@ -760,77 +798,42 @@
}); });
} }
function addNewsItem() { // Blog selection functions for About News section
const container = document.getElementById('newsItemsContainer'); function toggleAboutBlogSelection(card, blogId) {
const idx = container.children.length; const checkbox = card.querySelector('.about-blog-checkbox');
const html = ` const isChecking = !checkbox.checked;
<div class="card mb-3 news-item-row">
<div class="card-body p-3"> if (isChecking) {
<div class="row g-2"> const checkedCount = document.querySelectorAll('.about-blog-checkbox:checked').length;
<div class="col-md-6"> if (checkedCount >= 3) {
<label class="small text-muted">Title</label> alert('You can only select up to 3 blogs.');
<input type="text" class="form-control form-control-sm" name="newsItemTitle_${idx}"> return;
</div> }
<div class="col-md-3">
<label class="small text-muted">Category</label>
<input type="text" class="form-control form-control-sm" name="newsItemCategory_${idx}">
</div>
<div class="col-md-3">
<label class="small text-muted">Date</label>
<input type="text" class="form-control form-control-sm" name="newsItemDate_${idx}">
</div>
<div class="col-md-2">
<label class="small text-muted">Comments</label>
<input type="number" class="form-control form-control-sm" name="newsItemComments_${idx}">
</div>
<div class="col-md-5">
<label class="small text-muted">Author Name</label>
<input type="text" class="form-control form-control-sm" name="newsItemAuthorName_${idx}">
</div>
<div class="col-md-5">
<label class="small text-muted">Author Avatar</label>
<div class="input-group input-group-sm">
<input type="text" class="form-control" name="newsItemAuthorAvatar_${idx}">
<button class="btn btn-outline-primary btn-upload-image" type="button" data-target-input="newsItemAuthorAvatar_${idx}" data-image-type="about">
<i class="fas fa-upload"></i>
</button>
</div>
</div>
<div class="col-md-6">
<label class="small text-muted">Link</label>
<input type="text" class="form-control form-control-sm" name="newsItemLink_${idx}">
</div>
<div class="col-md-6">
<label class="small text-muted">Thumbnail</label>
<div class="input-group input-group-sm">
<input type="text" class="form-control" name="newsItemThumbnail_${idx}">
<button class="btn btn-outline-primary btn-upload-image" type="button" data-target-input="newsItemThumbnail_${idx}" data-image-type="about">
<i class="fas fa-upload"></i>
</button>
</div>
</div>
</div>
<button type="button" class="btn btn-outline-danger btn-sm mt-2" onclick="this.closest('.news-item-row').remove()">Remove Article</button>
</div>
</div>`;
container.insertAdjacentHTML('beforeend', html);
} }
function populateNewsItems(items) { checkbox.checked = isChecking;
const container = document.getElementById('newsItemsContainer'); handleAboutCheckboxUpdate(card, checkbox.checked);
container.innerHTML = ''; }
items.forEach((item, i) => {
addNewsItem(); function handleAboutCheckboxChange(checkbox) {
const last = container.lastElementChild; if (checkbox.checked) {
last.querySelector(`[name="newsItemTitle_${i}"]`).value = item.title || ''; const checkedCount = document.querySelectorAll('.about-blog-checkbox:checked').length;
last.querySelector(`[name="newsItemCategory_${i}"]`).value = item.category || ''; if (checkedCount > 3) {
last.querySelector(`[name="newsItemDate_${i}"]`).value = item.date || ''; checkbox.checked = false;
last.querySelector(`[name="newsItemComments_${i}"]`).value = item.comments || 0; alert('You can only select up to 3 blogs.');
last.querySelector(`[name="newsItemAuthorName_${i}"]`).value = item.author?.name || ''; return;
last.querySelector(`[name="newsItemAuthorAvatar_${i}"]`).value = item.author?.avatar || ''; }
last.querySelector(`[name="newsItemLink_${i}"]`).value = item.link || ''; }
last.querySelector(`[name="newsItemThumbnail_${i}"]`).value = item.thumbnail || ''; const card = checkbox.closest('.blog-select-card');
}); handleAboutCheckboxUpdate(card, checkbox.checked);
}
function handleAboutCheckboxUpdate(card, isChecked) {
if (isChecked) {
card.classList.add('border-primary', 'bg-light');
} else {
card.classList.remove('border-primary', 'bg-light');
}
} }
@@ -926,6 +929,11 @@
document.getElementById('featuresJson').value = JSON.stringify(featuresData); document.getElementById('featuresJson').value = JSON.stringify(featuresData);
// News // News
const selectedIds = [];
document.querySelectorAll('.about-blog-checkbox:checked').forEach(cb => {
selectedIds.push(cb.value);
});
const newsData = { const newsData = {
subheading: document.getElementById('newsSubheading').value.trim(), subheading: document.getElementById('newsSubheading').value.trim(),
heading: document.getElementById('newsHeading').value.trim(), heading: document.getElementById('newsHeading').value.trim(),
@@ -933,18 +941,8 @@
label: document.getElementById('newsCtaLabel').value.trim(), label: document.getElementById('newsCtaLabel').value.trim(),
href: document.getElementById('newsCtaHref').value.trim() href: document.getElementById('newsCtaHref').value.trim()
}, },
items: Array.from(document.querySelectorAll('.news-item-row')).map(item => ({ selectedBlogIds: selectedIds,
title: item.querySelector('[name^="newsItemTitle_"]').value.trim(), items: [] // Server will populate this from selectedBlogIds
category: item.querySelector('[name^="newsItemCategory_"]').value.trim(),
date: item.querySelector('[name^="newsItemDate_"]').value.trim(),
comments: parseInt(item.querySelector('[name^="newsItemComments_"]').value) || 0,
author: {
name: item.querySelector('[name^="newsItemAuthorName_"]').value.trim(),
avatar: item.querySelector('[name^="newsItemAuthorAvatar_"]').value.trim()
},
link: item.querySelector('[name^="newsItemLink_"]').value.trim(),
thumbnail: item.querySelector('[name^="newsItemThumbnail_"]').value.trim()
})).filter(i => i.title !== '')
}; };
document.getElementById('newsJson').value = JSON.stringify(newsData); document.getElementById('newsJson').value = JSON.stringify(newsData);
@@ -956,3 +954,14 @@
</script> </script>
<style>
.tiny {
font-size: 0.75rem;
}
.blog-select-card:hover {
transform: translateY(-3px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
</style>