483 lines
20 KiB
TypeScript
483 lines
20 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { Button } from './ui/button';
|
|
import { Badge } from './ui/badge';
|
|
import { Calendar, Clock, User, ChevronLeft, ChevronRight, Search, Filter } from 'lucide-react';
|
|
import { Input } from './ui/input';
|
|
import { navigateTo } from './Router';
|
|
import { ImageWithFallback } from './figma/ImageWithFallback';
|
|
|
|
// Mock blog data
|
|
const blogPosts = [
|
|
{
|
|
id: '1',
|
|
slug: 'future-of-leadership-development',
|
|
title: 'The Future of Leadership Development: Trends and Innovations',
|
|
excerpt: 'Explore emerging trends in leadership development, from AI-powered coaching to virtual reality training experiences that are reshaping how leaders learn and grow.',
|
|
content: 'Full blog content would go here...',
|
|
author: 'Dr. Sarah Mitchell',
|
|
authorRole: 'Chief Learning Officer',
|
|
publishDate: '2024-02-15',
|
|
readTime: '8 min read',
|
|
category: 'Leadership',
|
|
tags: ['Leadership Development', 'Innovation', 'Future Trends', 'Technology'],
|
|
thumbnail: 'https://images.unsplash.com/photo-1552664730-d307ca884978?w=600&h=400&fit=crop',
|
|
featured: true
|
|
},
|
|
{
|
|
id: '2',
|
|
slug: 'building-emotional-intelligence',
|
|
title: 'Building Emotional Intelligence: A Leader\'s Guide to Self-Awareness',
|
|
excerpt: 'Discover practical strategies for developing emotional intelligence and how self-aware leaders create more engaged and productive teams.',
|
|
content: 'Full blog content would go here...',
|
|
author: 'Marcus Rodriguez',
|
|
authorRole: 'Leadership Coach',
|
|
publishDate: '2024-02-10',
|
|
readTime: '6 min read',
|
|
category: 'Personal Development',
|
|
tags: ['Emotional Intelligence', 'Self-Awareness', 'Team Building', 'Communication'],
|
|
thumbnail: 'https://images.unsplash.com/photo-1559027615-cd4628902d4a?w=600&h=400&fit=crop',
|
|
featured: false
|
|
},
|
|
{
|
|
id: '3',
|
|
slug: 'remote-leadership-strategies',
|
|
title: 'Remote Leadership Strategies: Managing Distributed Teams Effectively',
|
|
excerpt: 'Learn proven strategies for leading remote teams, maintaining culture, and driving performance in a distributed work environment.',
|
|
content: 'Full blog content would go here...',
|
|
author: 'Dr. Emily Chen',
|
|
authorRole: 'Remote Work Expert',
|
|
publishDate: '2024-02-05',
|
|
readTime: '10 min read',
|
|
category: 'Remote Work',
|
|
tags: ['Remote Leadership', 'Virtual Teams', 'Digital Communication', 'Performance Management'],
|
|
thumbnail: 'https://images.unsplash.com/photo-1600880292203-757bb62b4baf?w=600&h=400&fit=crop',
|
|
featured: true
|
|
},
|
|
{
|
|
id: '4',
|
|
slug: 'diversity-inclusion-leadership',
|
|
title: 'Diversity and Inclusion: Leading Change in Your Organization',
|
|
excerpt: 'A comprehensive guide to implementing meaningful diversity and inclusion initiatives that drive real organizational change.',
|
|
content: 'Full blog content would go here...',
|
|
author: 'Jennifer Adams',
|
|
authorRole: 'D&I Consultant',
|
|
publishDate: '2024-01-28',
|
|
readTime: '12 min read',
|
|
category: 'Diversity & Inclusion',
|
|
tags: ['Diversity', 'Inclusion', 'Organizational Change', 'Culture'],
|
|
thumbnail: 'https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=600&h=400&fit=crop',
|
|
featured: false
|
|
},
|
|
{
|
|
id: '5',
|
|
slug: 'agile-leadership-mindset',
|
|
title: 'Developing an Agile Leadership Mindset for Rapid Change',
|
|
excerpt: 'Explore how agile principles can transform your leadership approach and help organizations navigate uncertainty and rapid change.',
|
|
content: 'Full blog content would go here...',
|
|
author: 'David Park',
|
|
authorRole: 'Agile Coach',
|
|
publishDate: '2024-01-20',
|
|
readTime: '7 min read',
|
|
category: 'Agile Leadership',
|
|
tags: ['Agile', 'Change Management', 'Adaptability', 'Innovation'],
|
|
thumbnail: 'https://images.unsplash.com/photo-1552664730-d307ca884978?w=600&h=400&fit=crop',
|
|
featured: false
|
|
},
|
|
{
|
|
id: '6',
|
|
slug: 'coaching-vs-mentoring',
|
|
title: 'Coaching vs. Mentoring: Understanding the Difference and When to Use Each',
|
|
excerpt: 'Learn the key differences between coaching and mentoring, and discover when each approach is most effective for leadership development.',
|
|
content: 'Full blog content would go here...',
|
|
author: 'Lisa Thompson',
|
|
authorRole: 'Executive Coach',
|
|
publishDate: '2024-01-15',
|
|
readTime: '9 min read',
|
|
category: 'Coaching',
|
|
tags: ['Coaching', 'Mentoring', 'Leadership Development', 'Professional Growth'],
|
|
thumbnail: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=600&h=400&fit=crop',
|
|
featured: false
|
|
}
|
|
];
|
|
|
|
export function Blogs() {
|
|
const [searchTerm, setSearchTerm] = useState('');
|
|
const [selectedCategory, setSelectedCategory] = useState('All');
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const postsPerPage = 6;
|
|
|
|
// Get unique categories
|
|
const categories = ['All', ...Array.from(new Set(blogPosts.map(post => post.category)))];
|
|
|
|
// Filter posts based on search and category
|
|
const filteredPosts = blogPosts.filter(post => {
|
|
const matchesSearch = post.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
|
post.excerpt.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
|
post.author.toLowerCase().includes(searchTerm.toLowerCase());
|
|
const matchesCategory = selectedCategory === 'All' || post.category === selectedCategory;
|
|
return matchesSearch && matchesCategory;
|
|
});
|
|
|
|
// Paginate results
|
|
const totalPages = Math.ceil(filteredPosts.length / postsPerPage);
|
|
const currentPosts = filteredPosts.slice((currentPage - 1) * postsPerPage, currentPage * postsPerPage);
|
|
|
|
const formatDate = (dateString: string) => {
|
|
return new Date(dateString).toLocaleDateString('en-US', {
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric'
|
|
});
|
|
};
|
|
|
|
return (
|
|
<div style={{ backgroundColor: 'var(--color-bg-white)' }}>
|
|
{/* Header Section */}
|
|
<div className="py-12">
|
|
<div className="hero-margin-x">
|
|
<div className="text-center mb-12">
|
|
<div className="branded-tag-system mb-6">
|
|
<div className="dot"></div>
|
|
<span className="text">INSIGHTS & EXPERTISE</span>
|
|
</div>
|
|
|
|
<h1
|
|
className="mb-6"
|
|
style={{
|
|
fontSize: 'var(--font-h1)',
|
|
fontWeight: 'var(--font-weight-h1)',
|
|
lineHeight: 'var(--line-height-h1)',
|
|
color: 'var(--color-black)',
|
|
fontFamily: 'var(--font-family-base)'
|
|
}}
|
|
>
|
|
Leadership Insights Blog
|
|
</h1>
|
|
|
|
<p
|
|
className="max-w-3xl mx-auto"
|
|
style={{
|
|
fontSize: 'var(--font-body-lg)',
|
|
lineHeight: 'var(--line-height-body-lg)',
|
|
color: 'var(--color-gray-muted)',
|
|
fontFamily: 'var(--font-family-base)'
|
|
}}
|
|
>
|
|
Discover thought-provoking articles, expert insights, and practical strategies from leading voices in organizational development and leadership excellence.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Search and Filter Section */}
|
|
<div className="mb-12">
|
|
<div className="flex flex-col lg:flex-row gap-6 items-center justify-between">
|
|
{/* Search Bar */}
|
|
<div className="relative flex-1 max-w-md">
|
|
<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 articles..."
|
|
value={searchTerm}
|
|
onChange={(e) => setSearchTerm(e.target.value)}
|
|
className="pl-10"
|
|
style={{
|
|
fontSize: 'var(--font-body)',
|
|
fontFamily: 'var(--font-family-base)'
|
|
}}
|
|
/>
|
|
</div>
|
|
|
|
{/* Category Filter */}
|
|
<div className="flex flex-wrap gap-2">
|
|
{categories.map((category) => (
|
|
<Button
|
|
key={category}
|
|
variant={selectedCategory === category ? "default" : "outline"}
|
|
onClick={() => {
|
|
setSelectedCategory(category);
|
|
setCurrentPage(1);
|
|
}}
|
|
style={{
|
|
fontSize: 'var(--font-small)',
|
|
fontFamily: 'var(--font-family-base)',
|
|
backgroundColor: selectedCategory === category ? 'var(--color-primary)' : 'transparent',
|
|
borderColor: 'var(--color-primary)',
|
|
color: selectedCategory === category ? 'white' : 'var(--color-primary)'
|
|
}}
|
|
>
|
|
{category}
|
|
</Button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Featured Posts Section */}
|
|
{searchTerm === '' && selectedCategory === 'All' && (
|
|
<div className="mb-16">
|
|
<h2
|
|
className="mb-8"
|
|
style={{
|
|
fontSize: 'var(--font-h2)',
|
|
fontWeight: 'var(--font-weight-h2)',
|
|
color: 'var(--color-black)',
|
|
fontFamily: 'var(--font-family-base)'
|
|
}}
|
|
>
|
|
Featured Articles
|
|
</h2>
|
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
|
{blogPosts.filter(post => post.featured).slice(0, 2).map((post) => (
|
|
<article
|
|
key={post.id}
|
|
className="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden hover:shadow-lg transition-all duration-300 cursor-pointer"
|
|
onClick={() => navigateTo(`/learning/blogs/${post.slug}`)}
|
|
>
|
|
<div className="aspect-video w-full bg-gray-100">
|
|
<ImageWithFallback
|
|
src={post.thumbnail}
|
|
alt={post.title}
|
|
className="w-full h-full object-cover"
|
|
/>
|
|
</div>
|
|
<div className="p-6">
|
|
<div className="flex items-center gap-3 mb-4">
|
|
<Badge
|
|
variant="secondary"
|
|
style={{
|
|
backgroundColor: 'rgba(248, 195, 1, 0.1)',
|
|
color: 'var(--color-black)',
|
|
fontSize: 'var(--font-small)',
|
|
fontFamily: 'var(--font-family-base)'
|
|
}}
|
|
>
|
|
{post.category}
|
|
</Badge>
|
|
<Badge
|
|
variant="outline"
|
|
style={{
|
|
fontSize: 'var(--font-small)',
|
|
fontFamily: 'var(--font-family-base)',
|
|
borderColor: 'var(--color-primary)',
|
|
color: 'var(--color-primary)'
|
|
}}
|
|
>
|
|
Featured
|
|
</Badge>
|
|
</div>
|
|
|
|
<h3
|
|
className="mb-3 hover:text-blue-600 transition-colors"
|
|
style={{
|
|
fontSize: 'var(--font-h3)',
|
|
fontWeight: 'var(--font-weight-h3)',
|
|
lineHeight: 'var(--line-height-h3)',
|
|
color: 'var(--color-black)',
|
|
fontFamily: 'var(--font-family-base)'
|
|
}}
|
|
>
|
|
{post.title}
|
|
</h3>
|
|
|
|
<p
|
|
className="mb-4"
|
|
style={{
|
|
fontSize: 'var(--font-body)',
|
|
lineHeight: 'var(--line-height-body)',
|
|
color: 'var(--color-gray-muted)',
|
|
fontFamily: 'var(--font-family-base)'
|
|
}}
|
|
>
|
|
{post.excerpt}
|
|
</p>
|
|
|
|
<div className="flex items-center justify-between text-sm text-gray-500">
|
|
<div className="flex items-center gap-4">
|
|
<div className="flex items-center gap-1">
|
|
<User className="w-4 h-4" />
|
|
<span style={{ fontSize: 'var(--font-small)', fontFamily: 'var(--font-family-base)' }}>
|
|
{post.author}
|
|
</span>
|
|
</div>
|
|
<div className="flex items-center gap-1">
|
|
<Calendar className="w-4 h-4" />
|
|
<span style={{ fontSize: 'var(--font-small)', fontFamily: 'var(--font-family-base)' }}>
|
|
{formatDate(post.publishDate)}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center gap-1">
|
|
<Clock className="w-4 h-4" />
|
|
<span style={{ fontSize: 'var(--font-small)', fontFamily: 'var(--font-family-base)' }}>
|
|
{post.readTime}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
))}
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{/* All Posts Grid */}
|
|
<div className="mb-12">
|
|
<h2
|
|
className="mb-8"
|
|
style={{
|
|
fontSize: 'var(--font-h2)',
|
|
fontWeight: 'var(--font-weight-h2)',
|
|
color: 'var(--color-black)',
|
|
fontFamily: 'var(--font-family-base)'
|
|
}}
|
|
>
|
|
{searchTerm || selectedCategory !== 'All' ? 'Search Results' : 'All Articles'}
|
|
</h2>
|
|
|
|
{currentPosts.length === 0 ? (
|
|
<div className="text-center py-12">
|
|
<p
|
|
style={{
|
|
fontSize: 'var(--font-body-lg)',
|
|
color: 'var(--color-gray-muted)',
|
|
fontFamily: 'var(--font-family-base)'
|
|
}}
|
|
>
|
|
No articles found matching your criteria.
|
|
</p>
|
|
</div>
|
|
) : (
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
|
{currentPosts.map((post) => (
|
|
<article
|
|
key={post.id}
|
|
className="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden hover:shadow-lg transition-all duration-300 cursor-pointer group"
|
|
onClick={() => navigateTo(`/learning/blogs/${post.slug}`)}
|
|
>
|
|
<div className="aspect-video w-full bg-gray-100 overflow-hidden">
|
|
<ImageWithFallback
|
|
src={post.thumbnail}
|
|
alt={post.title}
|
|
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
|
|
/>
|
|
</div>
|
|
<div className="p-6">
|
|
<div className="flex items-center gap-3 mb-3">
|
|
<Badge
|
|
variant="secondary"
|
|
style={{
|
|
backgroundColor: 'rgba(248, 195, 1, 0.1)',
|
|
color: 'var(--color-black)',
|
|
fontSize: 'var(--font-small)',
|
|
fontFamily: 'var(--font-family-base)'
|
|
}}
|
|
>
|
|
{post.category}
|
|
</Badge>
|
|
{post.featured && (
|
|
<Badge
|
|
variant="outline"
|
|
style={{
|
|
fontSize: 'var(--font-small)',
|
|
fontFamily: 'var(--font-family-base)',
|
|
borderColor: 'var(--color-primary)',
|
|
color: 'var(--color-primary)'
|
|
}}
|
|
>
|
|
Featured
|
|
</Badge>
|
|
)}
|
|
</div>
|
|
|
|
<h3
|
|
className="mb-3 group-hover:text-blue-600 transition-colors"
|
|
style={{
|
|
fontSize: 'var(--font-h4)',
|
|
fontWeight: 'var(--font-weight-h4)',
|
|
lineHeight: 'var(--line-height-h4)',
|
|
color: 'var(--color-black)',
|
|
fontFamily: 'var(--font-family-base)'
|
|
}}
|
|
>
|
|
{post.title}
|
|
</h3>
|
|
|
|
<p
|
|
className="mb-4"
|
|
style={{
|
|
fontSize: 'var(--font-small)',
|
|
lineHeight: 'var(--line-height-small)',
|
|
color: 'var(--color-gray-muted)',
|
|
fontFamily: 'var(--font-family-base)'
|
|
}}
|
|
>
|
|
{post.excerpt}
|
|
</p>
|
|
|
|
<div className="flex items-center justify-between text-sm text-gray-500">
|
|
<div className="flex items-center gap-1">
|
|
<User className="w-4 h-4" />
|
|
<span style={{ fontSize: 'var(--font-small)', fontFamily: 'var(--font-family-base)' }}>
|
|
{post.author}
|
|
</span>
|
|
</div>
|
|
<div className="flex items-center gap-1">
|
|
<Clock className="w-4 h-4" />
|
|
<span style={{ fontSize: 'var(--font-small)', fontFamily: 'var(--font-family-base)' }}>
|
|
{post.readTime}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
))}
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Pagination */}
|
|
{totalPages > 1 && (
|
|
<div className="flex items-center justify-center gap-4">
|
|
<Button
|
|
variant="outline"
|
|
onClick={() => setCurrentPage(prev => Math.max(prev - 1, 1))}
|
|
disabled={currentPage === 1}
|
|
style={{
|
|
fontSize: 'var(--font-body)',
|
|
fontFamily: 'var(--font-family-base)',
|
|
borderColor: 'var(--color-primary)'
|
|
}}
|
|
>
|
|
<ChevronLeft className="w-4 h-4 mr-2" />
|
|
Previous
|
|
</Button>
|
|
|
|
<span
|
|
style={{
|
|
fontSize: 'var(--font-body)',
|
|
fontFamily: 'var(--font-family-base)',
|
|
color: 'var(--color-black)'
|
|
}}
|
|
>
|
|
Page {currentPage} of {totalPages}
|
|
</span>
|
|
|
|
<Button
|
|
variant="outline"
|
|
onClick={() => setCurrentPage(prev => Math.min(prev + 1, totalPages))}
|
|
disabled={currentPage === totalPages}
|
|
style={{
|
|
fontSize: 'var(--font-body)',
|
|
fontFamily: 'var(--font-family-base)',
|
|
borderColor: 'var(--color-primary)'
|
|
}}
|
|
>
|
|
Next
|
|
<ChevronRight className="w-4 h-4 ml-2" />
|
|
</Button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
} |