fix hero btn and navigate on click bar

This commit is contained in:
priyanshuvish
2025-09-25 17:31:35 +05:30
parent 38a7b6a260
commit 9163e046d0
2 changed files with 137 additions and 271 deletions

View File

@@ -2,7 +2,8 @@ import React, { useState, useEffect, useCallback } from 'react';
import { ChevronLeft, ChevronRight } from 'lucide-react';
import { navigateTo } from './Router';
import svgPaths from "../imports/svg-i1joeov37f";
import PrimaryCTAButton from './PrimaryCTAButton';
interface SlideData {
id: number;
title: string;
@@ -11,12 +12,12 @@ interface SlideData {
ctaText: string;
route: string;
}
export default function HeroSection() {
const [currentSlide, setCurrentSlide] = useState(0);
const [isAutoPlaying, setIsAutoPlaying] = useState(true);
const [progressValues, setProgressValues] = useState([0, 0, 0, 0, 0, 0]);
const slides: SlideData[] = [
{
id: 1,
@@ -32,7 +33,7 @@ export default function HeroSection() {
backgroundImage: "https://images.unsplash.com/photo-1705234384669-c6d31c61b789?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxleGVjdXRpdmUlMjBsZWFkZXJzaGlwJTIwZGV2ZWxvcG1lbnQlMjB0cmFpbmluZ3xlbnwxfHx8fDE3NTY4MDcyNjJ8MA&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral",
shortTitle: "Leadership Development",
ctaText: "Explore Leadership Journeys",
route: '/services/leadership-development'
route: '/services/leadership-development'
},
{
id: 3,
@@ -67,25 +68,25 @@ export default function HeroSection() {
route: '/services/learning-facility'
}
];
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];
@@ -103,10 +104,10 @@ export default function HeroSection() {
return newProgress;
});
}, 100);
return () => clearInterval(interval);
}, [currentSlide, isAutoPlaying]);
// Reset progress when manually changing slides
useEffect(() => {
setProgressValues(prev => {
@@ -115,7 +116,7 @@ export default function HeroSection() {
return newProgress;
});
}, [currentSlide]);
const goToSlide = useCallback((slideIndex: number) => {
if (slideIndex !== currentSlide) {
setCurrentSlide(slideIndex);
@@ -124,23 +125,23 @@ export default function HeroSection() {
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
<section
className="hero-section"
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
@@ -157,7 +158,7 @@ export default function HeroSection() {
<div className="hero-overlay" />
</div>
))}
{/* Hero Content */}
<div className="hero-content">
<div className="hero-text-section">
@@ -167,144 +168,54 @@ export default function HeroSection() {
</h1>
{/* Dynamic CTA 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(slides[currentSlide].route);
}}
aria-label={slides[currentSlide].ctaText}
>
{/* 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'
}}
>
{slides[currentSlide].ctaText}
</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'
}}
>
{slides[currentSlide].ctaText}
</div>
</div>
</button>
<PrimaryCTAButton
text={slides[currentSlide].ctaText}
onClick={() => navigateTo(slides[currentSlide].route)}
ariaLabel="Learn more about KLC"
/>
</div>
</div>
{/* Bottom Navigation */}
<div className="hero-navigation">
{/* Progress Section */}
<div className="hero-progress-container">
{slides.map((slide, index) => (
<div
<div
key={slide.id}
className="hero-progress-item"
onClick={() => goToSlide(index)}
>
{/* Progress Bar */}
<div
className={`hero-progress-segment ${index === currentSlide ? 'active' : ''}`}
<div
key={slide.id}
className="hero-progress-item"
onClick={() => navigateTo(slide.route)}
>
<div
className="hero-progress-fill"
style={{ width: index === currentSlide ? `${progressValues[index]}%` : '0%' }}
/>
</div>
{/* 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 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}
{/* Progress Text */}
<div className={`hero-progress-text ${index === currentSlide ? 'active' : ''}`}>
{slide.shortTitle}
</div>
</div>
</div>
))}
</div>
{/* Navigation Arrows */}
<div className="hero-controls">
<button

View File

@@ -1,146 +1,101 @@
import React, { useEffect } from 'react';
import svgPaths from "../imports/svg-i1joeov37f";
import { navigateTo } from './Router';
import React, { useState } from 'react';
import { ArrowRight } from 'lucide-react';
interface PrimaryCTAButtonProps {
text: string;
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
className?: string;
onClick: () => void;
ariaLabel?: string;
debugId?: string; // Add debug identifier
className?: string;
disabled?: boolean;
}
export const PrimaryCTAButton: React.FC<PrimaryCTAButtonProps> = ({
text,
onClick,
export function PrimaryCTAButton({
text,
onClick,
ariaLabel,
className = '',
ariaLabel,
debugId = 'unknown'
}) => {
// Debug: Log when component mounts
useEffect(() => {
console.log(`PrimaryCTAButton ${debugId} mounted`);
}, [debugId]);
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
console.log(`Primary CTA Button ${debugId} clicked with text: "${text}"`); // Debug log
// Handle webinars navigation
if (text === "Join Our Webinars" || text === "Explore Webinars" || text === "View Webinars") {
console.log(`Navigating to webinars page for ${debugId}`);
navigateTo('/webinars');
} else if (text === "Register Free" || text === "Watch Replay" || text === "Launch in Zoom") {
// These are handled by individual webinar detail pages
console.log(`Webinar CTA handled by detail page for ${debugId}`);
} else if (onClick) {
console.log(`Custom onClick handler found for ${debugId}, executing it`); // Debug log
onClick(e);
} else {
console.log(`No custom onClick for ${debugId}, navigating to webcast page`); // Debug log
// Navigate to webcast page by default
navigateTo('/learning/webcast');
}
};
disabled = false
}: PrimaryCTAButtonProps) {
const [isHovered, setIsHovered] = useState(false);
return (
<button
className={`primary-cta-button group box-border content-stretch flex flex-row gap-2.5 items-center justify-start p-0 relative cursor-pointer overflow-hidden ${className}`}
style={{
background: 'transparent',
border: 'none',
width: 'fit-content' // Perfect width - no extra horizontal space
<button
onClick={onClick}
disabled={disabled}
aria-label={ariaLabel || text}
className={`primary-cta-button ${className}`}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
gap: '12px',
padding: '8px 20px',
borderRadius: '10px',
border: 'none',
cursor: disabled ? 'not-allowed' : 'pointer',
fontSize: 'var(--font-body-lg)',
fontWeight: 'var(--font-weight-h3)',
fontFamily: 'var(--font-family-base)',
backgroundColor: disabled ? '#9CA3AF' : 'var(--color-primary)',
color: '#FFFFFF',
boxShadow: disabled
? 'none'
: '0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06)',
transition: 'all 300ms ease-in-out',
position: 'relative',
overflow: 'hidden',
opacity: disabled ? 0.6 : 1,
transform: isHovered && !disabled ? 'translateY(-2px)' : 'translateY(0)',
...(isHovered && !disabled && {
backgroundColor: '#030359', // Darker shade of primary brand color
boxShadow: '0 8px 25px rgba(4, 4, 91, 0.3), 0 4px 6px rgba(4, 4, 91, 0.1)'
})
}}
>
{/* Text */}
<span
style={{
fontSize: 'var(--font-body-lg)',
fontWeight: 'var(--font-weight-h3)',
fontFamily: 'var(--font-family-base)',
color: '#FFFFFF',
whiteSpace: 'nowrap'
}}
onClick={handleClick}
aria-label={ariaLabel || text}
>
{/* Icon Container with Slide Animation */}
<div className="relative shrink-0 size-[50px] overflow-hidden">
{/* Background Rectangle - Consistent Yellow Color */}
<div className="absolute inset-0 bg-[#F8C301]" />
{/* 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_primary_cta_primary)">
<path d={svgPaths.p5b8d700} fill="white" />
<path d={svgPaths.p30b71a00} fill="white" />
</g>
<defs>
<clipPath id="clip0_primary_cta_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_primary_cta_secondary)">
<path d={svgPaths.p5b8d700} fill="white" />
<path d={svgPaths.p30b71a00} fill="white" />
</g>
<defs>
<clipPath id="clip0_primary_cta_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',
width: 'fit-content' // Perfect text width - no extra horizontal space
}}>
{/* 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',
fontFamily: 'Inter, sans-serif',
fontSize: '20px',
fontWeight: '400',
lineHeight: '28px'
}}
>
{text}
</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',
fontFamily: 'Inter, sans-serif',
fontSize: '20px',
fontWeight: '400',
lineHeight: '28px'
}}
>
{text}
</div>
</div>
</button>
{text}
</span>
{/* Arrow icon with enhanced animation */}
<span
style={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '20px',
height: '20px',
borderRadius: '50%',
backgroundColor: 'rgba(255, 255, 255, 0.2)',
transition: 'all 300ms ease-in-out',
transform: isHovered && !disabled ? 'translateX(4px) scale(1.1)' : 'translateX(0) scale(1)',
...(isHovered && !disabled && {
backgroundColor: 'rgba(255, 255, 255, 0.3)'
})
}}
>
<ArrowRight
size={14}
style={{
color: '#FFFFFF',
transition: 'all 300ms ease-in-out'
}}
/>
</span>
</button>
);
};
}
// Named exports for backward compatibility
export const PrimaryCTAButtonProps = PrimaryCTAButton;
export default PrimaryCTAButton;