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

883 lines
37 KiB
TypeScript
Raw Normal View History

2025-08-28 13:14:51 +05:30
import React, { useState, useRef, useEffect } from 'react';
import { Button } from './ui/button';
import { Card, CardContent } from './ui/card';
import { Badge } from './ui/badge';
import { Input } from './ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select';
import { ImageWithFallback } from './figma/ImageWithFallback';
import { PrimaryCTAButton } from './PrimaryCTAButton';
import { navigateTo } from './Router';
import {
Search,
Calendar,
Clock,
Users,
Play,
Filter,
Grid,
List,
ChevronLeft,
ChevronRight,
X,
TrendingUp,
Award,
Globe
} from 'lucide-react';
// Comprehensive webinar data
const webinarsData = [
{
id: '1',
slug: 'leadership-in-digital-age',
title: 'Leadership in the Digital Age: Navigating Change and Innovation',
description: 'Discover how modern leaders can adapt and thrive in an increasingly digital world. This comprehensive webcast covers digital transformation strategies, leading remote teams, and fostering innovation.',
presenter: 'Dr. Sarah Mitchell',
presenterTitle: 'Chief Digital Transformation Officer',
company: 'Global Leadership Institute',
date: '2024-02-15',
time: '2:00 PM EST',
duration: '90 minutes',
attendees: '2,400+',
category: 'Digital Transformation',
tags: ['Leadership', 'Digital Strategy', 'Innovation', 'Change Management'],
thumbnail: 'https://images.unsplash.com/photo-1560472355-536de3962603?w=600&h=400&fit=crop',
status: 'Available',
featured: true,
level: 'Advanced',
format: 'Hybrid',
rating: 4.8,
price: 'Free'
},
{
id: '2',
slug: 'building-resilient-teams',
title: 'Building Resilient Teams: Strategies for Sustainable Performance',
description: 'Learn proven methodologies for creating teams that can withstand challenges and maintain high performance under pressure.',
presenter: 'Marcus Rodriguez',
presenterTitle: 'Director of Organizational Development',
company: 'Excellence Consulting',
date: '2024-02-08',
time: '1:00 PM EST',
duration: '75 minutes',
attendees: '1,850+',
category: 'Team Development',
tags: ['Team Building', 'Resilience', 'Performance', 'Leadership'],
thumbnail: 'https://images.unsplash.com/photo-1522071820081-009f0129c71c?w=600&h=400&fit=crop',
status: 'Available',
featured: true,
level: 'Intermediate',
format: 'In Person',
rating: 4.9,
price: 'Free'
},
{
id: '3',
slug: 'strategic-decision-making',
title: 'Strategic Decision Making: Tools and Frameworks for Leaders',
description: 'Master the art of strategic thinking and decision-making with proven frameworks and methodologies used by top executives.',
presenter: 'Dr. Emily Chen',
presenterTitle: 'Strategic Leadership Consultant',
company: 'Strategy First',
date: '2024-01-25',
time: '3:00 PM EST',
duration: '60 minutes',
attendees: '3,200+',
category: 'Strategy',
tags: ['Strategic Thinking', 'Decision Making', 'Leadership', 'Planning'],
thumbnail: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=600&h=400&fit=crop',
status: 'Available',
featured: false,
level: 'Advanced',
format: 'Virtual',
rating: 4.7,
price: 'Free'
},
{
id: '4',
slug: 'emotional-intelligence-workplace',
title: 'Emotional Intelligence in the Workplace: Leading with Empathy',
description: 'Explore the critical role of emotional intelligence in effective leadership and learn practical techniques for developing empathy and emotional awareness.',
presenter: 'Jennifer Adams',
presenterTitle: 'Executive Coach & EQ Specialist',
company: 'Empathy Leadership Group',
date: '2024-01-18',
time: '2:30 PM EST',
duration: '85 minutes',
attendees: '2,100+',
category: 'Personal Development',
tags: ['Emotional Intelligence', 'Empathy', 'Communication', 'Leadership'],
thumbnail: 'https://images.unsplash.com/photo-1559027615-cd4628902d4a?w=600&h=400&fit=crop',
status: 'Recorded',
featured: false,
level: 'Intermediate',
format: 'Hybrid',
rating: 4.6,
price: 'Free'
},
{
id: '5',
slug: 'crisis-leadership-management',
title: 'Crisis Leadership: Managing Through Uncertainty and Change',
description: 'Learn essential crisis leadership skills and strategies for guiding organizations through challenging times and uncertainty.',
presenter: 'David Park',
presenterTitle: 'Crisis Management Expert',
company: 'Risk Management Solutions',
date: '2024-01-10',
time: '1:30 PM EST',
duration: '70 minutes',
attendees: '2,800+',
category: 'Crisis Management',
tags: ['Crisis Leadership', 'Change Management', 'Communication', 'Strategy'],
thumbnail: 'https://images.unsplash.com/photo-1552664730-d307ca884978?w=600&h=400&fit=crop',
status: 'Live',
featured: false,
level: 'Advanced',
format: 'Virtual',
rating: 4.8,
price: 'Free'
},
{
id: '6',
slug: 'future-workplace-trends',
title: 'The Future of Work: Preparing for Tomorrow\'s Workplace',
description: 'Discover emerging workplace trends and learn how to prepare your organization and teams for the future of work.',
presenter: 'Lisa Thompson',
presenterTitle: 'Future of Work Analyst',
company: 'Tomorrow Institute',
date: '2024-01-05',
time: '4:00 PM EST',
duration: '80 minutes',
attendees: '1,950+',
category: 'Future of Work',
tags: ['Future Trends', 'Workplace Evolution', 'Technology', 'Leadership'],
thumbnail: 'https://images.unsplash.com/photo-1600880292203-757bb62b4baf?w=600&h=400&fit=crop',
status: 'Upcoming',
featured: false,
level: 'Beginner',
format: 'Hybrid',
rating: 4.5,
price: 'Free'
},
{
id: '7',
slug: 'ai-leadership-transformation',
title: 'AI-Powered Leadership: Transforming Decision Making',
description: 'Explore how artificial intelligence is reshaping leadership practices and learn to leverage AI tools for better decision-making.',
presenter: 'Dr. Alex Kim',
presenterTitle: 'AI Strategy Director',
company: 'AI Leadership Labs',
date: '2024-03-15',
time: '2:00 PM EST',
duration: '75 minutes',
attendees: '3,500+',
category: 'Technology Leadership',
tags: ['Artificial Intelligence', 'Decision Making', 'Technology', 'Innovation'],
thumbnail: 'https://images.unsplash.com/photo-1677442136019-21780ecad995?w=600&h=400&fit=crop',
status: 'Upcoming',
featured: true,
level: 'Advanced',
format: 'Virtual',
rating: 4.9,
price: 'Free'
},
{
id: '8',
slug: 'sustainable-leadership-live',
title: 'Sustainable Leadership: Building for the Future - LIVE SESSION',
description: 'Join us LIVE as we discuss sustainable leadership practices and environmental responsibility in business leadership.',
presenter: 'Maria Santos',
presenterTitle: 'Sustainability Leadership Expert',
company: 'Green Leadership Council',
date: '2024-02-20',
time: '1:00 PM EST',
duration: '90 minutes',
attendees: '2,200+',
category: 'Sustainable Leadership',
tags: ['Sustainability', 'Environmental Leadership', 'Future Business', 'Corporate Responsibility'],
thumbnail: 'https://images.unsplash.com/photo-1542601906990-b4d3fb778b09?w=600&h=400&fit=crop',
status: 'Live',
featured: true,
level: 'Intermediate',
format: 'Virtual',
rating: 4.7,
price: 'Free'
},
{
id: '9',
slug: 'cross-cultural-leadership',
title: 'Cross-Cultural Leadership: Leading Global Teams Effectively',
description: 'Develop the skills needed to lead diverse, multicultural teams across different time zones and cultural contexts.',
presenter: 'Dr. Raj Patel',
presenterTitle: 'Global Leadership Specialist',
company: 'International Business Academy',
date: '2024-02-25',
time: '11:00 AM EST',
duration: '65 minutes',
attendees: '1,750+',
category: 'Global Leadership',
tags: ['Cross-Cultural', 'Global Teams', 'Diversity', 'Communication'],
thumbnail: 'https://images.unsplash.com/photo-1573164713714-d95e436ab8d6?w=600&h=400&fit=crop',
status: 'Available',
featured: false,
level: 'Intermediate',
format: 'Virtual',
rating: 4.6,
price: 'Free'
}
];
// Filter configurations
const categories = ['All Categories', 'Digital Transformation', 'Team Development', 'Strategy', 'Personal Development', 'Crisis Management', 'Future of Work', 'Technology Leadership', 'Sustainable Leadership', 'Global Leadership'];
const formats = ['All Formats', 'Virtual', 'Hybrid', 'In Person'];
const levels = ['All Levels', 'Beginner', 'Intermediate', 'Advanced'];
const statuses = ['All Status', 'Available', 'Live', 'Upcoming', 'Recorded', 'Featured'];
const sortOptions = [
{ value: 'Most Popular', label: 'Most Popular' },
{ value: 'newest', label: 'Newest First' },
{ value: 'oldest', label: 'Oldest First' },
{ value: 'title', label: 'Title A-Z' },
{ value: 'duration', label: 'Duration' },
{ value: 'rating', label: 'Highest Rated' }
];
export function WebinarsPage() {
const [searchTerm, setSearchTerm] = useState('');
const [selectedCategory, setSelectedCategory] = useState('All Categories');
const [selectedFormat, setSelectedFormat] = useState('All Formats');
const [selectedLevel, setSelectedLevel] = useState('All Levels');
const [selectedStatus, setSelectedStatus] = useState('All Status');
const [sortBy, setSortBy] = useState('Most Popular');
const [viewType, setViewType] = useState<'grid' | 'list'>('grid');
const [currentPage, setCurrentPage] = useState(1);
const webinarsPerPage = 9;
const containerRef = useRef<HTMLDivElement>(null);
// Filter and sort webinars
const filteredWebinars = webinarsData.filter(webinar => {
const matchesSearch = webinar.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
webinar.description.toLowerCase().includes(searchTerm.toLowerCase()) ||
webinar.presenter.toLowerCase().includes(searchTerm.toLowerCase()) ||
webinar.tags.some(tag => tag.toLowerCase().includes(searchTerm.toLowerCase()));
const matchesCategory = selectedCategory === 'All Categories' || webinar.category === selectedCategory;
const matchesFormat = selectedFormat === 'All Formats' || webinar.format === selectedFormat;
const matchesLevel = selectedLevel === 'All Levels' || webinar.level === selectedLevel;
const matchesStatus = selectedStatus === 'All Status' ||
webinar.status === selectedStatus ||
(selectedStatus === 'Featured' && webinar.featured);
return matchesSearch && matchesCategory && matchesFormat && matchesLevel && matchesStatus;
}).sort((a, b) => {
switch (sortBy) {
case 'newest':
return new Date(b.date).getTime() - new Date(a.date).getTime();
case 'oldest':
return new Date(a.date).getTime() - new Date(b.date).getTime();
case 'title':
return a.title.localeCompare(b.title);
case 'duration':
return parseInt(b.duration) - parseInt(a.duration);
case 'rating':
return b.rating - a.rating;
default:
return 0;
}
});
// Statistics
const stats = {
total: webinarsData.length,
available: webinarsData.filter(w => w.status === 'Available').length,
live: webinarsData.filter(w => w.status === 'Live').length,
upcoming: webinarsData.filter(w => w.status === 'Upcoming').length,
recorded: webinarsData.filter(w => w.status === 'Recorded').length,
featured: webinarsData.filter(w => w.featured).length,
avgRating: (webinarsData.reduce((sum, w) => sum + w.rating, 0) / webinarsData.length).toFixed(1)
};
// Paginate results
const totalPages = Math.ceil(filteredWebinars.length / webinarsPerPage);
const currentWebinars = filteredWebinars.slice((currentPage - 1) * webinarsPerPage, currentPage * webinarsPerPage);
const formatDate = (dateString: string) => {
return new Date(dateString).toLocaleDateString('en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
};
const clearAllFilters = () => {
setSearchTerm('');
setSelectedCategory('All Categories');
setSelectedFormat('All Formats');
setSelectedLevel('All Levels');
setSelectedStatus('All Status');
setSortBy('Most Popular');
};
const hasActiveFilters = searchTerm ||
selectedCategory !== 'All Categories' ||
selectedFormat !== 'All Formats' ||
selectedLevel !== 'All Levels' ||
selectedStatus !== 'All Status';
const renderStars = (rating: number) => {
return Array.from({ length: 5 }, (_, i) => (
<span key={i} className={`text-sm ${i < Math.floor(rating) ? 'text-yellow-400' : 'text-gray-300'}`}></span>
));
};
return (
<div style={{ backgroundColor: '#FFFFFF' }}>
{/* Hero Section with Background Image */}
<section className="relative h-[500px] overflow-hidden">
{/* Background Image */}
<div className="absolute inset-0">
<ImageWithFallback
src="https://images.unsplash.com/photo-1552664730-d307ca884978?crop=entropy&cs=tinysrgb&fit=max&fm=jpg&ixid=M3w3Nzg4Nzd8MHwxfHNlYXJjaHwxfHxidXNpbmVzcyUyMHByZXNlbnRhdGlvbiUyMHdlYmluYXIlMjBjb25mZXJlbmNlfGVufDF8fHx8MTc1NTg1NDI3MHww&ixlib=rb-4.1.0&q=80&w=1080"
alt="Professional webinar and conference presentation"
className="w-full h-full object-cover"
/>
<div className="absolute inset-0 bg-black/60" />
</div>
{/* Hero Content */}
<div className="relative h-full flex flex-col justify-center section-margin-x">
<div className="text-center max-w-4xl mx-auto">
<div className="branded-tag-system-white mb-6">
<span className="dot"></span>
<span className="text">Expert Leadership Insights</span>
</div>
<h1 className="text-h1-white mb-6">
Transform Your Leadership<br />
Through Expert Webcasts
</h1>
<p className="text-body-lg-white max-w-3xl mx-auto mb-8">
Access world-class leadership development content from industry experts.
Join thousands of leaders who are advancing their skills through our
comprehensive webcast library.
</p>
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
<PrimaryCTAButton
text="Browse All Webcasts"
onClick={() => {
const filtersSection = document.getElementById('webinars-filters');
if (filtersSection) {
filtersSection.scrollIntoView({ behavior: 'smooth' });
}
}}
className="cta-text-black"
/>
<Button
variant="outline"
size="lg"
className="bg-white/10 text-white border-white/30 hover:bg-white/20 backdrop-blur-sm"
onClick={() => navigateTo('/contact?topic=webinars')}
>
<Calendar className="w-5 h-5 mr-2" />
Schedule a Session
</Button>
</div>
</div>
</div>
{/* Statistics Strip at Bottom */}
<div className="absolute bottom-0 left-0 right-0">
<div className="bg-black/80 backdrop-blur-sm px-8 py-6">
<div className="section-margin-x">
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 text-center">
<div>
<div className="text-h2-white mb-2">{stats.total}+</div>
<div className="text-small-white">Expert Webcasts</div>
</div>
<div>
<div className="text-h2-white mb-2">{stats.live + stats.upcoming}</div>
<div className="text-small-white">Live & Upcoming</div>
</div>
<div>
<div className="text-h2-white mb-2">25K+</div>
<div className="text-small-white">Total Attendees</div>
</div>
<div>
<div className="text-h2-white mb-2">{stats.avgRating}/5</div>
<div className="text-small-white">Average Rating</div>
</div>
</div>
</div>
</div>
</div>
</section>
{/* Search and Controls Section */}
<section id="webinars-filters" className="py-8" style={{ backgroundColor: '#FFFFFF' }}>
<div className="section-margin-x">
{/* Search and View Controls */}
<div className="flex flex-col lg:flex-row gap-6 mb-8">
{/* 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 webcasts, presenters, topics..."
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>
{/* Controls */}
<div className="flex items-center gap-4">
{/* View Toggle */}
<div className="flex items-center border border-gray-300 rounded-lg overflow-hidden">
<button
onClick={() => setViewType('grid')}
className={`p-2 transition-colors ${
viewType === 'grid'
? 'text-white'
: 'bg-white text-gray-600 hover:bg-gray-50'
}`}
style={{
backgroundColor: viewType === 'grid' ? 'var(--color-primary)' : undefined
}}
aria-label="Grid view"
>
<Grid className="w-4 h-4" />
</button>
<button
onClick={() => setViewType('list')}
className={`p-2 transition-colors ${
viewType === 'list'
? 'text-white'
: 'bg-white text-gray-600 hover:bg-gray-50'
}`}
style={{
backgroundColor: viewType === 'list' ? 'var(--color-primary)' : undefined
}}
aria-label="List view"
>
<List className="w-4 h-4" />
</button>
</div>
{/* Sort */}
<Select value={sortBy} onValueChange={setSortBy}>
<SelectTrigger className="w-48 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>
{/* Filters */}
<div className="grid grid-cols-2 md:grid-cols-5 gap-4 mb-6">
<Select value={selectedCategory} onValueChange={setSelectedCategory}>
<SelectTrigger>
<SelectValue placeholder="Category" />
</SelectTrigger>
<SelectContent>
{categories.map((category) => (
<SelectItem key={category} value={category}>
{category}
</SelectItem>
))}
</SelectContent>
</Select>
<Select value={selectedFormat} onValueChange={setSelectedFormat}>
<SelectTrigger>
<SelectValue placeholder="Format" />
</SelectTrigger>
<SelectContent>
{formats.map((format) => (
<SelectItem key={format} value={format}>
{format}
</SelectItem>
))}
</SelectContent>
</Select>
<Select value={selectedLevel} onValueChange={setSelectedLevel}>
<SelectTrigger>
<SelectValue placeholder="Level" />
</SelectTrigger>
<SelectContent>
{levels.map((level) => (
<SelectItem key={level} value={level}>
{level}
</SelectItem>
))}
</SelectContent>
</Select>
<Select value={selectedStatus} onValueChange={setSelectedStatus}>
<SelectTrigger>
<SelectValue placeholder="Status" />
</SelectTrigger>
<SelectContent>
{statuses.map((status) => (
<SelectItem key={status} value={status}>
{status}
</SelectItem>
))}
</SelectContent>
</Select>
{hasActiveFilters && (
<Button
variant="outline"
onClick={clearAllFilters}
className="text-gray-600 hover:text-gray-800"
>
<X className="w-4 h-4 mr-2" />
Clear All
</Button>
)}
</div>
<div className="text-small text-gray-600 mb-8">
Showing {currentWebinars.length} of {filteredWebinars.length} webcasts
</div>
</div>
</section>
{/* Webinars Content */}
<section className="pb-16" style={{ backgroundColor: '#FFFFFF' }}>
<div className="section-margin-x">
{currentWebinars.length === 0 ? (
<div className="text-center py-16">
<div className="w-16 h-16 mx-auto mb-4 bg-gray-100 rounded-full flex items-center justify-center">
<Search className="w-8 h-8 text-gray-400" />
</div>
<h3 className="text-h4 mb-4">No webcasts found</h3>
<p className="text-body text-gray-600 mb-6">
Try adjusting your filters or search terms to find relevant content.
</p>
<Button onClick={clearAllFilters} variant="outline">
Clear All Filters
</Button>
</div>
) : (
<>
{/* Grid View */}
{viewType === 'grid' && (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{currentWebinars.map((webinar) => (
<Card
key={webinar.id}
className="overflow-hidden hover:shadow-xl transition-all duration-300 cursor-pointer group border-0 shadow-lg"
onClick={() => navigateTo(`/webinar/${webinar.slug}`)}
>
<div className="aspect-video w-full bg-gray-100 overflow-hidden relative">
<ImageWithFallback
src={webinar.thumbnail}
alt={webinar.title}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
/>
{/* Status Badge */}
<div className="absolute top-4 left-4">
{webinar.status === 'Live' && (
<Badge className="bg-red-600 text-white border-red-600 animate-pulse">
LIVE
</Badge>
)}
{webinar.status === 'Upcoming' && (
<Badge className="bg-blue-600 text-white border-blue-600">
Upcoming
</Badge>
)}
{webinar.status === 'Recorded' && (
<Badge className="bg-green-600 text-white border-green-600">
Replay Available
</Badge>
)}
</div>
{webinar.featured && (
<div className="absolute top-4 right-4">
<Badge className="bg-yellow-500 text-white border-yellow-500">
<Award className="w-3 h-3 mr-1" />
Featured
</Badge>
</div>
)}
{/* Play Button Overlay */}
<div className="absolute inset-0 bg-black bg-opacity-40 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-300">
<Button
variant="secondary"
size="lg"
className="bg-white text-black hover:bg-gray-100"
>
<Play className="w-5 h-5 mr-2" />
{webinar.status === 'Live' ? 'Join Live' : webinar.status === 'Upcoming' ? 'Register' : 'Watch'}
</Button>
</div>
</div>
<CardContent className="p-6">
{/* Meta Info */}
<div className="flex items-center gap-2 mb-3">
<Badge variant="outline" className="text-xs">
{webinar.format}
</Badge>
<Badge variant="outline" className="text-xs">
{webinar.level}
</Badge>
<div className="flex items-center gap-1 ml-auto">
{renderStars(webinar.rating)}
<span className="text-xs text-gray-600 ml-1">{webinar.rating}</span>
</div>
</div>
<h3 className="text-h4 mb-3 group-hover:text-blue-600 transition-colors line-clamp-2">
{webinar.title}
</h3>
<p className="text-small text-gray-600 mb-4 line-clamp-2">
{webinar.description}
</p>
{/* Presenter Info */}
<div className="flex items-center mb-4">
<div className="w-10 h-10 bg-gray-200 rounded-full flex items-center justify-center mr-3">
<Users className="w-5 h-5 text-gray-400" />
</div>
<div>
<div className="text-small font-medium">{webinar.presenter}</div>
<div className="text-xs text-gray-500">{webinar.presenterTitle}</div>
</div>
</div>
{/* Details */}
<div className="flex items-center justify-between text-small text-gray-500 mb-4">
<div className="flex items-center gap-4">
<div className="flex items-center gap-1">
<Clock className="w-4 h-4" />
<span>{webinar.duration}</span>
</div>
<div className="flex items-center gap-1">
<Users className="w-4 h-4" />
<span>{webinar.attendees}</span>
</div>
</div>
<div className="flex items-center gap-1">
<Globe className="w-4 h-4" />
<span>{webinar.format}</span>
</div>
</div>
{/* Date and Price */}
<div className="flex items-center justify-between">
<div className="text-small text-gray-600">
{formatDate(webinar.date)}
</div>
<div className="text-small font-medium text-green-600">
{webinar.price}
</div>
</div>
</CardContent>
</Card>
))}
</div>
)}
{/* List View */}
{viewType === 'list' && (
<div className="space-y-6">
{currentWebinars.map((webinar) => (
<Card
key={webinar.id}
className="overflow-hidden hover:shadow-xl transition-all duration-300 cursor-pointer border-0 shadow-lg"
onClick={() => navigateTo(`/webinar/${webinar.slug}`)}
>
<div className="flex">
<div className="w-80 h-48 bg-gray-100 overflow-hidden relative flex-shrink-0">
<ImageWithFallback
src={webinar.thumbnail}
alt={webinar.title}
className="w-full h-full object-cover"
/>
{webinar.featured && (
<div className="absolute top-4 right-4">
<Badge className="bg-yellow-500 text-white border-yellow-500">
<Award className="w-3 h-3 mr-1" />
Featured
</Badge>
</div>
)}
</div>
<CardContent className="flex-1 p-6">
<div className="flex items-start justify-between mb-4">
<div className="flex items-center gap-2">
<Badge variant="outline" className="text-xs">
{webinar.format}
</Badge>
<Badge variant="outline" className="text-xs">
{webinar.level}
</Badge>
{webinar.status === 'Live' && (
<Badge className="bg-red-600 text-white border-red-600 animate-pulse">
LIVE
</Badge>
)}
{webinar.status === 'Upcoming' && (
<Badge className="bg-blue-600 text-white border-blue-600">
Upcoming
</Badge>
)}
{webinar.status === 'Recorded' && (
<Badge className="bg-green-600 text-white border-green-600">
Replay Available
</Badge>
)}
</div>
<div className="flex items-center gap-1">
{renderStars(webinar.rating)}
<span className="text-xs text-gray-600 ml-1">{webinar.rating}</span>
</div>
</div>
<h3 className="text-h4 mb-3 hover:text-blue-600 transition-colors">
{webinar.title}
</h3>
<p className="text-small text-gray-600 mb-4">
{webinar.description}
</p>
<div className="flex items-center justify-between">
<div className="flex items-center gap-6 text-small text-gray-500">
<div className="flex items-center gap-1">
<Clock className="w-4 h-4" />
<span>{webinar.duration}</span>
</div>
<div className="flex items-center gap-1">
<Users className="w-4 h-4" />
<span>{webinar.attendees}</span>
</div>
<div className="flex items-center gap-2">
<span>By {webinar.presenter}</span>
</div>
</div>
<div className="flex items-center gap-4">
<div className="text-small text-gray-600">
{formatDate(webinar.date)}
</div>
<div className="text-small font-medium text-green-600">
{webinar.price}
</div>
</div>
</div>
</CardContent>
</div>
</Card>
))}
</div>
)}
{/* Pagination */}
{totalPages > 1 && (
<div className="flex items-center justify-center gap-2 mt-12">
<Button
variant="outline"
size="sm"
onClick={() => setCurrentPage(prev => Math.max(1, prev - 1))}
disabled={currentPage === 1}
>
<ChevronLeft className="w-4 h-4" />
Previous
</Button>
<div className="flex items-center gap-1">
{Array.from({ length: Math.min(totalPages, 7) }, (_, i) => {
let page;
if (totalPages <= 7) {
page = i + 1;
} else if (currentPage <= 4) {
page = i + 1;
} else if (currentPage >= totalPages - 3) {
page = totalPages - 6 + i;
} else {
page = currentPage - 3 + i;
}
return (
<Button
key={page}
variant={currentPage === page ? "default" : "outline"}
size="sm"
onClick={() => setCurrentPage(page)}
className="w-10 h-10 p-0"
style={{
backgroundColor: currentPage === page ? 'var(--color-primary)' : undefined,
color: currentPage === page ? 'white' : undefined
}}
>
{page}
</Button>
);
})}
</div>
<Button
variant="outline"
size="sm"
onClick={() => setCurrentPage(prev => Math.min(totalPages, prev + 1))}
disabled={currentPage === totalPages}
>
Next
<ChevronRight className="w-4 h-4" />
</Button>
</div>
)}
</>
)}
</div>
</section>
{/* CTA Section */}
<section className="py-16 bg-gray-50">
<div className="section-margin-x text-center">
<div className="max-w-3xl mx-auto">
<h2 className="text-h2 mb-6">Ready to Transform Your Leadership?</h2>
<p className="text-body-lg text-gray-600 mb-8">
Join thousands of professionals who are advancing their careers through our expert-led webcasts.
Start your leadership transformation today.
</p>
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
<PrimaryCTAButton
text="Get Started Today"
onClick={() => navigateTo('/contact?topic=leadership-development')}
className="cta-text-black"
/>
<Button
variant="outline"
size="lg"
onClick={() => navigateTo('/about/our-expertise')}
>
<TrendingUp className="w-5 h-5 mr-2" />
Learn More About Us
</Button>
</div>
</div>
</div>
</section>
</div>
);
}