diff --git a/src/app/[locale]/blog/page.tsx b/src/app/[locale]/blog/page.tsx index 7bbd402..1adc7ff 100644 --- a/src/app/[locale]/blog/page.tsx +++ b/src/app/[locale]/blog/page.tsx @@ -7,6 +7,7 @@ import { BlogList } from '@/components/blog/BlogList'; type Props = { params: Promise<{ locale: string }>; + searchParams: Promise<{ [key: string]: string | string[] | undefined }>; }; // Legacy blog posts with translations (these have manual translations) @@ -304,8 +305,9 @@ export async function generateMetadata({ params }: Props): Promise { } -export default async function BlogPage({ params }: Props) { +export default async function BlogPage({ params, searchParams }: Props) { const { locale } = await params; + const resolvedSearchParams = await searchParams; setRequestLocale(locale); const t = await getTranslations('blog'); @@ -323,6 +325,10 @@ export default async function BlogPage({ params }: Props) { ...legacyPosts, ].sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()); + // Extract search and category from URL params + const initialSearch = typeof resolvedSearchParams.search === 'string' ? resolvedSearchParams.search : ''; + const initialCategory = typeof resolvedSearchParams.category === 'string' ? resolvedSearchParams.category : null; + return (
@@ -344,6 +350,8 @@ export default async function BlogPage({ params }: Props) { diff --git a/src/components/blog/BlogList.tsx b/src/components/blog/BlogList.tsx index 381b537..40eedd6 100644 --- a/src/components/blog/BlogList.tsx +++ b/src/components/blog/BlogList.tsx @@ -1,9 +1,10 @@ 'use client'; -import { useState, useMemo } from 'react'; +import { useState, useMemo, useEffect } from 'react'; import { Calendar, Tag, ExternalLink, ChevronLeft, ChevronRight } from 'lucide-react'; import Link from 'next/link'; import Image from 'next/image'; +import { useRouter, usePathname } from 'next/navigation'; import { BlogPost } from '@/lib/blog'; import { SearchBar } from './SearchBar'; import { CategoryFilter } from './CategoryFilter'; @@ -281,6 +282,8 @@ function Pagination({ interface BlogListProps { posts: BlogPost[]; locale: string; + initialSearch?: string; + initialCategory?: string | null; translations: { searchPlaceholder: string; showingText: (start: number, end: number, total: number) => string; @@ -290,11 +293,32 @@ interface BlogListProps { }; } -export function BlogList({ posts, locale, translations }: BlogListProps) { - const [searchQuery, setSearchQuery] = useState(''); - const [selectedCategory, setSelectedCategory] = useState(null); +export function BlogList({ posts, locale, initialSearch = '', initialCategory = null, translations }: BlogListProps) { + const router = useRouter(); + const pathname = usePathname(); + + const [searchQuery, setSearchQuery] = useState(initialSearch); + const [selectedCategory, setSelectedCategory] = useState(initialCategory); const [currentPage, setCurrentPage] = useState(1); + // Update URL when filters change + useEffect(() => { + const params = new URLSearchParams(); + + if (searchQuery.trim()) { + params.set('search', searchQuery.trim()); + } + + if (selectedCategory) { + params.set('category', selectedCategory); + } + + const queryString = params.toString(); + const newUrl = queryString ? `${pathname}?${queryString}` : pathname; + + router.push(newUrl, { scroll: false }); + }, [searchQuery, selectedCategory, pathname, router]); + // Extract unique categories from all posts const allCategories = useMemo(() => { const categories = new Set(posts.map(post => post.category).filter(Boolean));