From 5f30e81557733f6d2216dd246c3777d49c2689e0 Mon Sep 17 00:00:00 2001 From: Jelaletdin12 Date: Sun, 22 Mar 2026 16:47:41 +0500 Subject: [PATCH] added real time search --- components/layout/Header.tsx | 32 +++++++++++---------- components/layout/ui/SearchBar.tsx | 34 ++++++++++++++++++++++- features/home/components/CategoryGrid.tsx | 6 ++-- i18n/messages/ru.json | 2 +- 4 files changed, 55 insertions(+), 19 deletions(-) diff --git a/components/layout/Header.tsx b/components/layout/Header.tsx index fe1a128..a9e48fb 100644 --- a/components/layout/Header.tsx +++ b/components/layout/Header.tsx @@ -1,7 +1,7 @@ // Header.tsx "use client"; -import { useState, useEffect, useCallback } from "react"; +import { useState, useEffect, useCallback, Suspense } from "react"; import Link from "next/link"; import Image from "next/image"; import { X, Search } from "lucide-react"; @@ -103,12 +103,14 @@ export default function Header({ locale = "ru" }: HeaderProps) { */} {/* Desktop Search Bar */} - + }> + + {/* Action Buttons */} - setIsMobileSearchOpen(false)} - searchPlaceholder={t("common.search")} - locale={locale} - /> + + setIsMobileSearchOpen(false)} + searchPlaceholder={t("common.search")} + locale={locale} + /> + setIsLoginOpen(false)} /> diff --git a/components/layout/ui/SearchBar.tsx b/components/layout/ui/SearchBar.tsx index 5b35ab8..0902698 100644 --- a/components/layout/ui/SearchBar.tsx +++ b/components/layout/ui/SearchBar.tsx @@ -10,7 +10,7 @@ import { DialogHeader, DialogTitle, } from "@/components/ui/dialog"; -import { useRouter } from "next/navigation"; +import { useRouter, useSearchParams, usePathname } from "next/navigation"; import { SearchIcon } from "@/components/icons"; interface SearchBarProps { @@ -31,8 +31,40 @@ export default function SearchBar({ locale = "ru", }: SearchBarProps) { const router = useRouter(); + const searchParams = useSearchParams(); + const pathname = usePathname(); const [searchValue, setSearchValue] = useState(""); + React.useEffect(() => { + // Sync URL param to input when URL changes + if (pathname?.includes("/search")) { + const q = searchParams?.get("q") || ""; + if (q !== searchValue.trim()) { + setSearchValue(q); + } + } else { + setSearchValue(""); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [searchParams, pathname]); + + React.useEffect(() => { + // Debounce updates to the URL query when typing on search page + if (pathname?.includes("/search")) { + const delayDebounceFn = setTimeout(() => { + const q = searchParams?.get("q") || ""; + const curVal = searchValue.trim(); + if (curVal !== q && curVal !== "") { + router.push(`/${locale}/search?q=${encodeURIComponent(curVal)}`); + } else if (curVal === "" && q !== "") { + router.push(`/${locale}/search`); + } + }, 500); + + return () => clearTimeout(delayDebounceFn); + } + }, [searchValue, pathname, router, locale, searchParams]); + const performSearch = () => { if (searchValue.trim()) { router.push( diff --git a/features/home/components/CategoryGrid.tsx b/features/home/components/CategoryGrid.tsx index 9a55209..f748081 100644 --- a/features/home/components/CategoryGrid.tsx +++ b/features/home/components/CategoryGrid.tsx @@ -55,7 +55,7 @@ export default function CategoryGrid({
{Array.from({ length: 12 }).map((_, i) => ( -
+
= 2 ? "hidden sm:block" : ""}`}>
@@ -69,11 +69,11 @@ export default function CategoryGrid({

{title}

- {categories?.map((cat) => ( + {categories?.map((cat, index) => ( = 2 ? "hidden sm:block" : ""}`} >
diff --git a/i18n/messages/ru.json b/i18n/messages/ru.json index 6f7eb64..9647cae 100644 --- a/i18n/messages/ru.json +++ b/i18n/messages/ru.json @@ -88,7 +88,7 @@ "become_seller": "Стать продавцом", "choose_region": "Выберите регион", "choose_or_enter_address": "Выберите или введите свой адрес", - "note": "Заметка", + "note": "Aдрес", "seller_application_form": "Форма подачи заявления на открытие магазина", "phone": "Телефон", "unit_price": "Цена за 1 шт.:",