This commit is contained in:
2026-06-03 01:06:32 +07:00
commit 31d30434d6
72 changed files with 11912 additions and 0 deletions
+381
View File
@@ -0,0 +1,381 @@
/* views\components\header\header.css */
/* Top ribbon */
.top-ribbon {
background-color: #e84e0f;
padding: 5px 0;
color: white;
font-size: 0.8rem;
}
.ribbon-content {
display: flex;
align-items: center;
justify-content: space-between;
}
.ribbon-logo {
width: 30px;
height: auto;
margin-right: 10px;
}
.ribbon-company-info {
display: flex;
align-items: center;
}
.ribbon-company-name {
font-weight: bold;
margin-right: 15px;
}
/* Custom colors and styling */
.header {
background-color: #fff;
border-bottom: 1px solid #ffffff;
margin: 0 40px; /* Add margins to shorten the nav */
}
.company-name {
color: #006241;
font-size: 1.4rem;
font-weight: bold;
text-decoration: none;
}
.company-name:hover {
color: #006241;
}
.company-slogan {
color: #e84e0f;
font-style: italic;
font-size: 1.1rem;
}
.company-year {
color: #006241;
font-size: 1rem;
font-weight: 500;
}
.contact-icon2 {
background-color: #f8f9fa;
border-radius: 50%;
width: 50px;
height: 50px;
color: #e84e0f;
font-size: 1.3rem;
border: 2px solid #e9ecef;
}
.contact-icon {
background-color: red;
border-radius: 50%;
width: 50px;
height: 50px;
color: white;
font-size: 1.3rem;
border: 2px solid #e9ecef;
}
.contact-text {
font-size: 1rem;
}
.contact-text a {
color: #006241;
text-decoration: none;
}
.contact-text a:hover {
color: #e84e0f;
}
.nav-container {
background-color: #30875f;
margin: 0 40px; /* Add margins to shorten the nav */
border-radius: 25px; /* Add rounded corners */
box-shadow: 0 4px 15px rgba(255, 255, 255, 0.2); /* Add subtle shadow */
}
.nav-container .container-fluid {
padding: 0 30px; /* Adjust internal padding */
}
.navbar-nav {
display: flex;
align-items: center;
justify-content: center;
}
.nav-link {
color: white !important;
font-weight: 600;
font-size: 15px;
text-transform: uppercase;
letter-spacing: 0.5px;
padding: 15px 30px !important; /* Increased horizontal padding for better centering */
transition: all var(--transition-speed);
text-decoration: none;
position: relative;
text-align: center; /* Center the text within the link */
}
.nav-link:hover {
color: #e84e0f !important;
background-color: rgba(255, 255, 255, 0.1);
border-radius: 8px;
}
.nav-link.active {
color: #e84e0f !important;
background-color: rgba(255, 255, 255, 0.15);
border-radius: 8px;
}
/* Separators - positioned to create equal spacing */
.navbar-nav .separator {
display: inline-block;
width: 4px;
height: 4px;
background: rgba(255, 255, 255, 0.6);
border-radius: 50%;
margin: 0 15px; /* space around separator */
/* stacked dots */
box-shadow: 0 6px 0 rgba(255, 255, 255, 0.6),
0 -6px 0 rgba(255, 255, 255, 0.6);
}
.logo {
width: 80px;
height: auto;
}
/* Floating Menu Button Styles */
.floating-menu-btn {
display: none;
position: fixed;
bottom: 25px;
right: 25px;
width: 60px;
height: 60px;
border-radius: 50%;
background-color: #e84e0f;
color: white;
border: none;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
z-index: 1030;
cursor: pointer;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
.floating-menu-btn:hover {
background-color: #c93d0a;
transform: scale(1.05);
}
.floating-menu-btn i {
font-size: 1.8rem;
}
/* Mobile Sidebar Styles */
.mobile-menu-btn {
display: none;
background: none;
border: none;
font-size: 1.8rem;
color: #006241;
cursor: pointer;
}
.sidebar-overlay {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1040;
}
.sidebar {
position: fixed;
top: 0;
left: -300px;
width: 300px;
height: 100%;
background-color: #30875f;
z-index: 1050;
overflow-y: auto;
transition: left 0.3s ease;
padding: 20px;
box-shadow: 2px 0 10px rgba(0, 0, 0, 0.2);
}
.sidebar.open {
left: 0;
}
.sidebar-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}
.sidebar-logo {
width: 60px;
height: auto;
}
.close-sidebar {
background: none;
border: none;
color: white;
font-size: 1.5rem;
cursor: pointer;
}
.sidebar-nav {
display: flex;
flex-direction: column;
}
.sidebar-nav .nav-link {
padding: 15px 10px !important;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.sidebar-contact {
margin-top: 20px;
color: white;
font-size: 0.9rem;
}
.sidebar-contact div {
margin-bottom: 10px;
}
/* Media Queries */
@media (max-width: 1200px) {
.header,
.nav-container {
margin: 0 20px;
}
.nav-link {
padding: 15px 20px !important;
font-size: 14px;
}
}
@media (max-width: 992px) {
.header,
.nav-container {
margin: 0 15px;
}
.company-name {
font-size: 1.2rem;
}
.nav-link {
padding: 12px 15px !important;
font-size: 13px;
}
.separator {
margin: 0 10px !important;
}
.banner-container {
height: 350px;
}
}
@media (max-width: 768px) {
.top-ribbon {
display: none; /* Hide ribbon on mobile */
}
.header,
.nav-container {
margin: 0 10px;
}
.nav-container {
display: none; /* Hide desktop nav on mobile */
}
.mobile-menu-btn {
display: block;
}
.header .col-lg-6:first-child {
display: flex;
justify-content: space-between;
align-items: center;
}
.company-info {
flex-grow: 1;
}
.contact-section {
display: none; /* Hide contact info on mobile - it will be in sidebar */
}
.logo {
width: 60px;
}
.company-name {
font-size: 1.1rem;
}
.company-slogan,
.company-year {
font-size: 0.9rem;
}
.banner-container {
height: 300px;
}
/* Show floating menu button on mobile */
.floating-menu-btn {
display: flex;
}
}
@media (max-width: 576px) {
.company-name {
font-size: 1rem;
}
.sidebar {
width: 250px;
}
.banner-container {
height: 250px;
}
.banner-indicator {
width: 10px;
height: 10px;
}
.floating-menu-btn {
width: 50px;
height: 50px;
bottom: 20px;
right: 20px;
}
}
+148
View File
@@ -0,0 +1,148 @@
<!-- views\components\header\header.html -->
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Kỳ Long Header</title>
</head>
<body>
<!-- Top Orange Ribbon -->
<div class="top-ribbon">
<div class="container-fluid px-4">
<div class="ribbon-content">
<div class="ribbon-company-info">
<img
src="https://ik.imagekit.io/1e8470bv5/companyLogo.webp?updatedAt=1754143468028"
alt="Ky Long Logo"
class="ribbon-logo"
/>
<span class="ribbon-company-name">KỲ LONG</span>
<span>Thắp sáng tương lai, vững bền thành quả</span>
</div>
</div>
</div>
</div>
<!-- Header Section -->
<header class="header py-3">
<div class="container-fluid px-4">
<div class="row align-items-center">
<!-- Logo and Company Info -->
<div class="col-lg-6 col-md-6 col-12">
<div class="d-flex align-items-center">
<img
src="https://ik.imagekit.io/1e8470bv5/companyLogo.webp?updatedAt=1754143468028"
alt="Ky Long Logo"
class="logo me-3"
/>
<div class="company-info">
<div>
<a
href="/"
title="Công ty TNHH Đầu Tư Thương Mại Dịch Vụ Kỳ Long"
class="company-name"
>
CÔNG TY TNHH ĐẦU TƯ THƯƠNG MẠI DỊCH VỤ KỲ LONG
</a>
</div>
<div class="company-slogan">
Thắp sáng tương lai, vững bền thành quả
</div>
<div class="company-year">SINCE 2010</div>
</div>
</div>
</div>
<!-- Contact Info - Horizontal Layout -->
<div class="col-lg-6 col-md-6 col-12 contact-section">
<div class="row g-3">
<!-- Address -->
<div class="col-md-6 col-12">
<div class="d-flex align-items-center">
<div
class="contact-icon2 d-flex align-items-center justify-content-center me-2"
>
<i class="bi bi-geo-alt-fill"></i>
</div>
<div class="contact-text">
<div>Lầu 12, số 27 Đinh Bộ Lĩnh,</div>
<div>P. Bình Thạnh, TP.Hồ Chí Minh</div>
</div>
</div>
</div>
<!-- Email -->
<div class="col-md-6 col-12">
<div class="d-flex align-items-center">
<div
class="contact-icon d-flex align-items-center justify-content-center me-2"
>
<i class="bi bi-envelope-open-fill"></i>
</div>
<div class="contact-text">
<div>Email:</div>
<div class="contact-text">info@kylongtech.com</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
<!-- Navigation Section -->
<nav class="nav-container">
<div class="container-fluid px-4">
<div class="navbar-nav d-flex flex-row justify-content-around py-3">
<a
href="/"
class="nav-link"
id="home"
title="Trang Chủ Kỳ Long - Dịch vụ khí đốt công nghiệp"
>TRANG CHỦ</a
>
<a
href="/aboutMain"
class="nav-link"
id="about"
title="Giới thiệu về Công ty Kỳ Long - Chuyên gia khí đốt"
>GIỚI THIỆU</a
>
<a
href="/productMain"
class="nav-link"
id="products"
title="Sản phẩm khí đốt và thiết bị công nghiệp Kỳ Long"
>SẢN PHẨM</a
>
<a
href="/serviceMain"
class="nav-link"
id="services"
title="Dịch vụ cung cấp khí đốt công nghiệp Kỳ Long"
>DỊCH VỤ</a
>
<a
href="/newsMain"
class="nav-link"
id="news"
title="Tin tức và cập nhật từ Kỳ Long"
>TIN TỨC</a
>
<a
href="/lien-he"
class="nav-link"
id="contact"
title="Liên hệ với Kỳ Long - Đối tác khí đốt tin cậy"
>LIÊN HỆ</a
>
</div>
</div>
</nav>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
</body>
</html>
+97
View File
@@ -0,0 +1,97 @@
//views/components/header/header.js
document.addEventListener("DOMContentLoaded", function () {
// Sidebar functionality
const mobileMenuBtn = document.querySelector(".mobile-menu-btn");
const floatingMenuBtn = document.getElementById("floatingMenuBtn");
const closeSidebarBtn = document.querySelector(".close-sidebar");
const sidebar = document.getElementById("sidebar");
const overlay = document.getElementById("sidebarOverlay");
// Open sidebar
function openSidebar() {
sidebar.classList.add("open");
overlay.style.display = "block";
document.body.style.overflow = "hidden"; // Prevent scrolling
}
mobileMenuBtn.addEventListener("click", openSidebar);
floatingMenuBtn.addEventListener("click", openSidebar);
// Close sidebar
function closeSidebar() {
sidebar.classList.remove("open");
overlay.style.display = "none";
document.body.style.overflow = ""; // Enable scrolling
}
closeSidebarBtn.addEventListener("click", closeSidebar);
overlay.addEventListener("click", closeSidebar);
// Close sidebar when a nav link is clicked
const sidebarLinks = document.querySelectorAll(".sidebar-nav .nav-link");
sidebarLinks.forEach((link) => {
link.addEventListener("click", closeSidebar);
});
// Banner functionality
const slides = document.querySelectorAll(".banner-slide");
const indicators = document.querySelectorAll(".banner-indicator");
const prevBtn = document.getElementById("prevBanner");
const nextBtn = document.getElementById("nextBanner");
let currentSlide = 0;
// Function to show a specific slide
function showSlide(index) {
// Hide all slides
slides.forEach((slide) => slide.classList.remove("active"));
indicators.forEach((indicator) => indicator.classList.remove("active"));
// Ensure index is within bounds
if (index < 0) {
currentSlide = slides.length - 1;
} else if (index >= slides.length) {
currentSlide = 0;
} else {
currentSlide = index;
}
// Show the current slide
slides[currentSlide].classList.add("active");
indicators[currentSlide].classList.add("active");
}
// Event listeners for navigation buttons
prevBtn.addEventListener("click", () => {
showSlide(currentSlide - 1);
});
nextBtn.addEventListener("click", () => {
showSlide(currentSlide + 1);
});
// Event listeners for indicator dots
indicators.forEach((indicator) => {
indicator.addEventListener("click", () => {
const index = parseInt(indicator.getAttribute("data-index"));
showSlide(index);
});
});
// Hide floating button when sidebar is open
const observer = new MutationObserver(function (mutations) {
mutations.forEach(function (mutation) {
if (mutation.attributeName === "class") {
if (sidebar.classList.contains("open")) {
floatingMenuBtn.style.display = "none";
} else {
floatingMenuBtn.style.display = "flex";
}
}
});
});
observer.observe(sidebar, {
attributes: true,
attributeFilter: ["class"],
});
});
+56
View File
@@ -0,0 +1,56 @@
// views/components/header/headerLoader.js
function loadHeader() {
// Check if header is already loaded
if (document.querySelector(".header")) {
return;
}
// Set Bootstrap theme before loading header
function setBootstrapTheme() {
const prefersDark = window.matchMedia(
"(prefers-color-scheme: dark)"
).matches;
document.documentElement.setAttribute(
"data-bs-theme",
prefersDark ? "dark" : "light"
);
}
// Set theme immediately
setBootstrapTheme();
// Create a new XMLHttpRequest object
const xhr = new XMLHttpRequest();
// Configure it to GET the header.html file
xhr.open("GET", "/components/header/header.html", true);
// Set up the callback function when the request completes
xhr.onload = function () {
if (this.status >= 200 && this.status < 300) {
// Insert the header HTML at the beginning of the body
document.body.insertAdjacentHTML("afterbegin", this.response);
// Ensure theme is set after header is loaded
setBootstrapTheme();
// Listen for changes in system preference
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", setBootstrapTheme);
} else {
console.error("Failed to load header:", this.statusText);
}
};
// Set up error handling
xhr.onerror = function () {
console.error("Error loading header");
};
// Send the request
xhr.send();
}
// Load the header when the script is executed
loadHeader();