From 80d9c16073c646be711ae94cb0ca9a07a74fa94e Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sat, 7 Feb 2026 10:07:02 +0330 Subject: [PATCH] search --- src/pages/service/hooks/useServiceData.ts | 8 +++ src/pages/service/service/ServiceService.ts | 27 ++++++---- src/shared/Header.tsx | 9 +--- src/shared/components/Search.tsx | 58 +++++++++++++++++++++ 4 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 src/shared/components/Search.tsx diff --git a/src/pages/service/hooks/useServiceData.ts b/src/pages/service/hooks/useServiceData.ts index da319b3..09157d2 100644 --- a/src/pages/service/hooks/useServiceData.ts +++ b/src/pages/service/hooks/useServiceData.ts @@ -23,6 +23,14 @@ export const useGetServicesByCategory = (categoryId: string) => { }); }; +export const useGetServiceSearch = (search: string) => { + return useQuery({ + queryKey: ["services-search", search], + queryFn: () => api.getServiceSearch(search), + enabled: !!search, + }); +}; + export const useGetDetailService = (serviceId: string) => { return useQuery({ queryKey: ["service", serviceId], diff --git a/src/pages/service/service/ServiceService.ts b/src/pages/service/service/ServiceService.ts index c2aff26..14f4378 100644 --- a/src/pages/service/service/ServiceService.ts +++ b/src/pages/service/service/ServiceService.ts @@ -26,6 +26,15 @@ export const getServicesByCategory = async (categoryId: string) => { return data; }; +export const getServiceSearch = async (search: string) => { + let query = ``; + if (search) { + query = `?q=${search}`; + } + const { data } = await axios.get(`/danak-services/search${query}`); + return data; +}; + export const getDetailService = async (serviceId: string) => { const { data } = await axios.get(`/danak-services/${serviceId}`); return data; @@ -34,7 +43,7 @@ export const getDetailService = async (serviceId: string) => { export const buyService = async (params: BuyServiceType) => { const { data } = await axios.post( `/subscriptions/${params.serviceId}/subscribe`, - params + params, ); return data; }; @@ -46,7 +55,7 @@ export const getMyServices = async (search: string) => { export const createReview = async (params: CreateReviewType) => { const { data } = await axios.post( `/danak-services/${params.id}/reviews`, - params + params, ); return data; }; @@ -57,41 +66,41 @@ export const getServiceBySlug = async (slug: string) => { }; export const extentSubscription = async ( - params: ExtentSubscriptionType + params: ExtentSubscriptionType, ): Promise => { const { data } = await axios.put( `/subscriptions/${params.subscriptionId}/subscribe`, - params + params, ); return data; }; export const getDmenuSubscription = async (subscriptionId: string) => { const { data } = await axios.get( - `/dmenu/restaurants/subscription/${subscriptionId}` + `/dmenu/restaurants/subscription/${subscriptionId}`, ); return data; }; export const createDmenuRestaurant = async ( - params: DmenuCreateRestaurantType + params: DmenuCreateRestaurantType, ) => { const { data } = await axios.post(`/dmenu/restaurants`, params); return data; }; export const getSubscription = async ( - subscriptionId: string + subscriptionId: string, ): Promise => { const { data } = await axios.get(`/subscriptions/user/${subscriptionId}`); return data; }; export const directLogin = async ( - userSubscriptionId: string + userSubscriptionId: string, ): Promise => { const { data } = await axios.post( - `/dmenu/auth/direct-login/${userSubscriptionId}` + `/dmenu/auth/direct-login/${userSubscriptionId}`, ); return data; }; diff --git a/src/shared/Header.tsx b/src/shared/Header.tsx index 6e075df..b31a287 100644 --- a/src/shared/Header.tsx +++ b/src/shared/Header.tsx @@ -1,5 +1,4 @@ import { FC, useEffect, useState } from 'react' -import Input from '../components/Input' import { ArrowDown2, Card, CloseCircle, Element3, HambergerMenu, Logout, ProfileCircle, Receipt1, Setting2, TicketDiscount, Wallet } from 'iconsax-react' import AvatarImage from '../assets/images/avatar_image.png' import { useTranslation } from 'react-i18next' @@ -12,6 +11,7 @@ import { Popover, PopoverButton, PopoverPanel } from '@headlessui/react' import SideBarItem from './SideBarItem' import { useGetWalletBalance } from '../pages/wallet/hooks/useWalletData' import { NumberFormat } from '../config/func' +import Search from './components/Search' const Header: FC = () => { @@ -29,12 +29,7 @@ const Header: FC = () => { return (
-
- -
+
setOpenSidebar(!openSidebar)} className='xl:hidden block'>
diff --git a/src/shared/components/Search.tsx b/src/shared/components/Search.tsx new file mode 100644 index 0000000..3205538 --- /dev/null +++ b/src/shared/components/Search.tsx @@ -0,0 +1,58 @@ +import { useEffect, useState, type FC } from 'react' +import Input from '../../components/Input' +import { useTranslation } from 'react-i18next' +import { useGetServiceSearch } from '../../pages/service/hooks/useServiceData' +import { ServiceType } from '../../pages/service/types/ServiecTypes' +import { Link } from 'react-router-dom' +import { Pages } from '../../config/Pages' +import { useOutsideClick } from '../../hooks/useOutSideClick' + +const Search: FC = () => { + + const { t } = useTranslation('global') + const [search, setSearch] = useState('') + const [showSearch, setShowSearch] = useState(false) + const { data } = useGetServiceSearch(search) + const ref = useOutsideClick(() => { + setShowSearch(false) + }) + + useEffect(() => { + + if (data?.data && data?.data?.services?.length) { + setShowSearch(true) + } else { + setShowSearch(false) + } + + }, [data]) + + + return ( +
+ + + { + showSearch && +
+ { + data?.data?.services?.map((item: ServiceType) => { + return ( + setShowSearch(false)} to={Pages.services.detail + item.slug} key={item.id} className='flex gap-3 items-center border-b pb-4'> + +
{item.name}
+ + ) + }) + } +
+ } +
+ ) +} + +export default Search \ No newline at end of file