prology-landingpage/assets/js/hero.js

353 lines
11 KiB
JavaScript

document.addEventListener("DOMContentLoaded", () => {
// Fix double H1: demote hidden Magento page-title h1 to <p>
const magH1 = document.querySelector(".page-title-wrapper h1");
if (magH1) {
const p = document.createElement("p");
p.className = magH1.className;
p.innerHTML = magH1.innerHTML;
magH1.parentNode.replaceChild(p, magH1);
}
// Hamburger menu toggle
const hamburgerBtn = document.querySelector(".hamburger-btn");
const navMenu = document.querySelector(".nav-links");
const navBackdrop = document.getElementById("nav-backdrop");
function closeNavMenu() {
navMenu.classList.remove("open");
hamburgerBtn.classList.remove("open");
hamburgerBtn.setAttribute("aria-expanded", "false");
if (navBackdrop) navBackdrop.classList.remove("open");
}
if (hamburgerBtn && navMenu) {
hamburgerBtn.addEventListener("click", () => {
const isOpen = navMenu.classList.toggle("open");
hamburgerBtn.classList.toggle("open", isOpen);
hamburgerBtn.setAttribute("aria-expanded", String(isOpen));
if (navBackdrop) navBackdrop.classList.toggle("open", isOpen);
});
navMenu.querySelectorAll("a").forEach((a) => {
a.addEventListener("click", closeNavMenu);
});
if (navBackdrop) navBackdrop.addEventListener("click", closeNavMenu);
}
const sections = document.querySelectorAll(".section");
const navLinks = document.querySelectorAll(".nav-links a");
const scrollIndicator = document.querySelector(".scroll-indicator");
const heroInput = document.getElementById("hero-input");
const typewriterEl = document.getElementById("typewriter-title");
// Hero search: open store picker, then redirect to {STORE_URL}/catalogsearch/result/?q=...
const buySearchForm = document.querySelector("#buy-section .hero-search-form");
if (buySearchForm) {
buySearchForm.addEventListener("submit", (e) => {
e.preventDefault();
const q = (heroInput?.value || "").trim();
if (!q) return;
const slug = `catalogsearch/result/?q=${encodeURIComponent(q)}`;
if (typeof window.openStoreModal === "function") {
window.openStoreModal(slug);
}
});
}
// Multi-stage Typewriter Sequence
const typeStrings = [
"Network hardware sourcing made simple",
"for every site",
"for every need",
"for every environment",
];
async function runTypewriter() {
if (!typewriterEl) return;
async function typeInto(element, text, speed) {
element.classList.add("typing-cursor");
for (const char of text) {
element.textContent += char;
await new Promise((r) => setTimeout(r, speed));
}
element.classList.remove("typing-cursor");
}
async function fadeStep() {
typewriterEl.style.opacity = "0";
await new Promise((r) => setTimeout(r, 600));
typewriterEl.innerHTML = "";
typewriterEl.style.opacity = "1";
await new Promise((r) => setTimeout(r, 200));
}
// Delay for server animation
await new Promise((r) => setTimeout(r, 3500));
// -- Text Phases --
for (let i = 0; i < typeStrings.length; i++) {
const span = document.createElement("span");
typewriterEl.appendChild(span);
await typeInto(span, typeStrings[i], 45);
await new Promise((r) => setTimeout(r, 1200));
await fadeStep();
}
// -- FINAL PHASE: BRAND LOGO --
const brandBox = document.createElement("div");
brandBox.style.display = "flex";
brandBox.style.flexDirection = "column";
brandBox.style.alignItems = "center";
brandBox.style.gap = "15px";
brandBox.style.opacity = "0"; // Start invisible
brandBox.style.transition = "opacity 0.6s ease-out";
const brandImg = document.createElement("img");
brandImg.src = window.PROLOGY_CONFIG.LOGO_SRC;
brandImg.alt = "Prology";
brandImg.style.height = "80px";
brandImg.style.width = "auto";
brandImg.style.filter = "none"; // Logo full màu
const finalTag = document.createElement("div");
finalTag.style.fontSize = "1.6rem";
finalTag.style.fontWeight = "600";
finalTag.style.color = "var(--primary)";
finalTag.style.letterSpacing = "0.15em";
finalTag.style.textTransform = "uppercase";
brandBox.appendChild(brandImg);
brandBox.appendChild(finalTag);
typewriterEl.appendChild(brandBox);
// 1. Kick off Logo Fade-in
setTimeout(() => {
brandBox.style.opacity = "1";
}, 200);
await new Promise((r) => setTimeout(r, 1000));
// 2. Type the final tagline
await typeInto(finalTag, "Your Network Hardware Partner", 50);
// 3. Wait a moment so user can read it, then fade out the tagline/logo
await new Promise((r) => setTimeout(r, 1500));
brandBox.style.opacity = "0";
// 4. Wait for fade out, hide it, and show the eBay Banner
await new Promise((r) => setTimeout(r, 600));
brandBox.style.display = "none";
const ebayBanner = document.getElementById("hero-ebay-integrated");
if (ebayBanner) {
// Typewriter xong hẳn — giờ mới hide wrapper và show banner
const wrapper = document.querySelector(".hero-animation-wrapper");
if (wrapper) wrapper.style.display = "none";
ebayBanner.classList.add("visible");
}
}
runTypewriter();
// Auto-focus timer removed here.
// Auto-focusing after 19s caused the browser to scroll back to the top while the user was reading below.
// Switch between Source (Buy) and Sell Modes
window.switchTab = function (mode) {
const buySection = document.getElementById("buy-section");
const sellSection = document.getElementById("sell-section");
const tabs = document.querySelectorAll(".search-tab");
// Toggle tabs
tabs.forEach((tab) => {
tab.classList.toggle(
"active",
tab.textContent.toLowerCase().includes(mode),
);
});
// Toggle sections with a small fade
if (mode === "buy") {
sellSection.style.display = "none";
buySection.style.display = "block";
document.getElementById("hero-input").focus();
} else {
buySection.style.display = "none";
sellSection.style.display = "block";
document.getElementById("sell-email-init").focus();
}
};
let isScrolling = false;
let currentSectionIndex = 0;
function updateUI(index) {
currentSectionIndex = index;
const currentSection = sections[index];
const id = currentSection.getAttribute("id");
// Update Top Nav based on href matches, not raw index parity
navLinks.forEach((link) => {
link.classList.remove("active", "past");
const targetId = link.getAttribute("href");
if (targetId === `#${id}`) {
link.classList.add("active");
} else if (id === "warehouse" && targetId === "#quality") {
link.classList.add("active");
}
});
// Toggle light color for scroll indicator on dark sections (1, 3, 5)
if (scrollIndicator) {
if (index % 2 !== 0) {
scrollIndicator.classList.add("light");
} else {
scrollIndicator.classList.remove("light");
}
}
// Hide Scroll Indicator on last page
if (scrollIndicator) {
if (index === sections.length - 1) {
scrollIndicator.style.opacity = "0";
} else {
scrollIndicator.style.opacity = "1";
}
}
}
// Logic cuộn tự động đã được chuyển qua CSS scroll-snap để tối ưu hiệu năng và tương thích màn hình
function scrollToSection(index) {
isScrolling = true;
updateUI(index);
sections[index].scrollIntoView({ behavior: "smooth" });
setTimeout(() => {
isScrolling = false;
}, 800); // Wait for animation to finish
}
// ============ SECTION OBSERVER ============
const observerOptions = {
threshold: 0.5,
};
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const id = entry.target.getAttribute("id");
const index = Array.from(sections).indexOf(entry.target);
// Update internal index for wheel/space navigation
if (!isScrolling) currentSectionIndex = index;
// Update Top Nav
navLinks.forEach((link) => {
link.classList.remove("active");
const targetId = link.getAttribute("href");
if (targetId === `#${id}`) {
link.classList.add("active");
}
// Special case: Keep 'Why Us' highlighted when inside Global Logistics
if (id === "warehouse" && targetId === "#quality") {
link.classList.add("active");
}
});
entry.target.classList.add("visible");
}
});
}, observerOptions);
sections.forEach((section) => observer.observe(section));
// ============ SMOOTH SCROLL (Navbar) ============
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
anchor.addEventListener("click", function (e) {
e.preventDefault();
const targetId = this.getAttribute("href");
const target = document.querySelector(targetId);
if (target) {
const index = Array.from(sections).indexOf(target);
if (index !== -1) scrollToSection(index);
}
});
});
// ============ ANIMATE PORT SEQUENCE ============
const switchPanel = document.getElementById("animated-switch-panel");
if (switchPanel) {
const totalColumns = 24;
const totalRows = 2;
for (let r = 0; r < totalRows; r++) {
const rowDiv = document.createElement("div");
rowDiv.className = "port-row";
for (let c = 0; c < totalColumns; c++) {
const portDiv = document.createElement("div");
// Randomly decide if this port gets a cable ( ~40% chance )
// EXCLUDE Port 22 of Bottom Row (r=1, c=21) for the master cable
if (Math.random() < 0.4 && !(r === 1 && c === 21)) {
portDiv.className = "port-front active-port";
// Random drop-in delay between 0 and 2.5 seconds
const plugDelay = Math.random() * 2.5;
portDiv.style.setProperty("--delay", `${plugDelay}s`);
portDiv.innerHTML = `
<div class="port-led"></div>
<div class="cable-front">
<div class="cable-head-front"></div>
<div class="cable-wire-front"></div>
</div>
`;
} else {
// Inactive port just has the base shell and an unlit LED
portDiv.className = "port-front";
portDiv.innerHTML = `<div class="port-led"></div>`;
}
rowDiv.appendChild(portDiv);
}
switchPanel.appendChild(rowDiv);
}
}
// ============ QUALITY SLIDER LOGIC ============
let currentQSlide = 0;
const qSlides = document.querySelectorAll(".q-slide");
const qDots = document.querySelectorAll(".dot");
let qInterval;
window.setQSlide = function (index) {
if (index === currentQSlide) return;
qSlides[currentQSlide].classList.remove("active");
qDots[currentQSlide].classList.remove("active");
currentQSlide = index;
qSlides[currentQSlide].classList.add("active");
qDots[currentQSlide].classList.add("active");
// Reset interval on manual click
clearInterval(qInterval);
startQAutoPlay();
};
function startQAutoPlay() {
qInterval = setInterval(() => {
let next = (currentQSlide + 1) % qSlides.length;
setQSlide(next);
}, 5000);
}
if (qSlides.length > 0) {
startQAutoPlay();
}
});