|
1 | 1 | import React, { useState, useEffect, useMemo } from 'react'; |
2 | 2 | import ShareModal from '@/components/ShareModal'; |
3 | | -import { useNavigate, useParams } from 'react-router-dom'; |
| 3 | +import { useNavigate, useParams, useLocation } from 'react-router-dom'; |
4 | 4 | import { getAllPosts, groupPostsByCategory, Post } from '@/utils/posts-utils'; |
5 | 5 | import Header from '@/sections/Header'; |
6 | 6 | import Footer from '@/sections/Footer'; |
@@ -42,7 +42,11 @@ const NewsPage: React.FC = () => { |
42 | 42 | const [viewMode, setViewMode] = useState<'grid' | 'list' | 'magazine'>( |
43 | 43 | 'grid', |
44 | 44 | ); |
45 | | - const [searchTerm, setSearchTerm] = useState<string>(''); |
| 45 | + const location = useLocation(); |
| 46 | + const [searchTerm, setSearchTerm] = useState<string>(() => { |
| 47 | + const params = new URLSearchParams(location.search); |
| 48 | + return params.get('q') || ''; |
| 49 | + }); |
46 | 50 |
|
47 | 51 | useEffect(() => { |
48 | 52 | async function load() { |
@@ -74,14 +78,22 @@ const NewsPage: React.FC = () => { |
74 | 78 | setActiveCategory('All'); |
75 | 79 | }, [categoryParam, categories]); |
76 | 80 |
|
| 81 | + // Keep searchTerm in sync with the URL (?q=) |
| 82 | + useEffect(() => { |
| 83 | + const params = new URLSearchParams(location.search); |
| 84 | + const q = params.get('q') || ''; |
| 85 | + setSearchTerm(q); |
| 86 | + }, [location.search]); |
| 87 | + |
77 | 88 | useEffect(() => { |
78 | 89 | const pathCat = |
79 | 90 | activeCategory === 'All' |
80 | 91 | ? 'all' |
81 | 92 | : activeCategory.toLowerCase().replace(/\s+/g, '-'); |
82 | | - navigate(`/news/${pathCat}`, { replace: true }); |
| 93 | + const query = searchTerm ? `?q=${encodeURIComponent(searchTerm)}` : ''; |
| 94 | + navigate(`/news/${pathCat}${query}`, { replace: true }); |
83 | 95 | setDisplayCount(6); |
84 | | - }, [activeCategory, navigate]); |
| 96 | + }, [activeCategory, navigate, searchTerm]); |
85 | 97 |
|
86 | 98 | const sortedCategories = useMemo(() => { |
87 | 99 | const others = categories |
@@ -124,7 +136,8 @@ const NewsPage: React.FC = () => { |
124 | 136 | activeCategory === 'All' |
125 | 137 | ? 'all' |
126 | 138 | : activeCategory.toLowerCase().replace(/\s+/g, '-'); |
127 | | - navigate(`/news/${catPath}/${slug}`); |
| 139 | + const query = searchTerm ? `?q=${encodeURIComponent(searchTerm)}` : ''; |
| 140 | + navigate(`/news/${catPath}/${slug}${query}`); |
128 | 141 | }; |
129 | 142 |
|
130 | 143 | const handleShareClick = (post: Post, e: React.MouseEvent) => { |
@@ -278,7 +291,18 @@ const NewsPage: React.FC = () => { |
278 | 291 | type="text" |
279 | 292 | placeholder="Search articles, topics, or categories..." |
280 | 293 | value={searchTerm} |
281 | | - onChange={(e) => setSearchTerm(e.target.value)} |
| 294 | + onChange={(e) => { |
| 295 | + const value = e.target.value; |
| 296 | + setSearchTerm(value); |
| 297 | + const catPath = |
| 298 | + activeCategory === 'All' |
| 299 | + ? 'all' |
| 300 | + : activeCategory.toLowerCase().replace(/\s+/g, '-'); |
| 301 | + const query = value |
| 302 | + ? `?q=${encodeURIComponent(value)}` |
| 303 | + : ''; |
| 304 | + navigate(`/news/${catPath}${query}`, { replace: true }); |
| 305 | + }} |
282 | 306 | className="w-full pl-10 pr-4 py-3 border border-gray-200 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-300" |
283 | 307 | /> |
284 | 308 | </div> |
@@ -380,7 +404,14 @@ const NewsPage: React.FC = () => { |
380 | 404 | <span>{filteredPosts.length} articles found</span> |
381 | 405 | {searchTerm && ( |
382 | 406 | <button |
383 | | - onClick={() => setSearchTerm('')} |
| 407 | + onClick={() => { |
| 408 | + setSearchTerm(''); |
| 409 | + const catPath = |
| 410 | + activeCategory === 'All' |
| 411 | + ? 'all' |
| 412 | + : activeCategory.toLowerCase().replace(/\s+/g, '-'); |
| 413 | + navigate(`/news/${catPath}`, { replace: true }); |
| 414 | + }} |
384 | 415 | className="text-blue-600 hover:text-blue-700 underline text-sm" |
385 | 416 | > |
386 | 417 | Clear search |
|
0 commit comments