api ulandi
This commit is contained in:
@@ -1,7 +1,15 @@
|
||||
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 { categories, ProductDetail } from '@/widgets/categories/lib/data';
|
||||
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';
|
||||
import { Fragment, useEffect, useState } from 'react';
|
||||
|
||||
@@ -10,62 +18,106 @@ type SearchResultProps = {
|
||||
};
|
||||
|
||||
export const SearchResult = ({ query }: SearchResultProps) => {
|
||||
const [searchProduct, setSearchProduct] = useState<ProductDetail[]>([]);
|
||||
const router = useRouter();
|
||||
const t = useTranslations();
|
||||
const [searchRes, setSearchRes] = useState<
|
||||
ProductListResult[] | SearchDataPro[] | []
|
||||
>([]);
|
||||
|
||||
const { data: product } = useQuery({
|
||||
queryKey: ['product_list'],
|
||||
queryFn: () => product_api.list({ page: 1, page_size: 99 }),
|
||||
select(data) {
|
||||
return data.data.results;
|
||||
},
|
||||
});
|
||||
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ['search', query],
|
||||
queryFn: () => product_api.search({ search: query, page: 1, page_szie: 5 }),
|
||||
select(data) {
|
||||
return data.data.products;
|
||||
},
|
||||
enabled: !!query,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setSearchProduct(
|
||||
categories.flatMap((cat) =>
|
||||
cat.products.filter((pro) =>
|
||||
pro.name.toLowerCase().includes(query.toLowerCase()),
|
||||
),
|
||||
),
|
||||
);
|
||||
}, [query]);
|
||||
if (data) {
|
||||
setSearchRes(data);
|
||||
} else if (product && product.length > 0) {
|
||||
setSearchRes(product);
|
||||
} else {
|
||||
setSearchRes([]);
|
||||
}
|
||||
}, [product, data]);
|
||||
|
||||
if (searchProduct.length === 0) {
|
||||
if (searchRes && searchRes.length === 0) {
|
||||
return (
|
||||
<div className="flex flex-col justify-center items-center min-h-[300px] max-h-[600px] gap-2">
|
||||
<PackageOpen className="size-22 text-muted-foreground" />
|
||||
<p className="text-lg text-muted-foreground text-center">
|
||||
Hech narsa topilmadi
|
||||
{t('Hech narsa topilmadi')}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
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 rounded-lg">
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<p className="text-sm font-semibold text-foreground">
|
||||
{query.length > 0 ? 'Qidiruv natijalari' : 'Tavsiya etiladi'}
|
||||
{query.length > 0 ? t('Qidiruv natijalari') : t('Tavsiya etiladi')}
|
||||
</p>
|
||||
|
||||
{searchProduct.slice(0, 5).map((product, index) => (
|
||||
<Fragment key={index}>
|
||||
<div
|
||||
className="flex items-center gap-3 p-2 rounded-lg hover:bg-slate-100 cursor-pointer transition"
|
||||
onClick={() => router.push(`/product/${product.id}`)}
|
||||
>
|
||||
<Image
|
||||
width={500}
|
||||
height={500}
|
||||
src={product.image}
|
||||
alt={product.name}
|
||||
className="w-10 h-10 rounded-md object-cover"
|
||||
/>
|
||||
{searchRes &&
|
||||
searchRes
|
||||
.filter((product) => product.is_active)
|
||||
.slice(0, 5)
|
||||
.map((product, index) => (
|
||||
<Fragment key={index}>
|
||||
<div
|
||||
className="flex items-center gap-3 p-2 rounded-lg hover:bg-slate-100 cursor-pointer transition"
|
||||
onClick={() => router.push(`/product/${product.id}`)}
|
||||
>
|
||||
<Image
|
||||
width={500}
|
||||
height={500}
|
||||
src={
|
||||
product.image.includes(BASE_URL)
|
||||
? product.image
|
||||
: BASE_URL + product.image
|
||||
}
|
||||
alt={product.name}
|
||||
className="w-16 h-16 rounded-md object-contain"
|
||||
/>
|
||||
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-medium text-slate-800">
|
||||
{product.name}
|
||||
</p>
|
||||
<p className="text-xs text-slate-500">{product.rating}</p>
|
||||
<p className="text-xs text-slate-600">
|
||||
{formatPrice(product.price)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
))}
|
||||
<div className="flex-1">
|
||||
<p className="text-sm font-medium text-slate-800">
|
||||
{product.name}
|
||||
</p>
|
||||
<p className="text-xs text-slate-600">
|
||||
{formatPrice(product.price)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Fragment>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user