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

310 lines
12 KiB
TypeScript
Raw Normal View History

2025-08-28 13:14:51 +05:30
import { useState, useEffect, useRef } from "react";
import { motion } from "motion/react";
import {
Users,
Settings,
User,
Globe,
MessageSquare,
2025-08-28 13:14:51 +05:30
GraduationCap,
TrendingUp,
Building,
2025-08-28 13:14:51 +05:30
ArrowRight
} from "lucide-react";
import { BrandedTag } from "./about/BrandedTag";
import { StandardCTAButton } from "./StandardCTAButton";
2025-08-28 13:14:51 +05:30
import { navigateTo } from "./Router";
// Services data
const recognitionItems = [
{
id: 1,
title: "Leadership Pipeline Development",
description: "Build a strong foundation for sustainable leadership succession. Identify, assess, and develop high-potential talent through structured pathways that ensure organizational continuity and growth.",
icon: <TrendingUp size={28} />,
route: '/services/leadership-pipeline-development'
},
{
id: 2,
2025-08-28 13:14:51 +05:30
title: "Leadership Development",
description: "Comprehensive programs designed to cultivate strategic thinking and emotional intelligence. Develop capabilities that drive organizational success through authentic leadership practices.",
icon: <Users size={28} />,
route: '/services/leadership-development'
2025-08-28 13:14:51 +05:30
},
{
id: 3,
2025-08-28 13:14:51 +05:30
title: "Management Development",
description: "Essential skills training for first-time and experienced managers seeking growth. Focus on communication, delegation, and performance management excellence.",
icon: <Settings size={28} />,
route: '/services/management-development'
2025-08-28 13:14:51 +05:30
},
{
id: 4,
title: "Culture & Competence Consulting",
description: "Transform organizational culture and build inclusive practices that enhance team collaboration. Navigate cultural differences with confidence and create environments where everyone thrives.",
icon: <Globe size={28} />,
route: '/services/culture-competence'
2025-08-28 13:14:51 +05:30
},
{
id: 5,
title: "Coaching & Mentoring",
description: "One-on-one personalized development for senior leaders and high-potential talent. Strategic guidance for complex leadership challenges, career advancement, and personal growth.",
2025-08-28 13:14:51 +05:30
icon: <MessageSquare size={28} />,
route: '/services/executive-coaching'
2025-08-28 13:14:51 +05:30
},
{
id: 6,
title: "Leadership Campus (Facility)",
description: "Experience learning in a world-class environment designed for transformation. Our state-of-the-art facility provides the perfect setting for immersive leadership development programs.",
icon: <Building size={28} />,
route: '/services/learning-facility'
2025-08-28 13:14:51 +05:30
}
];
export function ServicesSection() {
const [isVisible, setIsVisible] = useState(false);
const cardRefs = useRef<(HTMLDivElement | null)[]>([]);
const sectionRef = useRef<HTMLDivElement>(null);
// Add card refs helper
const addCardRef = (el: HTMLDivElement | null, index: number) => {
cardRefs.current[index] = el;
};
// Intersection observer for animations
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setIsVisible(true);
}
});
},
{ threshold: 0.2 }
);
if (sectionRef.current) {
observer.observe(sectionRef.current);
}
return () => observer.disconnect();
}, []);
// Keyboard navigation
const handleKeyDown = (e: React.KeyboardEvent, index: number) => {
if (e.key === 'ArrowDown' && index < cardRefs.current.length - 1) {
cardRefs.current[index + 1]?.focus();
e.preventDefault();
} else if (e.key === 'ArrowUp' && index > 0) {
cardRefs.current[index - 1]?.focus();
e.preventDefault();
}
};
return (
<section
2025-08-28 13:14:51 +05:30
ref={sectionRef}
className="py-16 lg:py-20"
style={{
2025-09-25 16:45:18 +05:30
backgroundColor: '#fff',
2025-08-28 13:14:51 +05:30
fontFamily: 'var(--font-family-brand)'
}}
aria-labelledby="recognition-section-heading"
>
<div className="section-margin-x">
<div className="max-w-7xl mx-auto">
{/* Desktop Layout - Grid with Sticky Sidebar */}
<div className="hidden lg:grid grid-cols-12 gap-12 min-h-screen">
2025-08-28 13:14:51 +05:30
{/* Left Side - Sticky Content */}
<div className="col-span-5 sticky top-24 self-start">
<div className="recognition-header pr-8">
<BrandedTag
text="Our Services"
2025-08-28 13:14:51 +05:30
/>
<h2
id="recognition-section-heading"
2025-08-28 13:14:51 +05:30
className="text-h2 mb-6"
>
2025-09-05 17:59:33 +05:30
Shaping Leaders, Cultures, and Institutions
2025-08-28 13:14:51 +05:30
</h2>
<p className="text-body-lg text-muted mb-8">
No two institutions are alike and neither are their leadership needs. That's why every KLC service is rooted in research, tailored to context, and aligned with strategy. From shaping leaders and managers to shaping culture, developing talent frameworks, and offering practical high impact learning, we partner with you to create leadership solutions that deliver lasting value.
</p>
{/* CTA Button - Left aligned */}
<div className="primary-cta-container-left cta-left-locked">
<StandardCTAButton
text="Services Page"
onClick={() => navigateTo('/services')}
ariaLabel="Explore our services"
/>
</div>
2025-08-28 13:14:51 +05:30
</div>
</div>
{/* Right Side - Scrolling Cards */}
<div className="col-span-7">
<div
2025-08-28 13:14:51 +05:30
className="recognition-cards space-y-6"
role="list"
aria-label="Leadership development services"
>
{recognitionItems.map((item, index) => (
<div
key={item.id}
ref={(el) => addCardRef(el, index)}
className={`recognition-card group scroll-animate-stagger cursor-pointer focus-ring ${isVisible ? 'animate-in' : ''}`}
2025-08-28 13:14:51 +05:30
role="listitem"
aria-labelledby={`recognition-title-${item.id}`}
aria-describedby={`recognition-desc-${item.id}`}
tabIndex={0}
onKeyDown={(e) => handleKeyDown(e, index)}
style={{
2025-08-28 13:14:51 +05:30
transitionDelay: `${(index + 1) * 150}ms`,
opacity: isVisible ? 1 : 0
}}
onClick={() => navigateTo(item.route)}
2025-08-28 13:14:51 +05:30
>
<div
2025-08-28 13:14:51 +05:30
className="p-8 transition-all duration-300 hover:shadow-xl hover:-translate-y-1 border bg-white"
style={{
2025-08-28 13:14:51 +05:30
borderColor: 'var(--color-border)',
borderRadius: '12px',
fontFamily: 'var(--font-family-brand)'
}}
>
<div className="flex items-start mb-6">
<div
2025-08-28 13:14:51 +05:30
className="w-14 h-14 flex items-center justify-center transition-transform duration-300 group-hover:scale-110"
style={{
2025-08-28 13:14:51 +05:30
backgroundColor: 'var(--color-brand-primary)',
borderRadius: '12px',
color: 'white'
}}
>
{item.icon}
</div>
</div>
2025-08-28 13:14:51 +05:30
<div className="recognition-card-content">
<h3
2025-08-28 13:14:51 +05:30
id={`recognition-title-${item.id}`}
className="text-h4 mb-4"
>
{item.title}
</h3>
<p
2025-08-28 13:14:51 +05:30
id={`recognition-desc-${item.id}`}
className="text-small text-muted leading-relaxed"
>
{item.description}
</p>
</div>
</div>
</div>
))}
</div>
</div>
</div>
{/* Mobile Layout - Stacked Header + Horizontal Scrollable Cards */}
<div className="lg:hidden">
{/* Mobile Header */}
<div className="text-center mb-8">
<BrandedTag
text="Our Services"
2025-08-28 13:14:51 +05:30
/>
<h2
id="recognition-section-heading-mobile"
className="text-h2 mb-6"
>
Shaping Leaders, Cultures, and Institutions
</h2>
<p className="text-body-lg text-muted mb-8">
No two institutions are alike and neither are their leadership needs. That's why every KLC service is rooted in research, tailored to context, and aligned with strategy. From shaping leaders and managers to shaping culture, developing talent frameworks, and offering practical high impact learning, we partner with you to create leadership solutions that deliver lasting value.
</p>
{/* CTA Button - Left aligned for mobile */}
<div className="primary-cta-container-left cta-left-locked">
<StandardCTAButton
text="Services Page"
onClick={() => navigateTo('/services')}
ariaLabel="Explore our services"
/>
</div>
</div>
{/* Mobile Horizontal Scrollable Cards */}
<div className="relative">
<div
className="flex gap-6 overflow-x-auto scrollbar-hide pb-4"
style={{
scrollSnapType: 'x mandatory',
WebkitOverflowScrolling: 'touch'
}}
role="list"
aria-label="Leadership development services"
>
{recognitionItems.map((item, index) => (
<div
key={item.id}
className={`recognition-card-mobile group focus-ring flex-shrink-0 ${isVisible ? 'animate-in' : ''}`}
role="listitem"
aria-labelledby={`recognition-title-mobile-${item.id}`}
aria-describedby={`recognition-desc-mobile-${item.id}`}
tabIndex={0}
onKeyDown={(e) => handleKeyDown(e, index)}
style={{
scrollSnapAlign: 'start',
width: '320px',
transitionDelay: `${(index + 1) * 150}ms`,
opacity: isVisible ? 1 : 0
}}
>
<div
className="p-6 transition-all duration-300 hover:shadow-xl hover:-translate-y-1 border bg-white h-full"
style={{
borderColor: 'var(--color-border)',
borderRadius: '12px',
fontFamily: 'var(--font-family-brand)'
}}
>
<div className="flex items-start mb-6">
<div
className="w-12 h-12 flex items-center justify-center transition-transform duration-300 group-hover:scale-110"
style={{
backgroundColor: 'var(--color-brand-primary)',
borderRadius: '12px',
color: 'white'
}}
>
{item.icon}
</div>
</div>
<div className="recognition-card-content">
<h3
id={`recognition-title-mobile-${item.id}`}
className="text-h4 mb-4"
>
{item.title}
</h3>
<p
id={`recognition-desc-mobile-${item.id}`}
className="text-small text-muted leading-relaxed"
>
{item.description}
</p>
</div>
</div>
</div>
))}
</div>
</div>
2025-08-28 13:14:51 +05:30
</div>
2025-08-28 13:14:51 +05:30
</div>
</div>
</section>
);
}