From 72575fc6a0382148c1a4e49bb3787172246435e7 Mon Sep 17 00:00:00 2001 From: Nishant Kaushal <101548649+nishant0708@users.noreply.github.com> Date: Mon, 29 Jul 2024 02:12:53 +0530 Subject: [PATCH 1/2] Added search_bar --- src/components/blogs/Blogs.jsx | 67 ++++++++++++++++++-------- src/components/blogs/BlogsSkeleton.css | 2 + 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/components/blogs/Blogs.jsx b/src/components/blogs/Blogs.jsx index 9016215f..2e16d9b3 100644 --- a/src/components/blogs/Blogs.jsx +++ b/src/components/blogs/Blogs.jsx @@ -1,20 +1,22 @@ import React, { useEffect, useState } from "react"; -import './Blogs.css'; // Import CSS file for styles +import './Blogs.css'; import Footer from "../Footer/Footer"; -import { useNavigate } from "react-router-dom"; // Import Link and useNavigate from react-router-dom +import { useNavigate } from "react-router-dom"; import { getDatabase, ref, get } from 'firebase/database'; import DOMPurify from "dompurify"; import { marked } from "marked"; import Navbar from "../Navbar/Navbar"; import { toast, ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; -import BlogsSkeleton from "./BlogsSkeleton"; // Import Skeleton component +import BlogsSkeleton from "./BlogsSkeleton"; +import SearchIcon from '../../assets/search_icon.png'; // Replace with your search icon path const Blogs = () => { const [isLoggedIn, setLogin] = useState(false); - const [ids, setIds] = useState({}); const [blogsData, setBlogsData] = useState([]); + const [filteredBlogs, setFilteredBlogs] = useState([]); // State for filtered blogs const [loading, setLoading] = useState(true); // Loading state + const [searchTerm, setSearchTerm] = useState(''); // State for search term const navigate = useNavigate(); const userId = localStorage.getItem('userUid'); const [user, setUser] = useState(null); @@ -30,7 +32,6 @@ const Blogs = () => { try { const db = getDatabase(); - // Fetch user data if logged in if (userId) { const userRef = ref(db, 'users/' + userId); const userSnap = await get(userRef); @@ -38,24 +39,11 @@ const Blogs = () => { if (userSnap.exists()) { const userData = userSnap.val(); setUser(userData); - - const articleCreated = userData.articleCreated; - if (articleCreated) { - const idArray = articleCreated.split(','); - const idObject = idArray.reduce((acc, id) => { - acc[id.trim()] = true; - return acc; - }, {}); - setIds(idObject); - } else { - console.log('No articles created by the user.'); - } } else { console.log('No user data available'); } } - // Fetch all articles const articlesRef = ref(db, 'articles'); const snapshot = await get(articlesRef); @@ -70,6 +58,7 @@ const Blogs = () => { link: `/blogs/${blog.id}` })); setBlogsData(blogsArray); + setFilteredBlogs(blogsArray); // Initialize filtered blogs } else { console.log('No data available'); } @@ -101,6 +90,26 @@ const Blogs = () => { } }, []); + const handleSearchChange = (e) => { + setSearchTerm(e.target.value); + filterBlogs(e.target.value.toLowerCase()); + }; + + const filterBlogs = (term) => { + if (!term) { + setFilteredBlogs(blogsData); + return; + } + + const filtered = blogsData.filter(blog => + blog.title.toLowerCase().includes(term) || + blog.author.toLowerCase().includes(term) || + blog.tags.some(tag => tag.toLowerCase().includes(term)) + ); + + setFilteredBlogs(filtered); + }; + return ( <> @@ -110,12 +119,30 @@ const Blogs = () => {

Our Latest Blogs

Stay updated with our latest news and articles on counseling.

