|
1 | | -import React, { type ChangeEvent } from "react"; |
| 1 | +import React from "react"; |
2 | 2 | import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; |
3 | 3 | import Layout from "@theme/Layout"; |
4 | 4 | import Link from "@docusaurus/Link"; |
5 | 5 | import blogs from "../../database/blogs/index"; |
6 | 6 | import Head from "@docusaurus/Head"; |
7 | 7 | import { getAuthorProfiles, getAuthorTooltip } from "../../utils/authors"; |
| 8 | +import { filterBlogsBySearchTerm } from "../../utils/blogFilters"; |
8 | 9 |
|
9 | 10 | import "./blogs-new.css"; |
10 | 11 |
|
11 | 12 | export default function Blogs() { |
12 | 13 | const { siteConfig } = useDocusaurusContext(); |
13 | 14 | const [searchInput, setSearchInput] = React.useState(""); |
14 | 15 | const [searchTerm, setSearchTerm] = React.useState(""); |
15 | | - const [filteredBlogs, setFilteredBlogs] = React.useState(blogs); |
16 | | - |
17 | | - // Filter blogs after the user submits the blog search form. |
18 | | - React.useEffect(() => { |
19 | | - let filtered = blogs; |
20 | | - |
21 | | - if (searchTerm.trim() !== "") { |
22 | | - const normalizedSearch = searchTerm.trim().toLowerCase(); |
23 | | - filtered = filtered.filter( |
24 | | - (blog) => |
25 | | - blog.title.toLowerCase().includes(normalizedSearch) || |
26 | | - blog.description.toLowerCase().includes(normalizedSearch) || |
27 | | - blog.tags?.some((tag) => |
28 | | - tag.toLowerCase().includes(normalizedSearch), |
29 | | - ), |
30 | | - ); |
31 | | - } |
32 | | - |
33 | | - setFilteredBlogs(filtered); |
34 | | - }, [searchTerm]); |
| 16 | + const filteredBlogs = React.useMemo( |
| 17 | + () => filterBlogsBySearchTerm(blogs, searchTerm), |
| 18 | + [searchTerm], |
| 19 | + ); |
35 | 20 |
|
36 | | - const handleSearchChange = (e: ChangeEvent<HTMLInputElement>) => { |
| 21 | + const handleSearchChange = (e: { target: { value: string } }) => { |
37 | 22 | setSearchInput(e.target.value); |
38 | 23 | }; |
39 | 24 |
|
40 | | - const handleSearchSubmit = (e: React.FormEvent<HTMLFormElement>) => { |
| 25 | + const handleSearchSubmit = (e: { preventDefault: () => void }) => { |
41 | 26 | e.preventDefault(); |
42 | 27 | setSearchTerm(searchInput.trim()); |
43 | 28 | }; |
@@ -157,7 +142,9 @@ export default function Blogs() { |
157 | 142 | <div className="articles-grid"> |
158 | 143 | {filteredBlogs.length > 0 ? ( |
159 | 144 | filteredBlogs.map((blog) => ( |
160 | | - <BlogCard key={blog.id ?? blog.slug} blog={blog} /> |
| 145 | + <React.Fragment key={blog.id ?? blog.slug}> |
| 146 | + <BlogCard blog={blog} /> |
| 147 | + </React.Fragment> |
161 | 148 | )) |
162 | 149 | ) : ( |
163 | 150 | <div className="no-results"> |
|
0 commit comments