Files
gastro-bot/src/widgets/navbar/ui/SearchResult.tsx
Samandar Turgunboyev 105c384994 bug fix
2026-01-24 17:23:50 +05:00

143 lines
4.3 KiB
TypeScript

'use client';
import LogosProduct from '@/assets/product.png';
import { product_api } from '@/shared/config/api/product/api';
import {
ProductListResult,
SearchDataPro,
} from '@/shared/config/api/product/type';
import { BASE_URL } from '@/shared/config/api/URLs';
import { useRouter } from '@/shared/config/i18n/navigation';
import formatPrice from '@/shared/lib/formatPrice';
import { Skeleton } from '@/shared/ui/skeleton';
import { useQuery } from '@tanstack/react-query';
import { PackageOpen } from 'lucide-react';
import { useTranslations } from 'next-intl';
import Image from 'next/image';
type SearchResultProps = {
query: string;
};
export const SearchResult = ({ query }: SearchResultProps) => {
const router = useRouter();
const t = useTranslations();
/* 🔹 Default products - query bo'lmaganda */
const { data: products, isLoading: isLoadingDefault } = useQuery<
ProductListResult[]
>({
queryKey: ['product_list'],
queryFn: async () => {
const res = await product_api.list({ page: 1, page_size: 10 });
return res.data.results;
},
enabled: !query,
});
/* 🔹 Search - query bo'lganda */
const { data: searchData, isLoading: isLoadingSearch } = useQuery<
ProductListResult[]
>({
queryKey: ['search', query],
queryFn: async () => {
const res = await product_api.search({
search: query,
page: 1,
page_size: 10,
});
// API response strukturasiga qarab to'g'rilash kerak
// Agar res.data.products array bo'lsa:
return Array.isArray(res.data.products)
? res.data.products
: (res.data.products as SearchDataPro[]).map(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(item: any) => item.products || item,
);
},
enabled: !!query && query.trim().length > 0,
});
const isLoading = query ? isLoadingSearch : isLoadingDefault;
const list: ProductListResult[] = query
? (searchData ?? [])
: (products ?? []);
if (isLoading) {
return (
<div className="space-y-3">
{Array.from({ length: 5 }).map((_, i) => (
<div key={i} className="flex items-center gap-3 p-2">
<Skeleton className="w-16 h-16 rounded-md" />
<div className="flex-1 space-y-2">
<Skeleton className="h-4 w-[70%]" />
<Skeleton className="h-3 w-[40%]" />
</div>
</div>
))}
</div>
);
}
if (!list.length) {
return (
<div className="flex flex-col justify-center items-center min-h-[300px] gap-2">
<PackageOpen className="size-20 text-muted-foreground" />
<p className="text-lg text-muted-foreground">
{query ? t('Hech narsa topilmadi') : t('Mahsulotlar mavjud emas')}
</p>
</div>
);
}
return (
<div className="space-y-3">
<p className="text-sm font-semibold text-slate-700">
{query ? t('Qidiruv natijalari') : t('Tavsiya etiladi')}
</p>
{list
.filter((item) => item.state === 'A')
.slice(0, 5)
.map((product) => {
const image =
product.images.length > 0
? product?.images[0].image?.includes(BASE_URL)
? product.images[0].image
: BASE_URL + product.images[0].image
: LogosProduct;
const price = product.prices?.[0]?.price;
return (
<div
key={product.id}
className="flex items-center gap-3 p-2 rounded-lg hover:bg-slate-100 cursor-pointer transition-colors"
onClick={() => router.push(`/product/${product.id}`)}
>
<Image
src={image}
alt={product.name}
width={64}
height={64}
unoptimized
className="w-16 h-16 rounded-md object-contain bg-white border border-slate-100"
/>
<div className="flex-1">
<p className="text-sm font-medium text-slate-900 line-clamp-2">
{product.name}
</p>
{price && (
<p className="text-sm font-semibold text-[#57A595] mt-1">
{formatPrice(price)}
</p>
)}
</div>
</div>
);
})}
</div>
);
};