Show filtered content related to an object by the value of an input JSX element

Show filtered content related to an object by the value of an input JSX element


0

Say i have an input element that filters categories on a given value. That category object has name, slug, posts, so what I want to do is to show only the posts that are related to that category as the input element in a Search function receives a value . In the console I can see the keys are printed and once a the word matched the a category name the object is printed as well. Here is my code so far
Home component

export default function Home({posts, categories, filteredCategories}) {

  

  return (
    <Layout categories={categories}>
            <div className="mt-20">
      <main className="flex      flex-col justify-center items-center h-screen pt-10 pb-30" >
      {filteredCategories && filteredCategories.length ? (
        filteredCategories.map((post) => (
          <BlogPosts
            coverPic={post.coverPic}
            createdAt={post.createdAt}
            publishedAt={post.publishedAt}
            title={post.title}
            slug={post.slug}
            author={post.author} // Use the author's ID
            key={post.id}
          />
        ))
      ) : (
        posts.map((post) => (
          <BlogPosts
            coverPic={post.coverPic}
            createdAt={post.createdAt}
            publishedAt={post.publishedAt}
            title={post.title}
            slug={post.slug}
            author={post.author} // Use the author's ID
            key={post.id}
          />
        ))
      )}
      </main>
      </div>
    </Layout>
  )
}

Initially I just had it like posts.map((post) => { /* rest of the code */} then I included filteredCategories.map((post) => { /* rest of the code */} as { ? : } conditional to only show filteredCategories when filtered by the value given to the input in the Search component, but it does not change

Layout component

const Layout = ({ categories ,children}) => {   

  const [filteredCategories, setFilteredCategories] = useState(categories);

  const handleSearch = (filteredCategories) => {
    setFilteredCategories(filteredCategories);
  };

  return (
    <div>
      {/* ... */}
      <Search categories={categories} onSearch={handleSearch} />
      {/* Pass filteredCategories to Home */}
    
    </div>
  );
};

Search


export function Search({categories, onSearch}){
    const [searchText, setSearchText] = useState('');

    const filterCategories = () => {
        if (categories) {
            const filteredCategories = categories.filter(category =>
                category.name.toLowerCase().includes(searchText.toLowerCase())
            );
            console.log("Filtered Categories:", filteredCategories);
            onSearch(filteredCategories);
        }
    };
    
      const handleInputChange = event => {
        const searchText = event.target.value;
    console.log("Input Change:", searchText);
    setSearchText(searchText);
    filterCategories();
      };


    return (
        <div className="flex items-center"> 
        <form className='flex space-x-1' >
         <input 
                     type="text"
                     className="block w-full px-4 py-2 text-purple-700 bg-white border rounded-full focus:border-purple-400 focus:ring-purple-300 focus:outline-none focus:ring focus:ring-opacity-40"
                     placeholder="Search..."  
                     value={searchText}
                     onChange={handleInputChange}
                    />
 
        </form>
        </div>
    )
}

On my Search component is where console.log("Filtered Categories:", filteredCategories); prints out the category object when the value typed in the input meets the category name, this is how far I’ve come in my code. How could I only show the posts that are related to the category?. Any suggestions?

Share
Improve this question


Load 4 more related questions


Show fewer related questions

0

Reset to default



Browse other questions tagged

or ask your own question.

Leave a Reply

Your email address will not be published. Required fields are marked *