{isLoggedIn && } + + {/* Search Box */} +
+
+ Search +
+ +
+
+ +
+
- { loading ? ( + {loading ? ( // Display skeleton while loading ) : ( - blogsData.map((blog, index) => ( + filteredBlogs.map((blog, index) => (
navigate(blog.link)}>

{blog.title}

{blog.date}

diff --git a/src/components/blogs/BlogsSkeleton.css b/src/components/blogs/BlogsSkeleton.css index 5423db89..62277400 100644 --- a/src/components/blogs/BlogsSkeleton.css +++ b/src/components/blogs/BlogsSkeleton.css @@ -2,6 +2,8 @@ .skeleton-container { display: flex; flex-wrap: wrap; + align-items: center; + justify-content: center; gap: 20px; padding: 20px; width: 100%; From 052fb068bc04a3c99b6db40a3dfb83a5e49f6c08 Mon Sep 17 00:00:00 2001 From: Nishant Kaushal <101548649+nishant0708@users.noreply.github.com> Date: Mon, 29 Jul 2024 02:43:36 +0530 Subject: [PATCH 2/2] search bar --- src/components/blogs/Blogs.css | 50 +++++++++++++++ src/components/blogs/Blogs.jsx | 110 ++++++++++++++++++++++++++++----- 2 files changed, 143 insertions(+), 17 deletions(-) diff --git a/src/components/blogs/Blogs.css b/src/components/blogs/Blogs.css index d73b1381..f0452c77 100644 --- a/src/components/blogs/Blogs.css +++ b/src/components/blogs/Blogs.css @@ -345,4 +345,54 @@ margin:20px 0px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; +} +.search-modes{ + display: flex; + justify-content: center; + align-items: center; + gap: 20px; +} +.search-modes input{ + margin-right: 5px; +} +#dark .search-modes{ + color: white; +} +/* Modal styles */ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0, 0, 0, 0.5); + backdrop-filter: blur(5px); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.modal { + background: white; + padding: 20px; + border-radius: 8px; + max-width: 500px; + width: 100%; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3); + text-align: center; +} + +.modal h2 { + margin-bottom: 20px; +} + +.modal .search-modes { + display: flex; + + gap: 10px; +} + +.modal button { + margin-top: 20px; } \ No newline at end of file diff --git a/src/components/blogs/Blogs.jsx b/src/components/blogs/Blogs.jsx index 2e16d9b3..c11010ee 100644 --- a/src/components/blogs/Blogs.jsx +++ b/src/components/blogs/Blogs.jsx @@ -9,14 +9,16 @@ import Navbar from "../Navbar/Navbar"; import { toast, ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; import BlogsSkeleton from "./BlogsSkeleton"; -import SearchIcon from '../../assets/search_icon.png'; // Replace with your search icon path +import SearchIcon from '../../assets/search_icon.png'; const Blogs = () => { const [isLoggedIn, setLogin] = useState(false); const [blogsData, setBlogsData] = useState([]); - const [filteredBlogs, setFilteredBlogs] = useState([]); // State for filtered blogs - const [loading, setLoading] = useState(true); // Loading state - const [searchTerm, setSearchTerm] = useState(''); // State for search term + const [filteredBlogs, setFilteredBlogs] = useState([]); + const [loading, setLoading] = useState(true); + const [searchTerm, setSearchTerm] = useState(''); + const [searchMode, setSearchMode] = useState('all'); // Default to 'all' search mode + const [isModalOpen, setIsModalOpen] = useState(false); const navigate = useNavigate(); const userId = localStorage.getItem('userUid'); const [user, setUser] = useState(null); @@ -58,7 +60,7 @@ const Blogs = () => { link: `/blogs/${blog.id}` })); setBlogsData(blogsArray); - setFilteredBlogs(blogsArray); // Initialize filtered blogs + setFilteredBlogs(blogsArray); } else { console.log('No data available'); } @@ -66,7 +68,7 @@ const Blogs = () => { console.error('Error fetching blogs:', error); } finally { setTimeout(() => { - setLoading(false); // Set loading to false after 2 seconds + setLoading(false); }, 500); } }; @@ -91,25 +93,51 @@ const Blogs = () => { }, []); const handleSearchChange = (e) => { - setSearchTerm(e.target.value); - filterBlogs(e.target.value.toLowerCase()); + const term = e.target.value.toLowerCase(); + setSearchTerm(term); + + switch (searchMode) { + case 'title': + searchByTitle(term); + break; + case 'author': + searchByAuthor(term); + break; + case 'tags': + searchByTags(term); + break; + default: + searchByAll(term); + } }; - const filterBlogs = (term) => { - if (!term) { - setFilteredBlogs(blogsData); - return; - } + const searchByTitle = (term) => { + const filtered = blogsData.filter(blog => blog.title.toLowerCase().includes(term)); + setFilteredBlogs(filtered); + }; + const searchByAuthor = (term) => { + const filtered = blogsData.filter(blog => blog.author.toLowerCase().includes(term)); + setFilteredBlogs(filtered); + }; + + const searchByTags = (term) => { + const filtered = blogsData.filter(blog => blog.tags.some(tag => tag.toLowerCase().includes(term))); + setFilteredBlogs(filtered); + }; + + const searchByAll = (term) => { const filtered = blogsData.filter(blog => blog.title.toLowerCase().includes(term) || blog.author.toLowerCase().includes(term) || blog.tags.some(tag => tag.toLowerCase().includes(term)) ); - setFilteredBlogs(filtered); }; + const openModal = () => setIsModalOpen(true); + const closeModal = () => setIsModalOpen(false); + return ( <> @@ -123,11 +151,11 @@ const Blogs = () => { {/* Search Box */}
- Search + Search
{
+ + {/* Modal */} + {isModalOpen && ( +
+
+

Select Search Mode

+
+ + + + +
+ +
+
+ )}
{loading ? ( - // Display skeleton while loading + ) : ( filteredBlogs.map((blog, index) => (
navigate(blog.link)}>