1150 lines
50 KiB
TypeScript
1150 lines
50 KiB
TypeScript
import React, { useState, useRef, useEffect } from 'react';
|
||
import { Button } from './ui/button';
|
||
import { Badge } from './ui/badge';
|
||
import { Tabs, TabsContent, TabsList, TabsTrigger } from './ui/tabs';
|
||
import { Card, CardContent, CardHeader, CardTitle } from './ui/card';
|
||
import { Input } from './ui/input';
|
||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select';
|
||
import {
|
||
Play,
|
||
Users,
|
||
Clock,
|
||
ChevronRight,
|
||
ChevronLeft,
|
||
GraduationCap,
|
||
MessageCircle,
|
||
Zap,
|
||
Video,
|
||
Smartphone,
|
||
Award,
|
||
Building2,
|
||
BookOpen,
|
||
Star,
|
||
Globe,
|
||
Target,
|
||
TrendingUp,
|
||
Lightbulb,
|
||
CheckCircle,
|
||
ArrowRight,
|
||
Calendar,
|
||
Search,
|
||
Filter,
|
||
Grid,
|
||
List,
|
||
X,
|
||
DollarSign,
|
||
ShoppingCart,
|
||
ArrowLeft
|
||
} from 'lucide-react';
|
||
import { motion } from 'motion/react';
|
||
import { navigateTo } from './Router';
|
||
import { ImageWithFallback } from './figma/ImageWithFallback';
|
||
import { BrandedTag } from './about/BrandedTag';
|
||
import { PrimaryCTAButton } from './PrimaryCTAButton';
|
||
import { CourseCard } from './CourseCard';
|
||
import { CartPopup, CartItem } from './CartPopup';
|
||
import { useCart } from './CartContext';
|
||
|
||
// Course Categories
|
||
const courseCategories = [
|
||
'Leadership Fundamentals',
|
||
'Decision Making & Strategy',
|
||
'Perspective & Risk',
|
||
'Communication & Influence',
|
||
'Change & Innovation'
|
||
];
|
||
|
||
// Featured Courses Data - Updated with Rupee pricing
|
||
const featuredCourses = [
|
||
{
|
||
id: '1',
|
||
title: 'Strategic Leadership Foundations',
|
||
thumbnail: 'https://images.unsplash.com/photo-1552664730-d307ca884978?w=400&h=250&fit=crop',
|
||
duration: '12 hours',
|
||
level: 'Intermediate',
|
||
format: 'Self-paced',
|
||
rating: 4.8,
|
||
participants: '2,400+',
|
||
category: 'Leadership Fundamentals',
|
||
description: 'Master the core principles of strategic leadership and organizational vision.',
|
||
price: '₹24,817',
|
||
originalPrice: '₹33,117'
|
||
},
|
||
{
|
||
id: '2',
|
||
title: 'Data-Driven Decision Making',
|
||
thumbnail: 'https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=400&h=250&fit=crop',
|
||
duration: '8 hours',
|
||
level: 'Advanced',
|
||
format: 'Cohort-based',
|
||
rating: 4.9,
|
||
participants: '1,800+',
|
||
category: 'Decision Making & Strategy',
|
||
description: 'Learn to make strategic decisions using data analytics and business intelligence.',
|
||
price: '₹37,267',
|
||
originalPrice: '₹45,567'
|
||
},
|
||
{
|
||
id: '3',
|
||
title: 'Risk Assessment & Management',
|
||
thumbnail: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&h=250&fit=crop',
|
||
duration: '10 hours',
|
||
level: 'Intermediate',
|
||
format: 'Self-paced',
|
||
rating: 4.7,
|
||
participants: '3,200+',
|
||
category: 'Perspective & Risk',
|
||
description: 'Develop expertise in identifying, analyzing, and mitigating organizational risks.',
|
||
price: '₹28,967',
|
||
originalPrice: '₹37,267'
|
||
},
|
||
{
|
||
id: '4',
|
||
title: 'Influential Communication',
|
||
thumbnail: 'https://images.unsplash.com/photo-1556761175-b413da4baf72?w=400&h=250&fit=crop',
|
||
duration: '6 hours',
|
||
level: 'Beginner',
|
||
format: 'Self-paced',
|
||
rating: 4.8,
|
||
participants: '5,100+',
|
||
category: 'Communication & Influence',
|
||
description: 'Master the art of persuasive communication and stakeholder engagement.',
|
||
price: '₹16,517',
|
||
originalPrice: '₹20,667'
|
||
},
|
||
{
|
||
id: '5',
|
||
title: 'Leading Innovation & Change',
|
||
thumbnail: 'https://images.unsplash.com/photo-1542744173-8e7e53415bb0?w=400&h=250&fit=crop',
|
||
duration: '14 hours',
|
||
level: 'Advanced',
|
||
format: 'Cohort-based',
|
||
rating: 4.9,
|
||
participants: '1,950+',
|
||
category: 'Change & Innovation',
|
||
description: 'Drive organizational transformation and foster a culture of innovation.',
|
||
price: '₹45,567',
|
||
originalPrice: '₹53,867'
|
||
},
|
||
{
|
||
id: '6',
|
||
title: 'Digital Leadership Essentials',
|
||
thumbnail: 'https://images.unsplash.com/photo-1551434678-e076c223a692?w=400&h=250&fit=crop',
|
||
duration: '9 hours',
|
||
level: 'Intermediate',
|
||
format: 'Self-paced',
|
||
rating: 4.6,
|
||
participants: '2,800+',
|
||
category: 'Leadership Fundamentals',
|
||
description: 'Navigate the digital transformation as a modern leader.',
|
||
price: '₹23,157',
|
||
originalPrice: '₹28,967'
|
||
},
|
||
{
|
||
id: '7',
|
||
title: 'Crisis Leadership Strategies',
|
||
thumbnail: 'https://images.unsplash.com/photo-1584697964358-3e14ca57658b?w=400&h=250&fit=crop',
|
||
duration: '7 hours',
|
||
level: 'Advanced',
|
||
format: 'Cohort-based',
|
||
rating: 4.7,
|
||
participants: '1,200+',
|
||
category: 'Leadership Fundamentals',
|
||
description: 'Navigate uncertainty and lead your team through challenging situations with confidence.',
|
||
price: '₹33,117',
|
||
originalPrice: '₹41,417'
|
||
},
|
||
{
|
||
id: '8',
|
||
title: 'Emotional Intelligence for Leaders',
|
||
thumbnail: 'https://images.unsplash.com/photo-1559027615-cd4628902d4a?w=400&h=250&fit=crop',
|
||
duration: '5 hours',
|
||
level: 'Beginner',
|
||
format: 'Self-paced',
|
||
rating: 4.9,
|
||
participants: '4,300+',
|
||
category: 'Communication & Influence',
|
||
description: 'Develop emotional intelligence to enhance your leadership effectiveness.',
|
||
price: '₹14,857',
|
||
originalPrice: '₹19,007'
|
||
},
|
||
{
|
||
id: '9',
|
||
title: 'Strategic Risk Analysis',
|
||
thumbnail: 'https://images.unsplash.com/photo-1560472355-536de3962603?w=400&h=250&fit=crop',
|
||
duration: '11 hours',
|
||
level: 'Advanced',
|
||
format: 'Self-paced',
|
||
rating: 4.8,
|
||
participants: '1,500+',
|
||
category: 'Perspective & Risk',
|
||
description: 'Master advanced risk analysis techniques for strategic decision-making.',
|
||
price: '₹39,757',
|
||
originalPrice: '₹49,717'
|
||
}
|
||
];
|
||
|
||
// Learning Methodology Points
|
||
const methodologyPoints = [
|
||
{
|
||
icon: Target,
|
||
title: 'Self-awareness through leadership orientations',
|
||
description: 'Understand your natural leadership style and how to adapt it for different situations and team dynamics.'
|
||
},
|
||
{
|
||
icon: BookOpen,
|
||
title: 'Research-backed frameworks',
|
||
description: 'Learn from proven methodologies based on decades of leadership research and real-world application.'
|
||
},
|
||
{
|
||
icon: Zap,
|
||
title: 'Practice-oriented skill development',
|
||
description: 'Apply concepts immediately through interactive exercises, simulations, and hands-on projects.'
|
||
},
|
||
{
|
||
icon: MessageCircle,
|
||
title: 'Expert-led conversations',
|
||
description: 'Engage with seasoned leaders and industry experts through live sessions and mentoring opportunities.'
|
||
}
|
||
];
|
||
|
||
export function LearningOnline() {
|
||
const [searchTerm, setSearchTerm] = useState('');
|
||
const [selectedCategory, setSelectedCategory] = useState('All Categories');
|
||
const [selectedLevel, setSelectedLevel] = useState('All Levels');
|
||
const [selectedFormat, setSelectedFormat] = useState('All Formats');
|
||
const [selectedPriceRange, setSelectedPriceRange] = useState('All Prices');
|
||
const [selectedDuration, setSelectedDuration] = useState('All Durations');
|
||
const [selectedRating, setSelectedRating] = useState('All Ratings');
|
||
const [sortBy, setSortBy] = useState('Most Popular');
|
||
const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');
|
||
const [currentPage, setCurrentPage] = useState(1);
|
||
const coursesPerPage = 9;
|
||
|
||
// Cart functionality - using global cart context
|
||
const { addToCart } = useCart();
|
||
const [isCartPopupOpen, setIsCartPopupOpen] = useState(false);
|
||
const [recentlyAddedItem, setRecentlyAddedItem] = useState<CartItem | null>(null);
|
||
|
||
// Get unique values for filters - Updated for Rupees
|
||
const categories = ['All Categories', ...courseCategories];
|
||
const levels = ['All Levels', ...Array.from(new Set(featuredCourses.map(course => course.level)))];
|
||
const formats = ['All Formats', ...Array.from(new Set(featuredCourses.map(course => course.format)))];
|
||
const priceRanges = ['All Prices', 'Under ₹20,000', '₹20,000 - ₹35,000', '₹35,000 - ₹50,000', 'Over ₹50,000'];
|
||
const durations = ['All Durations', 'Under 6 hours', '6-10 hours', '10-15 hours', 'Over 15 hours'];
|
||
const ratings = ['All Ratings', '4.5+ Stars', '4.0+ Stars', '3.5+ Stars'];
|
||
|
||
const sortOptions = [
|
||
{ value: 'Most Popular', label: 'Most Popular' },
|
||
{ value: 'newest', label: 'Newest First' },
|
||
{ value: 'title', label: 'Title A-Z' },
|
||
{ value: 'price_low', label: 'Price: Low to High' },
|
||
{ value: 'price_high', label: 'Price: High to Low' },
|
||
{ value: 'rating', label: 'Highest Rated' },
|
||
{ value: 'duration', label: 'Duration' }
|
||
];
|
||
|
||
// Helper function to parse rupee price
|
||
const parseRupeePrice = (priceStr: string) => {
|
||
return parseFloat(priceStr.replace('₹', '').replace(/,/g, ''));
|
||
};
|
||
|
||
// Filter and sort courses
|
||
const filteredCourses = featuredCourses.filter(course => {
|
||
const matchesSearch = course.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||
course.description.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||
course.category.toLowerCase().includes(searchTerm.toLowerCase());
|
||
|
||
const matchesCategory = selectedCategory === 'All Categories' || course.category === selectedCategory;
|
||
const matchesLevel = selectedLevel === 'All Levels' || course.level === selectedLevel;
|
||
const matchesFormat = selectedFormat === 'All Formats' || course.format === selectedFormat;
|
||
|
||
// Price filter - Updated for Rupees
|
||
const price = parseRupeePrice(course.price);
|
||
const matchesPrice = selectedPriceRange === 'All Prices' ||
|
||
(selectedPriceRange === 'Under ₹20,000' && price < 20000) ||
|
||
(selectedPriceRange === '₹20,000 - ₹35,000' && price >= 20000 && price <= 35000) ||
|
||
(selectedPriceRange === '₹35,000 - ₹50,000' && price >= 35000 && price <= 50000) ||
|
||
(selectedPriceRange === 'Over ₹50,000' && price > 50000);
|
||
|
||
// Duration filter
|
||
const durationHours = parseInt(course.duration);
|
||
const matchesDuration = selectedDuration === 'All Durations' ||
|
||
(selectedDuration === 'Under 6 hours' && durationHours < 6) ||
|
||
(selectedDuration === '6-10 hours' && durationHours >= 6 && durationHours <= 10) ||
|
||
(selectedDuration === '10-15 hours' && durationHours >= 10 && durationHours <= 15) ||
|
||
(selectedDuration === 'Over 15 hours' && durationHours > 15);
|
||
|
||
// Rating filter
|
||
const matchesRating = selectedRating === 'All Ratings' ||
|
||
(selectedRating === '4.5+ Stars' && course.rating >= 4.5) ||
|
||
(selectedRating === '4.0+ Stars' && course.rating >= 4.0) ||
|
||
(selectedRating === '3.5+ Stars' && course.rating >= 3.5);
|
||
|
||
return matchesSearch && matchesCategory && matchesLevel && matchesFormat && matchesPrice && matchesDuration && matchesRating;
|
||
}).sort((a, b) => {
|
||
switch (sortBy) {
|
||
case 'Most Popular':
|
||
return parseInt(b.participants.replace(/[^\d]/g, '')) - parseInt(a.participants.replace(/[^\d]/g, ''));
|
||
case 'newest':
|
||
return a.id.localeCompare(b.id); // Assuming newer courses have higher IDs
|
||
case 'title':
|
||
return a.title.localeCompare(b.title);
|
||
case 'price_low':
|
||
return parseRupeePrice(a.price) - parseRupeePrice(b.price);
|
||
case 'price_high':
|
||
return parseRupeePrice(b.price) - parseRupeePrice(a.price);
|
||
case 'rating':
|
||
return b.rating - a.rating;
|
||
case 'duration':
|
||
return parseInt(a.duration) - parseInt(b.duration);
|
||
default:
|
||
return 0;
|
||
}
|
||
});
|
||
|
||
// Paginate results
|
||
const totalPages = Math.ceil(filteredCourses.length / coursesPerPage);
|
||
const startIndex = (currentPage - 1) * coursesPerPage;
|
||
const currentCourses = filteredCourses.slice(startIndex, startIndex + coursesPerPage);
|
||
|
||
const clearAllFilters = () => {
|
||
setSearchTerm('');
|
||
setSelectedCategory('All Categories');
|
||
setSelectedLevel('All Levels');
|
||
setSelectedFormat('All Formats');
|
||
setSelectedPriceRange('All Prices');
|
||
setSelectedDuration('All Durations');
|
||
setSelectedRating('All Ratings');
|
||
setSortBy('Most Popular');
|
||
};
|
||
|
||
const hasActiveFilters = searchTerm ||
|
||
selectedCategory !== 'All Categories' ||
|
||
selectedLevel !== 'All Levels' ||
|
||
selectedFormat !== 'All Formats' ||
|
||
selectedPriceRange !== 'All Prices' ||
|
||
selectedDuration !== 'All Durations' ||
|
||
selectedRating !== 'All Ratings';
|
||
|
||
// Cart functions - using global cart context
|
||
const handleAddToCart = (item: CartItem) => {
|
||
addToCart(item);
|
||
setRecentlyAddedItem(item);
|
||
setIsCartPopupOpen(true);
|
||
};
|
||
|
||
const handleCloseCartPopup = () => {
|
||
setIsCartPopupOpen(false);
|
||
setRecentlyAddedItem(null);
|
||
};
|
||
|
||
return (
|
||
<div style={{ backgroundColor: '#FFFFFF' }}>
|
||
{/* Hero Banner – Digital Learning - Blog Style */}
|
||
<section className="relative min-h-[85vh] flex flex-col">
|
||
<div className="absolute inset-0 z-0">
|
||
<div
|
||
className="w-full h-full bg-cover bg-center bg-no-repeat"
|
||
style={{
|
||
backgroundImage: 'url(https://images.unsplash.com/photo-1522202176988-66273c2fd55f?w=1200&h=600&fit=crop)',
|
||
}}
|
||
/>
|
||
<div className="absolute inset-0 bg-gradient-to-r from-black/85 via-black/75 to-black/65"></div>
|
||
</div>
|
||
|
||
<div className="relative z-10 flex-1 flex items-center">
|
||
<div className="w-full section-margin-x">
|
||
<div className="max-w-6xl">
|
||
{/* Back Navigation */}
|
||
<div className="mb-8">
|
||
<Button
|
||
variant="ghost"
|
||
onClick={() => navigateTo('/services')}
|
||
className="text-white hover:text-white hover:bg-white/10 p-2 -ml-2"
|
||
>
|
||
<ArrowLeft className="w-4 h-4 mr-2" />
|
||
Back to Services
|
||
</Button>
|
||
</div>
|
||
|
||
<div className="mb-8">
|
||
<h1 className="text-h1-white">
|
||
Grow as a Leader, Anytime
|
||
</h1>
|
||
</div>
|
||
|
||
<p className="text-body-lg-white mb-8 max-w-3xl">
|
||
<strong>
|
||
Our Leadership Courses are designed to build your leadership abilities through targeted, structured packages. Each course increases self-awareness of your leadership style and provides practical insights to strengthen your skills. Courses feature curated content focused on specific abilities, including our proprietary Leadership Profilers, conceptual videos, leader webcasts, and supplemental resources.
|
||
</strong>
|
||
</p>
|
||
|
||
<div className="flex justify-start">
|
||
<PrimaryCTAButton
|
||
text="Talk to Us"
|
||
onClick={() => navigateTo('/contact?topic=management-development')}
|
||
ariaLabel="Talk to us about management development"
|
||
className="primary-cta-button-blue cta-text-white"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Search and Controls Section */}
|
||
<section className="py-8" style={{ backgroundColor: '#FFFFFF' }}>
|
||
<div className="section-margin-x">
|
||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-6">
|
||
{/* Search Bar */}
|
||
<div className="relative max-w-md flex-1">
|
||
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" />
|
||
<Input
|
||
type="text"
|
||
placeholder="Search courses, topics, categories..."
|
||
value={searchTerm}
|
||
onChange={(e) => setSearchTerm(e.target.value)}
|
||
className="pl-10 pr-4 py-3 text-body rounded-lg border border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 transition-all duration-200 w-full bg-gray-50"
|
||
style={{
|
||
fontSize: 'var(--font-body)',
|
||
fontFamily: 'var(--font-family-base)',
|
||
height: '48px'
|
||
}}
|
||
/>
|
||
</div>
|
||
|
||
{/* View Toggle and Sort */}
|
||
<div className="flex items-center gap-4">
|
||
<div className="flex items-center border border-gray-300 rounded-lg overflow-hidden">
|
||
<button
|
||
onClick={() => setViewMode('grid')}
|
||
className={`p-2 transition-colors ${viewMode === 'grid'
|
||
? 'text-white'
|
||
: 'bg-white text-gray-600 hover:bg-gray-50'
|
||
}`}
|
||
style={{
|
||
backgroundColor: viewMode === 'grid' ? 'var(--color-primary)' : undefined
|
||
}}
|
||
aria-label="Grid view"
|
||
>
|
||
<Grid className="w-4 h-4" />
|
||
</button>
|
||
<button
|
||
onClick={() => setViewMode('list')}
|
||
className={`p-2 transition-colors ${viewMode === 'list'
|
||
? 'text-white'
|
||
: 'bg-white text-gray-600 hover:bg-gray-50'
|
||
}`}
|
||
style={{
|
||
backgroundColor: viewMode === 'list' ? 'var(--color-primary)' : undefined
|
||
}}
|
||
aria-label="List view"
|
||
>
|
||
<List className="w-4 h-4" />
|
||
</button>
|
||
</div>
|
||
|
||
<Select value={sortBy} onValueChange={setSortBy}>
|
||
<SelectTrigger className="w-40 text-body">
|
||
<SelectValue placeholder="Sort by" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
{sortOptions.map((option) => (
|
||
<SelectItem key={option.value} value={option.value}>
|
||
{option.label}
|
||
</SelectItem>
|
||
))}
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Main Content Section with Sidebar */}
|
||
<section className="pb-16" style={{ backgroundColor: '#FFFFFF' }}>
|
||
<div className="section-margin-x">
|
||
<div className="grid grid-cols-12 gap-8">
|
||
{/* Left Sidebar - Sticky Filters */}
|
||
<div className="col-span-12 lg:col-span-3">
|
||
<div className="sticky top-4">
|
||
<Card className="bg-white border border-gray-200 rounded-lg shadow-md overflow-hidden">
|
||
{/* Filter Header */}
|
||
<div className="bg-gray-50 px-4 py-3 border-b border-gray-200">
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-center gap-2">
|
||
<div className="p-1.5 rounded-md" style={{ backgroundColor: 'rgba(4, 4, 91, 0.1)' }}>
|
||
<Filter className="w-3.5 h-3.5" style={{ color: 'var(--color-primary)' }} />
|
||
</div>
|
||
<h3 className="text-body font-semibold text-gray-800">
|
||
Filters
|
||
</h3>
|
||
</div>
|
||
{hasActiveFilters && (
|
||
<Button
|
||
variant="ghost"
|
||
size="sm"
|
||
onClick={clearAllFilters}
|
||
className="text-xs px-2 py-1 rounded-md transition-colors filter-clear-btn"
|
||
>
|
||
<X className="w-3 h-3 mr-1" />
|
||
Clear
|
||
</Button>
|
||
)}
|
||
</div>
|
||
</div>
|
||
|
||
{/* Filter Content */}
|
||
<div className="p-4">
|
||
<div className="space-y-4">
|
||
{/* Category Filter */}
|
||
<div className="filter-section">
|
||
<label className="block text-small mb-2 font-medium text-gray-700">
|
||
Category
|
||
</label>
|
||
<Select value={selectedCategory} onValueChange={setSelectedCategory}>
|
||
<SelectTrigger className="w-full text-small h-9 border-gray-300 hover:border-gray-400 transition-colors">
|
||
<SelectValue placeholder="All Categories" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
{categories.map((category) => (
|
||
<SelectItem key={category} value={category} className="text-small">
|
||
{category}
|
||
</SelectItem>
|
||
))}
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
|
||
{/* Level Filter */}
|
||
<div className="filter-section">
|
||
<label className="block text-small mb-2 font-medium text-gray-700">
|
||
Level
|
||
</label>
|
||
<Select value={selectedLevel} onValueChange={setSelectedLevel}>
|
||
<SelectTrigger className="w-full text-small h-9 border-gray-300 hover:border-gray-400 transition-colors">
|
||
<SelectValue placeholder="All Levels" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
{levels.map((level) => (
|
||
<SelectItem key={level} value={level} className="text-small">
|
||
{level}
|
||
</SelectItem>
|
||
))}
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
|
||
{/* Format Filter */}
|
||
<div className="filter-section">
|
||
<label className="block text-small mb-2 font-medium text-gray-700">
|
||
Format
|
||
</label>
|
||
<Select value={selectedFormat} onValueChange={setSelectedFormat}>
|
||
<SelectTrigger className="w-full text-small h-9 border-gray-300 hover:border-gray-400 transition-colors">
|
||
<SelectValue placeholder="All Formats" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
{formats.map((format) => (
|
||
<SelectItem key={format} value={format} className="text-small">
|
||
{format}
|
||
</SelectItem>
|
||
))}
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
|
||
{/* Price Range Filter */}
|
||
<div className="filter-section">
|
||
<label className="block text-small mb-2 font-medium text-gray-700">
|
||
Price Range
|
||
</label>
|
||
<Select value={selectedPriceRange} onValueChange={setSelectedPriceRange}>
|
||
<SelectTrigger className="w-full text-small h-9 border-gray-300 hover:border-gray-400 transition-colors">
|
||
<SelectValue placeholder="All Prices" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
{priceRanges.map((priceRange) => (
|
||
<SelectItem key={priceRange} value={priceRange} className="text-small">
|
||
{priceRange}
|
||
</SelectItem>
|
||
))}
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
|
||
{/* Duration Filter */}
|
||
<div className="filter-section">
|
||
<label className="block text-small mb-2 font-medium text-gray-700">
|
||
Duration
|
||
</label>
|
||
<Select value={selectedDuration} onValueChange={setSelectedDuration}>
|
||
<SelectTrigger className="w-full text-small h-9 border-gray-300 hover:border-gray-400 transition-colors">
|
||
<SelectValue placeholder="All Durations" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
{durations.map((duration) => (
|
||
<SelectItem key={duration} value={duration} className="text-small">
|
||
{duration}
|
||
</SelectItem>
|
||
))}
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
|
||
{/* Rating Filter */}
|
||
<div className="filter-section">
|
||
<label className="block text-small mb-2 font-medium text-gray-700">
|
||
Rating
|
||
</label>
|
||
<Select value={selectedRating} onValueChange={setSelectedRating}>
|
||
<SelectTrigger className="w-full text-small h-9 border-gray-300 hover:border-gray-400 transition-colors">
|
||
<SelectValue placeholder="All Ratings" />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
{ratings.map((rating) => (
|
||
<SelectItem key={rating} value={rating} className="text-small">
|
||
{rating}
|
||
</SelectItem>
|
||
))}
|
||
</SelectContent>
|
||
</Select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</Card>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Right Content Area - Scrollable Courses */}
|
||
<div className="col-span-12 lg:col-span-9">
|
||
<div className="mb-4 text-small text-muted">
|
||
Showing {currentCourses.length} of {filteredCourses.length} courses
|
||
</div>
|
||
|
||
{/* Courses Results */}
|
||
{currentCourses.length === 0 ? (
|
||
<div className="text-center py-12">
|
||
<p className="text-body-lg text-muted">
|
||
No courses found matching your criteria.
|
||
</p>
|
||
</div>
|
||
) : (
|
||
<>
|
||
{/* Grid View */}
|
||
{viewMode === 'grid' && (
|
||
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-2 gap-6">
|
||
{currentCourses.map((course) => (
|
||
<div key={course.id} className="w-full">
|
||
<CourseCard
|
||
course={course}
|
||
className="h-[600px] flex flex-col w-full"
|
||
onAddToCart={handleAddToCart}
|
||
/>
|
||
</div>
|
||
))}
|
||
</div>
|
||
)}
|
||
|
||
{/* List View */}
|
||
{viewMode === 'list' && (
|
||
<div className="space-y-4">
|
||
{currentCourses.map((course) => (
|
||
<Card
|
||
key={course.id}
|
||
className="overflow-hidden hover:shadow-lg transition-all duration-300 cursor-pointer group"
|
||
onClick={() => navigateTo(`/course/${course.id}`)}
|
||
>
|
||
<div className="flex flex-col md:flex-row">
|
||
<div className="md:w-80 flex-shrink-0">
|
||
<div className="aspect-video md:aspect-square w-full bg-gray-100 overflow-hidden relative">
|
||
<ImageWithFallback
|
||
src={course.thumbnail}
|
||
alt={course.title}
|
||
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
|
||
/>
|
||
<div className="absolute top-4 left-4">
|
||
<Badge
|
||
variant="secondary"
|
||
className="px-3 py-1 font-medium"
|
||
style={{
|
||
backgroundColor: 'rgba(248, 195, 1, 0.95)',
|
||
color: 'var(--color-black)',
|
||
fontSize: 'var(--font-small)',
|
||
fontFamily: 'var(--font-family-base)',
|
||
backdropFilter: 'blur(4px)'
|
||
}}
|
||
>
|
||
{course.category}
|
||
</Badge>
|
||
</div>
|
||
<div className="absolute top-4 right-4">
|
||
<Badge
|
||
variant="outline"
|
||
className="px-3 py-1 font-medium bg-white/90 backdrop-blur-sm"
|
||
style={{
|
||
fontSize: 'var(--font-small)',
|
||
fontFamily: 'var(--font-family-base)',
|
||
borderColor: 'var(--color-primary)',
|
||
color: 'var(--color-primary)'
|
||
}}
|
||
>
|
||
{course.level}
|
||
</Badge>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<CardContent className="p-6 flex-1">
|
||
<div className="flex flex-col h-full">
|
||
<h3
|
||
className="mb-3 group-hover:text-blue-600 transition-colors leading-snug"
|
||
style={{
|
||
fontSize: 'var(--font-h4)',
|
||
fontWeight: 'var(--font-weight-h4)',
|
||
lineHeight: '1.3',
|
||
color: 'var(--color-black)',
|
||
fontFamily: 'var(--font-family-base)'
|
||
}}
|
||
>
|
||
{course.title}
|
||
</h3>
|
||
|
||
<p
|
||
className="mb-4 flex-1 leading-relaxed"
|
||
style={{
|
||
fontSize: 'var(--font-body)',
|
||
lineHeight: '1.6',
|
||
color: 'var(--color-gray-muted)',
|
||
fontFamily: 'var(--font-family-base)'
|
||
}}
|
||
>
|
||
{course.description}
|
||
</p>
|
||
|
||
<div className="flex items-center justify-between mb-4 pt-4 border-t border-gray-100">
|
||
<div className="flex items-center gap-6">
|
||
<div className="flex items-center gap-2">
|
||
<Clock className="w-4 h-4 text-gray-400" />
|
||
<span style={{
|
||
fontSize: 'var(--font-small)',
|
||
fontFamily: 'var(--font-family-base)',
|
||
color: 'var(--color-gray-muted)',
|
||
fontWeight: '500'
|
||
}}>
|
||
{course.duration}
|
||
</span>
|
||
</div>
|
||
<div className="flex items-center gap-2">
|
||
<Users className="w-4 h-4 text-gray-400" />
|
||
<span style={{
|
||
fontSize: 'var(--font-small)',
|
||
fontFamily: 'var(--font-family-base)',
|
||
color: 'var(--color-gray-muted)',
|
||
fontWeight: '500'
|
||
}}>
|
||
{course.participants}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex items-center gap-1">
|
||
<Star className="w-4 h-4 fill-current text-yellow-400" />
|
||
<span
|
||
className="font-semibold"
|
||
style={{
|
||
fontSize: 'var(--font-small)',
|
||
fontFamily: 'var(--font-family-base)',
|
||
color: 'var(--color-black)'
|
||
}}
|
||
>
|
||
{course.rating}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex items-center justify-between">
|
||
<div className="flex items-baseline gap-3">
|
||
<span
|
||
className="font-bold"
|
||
style={{
|
||
fontSize: '1.5rem',
|
||
fontFamily: 'var(--font-family-base)',
|
||
color: '#04045B'
|
||
}}
|
||
>
|
||
{course.price}
|
||
</span>
|
||
{course.originalPrice && (
|
||
<span
|
||
className="line-through"
|
||
style={{
|
||
fontSize: 'var(--font-body)',
|
||
fontFamily: 'var(--font-family-base)',
|
||
color: 'var(--color-gray-muted)'
|
||
}}
|
||
>
|
||
{course.originalPrice}
|
||
</span>
|
||
)}
|
||
</div>
|
||
<Button
|
||
onClick={(e: React.MouseEvent) => {
|
||
e.stopPropagation();
|
||
const cartItem: CartItem = {
|
||
id: course.id,
|
||
title: course.title,
|
||
thumbnail: course.thumbnail,
|
||
price: course.price,
|
||
originalPrice: course.originalPrice,
|
||
category: course.category,
|
||
level: course.level
|
||
};
|
||
handleAddToCart(cartItem);
|
||
}}
|
||
variant="outline"
|
||
className="flex items-center gap-2"
|
||
style={{
|
||
borderColor: 'var(--color-primary)',
|
||
color: 'var(--color-primary)'
|
||
}}
|
||
>
|
||
<ShoppingCart className="w-4 h-4" />
|
||
Add to Cart
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</div>
|
||
</Card>
|
||
))}
|
||
</div>
|
||
)}
|
||
|
||
{/* Pagination */}
|
||
{totalPages > 1 && (
|
||
<div className="flex justify-center items-center gap-2 mt-8">
|
||
<Button
|
||
variant="outline"
|
||
size="sm"
|
||
onClick={() => setCurrentPage(Math.max(1, currentPage - 1))}
|
||
disabled={currentPage === 1}
|
||
>
|
||
<ChevronLeft className="w-4 h-4" />
|
||
</Button>
|
||
|
||
<div className="flex gap-2">
|
||
{Array.from({ length: totalPages }, (_, i) => i + 1).map((page) => (
|
||
<Button
|
||
key={page}
|
||
variant={currentPage === page ? "default" : "outline"}
|
||
size="sm"
|
||
onClick={() => setCurrentPage(page)}
|
||
className="w-8 h-8 p-0"
|
||
>
|
||
{page}
|
||
</Button>
|
||
))}
|
||
</div>
|
||
|
||
<Button
|
||
variant="outline"
|
||
size="sm"
|
||
onClick={() => setCurrentPage(Math.min(totalPages, currentPage + 1))}
|
||
disabled={currentPage === totalPages}
|
||
>
|
||
<ChevronRight className="w-4 h-4" />
|
||
</Button>
|
||
</div>
|
||
)}
|
||
</>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Cart Popup */}
|
||
<CartPopup
|
||
isOpen={isCartPopupOpen}
|
||
onClose={handleCloseCartPopup}
|
||
cartItems={[]} // Not used anymore as CartPopup will get items from context
|
||
onRemoveItem={() => { }} // Not used anymore
|
||
recentlyAddedItem={recentlyAddedItem}
|
||
/>
|
||
|
||
{/* Our Approach Section - Standard Design Pattern */}
|
||
<section className="py-20" style={{ backgroundColor: '#FFFFFF' }}>
|
||
<div className="section-margin-x">
|
||
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12 items-start max-w-7xl mx-auto">
|
||
|
||
{/* Left Side - Title & Description */}
|
||
<div className="lg:col-span-5 lg:pr-8">
|
||
<BrandedTag text="OUR APPROACH" />
|
||
|
||
<h2 className="text-h2 mb-6 leading-tight">
|
||
Orientation-Based <span className="text-primary">Learning</span>
|
||
</h2>
|
||
|
||
<p className="text-body-lg text-muted leading-relaxed mb-8">
|
||
Our unique methodology focuses on understanding your natural leadership orientation and building skills that align with your authentic style while expanding your capabilities across all dimensions.
|
||
</p>
|
||
|
||
{/* Key Stats */}
|
||
<div className="grid grid-cols-2 gap-6 mb-8">
|
||
<div className="text-center p-4 bg-gray-50 rounded-lg border">
|
||
<div className="text-3xl font-bold text-primary mb-1">95%</div>
|
||
<div className="text-small text-muted">Leader Effectiveness</div>
|
||
</div>
|
||
<div className="text-center p-4 bg-gray-50 rounded-lg border">
|
||
<div className="text-3xl font-bold text-primary mb-1">20+</div>
|
||
<div className="text-small text-muted">Years Research</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Primary CTA Button */}
|
||
<div className="flex justify-start">
|
||
<PrimaryCTAButton
|
||
text="Start Free Assessment"
|
||
onClick={() => navigateTo('/assessment')}
|
||
icon={Target}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Right Side - Methodology Points */}
|
||
<div className="lg:col-span-7">
|
||
<div className="space-y-8">
|
||
{methodologyPoints.map((point, index) => {
|
||
const IconComponent = point.icon;
|
||
return (
|
||
<div key={point.title} className="group">
|
||
<Card className="border-0 shadow-sm hover:shadow-lg transition-all duration-300 bg-white p-0">
|
||
<CardContent className="p-6">
|
||
<div className="flex items-start gap-4">
|
||
<div
|
||
className="w-14 h-14 rounded-xl flex items-center justify-center flex-shrink-0 group-hover:scale-110 transition-transform duration-300"
|
||
style={{ backgroundColor: 'var(--color-primary)' }}
|
||
>
|
||
<IconComponent className="w-7 h-7 text-white" />
|
||
</div>
|
||
|
||
<div className="flex-1">
|
||
<h4 className="text-h4 mb-3 text-black leading-tight">
|
||
{point.title}
|
||
</h4>
|
||
|
||
<p className="text-body text-muted leading-relaxed">
|
||
{point.description}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</CardContent>
|
||
</Card>
|
||
</div>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Corporate Solutions CTA */}
|
||
{/* CTA Banner Section - Enterprise Solutions */}
|
||
<section className="py-20 relative overflow-hidden" style={{ backgroundColor: '#FFFFFF' }}>
|
||
<div className="section-margin-x">
|
||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 items-center max-w-7xl mx-auto">
|
||
|
||
{/* Left Column - CTA Content */}
|
||
<motion.div
|
||
initial={{ opacity: 0, x: -30 }}
|
||
whileInView={{ opacity: 1, x: 0 }}
|
||
transition={{ duration: 0.8 }}
|
||
viewport={{ once: true }}
|
||
className="order-2 lg:order-1"
|
||
>
|
||
<BrandedTag text="TRANSFORM YOUR ORGANIZATION" />
|
||
|
||
<h2 className="text-h2 mb-6 leading-tight">
|
||
Scale Leadership Excellence Across Your <span className="text-primary">Enterprise</span>
|
||
</h2>
|
||
|
||
<p className="text-body-lg text-muted leading-relaxed mb-8">
|
||
Empower your leadership pipeline with our comprehensive online learning platform. Drive measurable results with scalable solutions designed for modern organizations.
|
||
</p>
|
||
|
||
{/* Key Benefits */}
|
||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4 mb-10">
|
||
{[
|
||
{ icon: Building2, text: 'Enterprise-grade platform' },
|
||
{ icon: TrendingUp, text: 'Real-time analytics & ROI' },
|
||
{ icon: Users, text: 'Custom learning cohorts' },
|
||
{ icon: Globe, text: 'Global deployment ready' }
|
||
].map((benefit, index) => {
|
||
const IconComponent = benefit.icon;
|
||
return (
|
||
<motion.div
|
||
key={benefit.text}
|
||
className="flex items-center gap-3"
|
||
initial={{ opacity: 0, y: 10 }}
|
||
whileInView={{ opacity: 1, y: 0 }}
|
||
transition={{ duration: 0.5, delay: index * 0.1 }}
|
||
viewport={{ once: true }}
|
||
>
|
||
<div className="w-8 h-8 rounded-full bg-primary/10 flex items-center justify-center">
|
||
<IconComponent className="w-4 h-4 text-primary" />
|
||
</div>
|
||
<span className="text-body text-black font-medium">
|
||
{benefit.text}
|
||
</span>
|
||
</motion.div>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
{/* Social Proof Stats */}
|
||
<div className="flex flex-wrap gap-6 mb-8 p-6 bg-gray-50 rounded-lg border">
|
||
<div className="flex items-center gap-2">
|
||
<div className="text-2xl font-bold text-primary">500+</div>
|
||
<div className="text-small text-muted">Companies</div>
|
||
</div>
|
||
<div className="flex items-center gap-2">
|
||
<div className="text-2xl font-bold text-primary">10K+</div>
|
||
<div className="text-small text-muted">Leaders</div>
|
||
</div>
|
||
<div className="flex items-center gap-2">
|
||
<div className="text-2xl font-bold text-primary">92%</div>
|
||
<div className="text-small text-muted">Completion</div>
|
||
</div>
|
||
<div className="flex items-center gap-2">
|
||
<div className="text-2xl font-bold text-primary">4.8★</div>
|
||
<div className="text-small text-muted">Rating</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* CTA Button */}
|
||
<div className="flex justify-start">
|
||
<PrimaryCTAButton
|
||
text="Schedule Enterprise Demo"
|
||
onClick={() => navigateTo('/contact?topic=corporate-learning')}
|
||
icon={Calendar}
|
||
ariaLabel="Schedule an enterprise demo with our team"
|
||
/>
|
||
</div>
|
||
</motion.div>
|
||
|
||
{/* Right Column - Hero Image */}
|
||
<motion.div
|
||
className="order-1 lg:order-2 relative"
|
||
initial={{ opacity: 0, x: 30 }}
|
||
whileInView={{ opacity: 1, x: 0 }}
|
||
transition={{ duration: 0.8 }}
|
||
viewport={{ once: true }}
|
||
>
|
||
<div className="relative rounded-2xl overflow-hidden shadow-2xl">
|
||
<ImageWithFallback
|
||
src="https://images.unsplash.com/photo-1603201667141-5a2d4c673378?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxlbnRlcnByaXNlJTIwdHJhaW5pbmclMjB0ZWFtJTIwbWVldGluZ3xlbnwxfHx8fDE3NTU3NTg2Mzl8MA&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral"
|
||
alt="Enterprise team in leadership training session"
|
||
className="w-full h-[480px] object-cover"
|
||
/>
|
||
|
||
{/* Overlay with gradient */}
|
||
<div className="absolute inset-0 bg-gradient-to-tr from-primary/20 to-transparent"></div>
|
||
|
||
{/* Floating Badge */}
|
||
<div className="absolute top-6 left-6 bg-white/95 backdrop-blur-sm rounded-lg px-4 py-2 shadow-lg">
|
||
<div className="flex items-center gap-2">
|
||
<div className="w-2 h-2 bg-green-500 rounded-full animate-pulse"></div>
|
||
<span className="text-small font-medium text-black">Live Training Session</span>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Bottom Achievement Badge */}
|
||
<div className="absolute bottom-6 right-6 bg-white/95 backdrop-blur-sm rounded-lg px-4 py-3 shadow-lg">
|
||
<div className="text-center">
|
||
<div className="text-lg font-bold text-primary">95%</div>
|
||
<div className="text-small text-muted">Engagement Rate</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</motion.div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<style>{`
|
||
.scrollbar-hide {
|
||
-ms-overflow-style: none;
|
||
scrollbar-width: none;
|
||
}
|
||
.scrollbar-hide::-webkit-scrollbar {
|
||
display: none;
|
||
}
|
||
`}</style>
|
||
{/* Individual Learning CTA Banner Section - Landing Page Style */}
|
||
<section className="relative h-[700px] overflow-hidden">
|
||
{/* Background Image */}
|
||
<div className="absolute inset-0">
|
||
<ImageWithFallback
|
||
src="https://images.unsplash.com/photo-1673515335586-f9f662c01482?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxvbmxpbmUlMjBsZWFybmluZyUyMGluZGl2aWR1YWwlMjBzdHVkeSUyMGxhcHRvcHxlbnwxfHx8fDE3NTU3NTg5MzN8MA&ixlib=rb-4.1.0&q=80&w=1080&utm_source=figma&utm_medium=referral"
|
||
alt="Individual online learning with laptop and study materials"
|
||
className="w-full h-full object-cover"
|
||
/>
|
||
|
||
{/* Subtle dark overlay for overall image */}
|
||
<div className="absolute inset-0 bg-black/30" />
|
||
|
||
{/* Gradient overlay for better text readability */}
|
||
<div className="absolute inset-0 bg-gradient-to-r from-black/20 via-transparent to-black/60" />
|
||
</div>
|
||
|
||
{/* Content Container */}
|
||
<div className="relative h-full flex items-center justify-end section-margin-x">
|
||
{/* CTA Content Block */}
|
||
<div
|
||
className="bg-opacity-95 backdrop-blur-sm rounded-lg p-16 max-w-2xl"
|
||
style={{
|
||
backgroundColor: 'var(--color-brand-primary)'
|
||
}}
|
||
>
|
||
{/* Branded Tag */}
|
||
<BrandedTag text="NEXT STEPS" variant="white" />
|
||
|
||
{/* Main Headline */}
|
||
<h2
|
||
className="text-h2-white mb-8"
|
||
>
|
||
Ready to transform your
|
||
<span
|
||
className="italic"
|
||
style={{ color: 'var(--color-brand-accent)' }}
|
||
>
|
||
{" "}leadership?{" "}
|
||
</span>
|
||
</h2>
|
||
|
||
{/* CTA Button - Yellow variant for online courses */}
|
||
<PrimaryCTAButton
|
||
text="Start Free Assessment"
|
||
onClick={() => navigateTo('/assessment')}
|
||
ariaLabel="Start your free leadership assessment"
|
||
className="cta-banner-yellow"
|
||
icon={Target}
|
||
/>
|
||
|
||
{/* Supporting Text */}
|
||
<p
|
||
className="text-body-white mt-6 opacity-90"
|
||
>
|
||
Connect with our leadership experts to discuss your organization's specific development needs.
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
</div>
|
||
);
|
||
} |