fix hero btn and navigate on click bar
This commit is contained in:
@@ -2,6 +2,7 @@ import React, { useState, useEffect, useCallback } from 'react';
|
|||||||
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
||||||
import { navigateTo } from './Router';
|
import { navigateTo } from './Router';
|
||||||
import svgPaths from "../imports/svg-i1joeov37f";
|
import svgPaths from "../imports/svg-i1joeov37f";
|
||||||
|
import PrimaryCTAButton from './PrimaryCTAButton';
|
||||||
|
|
||||||
interface SlideData {
|
interface SlideData {
|
||||||
id: number;
|
id: number;
|
||||||
@@ -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",
|
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",
|
shortTitle: "Leadership Development",
|
||||||
ctaText: "Explore Leadership Journeys",
|
ctaText: "Explore Leadership Journeys",
|
||||||
route: '/services/leadership-development'
|
route: '/services/leadership-development'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
@@ -167,111 +168,16 @@ export default function HeroSection() {
|
|||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
{/* Dynamic CTA Button - Enhanced with Proper Navigation */}
|
{/* 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 */}
|
<PrimaryCTAButton
|
||||||
<div className="icon-layer absolute inset-0 w-full h-full">
|
text={slides[currentSlide].ctaText}
|
||||||
{/* Primary Arrow - Slides out diagonally up-right */}
|
onClick={() => navigateTo(slides[currentSlide].route)}
|
||||||
<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">
|
ariaLabel="Learn more about KLC"
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{/* Bottom Navigation */}
|
{/* Bottom Navigation */}
|
||||||
<div className="hero-navigation">
|
<div className="hero-navigation">
|
||||||
{/* Progress Section */}
|
{/* Progress Section */}
|
||||||
@@ -284,22 +190,27 @@ export default function HeroSection() {
|
|||||||
>
|
>
|
||||||
{/* Progress Bar */}
|
{/* Progress Bar */}
|
||||||
<div
|
<div
|
||||||
className={`hero-progress-segment ${index === currentSlide ? 'active' : ''}`}
|
key={slide.id}
|
||||||
|
className="hero-progress-item"
|
||||||
|
onClick={() => navigateTo(slide.route)}
|
||||||
>
|
>
|
||||||
<div
|
{/* Progress Bar */}
|
||||||
className="hero-progress-fill"
|
<div className={`hero-progress-segment ${index === currentSlide ? 'active' : ''}`}>
|
||||||
style={{ width: index === currentSlide ? `${progressValues[index]}%` : '0%' }}
|
<div
|
||||||
/>
|
className="hero-progress-fill"
|
||||||
</div>
|
style={{ width: index === currentSlide ? `${progressValues[index]}%` : '0%' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Progress Number */}
|
{/* Progress Number */}
|
||||||
<div className={`hero-progress-number ${index === currentSlide ? 'active' : ''}`}>
|
<div className={`hero-progress-number ${index === currentSlide ? 'active' : ''}`}>
|
||||||
{String(index + 1).padStart(2, '0')}
|
{String(index + 1).padStart(2, '0')}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Progress Text */}
|
{/* Progress Text */}
|
||||||
<div className={`hero-progress-text ${index === currentSlide ? 'active' : ''}`}>
|
<div className={`hero-progress-text ${index === currentSlide ? 'active' : ''}`}>
|
||||||
{slide.shortTitle}
|
{slide.shortTitle}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -1,146 +1,101 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useState } from 'react';
|
||||||
import svgPaths from "../imports/svg-i1joeov37f";
|
import { ArrowRight } from 'lucide-react';
|
||||||
import { navigateTo } from './Router';
|
|
||||||
|
|
||||||
interface PrimaryCTAButtonProps {
|
interface PrimaryCTAButtonProps {
|
||||||
text: string;
|
text: string;
|
||||||
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
|
onClick: () => void;
|
||||||
className?: string;
|
|
||||||
ariaLabel?: string;
|
ariaLabel?: string;
|
||||||
debugId?: string; // Add debug identifier
|
className?: string;
|
||||||
|
disabled?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PrimaryCTAButton: React.FC<PrimaryCTAButtonProps> = ({
|
export function PrimaryCTAButton({
|
||||||
text,
|
text,
|
||||||
onClick,
|
onClick,
|
||||||
className = '',
|
|
||||||
ariaLabel,
|
ariaLabel,
|
||||||
debugId = 'unknown'
|
className = '',
|
||||||
}) => {
|
disabled = false
|
||||||
// Debug: Log when component mounts
|
}: PrimaryCTAButtonProps) {
|
||||||
useEffect(() => {
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
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');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<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}`}
|
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={{
|
style={{
|
||||||
background: 'transparent',
|
fontSize: 'var(--font-body-lg)',
|
||||||
border: 'none',
|
fontWeight: 'var(--font-weight-h3)',
|
||||||
width: 'fit-content' // Perfect width - no extra horizontal space
|
fontFamily: 'var(--font-family-base)',
|
||||||
|
color: '#FFFFFF',
|
||||||
|
whiteSpace: 'nowrap'
|
||||||
}}
|
}}
|
||||||
onClick={handleClick}
|
|
||||||
aria-label={ariaLabel || text}
|
|
||||||
>
|
>
|
||||||
{/* Icon Container with Slide Animation */}
|
{text}
|
||||||
<div className="relative shrink-0 size-[50px] overflow-hidden">
|
</span>
|
||||||
{/* Background Rectangle - Consistent Yellow Color */}
|
|
||||||
<div className="absolute inset-0 bg-[#F8C301]" />
|
|
||||||
|
|
||||||
{/* Icon Layer - Sliding Animation */}
|
{/* Arrow icon with enhanced animation */}
|
||||||
<div className="icon-layer absolute inset-0 w-full h-full">
|
<span
|
||||||
{/* Primary Arrow - Slides out diagonally up-right */}
|
style={{
|
||||||
<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">
|
display: 'flex',
|
||||||
<svg
|
alignItems: 'center',
|
||||||
className="block w-full h-full"
|
justifyContent: 'center',
|
||||||
fill="none"
|
width: '20px',
|
||||||
preserveAspectRatio="none"
|
height: '20px',
|
||||||
viewBox="0 0 50 50"
|
borderRadius: '50%',
|
||||||
>
|
backgroundColor: 'rgba(255, 255, 255, 0.2)',
|
||||||
<g clipPath="url(#clip0_primary_cta_primary)">
|
transition: 'all 300ms ease-in-out',
|
||||||
<path d={svgPaths.p5b8d700} fill="white" />
|
transform: isHovered && !disabled ? 'translateX(4px) scale(1.1)' : 'translateX(0) scale(1)',
|
||||||
<path d={svgPaths.p30b71a00} fill="white" />
|
...(isHovered && !disabled && {
|
||||||
</g>
|
backgroundColor: 'rgba(255, 255, 255, 0.3)'
|
||||||
<defs>
|
})
|
||||||
<clipPath id="clip0_primary_cta_primary">
|
}}
|
||||||
<rect fill="white" height="50" width="50" />
|
>
|
||||||
</clipPath>
|
<ArrowRight
|
||||||
</defs>
|
size={14}
|
||||||
</svg>
|
style={{
|
||||||
</div>
|
color: '#FFFFFF',
|
||||||
|
transition: 'all 300ms ease-in-out'
|
||||||
{/* 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
|
</span>
|
||||||
className="block w-full h-full"
|
</button>
|
||||||
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>
|
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// Named exports for backward compatibility
|
||||||
|
export const PrimaryCTAButtonProps = PrimaryCTAButton;
|
||||||
|
export default PrimaryCTAButton;
|
||||||
Reference in New Issue
Block a user