Skip to content

Commit 4ac8fbb

Browse files
authored
Merge pull request #1599 from MiniduOshan/issue-1597-refactor-blog-filtering
fixed #1597 Refactor blog filtering logic for maintainability
2 parents 9e09962 + 428b220 commit 4ac8fbb

2 files changed

Lines changed: 34 additions & 24 deletions

File tree

src/pages/blogs/index.tsx

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,28 @@
1-
import React, { type ChangeEvent } from "react";
1+
import React from "react";
22
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
33
import Layout from "@theme/Layout";
44
import Link from "@docusaurus/Link";
55
import blogs from "../../database/blogs/index";
66
import Head from "@docusaurus/Head";
77
import { getAuthorProfiles, getAuthorTooltip } from "../../utils/authors";
8+
import { filterBlogsBySearchTerm } from "../../utils/blogFilters";
89

910
import "./blogs-new.css";
1011

1112
export default function Blogs() {
1213
const { siteConfig } = useDocusaurusContext();
1314
const [searchInput, setSearchInput] = React.useState("");
1415
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+
);
3520

36-
const handleSearchChange = (e: ChangeEvent<HTMLInputElement>) => {
21+
const handleSearchChange = (e: { target: { value: string } }) => {
3722
setSearchInput(e.target.value);
3823
};
3924

40-
const handleSearchSubmit = (e: React.FormEvent<HTMLFormElement>) => {
25+
const handleSearchSubmit = (e: { preventDefault: () => void }) => {
4126
e.preventDefault();
4227
setSearchTerm(searchInput.trim());
4328
};
@@ -157,7 +142,9 @@ export default function Blogs() {
157142
<div className="articles-grid">
158143
{filteredBlogs.length > 0 ? (
159144
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>
161148
))
162149
) : (
163150
<div className="no-results">

src/utils/blogFilters.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
type BlogLike = {
2+
title: string;
3+
description: string;
4+
tags?: string[];
5+
};
6+
7+
export function filterBlogsBySearchTerm<T extends BlogLike>(
8+
blogs: T[],
9+
searchTerm: string,
10+
): T[] {
11+
const normalizedSearch = searchTerm.trim().toLowerCase();
12+
13+
if (normalizedSearch === "") {
14+
return blogs;
15+
}
16+
17+
return blogs.filter(
18+
(blog) =>
19+
blog.title.toLowerCase().includes(normalizedSearch) ||
20+
blog.description.toLowerCase().includes(normalizedSearch) ||
21+
blog.tags?.some((tag) => tag.toLowerCase().includes(normalizedSearch)),
22+
);
23+
}

0 commit comments

Comments
 (0)