From 9b37739319aa94223856c82adf1e55477f3bfc5f Mon Sep 17 00:00:00 2001 From: Kabir <44284877+kabir0x23@users.noreply.github.com> Date: Mon, 27 May 2024 02:52:03 +0530 Subject: [PATCH] feat/ench/bug fxies --- src/App.jsx | 5 +- src/components/Blogs/BlogCard/BlogCard.jsx | 35 ++++- .../Blogs/BlogCard/BlogCardElements.jsx | 36 +++-- src/components/Blogs/BlogCard/BlogCards.jsx | 4 +- .../BlogComments/AddCommentFormElements.jsx | 8 +- src/components/Blogs/Blogs.jsx | 6 +- src/components/Blogs/BlogsElements.jsx | 9 +- src/components/Blogs/BlogsRoute.jsx | 10 +- src/components/Blogs/ReactBarr/ReactBar.jsx | 30 ++-- .../OldDashbaord => }/Blogs/UserBlogs.jsx | 16 +- src/components/Blogs/ViewBlog/ViewBlog.jsx | 35 ++++- src/components/CaptureTheFlag/CTF.jsx | 18 +++ src/components/CaptureTheFlag/CTFRoute.jsx | 3 + src/components/CaptureTheFlag/Team/Team.jsx | 15 +- .../CaptureTheFlag/Team/TeamElements.jsx | 1 + .../Common/SocialSidebar/Sidebar.jsx | 101 ++---------- .../Common/SocialSidebar/SidebarElements.jsx | 2 +- .../Dashboard/Bookmarks/Bookmarks.jsx | 85 ++++++++-- .../DashbaordSidebar/DashboardSidebar.jsx | 14 +- src/components/Dashboard/DashboardRoute.jsx | 11 +- .../Dashboard/Reconage/Reconage.jsx | 145 ++++++++++++++++++ .../Dashboard/Reconage/ReconageElements.jsx | 0 src/components/Feeds/Feeds.jsx | 2 + src/components/Feeds/FeedsRoute.jsx | 3 + src/components/Feeds/UserFeeds.jsx | 37 +++++ src/components/Header/Dropdowns/Dropdown.jsx | 2 +- .../Header/Navbar/NavbarElements.jsx | 1 - .../Tools/BreachCheck/BreachCheckElements.jsx | 8 + .../Tools/SubdomainFinder/SubdomainFinder.jsx | 3 +- src/components/Tools/Tools.jsx | 15 +- src/components/Tools/ToolsRoute.jsx | 4 +- src/components/index.js | 2 +- 32 files changed, 467 insertions(+), 199 deletions(-) rename src/components/{Dashboard/OldDashbaord => }/Blogs/UserBlogs.jsx (89%) create mode 100644 src/components/Dashboard/Reconage/Reconage.jsx create mode 100644 src/components/Dashboard/Reconage/ReconageElements.jsx create mode 100644 src/components/Feeds/UserFeeds.jsx diff --git a/src/App.jsx b/src/App.jsx index 77eab9c5..e0378e71 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -8,7 +8,6 @@ import ScrollToTop from "./components/Other/ScrollToTop"; import { About, Community, - CreateBlog, // CyberGames, Footer, InterviewQuestions, @@ -72,6 +71,7 @@ import ResetPassword from "src/pages/ResetPassword"; import Register from "src/pages/Register"; // import CyberNews from "./components/Resources/CyberNews/CyberNews"; import ChatBox from "src/components/Chat/ChatBox/ChatBox"; +import CheatSheetsRoutes from "src/components/CheatSheets/CheatSheetsRoutes.jsx"; // import isAuthenticated from "./features/isAuthenticated"; // import ChatBot from "./components/ChatBot/ChatBot"; @@ -153,7 +153,6 @@ const App = () => { } /> } /> } /> - } /> } /> @@ -170,7 +169,7 @@ const App = () => { } /> } /> } /> - {/* } /> */} + } /> } /> } /> diff --git a/src/components/Blogs/BlogCard/BlogCard.jsx b/src/components/Blogs/BlogCard/BlogCard.jsx index c907cc75..db000c36 100644 --- a/src/components/Blogs/BlogCard/BlogCard.jsx +++ b/src/components/Blogs/BlogCard/BlogCard.jsx @@ -25,18 +25,35 @@ import { useDispatch, useSelector } from "react-redux"; import { BiEdit } from "react-icons/bi"; import { deleteBlog } from "src/features/blogs/blogSlice"; import { AiFillDelete } from "react-icons/ai"; +import { PostStat, PostStatLabel } from "src/components/Feeds/FeedPosts/FeedPostsElements.jsx"; +import { BsBookmarks, BsBookmarksFill } from "react-icons/bs"; +import { addBookmark, removeBookmark } from "src/features/bookmarks/bookmarkSlice.js"; const image = "https://user-images.githubusercontent.com/44284877/210166161-ad2f71a7-df74-43b9-8330-af9740d9e8ba.png"; -const BlogCard = ({ blog }) => { +const BlogCard = ({ blog, bookmarks }) => { const pathname = window.location.pathname; - const isDashboard = pathname.split("/").includes("dashboard"); - console.log(pathname.split("/")[1]); + const isDashboard = pathname.split("/").includes("my-blogs"); const dispatch = useDispatch(); const coverImage = blog?.coverImage; const coverImageUrl = cdnContentImagesUrl(`/blog/${coverImage}`) || image; const { user } = useSelector((state) => state.auth); + const userId = user?._id; + + const isBookmarked = () => { + return bookmarks?.some((bookmark) => bookmark.user === userId && bookmark.itemId === blog?._id); + }; + + const itemType = "blog"; + + const handleBookmark = (_id) => { + if (isBookmarked(_id)) { + dispatch(removeBookmark({ itemType, itemId: _id })); + } else { + dispatch(addBookmark({ itemType, itemId: _id })); + } + }; return ( @@ -57,13 +74,13 @@ const BlogCard = ({ blog }) => { + @{blog?.username} {blog?.title} - {/* {blog?.content.slice(0, 125)} */} @@ -72,11 +89,15 @@ const BlogCard = ({ blog }) => { {blog?.tags .slice(0, 3) - .map((tag, id) => (tag.length !== 0 ? {tag.slice(0, 30)} : null))} - + .map((tag, id) => (tag.length !== 0 ? {tag.slice(0, 18)} : null))} {blog?.tags.length > 3 ? + {blog?.tags.length - 3} : null} - @{blog?.username} + + + handleBookmark(blog?._id)}> + {isBookmarked(blog?._id) ? : } + + ); diff --git a/src/components/Blogs/BlogCard/BlogCardElements.jsx b/src/components/Blogs/BlogCard/BlogCardElements.jsx index 41127187..1c56759e 100644 --- a/src/components/Blogs/BlogCard/BlogCardElements.jsx +++ b/src/components/Blogs/BlogCard/BlogCardElements.jsx @@ -1,24 +1,24 @@ import styled from "styled-components"; import { BsCheck } from "react-icons/bs"; - export const ContainerCard = styled.div` display: flex; flex-direction: column; width: 100%; + max-width: 400px; text-align: start; background: #111; justify-content: space-between; border-radius: 5px; - transition: 0.3s ease-in-out; + transition: transform 0.3s ease-in-out; /* Corrected property name */ border: 1px solid #1f1f1f; &:hover { - scale: 1.03; - transition: 0.3s ease-in-out; + transform: scale(1.03); /* Corrected property name */ } `; export const BlogImageSection = styled.div` + position: relative; display: flex; flex-direction: column; justify-content: end; @@ -75,7 +75,7 @@ export const BlogCardImage = styled.img` width: 100%; height: auto; object-fit: cover; - max-height: 300px; + max-height: 150px; display: block; margin: 0 auto; border-radius: 15px 15px 0 0; @@ -91,7 +91,7 @@ export const MainSection = styled.div` `; export const SubSection = styled.div` - padding: 25px; + padding: 15px 15px 10px; @media screen and (width <= 600px) { padding: 10px 10px 15px 15px; @@ -100,6 +100,7 @@ export const SubSection = styled.div` export const DetailsSection = styled.div` display: flex; + position: relative; flex-direction: column; text-align: start; width: 100%; @@ -115,11 +116,11 @@ export const FooterDetailsSection = styled.div` display: flex; align-items: end; justify-content: space-between; - padding: 5px 5px 15px 0; + padding: 0 10px 10px; `; export const Title = styled.div` - font-size: 20px; + font-size: 14px; font-weight: bold; margin-bottom: 5px; word-wrap: break-word; @@ -149,18 +150,23 @@ export const Description = styled.div` } `; export const Username = styled.p` - padding: 0 5px 0 0; - - @media screen and (width <= 600px) { - font-size: 10px; - } + position: absolute; + bottom: 5px; + right: 5px; + background-color: rgb(0 0 0 / 70%); + color: #d3d3d3; + padding: 5px; + border-radius: 5px; + font-size: 10px; + font-weight: bold; `; + export const Date = styled.p` font-size: 10px; margin: 0 5px 0 0; `; + export const Categories = styled.div` - margin-left: 25px; display: flex; flex-wrap: wrap; word-wrap: break-word; @@ -175,7 +181,7 @@ export const Category = styled.p` margin: 5px 5px 5px 0; border-radius: 2px; cursor: pointer; - font-size: 13px; + font-size: 11px; transition: transform 0.3s; &:hover { diff --git a/src/components/Blogs/BlogCard/BlogCards.jsx b/src/components/Blogs/BlogCard/BlogCards.jsx index 52135924..7b8ec26f 100644 --- a/src/components/Blogs/BlogCard/BlogCards.jsx +++ b/src/components/Blogs/BlogCard/BlogCards.jsx @@ -4,7 +4,7 @@ import BlogCard from "./BlogCard"; import LoadingSpinner from "src/components/Other/MixComponents/Spinner/LoadingSpinner"; import NotFound from "src/NotFound"; -const BlogCards = ({ blogs, searchTerm, isBlogLoading, blogsBookmarksData, displayAt, selectedTags }) => { +const BlogCards = ({ blogs, searchTerm, isBlogLoading, blogsBookmarksData, displayAt, selectedTags, bookmarks }) => { if (isBlogLoading) return ; if (!blogs.length) return ; @@ -35,7 +35,7 @@ const BlogCards = ({ blogs, searchTerm, isBlogLoading, blogsBookmarksData, displ ?.slice() .reverse() .map((blog) => ( - + ))} ) : null; diff --git a/src/components/Blogs/BlogComments/AddCommentFormElements.jsx b/src/components/Blogs/BlogComments/AddCommentFormElements.jsx index d16336c9..b0026b2f 100644 --- a/src/components/Blogs/BlogComments/AddCommentFormElements.jsx +++ b/src/components/Blogs/BlogComments/AddCommentFormElements.jsx @@ -13,7 +13,6 @@ export const AddCommentFormContainer = styled.div` overflow-y: auto; box-shadow: 0 4px 8px 0 rgb(0 0 0 / 20%); color: #f5f5f5; - border: 1px solid rgb(65 65 65); background: transparent; `; @@ -35,7 +34,7 @@ export const Input = styled.input` border-radius: 5px; background: #262525; border: transparent; - color: #f5f5f5; + color: #c6c6c6; width: 100%; height: 50px; font-size: 15px; @@ -47,7 +46,10 @@ export const Input = styled.input` } &:hover { - border: 1px solid #aaa; + background: #292828; + border: transparent; + color: #ddd; + outline: none; } &::placeholder { diff --git a/src/components/Blogs/Blogs.jsx b/src/components/Blogs/Blogs.jsx index 1bbbd8eb..bfbbc876 100644 --- a/src/components/Blogs/Blogs.jsx +++ b/src/components/Blogs/Blogs.jsx @@ -10,6 +10,7 @@ import BlogCards from "src/components/Blogs/BlogCard/BlogCards"; import { getAllUserDetails, userDetailReset } from "src/features/userDetail/userDetailSlice"; import { getFollowData, reset } from "src/features/follow/followSlice"; import Sidebar from "src/components/Common/SocialSidebar/Sidebar"; +import { getBookmarks } from "src/features/bookmarks/bookmarkSlice.js"; const Blogs = () => { const dispatch = useDispatch(); @@ -26,6 +27,7 @@ const Blogs = () => { (state) => state.userDetail, ); const { followData } = useSelector((state) => state.followData); + const { bookmarks } = useSelector((state) => state.bookmarks); const userId = user?._id; @@ -33,7 +35,9 @@ const Blogs = () => { if (isBlogError) console.log(blogMessage); if (isUserDetailError) console.log(userDetailMessage); if (userId) dispatch(getFollowData(userId)); + dispatch(getAllBlogs()); + dispatch(getBookmarks()); dispatch(getAllUserDetails()); return () => { @@ -105,7 +109,7 @@ const Blogs = () => { - + (props.$displayAt === "explore" ? "#090909" : "#000000")}; padding: ${(props) => (props.$displayAt ? "15px" : "0")}; + width: 100%; + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); /* Adjust this as per your requirement */ + gap: 15px; @media screen and (width <= 800px) { - grid-auto-rows: 0fr; - gap: 15px; - padding: 15px; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); } `; diff --git a/src/components/Blogs/BlogsRoute.jsx b/src/components/Blogs/BlogsRoute.jsx index 7d2e9290..7b278e12 100644 --- a/src/components/Blogs/BlogsRoute.jsx +++ b/src/components/Blogs/BlogsRoute.jsx @@ -1,12 +1,20 @@ import React from "react"; import { Route, Routes } from "react-router-dom"; -import { Blogs, NotFound, SingleBlog } from "src/components/index"; +import { Blogs, CreateBlog, EditBlog, NotFound, SingleBlog, UserBlogs } from "src/components/index"; +import CreateBlogV2 from "src/components/Blogs/ManageBlogs/CreateBlogV2/CreateBlogV2.jsx"; const BlogsRoute = () => { return ( } /> } /> + } /> + + } /> + + } /> + } /> + {/* }/> */} } /> diff --git a/src/components/Blogs/ReactBarr/ReactBar.jsx b/src/components/Blogs/ReactBarr/ReactBar.jsx index f20cb229..3e19d428 100644 --- a/src/components/Blogs/ReactBarr/ReactBar.jsx +++ b/src/components/Blogs/ReactBarr/ReactBar.jsx @@ -1,11 +1,12 @@ -// ReactBar.jsx import React from "react"; -import { FaHeart, FaComment, FaBookmark, FaShare } from "react-icons/fa"; +import { FaHeart, FaComment, FaShare } from "react-icons/fa"; import styled from "styled-components"; +import { PostStat, PostStatLabel } from "src/components/Feeds/FeedPosts/FeedPostsElements.jsx"; +import { BsBookmarks, BsBookmarksFill } from "react-icons/bs"; +import { Link as ScrollLink } from "react-scroll"; -// Styled Components const SocialBarContainer = styled.div` - color: black; + color: #f4f4f4; position: fixed; bottom: 0; width: 20%; @@ -13,7 +14,7 @@ const SocialBarContainer = styled.div` display: flex; justify-content: space-around; align-items: center; - background-color: #fff; + background-color: #1e1e1e; padding: 10px; margin-bottom: 10px; box-shadow: 0 -2px 8px rgb(0 0 0 / 10%); @@ -31,16 +32,15 @@ const IconContainer = styled.div` & svg { width: 20px; height: 20px; - color: #333; + color: #d5d5d5; } &:hover svg { - color: rgb(255 107 8); + color: #ff6b08; } `; -// React Component -const ReactBar = () => { +const ReactBar = ({ handleBookmark, isBookmarked, blog }) => { return ( @@ -48,11 +48,15 @@ const ReactBar = () => { 10 - - - - + + + + + handleBookmark(blog?._id)}> + {isBookmarked(blog?._id) ? : } + + diff --git a/src/components/Dashboard/OldDashbaord/Blogs/UserBlogs.jsx b/src/components/Blogs/UserBlogs.jsx similarity index 89% rename from src/components/Dashboard/OldDashbaord/Blogs/UserBlogs.jsx rename to src/components/Blogs/UserBlogs.jsx index 97f71ed9..7aa9c137 100644 --- a/src/components/Dashboard/OldDashbaord/Blogs/UserBlogs.jsx +++ b/src/components/Blogs/UserBlogs.jsx @@ -1,14 +1,14 @@ import React, { useEffect } from "react"; -import { Wrapper } from "src/components/Dashboard/Profile/ProfileElements"; -import { AllBlogs, BlogsContainer, MiddleContainer } from "src/components/Blogs/BlogsElements"; -import LoadingBlogCard from "src/components/Blogs/BlogCard/LoadingBlogCard"; -import BlogCard from "src/components/Blogs/BlogCard/BlogCard"; +import { Wrapper } from "src/components/Dashboard/Profile/ProfileElements.jsx"; +import { AllBlogs, BlogsContainer, MiddleContainer } from "src/components/Blogs/BlogsElements.jsx"; +import LoadingBlogCard from "src/components/Blogs/BlogCard/LoadingBlogCard.jsx"; +import BlogCard from "src/components/Blogs/BlogCard/BlogCard.jsx"; import { useDispatch, useSelector } from "react-redux"; -import { getBlogs, blogReset } from "src/features/blogs/blogSlice"; -import LoadingSpinner from "src/components/Other/MixComponents/Spinner/LoadingSpinner"; -import UnderMaintenance from "src/components/Other/UnderMaintenance/UnderMaintenance"; -import apiStatus from "src/features/apiStatus"; +import { getBlogs, blogReset } from "src/features/blogs/blogSlice.js"; +import LoadingSpinner from "src/components/Other/MixComponents/Spinner/LoadingSpinner.jsx"; +import UnderMaintenance from "src/components/Other/UnderMaintenance/UnderMaintenance.jsx"; +import apiStatus from "src/features/apiStatus.jsx"; const UserBlogs = () => { const { isApiLoading, isApiWorking } = apiStatus(); diff --git a/src/components/Blogs/ViewBlog/ViewBlog.jsx b/src/components/Blogs/ViewBlog/ViewBlog.jsx index ca41f77f..b881044c 100644 --- a/src/components/Blogs/ViewBlog/ViewBlog.jsx +++ b/src/components/Blogs/ViewBlog/ViewBlog.jsx @@ -5,6 +5,7 @@ import { useDispatch, useSelector } from "react-redux"; import { blogReset, getAllBlogs } from "src/features/blogs/blogSlice"; import { Helmet, HelmetProvider } from "react-helmet-async"; import ReactBar from "src/components/Blogs/ReactBarr/ReactBar"; // Ensure this path is correct + import { BlogContent, BlogImage, @@ -34,6 +35,7 @@ import { blogCommentReset, getBlogComments } from "src/features/blogs/blogCommen import { getAllUserDetails, userDetailReset } from "src/features/userDetail/userDetailSlice"; import { RouterLink } from "src/components/Tools/ToolsElements"; import DOMPurify from "dompurify"; +import { addBookmark, getBookmarks, removeBookmark } from "src/features/bookmarks/bookmarkSlice.js"; const ViewBlog = () => { const dispatch = useDispatch(); const { isApiLoading, isApiWorking } = apiStatus(); @@ -43,8 +45,8 @@ const ViewBlog = () => { const { userDetails, isUserDetailLoading, isUserDetailError, userDetailMessage } = useSelector( (state) => state.userDetail, ); - - // const {user} = useSelector(state => state.auth); + const { bookmarks } = useSelector((state) => state.bookmarks); + const { user } = useSelector((state) => state.auth); useEffect(() => { if (isBlogError) console.log(blogMessage); @@ -53,6 +55,7 @@ const ViewBlog = () => { dispatch(getAllBlogs()); dispatch(getBlogComments()); dispatch(getAllUserDetails()); + dispatch(getBookmarks()); return () => { dispatch(blogReset()); @@ -70,6 +73,7 @@ const ViewBlog = () => { } if (!isApiWorking) return ; + const userId = user?._id; const blogsData = blogs.map((blog) => { const userDetail = userDetails?.find((user) => user.user === blog.user); @@ -136,6 +140,25 @@ const ViewBlog = () => { const blogCommentsData = blogsCommentsData.filter((comment) => comment.blogId === blog?._id); const purifiedCode = DOMPurify.sanitize(filterContent); + + const isBookmarked = () => { + return bookmarks?.some((bookmark) => bookmark.user === userId && bookmark.itemId === blog?._id); + }; + + const itemType = "blog"; + + const handleBookmark = (_id) => { + // if (!user) { + // setShowAuthPopup(true); + // // setStopRefresh && setStopRefresh(true); + // return; + // } + if (isBookmarked(_id)) { + dispatch(removeBookmark({ itemType, itemId: _id })); + } else { + dispatch(addBookmark({ itemType, itemId: _id })); + } + }; return ( @@ -148,6 +171,7 @@ const ViewBlog = () => { {/* {blog?.category} */} + {blog?.title} @@ -174,13 +198,16 @@ const ViewBlog = () => { {/* */} - + {/* */} - {/* Fixed ReactBar component at the bottom */} + {/* */} + {/* */} + {" "} + {/* Fixed ReactBar component at the bottom */} ); }; diff --git a/src/components/CaptureTheFlag/CTF.jsx b/src/components/CaptureTheFlag/CTF.jsx index 55d3538d..43a178ad 100644 --- a/src/components/CaptureTheFlag/CTF.jsx +++ b/src/components/CaptureTheFlag/CTF.jsx @@ -98,6 +98,24 @@ const CTF = () => { insane + + + + + Teams + + + { return ( @@ -10,6 +11,8 @@ const CtfRoute = () => { } /> } /> } /> + } /> + } /> } /> diff --git a/src/components/CaptureTheFlag/Team/Team.jsx b/src/components/CaptureTheFlag/Team/Team.jsx index d8fff1be..06518f8e 100644 --- a/src/components/CaptureTheFlag/Team/Team.jsx +++ b/src/components/CaptureTheFlag/Team/Team.jsx @@ -16,16 +16,21 @@ import { AiFillEdit } from "react-icons/ai"; import { BiTimeFive } from "react-icons/bi"; import { BsCheck } from "react-icons/bs"; import { ImCross } from "react-icons/im"; -import { registeredUser } from "src/components/CaptureTheFlag/CTFData"; +import { registeredUser, teams } from "src/components/CaptureTheFlag/CTFData"; +import { Wrapper } from "src/components/Dashboard/Profile/ProfileElements.jsx"; -const Team = ({ team, isTeamEdit }) => { +const Team = () => { + const [team, setTeam] = useState(teams[0]); const [editTeam, setEditTeam] = useState(false); const [teamName, setTeamName] = useState(team.teamName || ""); const [teamMembersList, setTeamMembersList] = useState(team.teamMembers || []); const [searchResults, setSearchResults] = useState([]); + const [isTeamEdit, setIsTeamEdit] = useState(true); const handleEditTeamName = () => { setEditTeam(!editTeam); + setIsTeamEdit(false); + setTeam(teams[0]); }; const handleTeamNameChange = (e) => { @@ -69,7 +74,7 @@ const Team = ({ team, isTeamEdit }) => { }; return ( - + {editTeam ? ( @@ -83,9 +88,9 @@ const Team = ({ team, isTeamEdit }) => { ) : ( teamName )} - {isTeamEdit ? : null} + {editTeam && teamMembersList.length < 2 ? ( @@ -113,7 +118,7 @@ const Team = ({ team, isTeamEdit }) => { ))} - + ); }; diff --git a/src/components/CaptureTheFlag/Team/TeamElements.jsx b/src/components/CaptureTheFlag/Team/TeamElements.jsx index 9eff29aa..00564eb1 100644 --- a/src/components/CaptureTheFlag/Team/TeamElements.jsx +++ b/src/components/CaptureTheFlag/Team/TeamElements.jsx @@ -2,6 +2,7 @@ import styled from "styled-components"; export const TeamName = styled.div` display: flex; + color: #fff; justify-content: space-between; align-items: center; width: 100%; diff --git a/src/components/Common/SocialSidebar/Sidebar.jsx b/src/components/Common/SocialSidebar/Sidebar.jsx index 97f17cbd..fc3ceb88 100644 --- a/src/components/Common/SocialSidebar/Sidebar.jsx +++ b/src/components/Common/SocialSidebar/Sidebar.jsx @@ -4,8 +4,6 @@ import { FilterButton, FilterContainer } from "src/components/Feeds/FeedsElement import SearchInputBox from "src/components/Common/SearchInputBox"; import SocialTags from "src/components/Feeds/FeedTags/SocialTags"; import { SidebarContainer } from "./SidebarElements"; -import { RouterLink } from "src/components/Tools/ToolsElements"; -import { encodeURL } from "src/components/Blogs/util"; import { RouterNavCreateButtonLink } from "src/components/Header/Navbar/NavbarElements"; const Sidebar = ({ @@ -92,15 +90,18 @@ const Sidebar = ({ {sidebarType === "blogs" && ( - Create Blog - View My Blogs + Create Blog + View My Blogs + Saved )} - {/* {sidebarType === "feeds" && */} - {/* Create */} - {/* View My Feeds */} - {/* } */} + {sidebarType === "feeds" && ( + + View My Feeds + Saved + + )} {user && {renderFollowingFilterButtons()}} @@ -121,90 +122,6 @@ const Sidebar = ({ selectedTags={selectedTags} setSelectedTags={setSelectedTags} /> - - {(sidebarType === "blogs" || sidebarType === "feeds") && data && data.length > 0 && ( - - - - setShowOnlyFollowing(false)} - > - {sidebarType === "blogs" && "Trending Blogs"} - {sidebarType === "feeds" && "Trending Feeds"} - - - - - - {data.slice(0, 4).map((item, index) => ( - - - - {item.title - ? item.title.slice(0, 48) - : item.content.replace(/[^a-zA-Z ]/g, "").slice(0, 48)} - - - {item.title ? item.content.replace(/<[^>]+>/g, "").slice(0, 100) : null} - - - - ))} - - - )} ); }; diff --git a/src/components/Common/SocialSidebar/SidebarElements.jsx b/src/components/Common/SocialSidebar/SidebarElements.jsx index ed13e6c9..ebfa72ed 100644 --- a/src/components/Common/SocialSidebar/SidebarElements.jsx +++ b/src/components/Common/SocialSidebar/SidebarElements.jsx @@ -8,7 +8,7 @@ export const SidebarContainer = styled.div` gap: 10px; top: 100px; width: 100%; - max-width: 400px; + max-width: 200px; min-width: ${(props) => (props.$sidebarType === "explore" ? "310px" : "400px")}; color: #fff; box-shadow: 0 4px 8px rgb(0 0 0 / 10%); diff --git a/src/components/Dashboard/Bookmarks/Bookmarks.jsx b/src/components/Dashboard/Bookmarks/Bookmarks.jsx index 1bfd78da..65cd894f 100644 --- a/src/components/Dashboard/Bookmarks/Bookmarks.jsx +++ b/src/components/Dashboard/Bookmarks/Bookmarks.jsx @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useState, useEffect } from "react"; import { BookmarksContainer } from "./BookmarksElements"; import { useDispatch, useSelector } from "react-redux"; import { getBookmarks } from "src/features/bookmarks/bookmarkSlice"; @@ -8,6 +8,9 @@ import { getAllUserDetails } from "src/features/userDetail/userDetailSlice"; import LoadingSpinner from "src/components/Other/MixComponents/Spinner/LoadingSpinner"; import UnderMaintenance from "src/components/Other/UnderMaintenance/UnderMaintenance"; import apiStatus from "src/features/apiStatus"; +import BlogCards from "src/components/Blogs/BlogCard/BlogCards.jsx"; +import { getAllBlogs } from "src/features/blogs/blogSlice.js"; +import { FilterButton } from "src/components/Feeds/FeedsElements.jsx"; const Bookmarks = () => { const dispatch = useDispatch(); @@ -15,30 +18,90 @@ const Bookmarks = () => { const { bookmarks } = useSelector((state) => state.bookmarks); const { feeds, isFeedLoading } = useSelector((state) => state.feeds); - const { userDetails, isUserDetailLoading } = useSelector((state) => state.userDetail); + const { blogs, isBlogLoading } = useSelector((state) => state.blogs); useEffect(() => { dispatch(getBookmarks()); dispatch(getAllFeeds()); + dispatch(getAllBlogs()); dispatch(getAllUserDetails()); }, [dispatch]); - const feedBookmarksData = bookmarks.map((bookmark) => { - const feed = feeds.find((feed) => feed?._id === bookmark?.itemId && bookmark?.itemType === "feed") || {}; + const [selectedFilter, setSelectedFilter] = useState("Feeds"); - const userDetail = userDetails?.find((userDetail) => userDetail?.user === feed?.user); - const { username, avatar, verified } = userDetail || {}; - return { ...feed, username, avatar, verified }; - }); + const handleFilterChange = (filter) => { + setSelectedFilter(filter); + }; - const filteredFeedBookmarksData = feedBookmarksData.filter((feed) => feed.user); - if (isApiLoading || isUserDetailLoading || isFeedLoading) return ; + if (isApiLoading || isFeedLoading || isBlogLoading) return ; if (!isApiWorking) return ; + const filteredFeeds = bookmarks + .filter((bookmark) => bookmark.itemType === "feed") + .map((bookmark) => feeds.find((feed) => feed?._id === bookmark?.itemId)); + + const filteredBlogs = bookmarks + .filter((bookmark) => bookmark.itemType === "blog") + .map((bookmark) => blogs.find((blog) => blog?._id === bookmark?.itemId)); + return ( - + + Saved + + + handleFilterChange("Feeds")} + > + Feeds + + handleFilterChange("Blogs")} + > + Blogs + + handleFilterChange("CTF")} + > + CTF + + handleFilterChange("WebSecurity")} + > + Web Security + + + {selectedFilter === "Feeds" ? ( + + ) : ( + + )} ); }; diff --git a/src/components/Dashboard/DashbaordSidebar/DashboardSidebar.jsx b/src/components/Dashboard/DashbaordSidebar/DashboardSidebar.jsx index f2d2f49e..d477d3cb 100644 --- a/src/components/Dashboard/DashbaordSidebar/DashboardSidebar.jsx +++ b/src/components/Dashboard/DashbaordSidebar/DashboardSidebar.jsx @@ -1,15 +1,14 @@ import React from "react"; import { BiHomeCircleIcon, - BiLogoAlgoliaIcon, BiChatIcon, - CgOpenCollectiveIcon, PiNotebookDuotoneIcon, MdAnalyticsIcon, - BiLogoBloggerIcon, BiBookmarksIcon, + BsClipboardCheckIcon, } from "./DashbaordSidebarElements"; import GeneralDashboardSidebar from "src/components/Common/GeneralDashboardSidebar"; +import { GiTridentShield } from "react-icons/gi"; const DashboardSidebar = ({ userDetail }) => { const sidebarItems = [ @@ -17,12 +16,9 @@ const DashboardSidebar = ({ userDetail }) => { { to: "/dashboard/analytics", icon: , label: "Analytics" }, { to: "/dashboard/chat", icon: , label: "Chat" }, { to: "/dashboard/notes", icon: , label: "Notes" }, - { to: "/dashboard/goals", icon: , label: "Goals" }, - { to: "/dashboard/tools", icon: , label: "Tools" }, - { to: "/dashboard/blogs", icon: , label: "User Blogs" }, - { to: "/dashboard/bookmarks", icon: , label: "Bookmarks" }, - // { to: "/dashboard/tasks", icon: , label: "Tasks" }, - // { to: "/settings/profile", icon: , label: "Settings" }, + { to: "/dashboard/tasks", icon: , label: "Tasks" }, + { to: "/dashboard/reconage", icon: , label: "Reconage" }, + { to: "/dashboard/saved", icon: , label: "Saved" }, ]; return ; diff --git a/src/components/Dashboard/DashboardRoute.jsx b/src/components/Dashboard/DashboardRoute.jsx index d06ae81b..405503a3 100644 --- a/src/components/Dashboard/DashboardRoute.jsx +++ b/src/components/Dashboard/DashboardRoute.jsx @@ -1,6 +1,6 @@ import React, { useEffect } from "react"; import { Route, Routes, useNavigate } from "react-router-dom"; -import { EditBlog, GoalSetter, NotFound, UserBlogs } from "src/components/index"; +import { GoalSetter, NotFound } from "src/components/index"; import CreateBlogV2 from "src/components/Blogs/ManageBlogs/CreateBlogV2/CreateBlogV2"; import DashboardSidebar from "./DashbaordSidebar/DashboardSidebar"; import { DashboardRoutesContainer } from "./DashboardElements"; @@ -11,6 +11,7 @@ import CommunityChat from "src/components/Chat/CommunityChat"; import { useDispatch, useSelector } from "react-redux"; import { getAllUserDetails } from "src/features/userDetail/userDetailSlice"; import { Analytics } from "./Analytics/Analytics"; +import Reconage from "src/components/Dashboard/Reconage/Reconage.jsx"; const DashboardRoute = () => { const dispatch = useDispatch(); @@ -47,14 +48,14 @@ const DashboardRoute = () => { } /> } /> } /> - } /> + } /> } /> } /> } /> - - } /> + + + } /> } /> - } /> } /> diff --git a/src/components/Dashboard/Reconage/Reconage.jsx b/src/components/Dashboard/Reconage/Reconage.jsx new file mode 100644 index 00000000..00356344 --- /dev/null +++ b/src/components/Dashboard/Reconage/Reconage.jsx @@ -0,0 +1,145 @@ +import React, { useEffect, useState } from "react"; +import axios from "axios"; +import { + Button, + CopyButton, + CopyButtonSection, + DownloadButton, + Form, + SubdomainFinderSpinner, + SubdomainItem, + SubdomainLink, + SubdomainList, + Title, +} from "src/components/Tools/SubdomainFinder/SubdomainFinderElements.jsx"; +import { Wrapper } from "src/components/Dashboard/Profile/ProfileElements"; +import { CircleSpinner } from "react-spinners-kit"; +import apiStatus from "src/features/apiStatus"; +import UnderMaintenance from "src/components/Other/UnderMaintenance/UnderMaintenance"; +import { RiEarthFill } from "react-icons/ri"; +import { Input } from "src/components/Blogs/BlogComments/AddCommentFormElements.jsx"; + +const Reconage = () => { + const { isApiLoading, isApiWorking } = apiStatus(); + const [domainName, setDomainName] = useState(""); + const [subdomains, setSubdomains] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [isError, setIsError] = useState(false); + const [errorMessage, setErrorMessage] = useState(""); + const [isCopied, setIsCopied] = useState(false); + const [isDownloaded, setIsDownloaded] = useState(false); + + const handleSubmit = async (e) => { + e.preventDefault(); + setIsLoading(true); + setIsError(false); + setErrorMessage(""); + setSubdomains([]); + + if (!domainName) { + setIsLoading(false); + return; + } + try { + const response = await axios.get(`http://localhost:5001/api/subdomains?domain=${domainName}`); + setSubdomains(response?.data?.subdomains); + setIsLoading(false); + } catch (error) { + setIsError(true); + setErrorMessage(error?.response?.data?.message); + setIsLoading(false); + } + }; + + const handleCopyToClipboard = (subdomains) => { + const subdomainsText = subdomains?.join("\n"); + navigator.clipboard + .writeText(subdomainsText) + .then(() => { + setIsCopied(true); + setTimeout(() => { + setIsCopied(false); + }, 1000); + }) + .catch((error) => { + console.error("Failed to copy to clipboard:", error); + }); + }; + + const handleDownloadTxtFile = () => { + const subdomainsText = subdomains?.join("\n"); + const element = document.createElement("a"); + const file = new Blob([subdomainsText], { type: "text/plain" }); + element.href = URL.createObjectURL(file); + element.download = `${domainName}.txt`; + document.body.appendChild(element); // Append the element to the DOM + element.click(); // Simulate a click on the element to trigger the download + document.body.removeChild(element); // Remove the element from the DOM + setIsDownloaded(true); + setTimeout(() => { + setIsDownloaded(false); + }, 1000); + }; + const [isLoading2, setIsLoading2] = useState(true); + + useEffect(() => { + setTimeout(() => { + setIsLoading2(false); + }, 100); + }, []); + if (isLoading2 || isApiLoading) { + return ( + + + + ); + } + + if (!isApiWorking) return ; + + return ( + + + + Subdomain Finder + + + setDomainName(e.target.value)} + /> + {!isLoading && Fetch Subdomains} + {isLoading && } + + + {isError && {errorMessage}} + + {subdomains?.length > 0 && ( + + {subdomains?.length} subdomains found for {domainName} + + {isDownloaded && Downloaded!} + {isCopied && Copied!} + + handleCopyToClipboard(subdomains)} /> + + {subdomains?.map((subdomain, index) => ( + + + {subdomain} + + + ))} + + )} + + + ); +}; + +export default Reconage; diff --git a/src/components/Dashboard/Reconage/ReconageElements.jsx b/src/components/Dashboard/Reconage/ReconageElements.jsx new file mode 100644 index 00000000..e69de29b diff --git a/src/components/Feeds/Feeds.jsx b/src/components/Feeds/Feeds.jsx index 9c9f4cef..893b1692 100644 --- a/src/components/Feeds/Feeds.jsx +++ b/src/components/Feeds/Feeds.jsx @@ -62,6 +62,8 @@ const Feeds = () => { return ( + + { return ( } /> } /> + } /> + } /> ); diff --git a/src/components/Feeds/UserFeeds.jsx b/src/components/Feeds/UserFeeds.jsx new file mode 100644 index 00000000..f69fd730 --- /dev/null +++ b/src/components/Feeds/UserFeeds.jsx @@ -0,0 +1,37 @@ +import React, { useEffect } from "react"; + +import { Wrapper } from "src/components/Dashboard/Profile/ProfileElements.jsx"; +import { useDispatch, useSelector } from "react-redux"; +import LoadingSpinner from "src/components/Other/MixComponents/Spinner/LoadingSpinner.jsx"; +import UnderMaintenance from "src/components/Other/UnderMaintenance/UnderMaintenance.jsx"; +import apiStatus from "src/features/apiStatus.jsx"; +import { feedReset, getFeeds } from "src/features/feeds/feedsSlice.js"; +import FeedPosts from "src/components/Feeds/FeedPosts/FeedPosts.jsx"; + +const UserBlogs = () => { + const { isApiLoading, isApiWorking } = apiStatus(); + + const dispatch = useDispatch(); + const { feeds } = useSelector((state) => state.feeds); + + useEffect(() => { + dispatch(getFeeds()); + return () => dispatch(feedReset()); + }, [dispatch]); + + if (isApiLoading) return ; + + if (!isApiWorking) return ; + + return ( + + + + ); +}; + +export default UserBlogs; diff --git a/src/components/Header/Dropdowns/Dropdown.jsx b/src/components/Header/Dropdowns/Dropdown.jsx index 20be3c09..3080dfa7 100644 --- a/src/components/Header/Dropdowns/Dropdown.jsx +++ b/src/components/Header/Dropdowns/Dropdown.jsx @@ -55,7 +55,7 @@ export default function Dropdown({ { title: "Roadmap", to: "/roadmaps", desc: "Guide to becoming a cybersecurity professional" }, { title: "Interview Questions", to: "/interviewQuestions", desc: "Prepare for your interview" }, { title: "Quiz", to: "/quiz", desc: "Test your knowledge" }, - // { title: "Cheat Sheets", to: "/cheatsheets", desc: "Cheat Sheets for quick reference" }, + { title: "Cheat Sheets", to: "/cheatsheets", desc: "Cheat Sheets for quick reference" }, { title: "Tools", to: "tools", desc: "Tools for your hacking needs" }, { title: "Community", to: "/community", desc: "Join our community" }, { title: "Methodology", to: "/resources/methodology", desc: "Test your knowledge" }, diff --git a/src/components/Header/Navbar/NavbarElements.jsx b/src/components/Header/Navbar/NavbarElements.jsx index 5fa91e88..fb0542f2 100644 --- a/src/components/Header/Navbar/NavbarElements.jsx +++ b/src/components/Header/Navbar/NavbarElements.jsx @@ -5,7 +5,6 @@ import { BsTrophyFill } from "react-icons/bs"; export const DropdownIcon = styled(AiFillCaretDown)` margin: 2px 0 0 5px; - transform: ${(props) => props.clicked}; `; export const Nav = styled.nav` diff --git a/src/components/Tools/BreachCheck/BreachCheckElements.jsx b/src/components/Tools/BreachCheck/BreachCheckElements.jsx index 555ed48f..b53c38fa 100644 --- a/src/components/Tools/BreachCheck/BreachCheckElements.jsx +++ b/src/components/Tools/BreachCheck/BreachCheckElements.jsx @@ -30,6 +30,14 @@ export const EmailInput = styled.input` border-radius: 5px; width: 100%; + &:focus { + outline: none; + } + + &:hover { + background: #1a1c1d; + } + @media (width <= 768px) { padding-left: 0.5rem; min-width: auto; diff --git a/src/components/Tools/SubdomainFinder/SubdomainFinder.jsx b/src/components/Tools/SubdomainFinder/SubdomainFinder.jsx index ea47e589..da420063 100644 --- a/src/components/Tools/SubdomainFinder/SubdomainFinder.jsx +++ b/src/components/Tools/SubdomainFinder/SubdomainFinder.jsx @@ -15,7 +15,6 @@ import { } from "./SubdomainFinderElements"; import { Wrapper } from "src/components/Dashboard/Profile/ProfileElements"; import { CircleSpinner } from "react-spinners-kit"; -import { getApiUrl } from "src/features/apiUrl"; import apiStatus from "src/features/apiStatus"; import UnderMaintenance from "src/components/Other/UnderMaintenance/UnderMaintenance"; import { RiEarthFill } from "react-icons/ri"; @@ -42,7 +41,7 @@ const SubdomainFinder = () => { return; } try { - const response = await axios.post(getApiUrl("api/tool/subdomainFinder"), { domainName }); + const response = await axios.get(`http://localhost:5000/api/subdomains?domain=${domainName}`); setSubdomains(response?.data?.subdomains); setIsLoading(false); } catch (error) { diff --git a/src/components/Tools/Tools.jsx b/src/components/Tools/Tools.jsx index 7b757ddf..ddb8faa9 100644 --- a/src/components/Tools/Tools.jsx +++ b/src/components/Tools/Tools.jsx @@ -2,25 +2,24 @@ import React from "react"; import { Wrapper } from "src/components/Dashboard/Profile/ProfileElements"; import { CardTool, CardToolHeading, CardTools, ContainerTools, RouterLink, ToolIcon } from "./ToolsElements"; import { GoFileBinary } from "react-icons/go"; -import { RiEarthFill } from "react-icons/ri"; -import { GiNautilusShell } from "react-icons/gi"; -import { - MdPassword, - // MdScreenSearchDesktop -} from "react-icons/md"; +import { GiNautilusShell, GiTridentShield } from "react-icons/gi"; +import { MdPassword } from "react-icons/md"; import { TbHash } from "react-icons/tb"; import HeadingBanner from "src/components/Common/HeadingBanner/HeadingBanner"; +import { RiEarthFill } from "react-icons/ri"; const Tools = () => { const tools = [ - { name: "Sub Finder", link: "/tools/subfinder", icon: }, + { name: "Reconage", link: "/dashboard/reconage", icon: }, + { name: "Rev Shell", desc: "Reverse Shell Generator", link: "/tools/revshell", icon: }, { name: "Bin Exploit", link: "/tools/binexploits", icon: }, { name: "Encoder", link: "/tools/encoder", icon: }, { name: "Pass Gen", link: "/tools/passgen", icon: }, + { name: "Sub Finder", link: "/tools/subfinder", icon: }, + { name: "Breach Check", link: "/tools/breachcheck", icon: }, // { name: "Dorking", link: "/tools/dorking", icon: }, - // {name: "Breach Check", link: "/tools/breachcheck", icon: ,}, // {name: "Binary Exploits", link: "/tools/binaryexploitation", icon: ,}, // {name: "jwt Decoder", link: "/tools/jwtdecoder", icon: ,}, // {name: "Hash Cracker", link: "/tools/hashcracker", icon: ,}, diff --git a/src/components/Tools/ToolsRoute.jsx b/src/components/Tools/ToolsRoute.jsx index 5c704eae..52fd308c 100644 --- a/src/components/Tools/ToolsRoute.jsx +++ b/src/components/Tools/ToolsRoute.jsx @@ -2,7 +2,6 @@ import React from "react"; import { Route, Routes } from "react-router-dom"; import Tools from "./Tools"; import BreachCheck from "./BreachCheck/BreachCheck"; -import SubdomainFinder from "./SubdomainFinder/SubdomainFinder"; import ReverseShellGenerator from "./ReverseShell/ShellGenerator"; import { NotFound } from "src/components/index"; import PassGen from "./PassGen/PassGen"; @@ -16,12 +15,13 @@ const ToolsRoutes = () => { } /> } /> - } /> } /> } /> } /> + } /> } /> + } /> {/* }/> */} diff --git a/src/components/index.js b/src/components/index.js index 4a9b1455..685769b6 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -46,7 +46,7 @@ export { default as UserProfile } from "src/components/Dashboard/Profile/UserPro export { default as LearningPath } from "./Resources/LearningPath/LearningPath"; export { default as CreateBlog } from "./Blogs/ManageBlogs/CreateBlog/CreateBlog"; export { default as GoalSetter } from "./Dashboard/OldDashbaord/GoalSetter/GoalSetter"; -export { default as UserBlogs } from "./Dashboard/OldDashbaord/Blogs/UserBlogs"; +export { default as UserBlogs } from "./Blogs/UserBlogs.jsx"; export { default as Blogs } from "./Blogs/Blogs"; export { default as SingleBlog } from "./Blogs/SingleBlog/SingleBlog"; export { default as EditBlog } from "./Blogs/ManageBlogs/EditBlog/EditBlog";
- {item.title ? item.content.replace(/<[^>]+>/g, "").slice(0, 100) : null} -
Downloaded!
Copied!