Refactor: Extract sidebar into a reusable component
This commit is contained in:
@@ -144,7 +144,8 @@
|
||||
margin: 0 15px; /* space around separator */
|
||||
|
||||
/* stacked dots */
|
||||
box-shadow: 0 6px 0 rgba(255, 255, 255, 0.6),
|
||||
box-shadow:
|
||||
0 6px 0 rgba(255, 255, 255, 0.6),
|
||||
0 -6px 0 rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
@@ -328,7 +329,7 @@
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.contact-section {
|
||||
.header-contact-section {
|
||||
display: none; /* Hide contact info on mobile - it will be in sidebar */
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Contact Info - Horizontal Layout -->
|
||||
<div class="col-lg-6 col-md-6 col-12 contact-section">
|
||||
<div class="col-lg-6 col-md-6 col-12 header-contact-section">
|
||||
<div class="row g-3">
|
||||
<!-- Address -->
|
||||
<div class="col-md-6 col-12">
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/* views/components/sidebar/sidebar.css */
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Sidebar Overlay */
|
||||
.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-overlay.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Sidebar Styles */
|
||||
.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);
|
||||
color: white !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.sidebar-contact {
|
||||
margin-top: 20px;
|
||||
color: white;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.sidebar-contact div {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Media Queries for Sidebar */
|
||||
@media (max-width: 768px) {
|
||||
.floating-menu-btn {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
.floating-menu-btn {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<!-- Floating Menu Button -->
|
||||
<button class="floating-menu-btn" id="floatingMenuBtn">
|
||||
<i class="bi bi-list"></i>
|
||||
</button>
|
||||
|
||||
<!-- Sidebar Overlay -->
|
||||
<div class="sidebar-overlay" id="sidebarOverlay"></div>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar" id="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<img
|
||||
src="https://ik.imagekit.io/1e8470bv5/companyLogo.webp?updatedAt=1754143468028"
|
||||
alt="Ky Long Logo"
|
||||
class="sidebar-logo"
|
||||
/>
|
||||
<button class="close-sidebar">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<nav class="sidebar-nav">
|
||||
<a href="/" class="nav-link">TRANG CHỦ</a>
|
||||
<a href="/aboutMain" class="nav-link">GIỚI THIỆU</a>
|
||||
<a href="/productMain" class="nav-link">SẢN PHẨM</a>
|
||||
<a href="/serviceMain" class="nav-link">DỊCH VỤ</a>
|
||||
<a href="/newsMain" class="nav-link">TIN TỨC</a>
|
||||
<a href="/contactMain" class="nav-link">LIÊN HỆ</a>
|
||||
</nav>
|
||||
|
||||
<div class="sidebar-contact">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div
|
||||
class="contact-icon2 d-flex align-items-center justify-content-center me-2"
|
||||
>
|
||||
<i class="bi bi-geo-alt-fill"></i>
|
||||
</div>
|
||||
<div>
|
||||
<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 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>
|
||||
<div>Email:</div>
|
||||
<div>info@kylongtech.com</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,69 @@
|
||||
// views/components/sidebar/sidebar.js
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
initSidebar();
|
||||
});
|
||||
|
||||
function initSidebar() {
|
||||
const floatingMenuBtn = document.getElementById("floatingMenuBtn");
|
||||
const sidebarOverlay = document.getElementById("sidebarOverlay");
|
||||
const sidebar = document.getElementById("sidebar");
|
||||
const closeSidebarBtn = document.querySelector(".close-sidebar");
|
||||
|
||||
function openSidebar() {
|
||||
if (sidebar && sidebarOverlay) {
|
||||
sidebar.classList.add("open");
|
||||
sidebarOverlay.style.display = "block";
|
||||
}
|
||||
}
|
||||
|
||||
function closeSidebar() {
|
||||
if (sidebar && sidebarOverlay) {
|
||||
sidebar.classList.remove("open");
|
||||
sidebarOverlay.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
if (floatingMenuBtn) {
|
||||
floatingMenuBtn.addEventListener("click", openSidebar);
|
||||
}
|
||||
|
||||
if (closeSidebarBtn) {
|
||||
closeSidebarBtn.addEventListener("click", closeSidebar);
|
||||
}
|
||||
|
||||
if (sidebarOverlay) {
|
||||
sidebarOverlay.addEventListener("click", closeSidebar);
|
||||
}
|
||||
|
||||
// Close sidebar when clicking outside or on a link
|
||||
document.addEventListener("click", (e) => {
|
||||
if (sidebar && sidebar.classList.contains("open")) {
|
||||
// Click outside sidebar and not on floating menu button
|
||||
if (
|
||||
!sidebar.contains(e.target) &&
|
||||
!e.target.closest("#floatingMenuBtn")
|
||||
) {
|
||||
closeSidebar();
|
||||
}
|
||||
// Click on a nav link
|
||||
if (e.target.closest(".sidebar-nav .nav-link")) {
|
||||
closeSidebar();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Handle scroll behavior to hide/show floating menu button smoothly
|
||||
let lastScrollY = window.scrollY;
|
||||
window.addEventListener("scroll", () => {
|
||||
if (window.innerWidth <= 768 && floatingMenuBtn) {
|
||||
if (window.scrollY > lastScrollY && window.scrollY > 100) {
|
||||
// Scrolling down
|
||||
floatingMenuBtn.style.display = "none";
|
||||
} else {
|
||||
// Scrolling up
|
||||
floatingMenuBtn.style.display = "flex";
|
||||
}
|
||||
}
|
||||
lastScrollY = window.scrollY;
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// views/components/sidebar/sidebarLoader.js
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const sidebarContainer = document.getElementById("sidebar-container");
|
||||
if (!sidebarContainer) return;
|
||||
|
||||
// Load HTML
|
||||
fetch("/components/sidebar/sidebar.html")
|
||||
.then((response) => response.text())
|
||||
.then((data) => {
|
||||
sidebarContainer.innerHTML = data;
|
||||
|
||||
// Load CSS
|
||||
const link = document.createElement("link");
|
||||
link.rel = "stylesheet";
|
||||
link.href = "/components/sidebar/sidebar.css";
|
||||
document.head.appendChild(link);
|
||||
|
||||
// Load JS
|
||||
const script = document.createElement("script");
|
||||
script.src = "/components/sidebar/sidebar.js";
|
||||
document.body.appendChild(script);
|
||||
})
|
||||
.catch((error) => console.error("Error loading sidebar:", error));
|
||||
});
|
||||
@@ -25,62 +25,8 @@
|
||||
<!-- Header Component -->
|
||||
<div id="header"></div>
|
||||
|
||||
<!-- Floating Menu Button -->
|
||||
<button class="floating-menu-btn" id="floatingMenuBtn">
|
||||
<i class="bi bi-list"></i>
|
||||
</button>
|
||||
|
||||
<!-- Sidebar Overlay -->
|
||||
<div class="sidebar-overlay" id="sidebarOverlay"></div>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<div class="sidebar" id="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<img
|
||||
src="https://ik.imagekit.io/1e8470bv5/companyLogo.webp?updatedAt=1754143468028"
|
||||
alt="Ky Long Logo"
|
||||
class="sidebar-logo"
|
||||
/>
|
||||
<button class="close-sidebar">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<nav class="sidebar-nav">
|
||||
<a href="/" class="nav-link">TRANG CHỦ</a>
|
||||
<a href="/aboutMain" class="nav-link">GIỚI THIỆU</a>
|
||||
<a href="/productMain" class="nav-link">SẢN PHẨM</a>
|
||||
<a href="/serviceMain" class="nav-link">DỊCH VỤ</a>
|
||||
<a href="/newsMain" class="nav-link">TIN TỨC</a>
|
||||
<a href="/contactMain" class="nav-link">LIÊN HỆ</a>
|
||||
</nav>
|
||||
|
||||
<div class="sidebar-contact">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<div
|
||||
class="contact-icon2 d-flex align-items-center justify-content-center me-2"
|
||||
>
|
||||
<i class="bi bi-geo-alt-fill"></i>
|
||||
</div>
|
||||
<div>
|
||||
<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 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>
|
||||
<div>Email:</div>
|
||||
<div>info@kylongtech.com</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Sidebar Component -->
|
||||
<div id="sidebar-container"></div>
|
||||
|
||||
<!-- BANNER SECTION -->
|
||||
<div class="banner">
|
||||
@@ -603,6 +549,7 @@
|
||||
|
||||
<script src="homePages/homeMain.js?v=1.3"></script>
|
||||
<script src="/components/header/headerLoader.js"></script>
|
||||
<script src="/components/sidebar/sidebarLoader.js"></script>
|
||||
<script src="/components/footer/footerLoader.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user