143 lines
4.3 KiB
TypeScript
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>
|
|
);
|
|
};
|