diff --git a/src/components/search/SearchBar.js b/src/components/search/SearchBar.js
index 9844e3b..3c53a5b 100644
--- a/src/components/search/SearchBar.js
+++ b/src/components/search/SearchBar.js
@@ -1,146 +1,200 @@
-import React, { useState, useRef, useEffect } from 'react';
-import { InputText } from 'primereact/inputtext';
-import { InputIcon } from 'primereact/inputicon';
-import { IconField } from 'primereact/iconfield';
-import { Dropdown } from 'primereact/dropdown';
-import { OverlayPanel } from 'primereact/overlaypanel';
-import ContentDropdownItem from '@/components/content/dropdowns/ContentDropdownItem';
-import MessageDropdownItem from '@/components/content/dropdowns/MessageDropdownItem';
-import { useContentSearch } from '@/hooks/useContentSearch';
-import { useCommunitySearch } from '@/hooks/useCommunitySearch';
-import { useRouter } from 'next/router';
-import useWindowWidth from '@/hooks/useWindowWidth';
-import styles from './searchbar.module.css';
+import React, { useState, useRef, useEffect } from "react";
+import { InputText } from "primereact/inputtext";
+import { InputIcon } from "primereact/inputicon";
+import { IconField } from "primereact/iconfield";
+import { Dropdown } from "primereact/dropdown";
+import { OverlayPanel } from "primereact/overlaypanel";
+import ContentDropdownItem from "@/components/content/dropdowns/ContentDropdownItem";
+import MessageDropdownItem from "@/components/content/dropdowns/MessageDropdownItem";
+import { useContentSearch } from "@/hooks/useContentSearch";
+import { useCommunitySearch } from "@/hooks/useCommunitySearch";
+import { useRouter } from "next/router";
+import useWindowWidth from "@/hooks/useWindowWidth";
+import styles from "./searchbar.module.css";
const SearchBar = () => {
- const { searchContent, searchResults: contentResults } = useContentSearch();
- const { searchCommunity, searchResults: communityResults } = useCommunitySearch();
- const router = useRouter();
- const windowWidth = useWindowWidth();
- const [selectedSearchOption, setSelectedSearchOption] = useState({ name: 'Content', code: 'content', icon: 'pi pi-video' });
- const searchOptions = [
- { name: 'Content', code: 'content', icon: 'pi pi-video' },
- { name: 'Community', code: 'community', icon: 'pi pi-users' },
- ];
- const [searchTerm, setSearchTerm] = useState('');
- const [searchResults, setSearchResults] = useState([]);
- const op = useRef(null);
+ const { searchContent, searchResults: contentResults } = useContentSearch();
+ const { searchCommunity, searchResults: communityResults } =
+ useCommunitySearch();
+ const router = useRouter();
+ const windowWidth = useWindowWidth();
+ const [selectedSearchOption, setSelectedSearchOption] = useState({
+ name: "Content",
+ code: "content",
+ icon: "pi pi-video",
+ });
+ const searchOptions = [
+ { name: "Content", code: "content", icon: "pi pi-video" },
+ { name: "Community", code: "community", icon: "pi pi-users" },
+ ];
+ const [searchTerm, setSearchTerm] = useState("");
+ const [searchResults, setSearchResults] = useState([]);
+ const op = useRef(null);
+ const [isSearchActive, setIsSearchActive] = useState(false);
- const selectedOptionTemplate = (option, props) => {
- if (!props?.placeholder) {
- return (
-
-
- {option.code}
-
- );
- }
- return
- };
+ const selectedOptionTemplate = (option, props) => {
+ if (!props?.placeholder) {
+ return (
+
+
+ {option.code}
+
+ );
+ }
+ return ;
+ };
- const handleSearch = (e) => {
- const term = e.target.value;
- setSearchTerm(term);
-
- if (selectedSearchOption.code === 'content') {
- searchContent(term);
- setSearchResults(contentResults);
- } else if (selectedSearchOption.code === 'community') {
- searchCommunity(term);
- setSearchResults(communityResults);
- }
+ const handleSearch = (e) => {
+ const term = e.target.value;
+ setSearchTerm(term);
- if (term.length > 2) {
- op.current.show(e);
- } else {
- op.current.hide();
- }
- };
-
- useEffect(() => {
- if (selectedSearchOption.code === 'content') {
- setSearchResults(contentResults);
- } else if (selectedSearchOption.code === 'community') {
- setSearchResults(communityResults);
- }
- }, [selectedSearchOption, contentResults, communityResults]);
-
- const handleContentSelect = (content) => {
- if (content?.type === 'course') {
- router.push(`/course/${content.id}`);
- } else {
- router.push(`/details/${content.id}`);
- }
- setSearchTerm('');
- searchContent('');
- op.current.hide();
+ if (selectedSearchOption.code === "content") {
+ searchContent(term);
+ setSearchResults(contentResults);
+ } else if (selectedSearchOption.code === "community") {
+ searchCommunity(term);
+ setSearchResults(communityResults);
}
- return (
-
-
-
- 845 ? 'w-[300px]' : 'w-[160px]'}`}
- value={searchTerm}
- onChange={handleSearch}
- placeholder={`Search ${selectedSearchOption.name.toLowerCase()}`}
- pt={{
- root: {
- className: 'border-none rounded-tr-none rounded-br-none focus:border-none focus:ring-0 pr-0'
- }
- }}
- />
+ if (term.length > 2) {
+ setIsSearchActive(true);
+ op.current.show(e);
+ } else {
+ setIsSearchActive(false);
+ op.current.hide();
+ }
+ };
- setSelectedSearchOption(e.value)}
- options={searchOptions}
- optionLabel="name"
- placeholder="Search"
- dropdownIcon={
-
-
-
-
- }
- valueTemplate={selectedOptionTemplate}
- itemTemplate={selectedOptionTemplate}
- required
- />
-
+ useEffect(() => {
+ if (selectedSearchOption.code === "content") {
+ setSearchResults(contentResults);
+ } else if (selectedSearchOption.code === "community") {
+ setSearchResults(communityResults);
+ }
+ }, [selectedSearchOption, contentResults, communityResults]);
-
- {searchResults.map((item, index) => (
- item.type === 'discord' || item.type === 'nostr' || item.type === 'stackernews' ? (
-
- ) : (
-
- )
- ))}
- {searchResults.length === 0 && searchTerm.length > 2 && (
- No results found
- )}
-
-
- );
+ useEffect(() => {
+ const mainContent = document.querySelector(".main-content");
+ if (mainContent) {
+ if (isSearchActive) {
+ mainContent.classList.add(styles.blurredContent);
+ } else {
+ mainContent.classList.remove(styles.blurredContent);
+ }
+ }
+ }, [isSearchActive]);
+
+ useEffect(() => {
+ const handleClickOutside = (event) => {
+ const overlayElement = document.querySelector(".p-overlaypanel");
+ const searchElement = event.target.closest(".search-container");
+
+ if (
+ (!overlayElement || !overlayElement.contains(event.target)) &&
+ !searchElement
+ ) {
+ setSearchTerm("");
+ setIsSearchActive(false);
+ setSearchResults([]);
+ op.current?.hide();
+ }
+ };
+
+ document.addEventListener("mousedown", handleClickOutside);
+
+ return () => {
+ document.removeEventListener("mousedown", handleClickOutside);
+ };
+ }, []);
+
+ const handleContentSelect = (content) => {
+ if (content?.type === "course") {
+ router.push(`/course/${content.id}`);
+ } else {
+ router.push(`/details/${content.id}`);
+ }
+ setSearchTerm("");
+ searchContent("");
+ setIsSearchActive(false);
+ op.current.hide();
+ };
+
+ return (
+
+
+
+ 845 ? "w-[300px]" : "w-[160px]"}`}
+ value={searchTerm}
+ onChange={handleSearch}
+ placeholder={`Search ${selectedSearchOption.name.toLowerCase()}`}
+ pt={{
+ root: {
+ className:
+ "border-none rounded-tr-none rounded-br-none focus:border-none focus:ring-0 pr-0",
+ },
+ }}
+ />
+
+ setSelectedSearchOption(e.value)}
+ options={searchOptions}
+ optionLabel="name"
+ placeholder="Search"
+ dropdownIcon={
+
+
+
+
+ }
+ valueTemplate={selectedOptionTemplate}
+ itemTemplate={selectedOptionTemplate}
+ required
+ />
+
+
+
+ {searchResults.map((item, index) =>
+ item.type === "discord" ||
+ item.type === "nostr" ||
+ item.type === "stackernews" ? (
+
+ ) : (
+
+ )
+ )}
+ {searchResults.length === 0 && searchTerm.length > 2 && (
+ No results found
+ )}
+
+
+ );
};
export default SearchBar;
diff --git a/src/components/search/searchbar.module.css b/src/components/search/searchbar.module.css
index f9dd596..4c4acbc 100644
--- a/src/components/search/searchbar.module.css
+++ b/src/components/search/searchbar.module.css
@@ -17,3 +17,23 @@
outline: none !important;
box-shadow: none !important;
} */
+
+.dropdown {
+ background: rgba(0, 0, 0, 0.3) !important;
+ backdrop-filter: blur(8px) !important;
+}
+
+/* Add this to style the overlay panel */
+.overlayPanel {
+ background: rgba(0, 0, 0, 0.75) !important;
+ border: 1px solid rgba(255, 255, 255, 0.1) !important;
+}
+
+.overlayPanelContent {
+ background: transparent !important;
+}
+
+.blurredContent {
+ filter: blur(8px);
+ transition: filter 0.2s ease-in-out;
+}
diff --git a/src/pages/_app.js b/src/pages/_app.js
index 496dc50..87b3d95 100644
--- a/src/pages/_app.js
+++ b/src/pages/_app.js
@@ -1,61 +1,61 @@
-import { PrimeReactProvider } from 'primereact/api';
-import { useEffect, useState } from 'react';
-import Navbar from '@/components/navbar/Navbar';
-import { ToastProvider } from '@/hooks/useToast';
-import { SessionProvider } from "next-auth/react"
-import Layout from '@/components/Layout';
-import '@/styles/globals.css'
-import 'primereact/resources/themes/lara-dark-blue/theme.css'
-import '@/styles/custom-theme.css'; // custom theme
-import 'primereact/resources/primereact.min.css';
-import 'primeicons/primeicons.css';
+import { PrimeReactProvider } from "primereact/api";
+import { useEffect, useState } from "react";
+import Navbar from "@/components/navbar/Navbar";
+import { ToastProvider } from "@/hooks/useToast";
+import { SessionProvider } from "next-auth/react";
+import Layout from "@/components/Layout";
+import "@/styles/globals.css";
+import "primereact/resources/themes/lara-dark-blue/theme.css";
+import "@/styles/custom-theme.css"; // custom theme
+import "primereact/resources/primereact.min.css";
+import "primeicons/primeicons.css";
import "@uiw/react-md-editor/markdown-editor.css";
import "@uiw/react-markdown-preview/markdown.css";
-import Sidebar from '@/components/sidebar/Sidebar';
-import { useRouter } from 'next/router';
-import { NDKProvider } from '@/context/NDKContext';
-import { Analytics } from '@vercel/analytics/react';
-import {
- QueryClient,
- QueryClientProvider,
-} from '@tanstack/react-query'
-import BottomBar from '@/components/BottomBar';
+import Sidebar from "@/components/sidebar/Sidebar";
+import { useRouter } from "next/router";
+import { NDKProvider } from "@/context/NDKContext";
+import { Analytics } from "@vercel/analytics/react";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import BottomBar from "@/components/BottomBar";
-const queryClient = new QueryClient()
+const queryClient = new QueryClient();
export default function MyApp({
- Component, pageProps: { session, ...pageProps }
+ Component,
+ pageProps: { session, ...pageProps },
}) {
- const [isCourseView, setIsCourseView] = useState(false);
- const router = useRouter();
+ const [isCourseView, setIsCourseView] = useState(false);
+ const router = useRouter();
- useEffect(() => {
- setIsCourseView(router.pathname.includes('course') && !router.pathname.includes('draft'));
- }, [router.pathname]);
-
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
+ useEffect(() => {
+ setIsCourseView(
+ router.pathname.includes("course") && !router.pathname.includes("draft")
);
-}
\ No newline at end of file
+ }, [router.pathname]);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}