pagination added in artical and other changes

This commit is contained in:
priyanshuvish
2025-09-30 15:56:17 +05:30
parent c67ace8edb
commit 7b8fe79917
11 changed files with 2369 additions and 934 deletions

View File

@@ -134,7 +134,25 @@ const articles = [
featured: false,
views: '1.5k',
likes: 28
}
},
{
id: '7',
slug: 'strategic-thinking-frameworks',
title: 'Strategic Thinking Frameworks for Modern Leaders',
excerpt: 'Master strategic thinking with proven frameworks that help leaders anticipate challenges and seize opportunities.',
content: 'Strategic thinking is a critical skill for leaders navigating complex business environments...',
author: 'Dr. Amanda Foster',
authorTitle: 'Strategic Leadership Coach',
authorAvatar: 'https://images.unsplash.com/photo-1544725176-7c40e5a71c5e?w=150&h=150&fit=crop&crop=face',
date: '2024-02-05',
readTime: '11 min read',
category: 'Strategy',
tags: ['Strategic Thinking', 'Frameworks', 'Decision Making', 'Planning'],
thumbnail: 'https://images.unsplash.com/photo-1552664730-d307ca884978?w=600&h=400&fit=crop',
featured: false,
views: '2.1k',
likes: 39
},
];
export function Articles() {
@@ -147,7 +165,9 @@ export function Articles() {
const [sortBy, setSortBy] = useState('Most Recent');
const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid');
const [currentPage, setCurrentPage] = useState(1);
const articlesPerPage = 6;
const articlesPerPage = 4;
const containerRef = useRef<HTMLDivElement>(null);
// Get unique values for filters
const categories = ['All Categories', ...Array.from(new Set(articles.map(article => article.category)))];
@@ -166,31 +186,31 @@ export function Articles() {
// Filter and sort articles
const filteredArticles = articles.filter(article => {
const matchesSearch = article.title.toLowerCase().includes(searchTerm.toLowerCase()) ||
article.excerpt.toLowerCase().includes(searchTerm.toLowerCase()) ||
article.author.toLowerCase().includes(searchTerm.toLowerCase()) ||
article.tags.some(tag => tag.toLowerCase().includes(searchTerm.toLowerCase()));
article.excerpt.toLowerCase().includes(searchTerm.toLowerCase()) ||
article.author.toLowerCase().includes(searchTerm.toLowerCase()) ||
article.tags.some(tag => tag.toLowerCase().includes(searchTerm.toLowerCase()));
const matchesCategory = selectedCategory === 'All Categories' || article.category === selectedCategory;
const matchesAuthor = selectedAuthor === 'All Authors' || article.author === selectedAuthor;
// Read time filter
const readTimeMinutes = parseInt(article.readTime);
// FIXED: Read time filter - properly parse the read time
const readTimeMinutes = parseInt(article.readTime.replace(' min read', '')) || 0;
const matchesReadTime = selectedReadTime === 'All Read Times' ||
(selectedReadTime === 'Under 5 min' && readTimeMinutes < 5) ||
(selectedReadTime === '5-10 min' && readTimeMinutes >= 5 && readTimeMinutes <= 10) ||
(selectedReadTime === 'Over 10 min' && readTimeMinutes > 10);
(selectedReadTime === 'Under 5 min' && readTimeMinutes < 5) ||
(selectedReadTime === '5-10 min' && readTimeMinutes >= 5 && readTimeMinutes <= 10) ||
(selectedReadTime === 'Over 10 min' && readTimeMinutes > 10);
// Date range filter
const articleDate = new Date(article.date);
const now = new Date();
const matchesDateRange = selectedDateRange === 'All Time' ||
(selectedDateRange === 'Last 7 days' && (now.getTime() - articleDate.getTime()) <= 7 * 24 * 60 * 60 * 1000) ||
(selectedDateRange === 'Last 30 days' && (now.getTime() - articleDate.getTime()) <= 30 * 24 * 60 * 60 * 1000) ||
(selectedDateRange === 'Last 3 months' && (now.getTime() - articleDate.getTime()) <= 90 * 24 * 60 * 60 * 1000);
(selectedDateRange === 'Last 7 days' && (now.getTime() - articleDate.getTime()) <= 7 * 24 * 60 * 60 * 1000) ||
(selectedDateRange === 'Last 30 days' && (now.getTime() - articleDate.getTime()) <= 30 * 24 * 60 * 60 * 1000) ||
(selectedDateRange === 'Last 3 months' && (now.getTime() - articleDate.getTime()) <= 90 * 24 * 60 * 60 * 1000);
// Topic filter
const matchesTopic = selectedTopic === 'All Topics' ||
article.tags.includes(selectedTopic);
const matchesTopic = selectedTopic === 'All Topics' ||
article.tags.includes(selectedTopic);
return matchesSearch && matchesCategory && matchesAuthor && matchesReadTime && matchesDateRange && matchesTopic;
}).sort((a, b) => {
switch (sortBy) {
@@ -201,7 +221,8 @@ export function Articles() {
case 'title':
return a.title.localeCompare(b.title);
case 'readTime':
return parseInt(a.readTime) - parseInt(b.readTime);
// FIXED: Sort by read time - properly parse the values
return (parseInt(a.readTime.replace(' min read', '')) || 0) - (parseInt(b.readTime.replace(' min read', '')) || 0);
case 'popular':
return parseInt(b.views) - parseInt(a.views);
default:
@@ -234,12 +255,12 @@ export function Articles() {
const hasActiveFilters = searchTerm ||
selectedCategory !== 'All Categories' ||
selectedAuthor !== 'All Authors' ||
selectedReadTime !== 'All Read Times' ||
selectedDateRange !== 'All Time' ||
selectedTopic !== 'All Topics';
const hasActiveFilters = searchTerm ||
selectedCategory !== 'All Categories' ||
selectedAuthor !== 'All Authors' ||
selectedReadTime !== 'All Read Times' ||
selectedDateRange !== 'All Time' ||
selectedTopic !== 'All Topics';
return (
<div style={{ backgroundColor: '#FFFFFF' }}>
@@ -260,11 +281,11 @@ export function Articles() {
<div className="dot"></div>
<span className="text">INSIGHTS & KNOWLEDGE</span>
</div>
<h1 className="text-h1-white mb-6">
Articles & Research
</h1>
<p className="text-body-lg-white mb-8 max-w-2xl mx-auto">
Discover cutting-edge insights, research findings, and expert perspectives on leadership development, management strategies, and organizational excellence.
</p>
@@ -320,11 +341,10 @@ export function Articles() {
<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'
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
}}
@@ -334,11 +354,10 @@ export function Articles() {
</button>
<button
onClick={() => setViewMode('list')}
className={`p-2 transition-colors ${
viewMode === 'list'
? 'text-white'
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
}}
@@ -521,9 +540,9 @@ export function Articles() {
<>
{/* Grid View */}
{viewMode === 'grid' && (
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
{currentArticles.map((article) => (
<Card
<Card
key={article.id}
className="overflow-hidden hover:shadow-lg transition-all duration-300 cursor-pointer group"
onClick={() => navigateTo(`/learning/articles/${article.slug}`)}
@@ -536,7 +555,7 @@ export function Articles() {
/>
{article.featured && (
<div className="absolute top-4 right-4">
<Badge
<Badge
variant="secondary"
className="bg-yellow-100 text-yellow-800 border-yellow-200"
>
@@ -552,11 +571,11 @@ export function Articles() {
</Badge>
<span className="text-small text-muted">{article.readTime}</span>
</div>
<h3 className="text-h4 mb-3 group-hover:text-blue-600 transition-colors line-clamp-2">
{article.title}
</h3>
<p className="text-small text-muted mb-4 line-clamp-3">
{article.excerpt}
</p>
@@ -584,7 +603,7 @@ export function Articles() {
{viewMode === 'list' && (
<div className="space-y-6">
{currentArticles.map((article) => (
<Card
<Card
key={article.id}
className="overflow-hidden hover:shadow-lg transition-all duration-300 cursor-pointer group"
onClick={() => navigateTo(`/learning/articles/${article.slug}`)}
@@ -598,7 +617,7 @@ export function Articles() {
/>
{article.featured && (
<div className="absolute top-2 right-2">
<Badge
<Badge
variant="secondary"
className="bg-yellow-100 text-yellow-800 border-yellow-200 text-xs"
>
@@ -621,11 +640,11 @@ export function Articles() {
<span>{article.views}</span>
</div>
</div>
<h3 className="text-h4 mb-2 group-hover:text-blue-600 transition-colors">
{article.title}
</h3>
<p className="text-body text-muted mb-3">
{article.excerpt}
</p>
@@ -657,29 +676,71 @@ export function Articles() {
{/* Pagination */}
{totalPages > 1 && (
<div className="flex items-center justify-center gap-4 mt-12">
<div className="flex items-center justify-center gap-2">
<Button
variant="outline"
onClick={() => setCurrentPage(prev => Math.max(prev - 1, 1))}
size="sm"
onClick={() => {
setCurrentPage(prev => Math.max(1, prev - 1));
containerRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
}}
disabled={currentPage === 1}
className="text-body"
className="flex items-center gap-1 border-gray-300 disabled:opacity-50 disabled:cursor-not-allowed"
>
<ChevronLeft className="w-4 h-4 mr-2" />
<ChevronLeft className="w-4 h-4" />
Previous
</Button>
<span className="text-body">
Page {currentPage} of {totalPages}
</span>
<div className="flex items-center gap-1">
{Array.from({ length: totalPages }, (_, i) => {
const page = i + 1;
// Show limited pages for better UX
if (totalPages > 7) {
const showPage =
page === 1 ||
page === totalPages ||
(page >= currentPage - 1 && page <= currentPage + 1);
if (!showPage) {
if (page === currentPage - 2 || page === currentPage + 2) {
return <span key={page} className="px-2">...</span>;
}
return null;
}
}
return (
<Button
key={page}
variant={currentPage === page ? "default" : "outline"}
size="sm"
onClick={() => {
setCurrentPage(page);
containerRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
}}
className={`min-w-10 ${currentPage === page
? 'bg-blue-600 text-white hover:bg-blue-700'
: 'border-gray-300 text-gray-700 hover:bg-gray-50'
}`}
>
{page}
</Button>
);
})}
</div>
<Button
variant="outline"
onClick={() => setCurrentPage(prev => Math.min(prev + 1, totalPages))}
size="sm"
onClick={() => {
setCurrentPage(prev => Math.min(totalPages, prev + 1));
containerRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
}}
disabled={currentPage === totalPages}
className="text-body"
className="flex items-center gap-1 border-gray-300 disabled:opacity-50 disabled:cursor-not-allowed"
>
Next
<ChevronRight className="w-4 h-4 ml-2" />
<ChevronRight className="w-4 h-4" />
</Button>
</div>
)}
@@ -703,9 +764,9 @@ export function Articles() {
</div>
<div className="relative h-full flex items-center justify-end section-margin-x">
<div
<div
className="bg-opacity-95 backdrop-blur-sm rounded-lg p-16 max-w-2xl"
style={{
style={{
backgroundColor: 'var(--color-brand-primary)'
}}
>
@@ -715,8 +776,8 @@ export function Articles() {
</div>
<h2 className="text-h2-white mb-8">
Ready to explore more insights?
<span
Ready to explore more insights?
<span
className="italic"
style={{ color: 'var(--color-brand-accent)' }}
>
@@ -725,7 +786,7 @@ export function Articles() {
our complete library of leadership resources.
</h2>
<PrimaryCTAButton
<PrimaryCTAButton
text="Browse All Resources"
onClick={() => navigateTo('/learning/articles')}
ariaLabel="Browse all leadership articles and resources"