'use client' import { useMemo, useState } from 'react' import { useTranslations } from 'next-intl' import { Post } from '@/lib/types/frontmatter' import { BlogCard } from '@/components/blog/blog-card' import { SearchBar } from '@/components/blog/search-bar' import { SortDropdown } from '@/components/blog/sort-dropdown' import { TagFilter } from '@/components/blog/tag-filter' interface BlogPageClientProps { posts: Post[] allTags: string[] } type SortOption = 'newest' | 'oldest' | 'title' export default function BlogPageClient({ posts, allTags }: BlogPageClientProps) { const t = useTranslations('BlogListing') const [searchQuery, setSearchQuery] = useState('') const [selectedTags, setSelectedTags] = useState([]) const [sortBy, setSortBy] = useState('newest') const [currentPage, setCurrentPage] = useState(1) const postsPerPage = 9 const filteredAndSortedPosts = useMemo(() => { const result = posts.filter(post => { const matchesSearch = searchQuery === '' || post.frontmatter.title.toLowerCase().includes(searchQuery.toLowerCase()) || post.frontmatter.description.toLowerCase().includes(searchQuery.toLowerCase()) const matchesTags = selectedTags.length === 0 || selectedTags.every(tag => post.frontmatter.tags.includes(tag)) return matchesSearch && matchesTags }) result.sort((a, b) => { switch (sortBy) { case 'oldest': return new Date(a.frontmatter.date).getTime() - new Date(b.frontmatter.date).getTime() case 'title': return a.frontmatter.title.localeCompare(b.frontmatter.title) case 'newest': default: return new Date(b.frontmatter.date).getTime() - new Date(a.frontmatter.date).getTime() } }) return result }, [posts, searchQuery, selectedTags, sortBy]) const totalPages = Math.ceil(filteredAndSortedPosts.length / postsPerPage) const paginatedPosts = filteredAndSortedPosts.slice( (currentPage - 1) * postsPerPage, currentPage * postsPerPage ) const toggleTag = (tag: string) => { setSelectedTags(prev => (prev.includes(tag) ? prev.filter(t => t !== tag) : [...prev, tag])) setCurrentPage(1) } return (
{/* Header */}

{t('subtitle')}

> {t('title')}_

{/* Search Bar */}
{ setSearchQuery(value) setCurrentPage(1) }} />
{/* Tag Filters */} { setSelectedTags([]) setCurrentPage(1) }} /> {/* Results Count */}

{t('foundPosts', { count: filteredAndSortedPosts.length })}{' '}

{/* Blog Grid */} {paginatedPosts.length > 0 ? (
{paginatedPosts.map((post, index) => { const hasImage = !!post.frontmatter.image let variant: 'image-top' | 'image-side' | 'text-only' if (!hasImage) { variant = 'text-only' } else { variant = index % 3 === 1 ? 'image-side' : 'image-top' } return })}
) : (

{t('noPosts')}

)} {/* Pagination */} {totalPages > 1 && (
{Array.from({ length: totalPages }, (_, i) => i + 1).map(page => ( ))}
)}
) }