Files
GNX-WEB/frontEnd/components/pages/home/HomeBanner.tsx
Iliyan Angelov 136f75a859 update
2025-11-24 08:18:18 +02:00

437 lines
17 KiB
TypeScript

"use client";
import Link from "next/link";
import { useState, useEffect, useMemo } from "react";
import { useHomeBanners } from "@/lib/hooks/useHome";
const HomeBanner = () => {
const [currentTextIndex, setCurrentTextIndex] = useState(0);
const [isTransitioning, setIsTransitioning] = useState(false);
const { data: banners, loading, error } = useHomeBanners();
// Fix viewport height for mobile browsers (especially iOS Safari)
useEffect(() => {
const setVH = () => {
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
};
setVH();
window.addEventListener('resize', setVH);
// Use 'resize' event instead of deprecated 'orientationchange'
// The resize event fires on orientation change as well
const handleOrientationChange = () => {
// Small delay to ensure viewport has updated
setTimeout(setVH, 100);
};
window.addEventListener('resize', handleOrientationChange);
return () => {
window.removeEventListener('resize', setVH);
window.removeEventListener('resize', handleOrientationChange);
};
}, []);
// Transform API data to match component format
const carouselTexts = useMemo(() => {
if (!banners || banners.length === 0) return [];
return banners.map(banner => ({
icon: banner.icon,
badge: banner.badge,
heading: banner.heading,
highlight: banner.highlight,
subheading: banner.subheading,
description: banner.description,
button_text: banner.button_text,
button_url: banner.button_url,
}));
}, [banners]);
// Carousel rotation effect
useEffect(() => {
if (carouselTexts.length <= 1) return;
const interval = setInterval(() => {
setIsTransitioning(true);
setTimeout(() => {
setCurrentTextIndex((prevIndex) =>
prevIndex === carouselTexts.length - 1 ? 0 : prevIndex + 1
);
setIsTransitioning(false);
}, 1000); // Slightly longer for smoother transition
}, 6000); // Increased interval for slower changes
return () => clearInterval(interval);
}, [carouselTexts.length]);
const currentText = carouselTexts[currentTextIndex];
// Show loading state
if (loading) {
return (
<section className="modern-banner">
<div className="container">
<div className="banner-content">
<div className="content-center">
<div className="spinner-border text-primary" role="status">
<span className="visually-hidden">Loading...</span>
</div>
<p className="mt-3">Loading banner content...</p>
</div>
</div>
</div>
</section>
);
}
// Show error state
if (error) {
return (
<section className="modern-banner">
<div className="container">
<div className="banner-content">
<div className="content-center">
<div className="alert alert-danger" role="alert">
<h4 className="alert-heading">Error Loading Content</h4>
<p>{error}</p>
<hr />
<p className="mb-0">Please try refreshing the page or contact support if the problem persists.</p>
</div>
</div>
</div>
</div>
</section>
);
}
// Show no data message when there's no banner content
if (!currentText || carouselTexts.length === 0) {
return (
<section className="modern-banner">
<div className="container">
<div className="banner-content">
<div className="content-center">
<h1 className="main-heading">No data available</h1>
</div>
</div>
</div>
</section>
);
}
return (
<>
<section className="modern-banner">
<div className="banner-background">
<div className="gradient-orb orb-1"></div>
<div className="gradient-orb orb-2"></div>
<div className="gradient-orb orb-3"></div>
{/* Industrial Enterprise Background Elements */}
<div className="enterprise-bg-elements">
{/* Flying Code Elements */}
<div className="flying-code">
<div className="code-snippet code-1">
<span className="code-line">const enterprise = {'{'}</span>
<span className="code-line"> security: &apos;enterprise-grade&apos;,</span>
<span className="code-line"> scalability: &apos;unlimited&apos;</span>
<span className="code-line">{'}'};</span>
</div>
<div className="code-snippet code-2">
<span className="code-line">if (security === &apos;max&apos;) {'{'}</span>
<span className="code-line"> deploy.enterprise();</span>
<span className="code-line">{'}'}</span>
</div>
<div className="code-snippet code-3">
<span className="code-line">class EnterpriseSoftware {'{'}</span>
<span className="code-line"> constructor() {'{'}</span>
<span className="code-line"> this.secure = true;</span>
<span className="code-line"> {'}'}</span>
<span className="code-line">{'}'}</span>
</div>
<div className="code-snippet code-4">
<span className="code-line">API.authenticate({'{'}</span>
<span className="code-line"> level: &apos;enterprise&apos;,</span>
<span className="code-line"> encryption: &apos;AES-256&apos;</span>
<span className="code-line">{'}'});</span>
</div>
</div>
{/* Industrial Grid */}
<div className="industrial-grid">
<div className="grid-line horizontal h-1"></div>
<div className="grid-line horizontal h-2"></div>
<div className="grid-line horizontal h-3"></div>
<div className="grid-line horizontal h-4"></div>
<div className="grid-line vertical v-1"></div>
<div className="grid-line vertical v-2"></div>
<div className="grid-line vertical v-3"></div>
<div className="grid-line vertical v-4"></div>
</div>
{/* Security Elements */}
<div className="security-elements">
<div className="shield shield-1">
<i className="fa-solid fa-shield-halved"></i>
</div>
<div className="shield shield-2">
<i className="fa-solid fa-lock"></i>
</div>
<div className="shield shield-3">
<i className="fa-solid fa-key"></i>
</div>
<div className="shield shield-4">
<i className="fa-solid fa-fingerprint"></i>
</div>
</div>
{/* Circuit Patterns */}
<div className="circuit-patterns">
<div className="circuit circuit-1">
<div className="circuit-node"></div>
<div className="circuit-line"></div>
<div className="circuit-node"></div>
</div>
<div className="circuit circuit-2">
<div className="circuit-node"></div>
<div className="circuit-line"></div>
<div className="circuit-node"></div>
<div className="circuit-line"></div>
<div className="circuit-node"></div>
</div>
<div className="circuit circuit-3">
<div className="circuit-node"></div>
<div className="circuit-line"></div>
<div className="circuit-node"></div>
</div>
</div>
{/* Data Streams */}
<div className="data-streams">
<div className="stream stream-1">
<div className="data-bit"></div>
<div className="data-bit"></div>
<div className="data-bit"></div>
<div className="data-bit"></div>
</div>
<div className="stream stream-2">
<div className="data-bit"></div>
<div className="data-bit"></div>
<div className="data-bit"></div>
<div className="data-bit"></div>
<div className="data-bit"></div>
</div>
<div className="stream stream-3">
<div className="data-bit"></div>
<div className="data-bit"></div>
<div className="data-bit"></div>
</div>
</div>
{/* Request/Response Data */}
<div className="request-response-data">
<div className="api-request req-1">
<div className="request-label">POST /api/enterprise</div>
<div className="request-data">
<div className="data-packet"></div>
<div className="data-packet"></div>
<div className="data-packet"></div>
</div>
</div>
<div className="api-response resp-1">
<div className="response-label">200 OK</div>
<div className="response-data">
<div className="data-packet"></div>
<div className="data-packet"></div>
<div className="data-packet"></div>
<div className="data-packet"></div>
</div>
</div>
<div className="api-request req-2">
<div className="request-label">GET /api/analytics</div>
<div className="request-data">
<div className="data-packet"></div>
<div className="data-packet"></div>
</div>
</div>
<div className="api-response resp-2">
<div className="response-label">201 Created</div>
<div className="response-data">
<div className="data-packet"></div>
<div className="data-packet"></div>
<div className="data-packet"></div>
</div>
</div>
</div>
{/* Space Data Generation */}
<div className="space-data-generation">
<div className="data-cluster cluster-1">
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
</div>
<div className="data-cluster cluster-2">
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
</div>
<div className="data-cluster cluster-3">
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
</div>
<div className="data-cluster cluster-4">
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
<div className="data-point"></div>
</div>
</div>
{/* Database Connections */}
<div className="database-connections">
<div className="db-connection conn-1">
<div className="connection-line"></div>
<div className="db-node">
<i className="fa-solid fa-database"></i>
</div>
<div className="connection-pulse"></div>
</div>
<div className="db-connection conn-2">
<div className="connection-line"></div>
<div className="db-node">
<i className="fa-solid fa-server"></i>
</div>
<div className="connection-pulse"></div>
</div>
<div className="db-connection conn-3">
<div className="connection-line"></div>
<div className="db-node">
<i className="fa-solid fa-cloud"></i>
</div>
<div className="connection-pulse"></div>
</div>
</div>
{/* Real-time Metrics */}
<div className="real-time-metrics">
<div className="metric metric-1">
<div className="metric-label">API Calls/sec</div>
<div className="metric-value">2,847</div>
<div className="metric-bar">
<div className="bar-fill"></div>
</div>
</div>
<div className="metric metric-2">
<div className="metric-label">Data Processed</div>
<div className="metric-value">15.2TB</div>
<div className="metric-bar">
<div className="bar-fill"></div>
</div>
</div>
<div className="metric metric-3">
<div className="metric-label">Active Users</div>
<div className="metric-value">45,892</div>
<div className="metric-bar">
<div className="bar-fill"></div>
</div>
</div>
</div>
</div>
</div>
<div className="container">
<div className="banner-content">
<div className="content-center">
<div className="badge-container">
<span className="badge">
<i className={currentText.icon}></i>
{currentText.badge}
</span>
</div>
<h1 className={`main-heading carousel-text ${isTransitioning ? 'fade-out' : 'fade-in'}`}>
{currentText.heading}
<span className="gradient-text"> {currentText.highlight}</span>
<br />
{currentText.subheading}
</h1>
<p className={`description carousel-text ${isTransitioning ? 'fade-out' : 'fade-in'}`}>
{currentText.description}
</p>
{/* Carousel Indicators */}
<div className="carousel-indicators">
{carouselTexts.map((_, index) => (
<button
key={index}
className={`indicator ${index === currentTextIndex ? 'active' : ''}`}
onClick={() => {
if (index !== currentTextIndex) {
setIsTransitioning(true);
setTimeout(() => {
setCurrentTextIndex(index);
setIsTransitioning(false);
}, 1000);
}
}}
/>
))}
</div>
<div className="cta-section">
<Link href={currentText.button_url || "#"} className="cta-primary">
<span>{currentText.button_text || "Learn More"}</span>
<i className="fa-solid fa-arrow-right"></i>
</Link>
<Link href="/contact-us" className="cta-secondary">
<i className="fa-solid fa-phone"></i>
<span>Contact Sales</span>
</Link>
</div>
<div className="trust-indicators">
<div className="trust-item">
<div className="trust-number">30+</div>
<div className="trust-label">Enterprise Clients</div>
</div>
<div className="trust-item">
<div className="trust-number">99.9%</div>
<div className="trust-label">Uptime SLA</div>
</div>
<div className="trust-item">
<div className="trust-number">24/7</div>
<div className="trust-label">Enterprise Support</div>
</div>
</div>
</div>
</div>
</div>
<div className="scroll-indicator" onClick={() => window.scrollTo({ top: window.innerHeight, behavior: 'smooth' })}>
<div className="scroll-text">Scroll to explore</div>
<div className="scroll-arrow">
<i className="fa-solid fa-chevron-down"></i>
</div>
</div>
</section>
</>
);
};
export default HomeBanner;