Files
KLC-Website-Frontend/src/components/HeroSection.tsx

304 lines
11 KiB
TypeScript
Raw Normal View History

2025-08-28 13:14:51 +05:30
import React, { useState, useEffect, useCallback } from 'react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { navigateTo } from './Router';
import svgPaths from "../imports/svg-i1joeov37f";
interface SlideData {
id: number;
title: string;
description: string;
backgroundImage: string;
shortTitle: string;
}
export default function HeroSection() {
const [currentSlide, setCurrentSlide] = useState(0);
const [isAutoPlaying, setIsAutoPlaying] = useState(true);
const [progressValues, setProgressValues] = useState([0, 0, 0]);
const slides: SlideData[] = [
{
id: 1,
title: "Empowering Future-Ready\nLeaders",
description: "Build confidence, agility, and clarity for today's complex challenges.",
backgroundImage: "https://images.unsplash.com/photo-1552664730-d307ca884978?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1920&q=80",
shortTitle: "Leadership Is Learned. We Teach It Right."
},
{
id: 2,
title: "Turn Managers into\nImpactful Leaders",
description: "Transform your management team into visionary leaders who inspire teams, drive innovation, and achieve exceptional business outcomes.",
backgroundImage: "https://images.unsplash.com/photo-1600880292203-757bb62b4baf?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1920&q=80",
shortTitle: "Turn Managers into Impactful Leaders"
},
{
id: 3,
title: "Struggling with\nManagerial Gaps?",
description: "Bridge the leadership gap in your organization with our proven methodologies that develop confident, capable leaders at every level.",
backgroundImage: "https://images.unsplash.com/photo-1542744173-8e7e53415bb0?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1920&q=80",
shortTitle: "Struggling with Managerial Gaps?"
}
];
const totalSlides = slides.length;
const slideDuration = 5000; // 5 seconds per slide
// Auto-advance slides
useEffect(() => {
if (!isAutoPlaying) return;
const interval = setInterval(() => {
setCurrentSlide((prev) => (prev + 1) % totalSlides);
}, slideDuration);
return () => clearInterval(interval);
}, [isAutoPlaying, totalSlides]);
// Progress bar animation
useEffect(() => {
if (!isAutoPlaying) return;
const interval = setInterval(() => {
setProgressValues(prev => {
const newProgress = [...prev];
newProgress[currentSlide] = Math.min(newProgress[currentSlide] + (100 / (slideDuration / 100)), 100);
// Reset progress when slide changes
if (newProgress[currentSlide] >= 100) {
newProgress[currentSlide] = 0;
// Reset other slides
newProgress.forEach((_, index) => {
if (index !== currentSlide) {
newProgress[index] = 0;
}
});
}
return newProgress;
});
}, 100);
return () => clearInterval(interval);
}, [currentSlide, isAutoPlaying]);
// Reset progress when manually changing slides
useEffect(() => {
setProgressValues(prev => {
const newProgress = [0, 0, 0];
newProgress[currentSlide] = 0;
return newProgress;
});
}, [currentSlide]);
const goToSlide = useCallback((slideIndex: number) => {
if (slideIndex !== currentSlide) {
setCurrentSlide(slideIndex);
setIsAutoPlaying(false);
// Resume auto-play after manual interaction
setTimeout(() => setIsAutoPlaying(true), 3000);
}
}, [currentSlide]);
const nextSlide = useCallback(() => {
const next = (currentSlide + 1) % totalSlides;
goToSlide(next);
}, [currentSlide, totalSlides, goToSlide]);
const prevSlide = useCallback(() => {
const prev = (currentSlide - 1 + totalSlides) % totalSlides;
goToSlide(prev);
}, [currentSlide, totalSlides, goToSlide]);
// Pause auto-play on hover
const handleMouseEnter = () => setIsAutoPlaying(false);
const handleMouseLeave = () => setIsAutoPlaying(true);
return (
<section
className="hero-section"
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{/* Background Slides */}
{slides.map((slide, index) => (
<div
key={slide.id}
className={`hero-slide ${index === currentSlide ? 'active' : ''}`}
style={{
backgroundImage: `url('${slide.backgroundImage}')`
}}
>
<div className="hero-overlay" />
</div>
))}
{/* Hero Content */}
<div className="hero-content">
<div className="hero-text-section">
{/* Title */}
<h1 className="hero-title" style={{ whiteSpace: 'pre-line' }}>
{slides[currentSlide].title}
</h1>
{/* Description */}
<p className="hero-description">
{slides[currentSlide].description}
</p>
{/* Build Your Leadership Pipeline Button - Enhanced with Proper Navigation */}
<button
className="hero-slide-button group box-border content-stretch flex flex-row gap-2.5 items-center justify-start p-0 relative cursor-pointer overflow-hidden"
style={{
background: 'transparent',
border: 'none'
}}
onClick={() => {
console.log('Hero button clicked - navigating to contact page');
navigateTo('/contact?topic=leadership-pipeline');
}}
aria-label="Build Your Leadership Pipeline"
>
{/* Icon Container with Slide Animation */}
<div className="relative shrink-0 size-[50px] overflow-hidden">
{/* Background Rectangle - Consistent Blue Color */}
<div className="absolute inset-0 bg-[#04045B]" />
{/* Icon Layer - Sliding Animation */}
<div className="icon-layer absolute inset-0 w-full h-full">
{/* Primary Arrow - Slides out diagonally up-right */}
<div className="icon absolute inset-0 flex items-center justify-center transition-all duration-300 ease-in-out group-hover:translate-x-6 group-hover:-translate-y-6 group-hover:opacity-0">
<svg
className="block w-full h-full"
fill="none"
preserveAspectRatio="none"
viewBox="0 0 50 50"
>
<g clipPath="url(#clip0_95_1043_primary)">
<path d={svgPaths.p5b8d700} fill="white" />
<path d={svgPaths.p30b71a00} fill="white" />
</g>
<defs>
<clipPath id="clip0_95_1043_primary">
<rect fill="white" height="50" width="50" />
</clipPath>
</defs>
</svg>
</div>
{/* Secondary Arrow - Slides in from bottom-left */}
<div className="icon absolute inset-0 flex items-center justify-center opacity-0 -translate-x-6 translate-y-6 transition-all duration-300 ease-in-out group-hover:translate-x-0 group-hover:translate-y-0 group-hover:opacity-100">
<svg
className="block w-full h-full"
fill="none"
preserveAspectRatio="none"
viewBox="0 0 50 50"
>
<g clipPath="url(#clip0_95_1043_secondary)">
<path d={svgPaths.p5b8d700} fill="white" />
<path d={svgPaths.p30b71a00} fill="white" />
</g>
<defs>
<clipPath id="clip0_95_1043_secondary">
<rect fill="white" height="50" width="50" />
</clipPath>
</defs>
</svg>
</div>
</div>
</div>
{/* Text Section with Vertical Slide Animation */}
<div className="text-layer relative shrink-0 overflow-hidden flex items-center" style={{
height: '28px',
fontFamily: 'Inter, sans-serif',
fontSize: '20px',
fontWeight: '400',
lineHeight: '28px',
whiteSpace: 'nowrap',
color: '#ffffff'
}}>
{/* Primary Text - Slides up and out */}
<div
className="text-element absolute inset-0 flex items-center justify-start transition-all duration-300 ease-in-out group-hover:-translate-y-full group-hover:opacity-0"
style={{
color: '#ffffff !important',
textShadow: '0 1px 2px rgba(0, 0, 0, 0.4)',
fontFamily: 'Inter, sans-serif',
fontSize: '20px',
fontWeight: '400',
lineHeight: '28px'
}}
>
Build Your Leadership Pipeline
</div>
{/* Secondary Text - Slides in from bottom */}
<div
className="text-element absolute inset-0 flex items-center justify-start translate-y-full opacity-0 transition-all duration-300 ease-in-out group-hover:translate-y-0 group-hover:opacity-100"
style={{
color: '#ffffff !important',
textShadow: '0 1px 2px rgba(0, 0, 0, 0.4)',
fontFamily: 'Inter, sans-serif',
fontSize: '20px',
fontWeight: '400',
lineHeight: '28px'
}}
>
Build Your Leadership Pipeline
</div>
</div>
</button>
</div>
</div>
{/* Bottom Navigation */}
<div className="hero-navigation">
{/* Progress Section */}
<div className="hero-progress-container">
{slides.map((slide, index) => (
<div
key={slide.id}
className="hero-progress-item"
onClick={() => goToSlide(index)}
>
{/* Progress Bar */}
<div
className={`hero-progress-segment ${index === currentSlide ? 'active' : ''}`}
>
<div
className="hero-progress-fill"
style={{ width: index === currentSlide ? `${progressValues[index]}%` : '0%' }}
/>
</div>
{/* Progress Number */}
<div className={`hero-progress-number ${index === currentSlide ? 'active' : ''}`}>
{String(index + 1).padStart(2, '0')}
</div>
{/* Progress Text */}
<div className={`hero-progress-text ${index === currentSlide ? 'active' : ''}`}>
{slide.shortTitle}
</div>
</div>
))}
</div>
{/* Navigation Arrows */}
<div className="hero-controls">
<button
className="hero-nav-button"
onClick={prevSlide}
aria-label="Previous slide"
>
<ChevronLeft className="w-5 h-5" />
</button>
<button
className="hero-nav-button"
onClick={nextSlide}
aria-label="Next slide"
>
<ChevronRight className="w-5 h-5" />
</button>
</div>
</div>
</section>
);
}