add catalog filter card

This commit is contained in:
nabijonovdavronbek619@gmail.com
2026-02-07 11:27:13 +05:00
parent 66bf104cb7
commit dbe8399086
9 changed files with 199 additions and 78 deletions

View File

@@ -1,12 +1,13 @@
import Catalog from "@/components/pages/home/blog/catalog";
import { ProductBanner } from "@/components/pages/products";
import { MainSubCategory } from "@/components/pages/subCategory";
export default function Page() {
return (
<div className="bg-[#1e1d1c] pb-30">
<ProductBanner />
<div className="max-w-300 mx-auto w-full pt-20">
<Catalog />
<MainSubCategory />
</div>
</div>
);

View File

@@ -1,9 +1,11 @@
import { ProductBanner, Products } from "@/components/pages/products";
import FilterCatalog from "@/components/pages/products/filter/catalog/filterCatalog";
export default function Page() {
return (
<div className="bg-[#1e1d1c] pb-30">
<ProductBanner />
{/* <FilterCatalog /> */}
<Products />
</div>
);

View File

@@ -4,7 +4,7 @@ import { useTranslations } from "next-intl";
export function ProductBanner() {
const t = useTranslations();
return (
<section className="relative w-full h-[60vh] min-h-100 overflow-hidden pt-10">
<section className="relative w-full min-[400px]:h-[60vh] h-[75vh] min-h-100 overflow-hidden pt-10">
{/* Background Image */}
<div
className="absolute inset-0 z-0"

View File

@@ -84,7 +84,7 @@ export default function CatalogCard({
};
const navigateLink = have_sub_category
? `/${locale}/subCategory?category=${id}`
? `/${locale}/catalog_page?category=${id}`
: `/${locale}/products?category=${id}`;
return (

View File

@@ -0,0 +1,96 @@
"use client";
import EmptyData from "@/components/EmptyData";
import { CategoryType } from "@/lib/types";
import httpClient from "@/request/api";
import { getRouteLang } from "@/request/getLang";
import { endPoints } from "@/request/links";
import { useCategory } from "@/store/useCategory";
import { useQuery } from "@tanstack/react-query";
import { useEffect } from "react";
import CatalogCardSkeletonSmall from "./loading";
import Image from "next/image";
import { ArrowUpRight } from "lucide-react";
export default function FilterCatalog() {
const language = getRouteLang();
const setCategory = useCategory((state) => state.setCategory);
const { data, isLoading } = useQuery({
queryKey: ["category", language],
queryFn: () => httpClient(endPoints.category.all),
select: (data): CategoryType[] => data?.data?.results,
});
useEffect(() => {
console.log("product catalog data: ", data);
}, [data]);
if (isLoading) {
return (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{[...Array(3)].map((_, index) => (
<CatalogCardSkeletonSmall key={index} />
))}
</div>
);
}
// Ma'lumot yo'q holati
if (!data || data.length === 0) {
return (
<EmptyData
title="Katalog topilmadi"
description="Hozircha kategoriyalar mavjud emas. Keyinroq qaytib keling."
icon="shopping"
/>
);
}
return (
<div className="max-w-200 w-full mx-auto space-x-5 px-5 flex items-center justify-around my-10 -mt-30 pb-5 relative z-20 sm:overflow-x-hidden overflow-x-scroll">
{data?.map((item) => (
<div
onClick={() => setCategory(item)}
className="shrink-0 group relative w-55 h-60 overflow-hidden rounded-2xl bg-[#17161679] border border-white/10 transition-all duration-500 hover:-translate-y-1 hover:border-red-700 cursor-pointer"
>
{/* Background glow effect */}
<div className="absolute inset-0 bg-linear-to-t from-red-600/20 via-transparent to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
{/* Decorative corner accent */}
<div className="absolute top-0 right-0 w-16 h-16 bg-linear-to-br from-red-500/20 to-transparent rounded-bl-full opacity-0 group-hover:opacity-100 transition-opacity duration-500" />
{/* Content container */}
<div className="relative h-full flex flex-col p-4">
{/* Title section */}
<div className="mb-3">
<div className="flex items-start justify-between gap-2">
<h3 className="text-lg font-unbounded font-bold text-white leading-tight transition-colors duration-300">
{item.name}
</h3>
<div className="shrink-0 w-6 h-6 rounded-full bg-white/10 flex items-center justify-center group-hover:bg-red-500 transition-all duration-300 group-hover:scale-110">
<ArrowUpRight
className="w-3.5 h-3.5 text-white"
strokeWidth={2.5}
/>
</div>
</div>
</div>
{/* Image container */}
<div className="relative flex-1 rounded-xl overflow-hidden bg-linear-to-br from-[#444242] to-gray-900/50 border border-white/5 group-hover:border-white/20 transition-all duration-500">
<div className="absolute inset-0 bg-linear-to-t from-black/60 via-transparent to-transparent z-10" />
<div className="relative w-full h-full">
<Image
src={item.image}
alt={item.name}
fill
className="object-contain p-3 transition-transform duration-700 group-hover:scale-105"
/>
</div>
</div>
</div>
</div>
))}
</div>
);
}

View File

@@ -0,0 +1,23 @@
// components/CatalogCardSkeletonSmall.tsx
export default function CatalogCardSkeletonSmall() {
return (
<div className="relative w-50 h-87.5 overflow-hidden rounded-2xl bg-[#17161679] border border-white/10 animate-pulse">
<div className="flex flex-col h-full p-4 gap-3">
{/* Title skeleton */}
<div className="space-y-2">
<div className="h-5 bg-white/10 rounded-md w-3/4" />
<div className="h-5 bg-white/10 rounded-md w-1/2" />
</div>
{/* Image skeleton */}
<div className="flex-1 rounded-xl bg-linear-to-br from-[#444242] to-gray-900/50 border border-white/5 flex items-center justify-center">
<div className="w-20 h-20 bg-white/5 rounded-lg" />
</div>
</div>
{/* Shimmer */}
<div className="absolute inset-0 -translate-x-full animate-shimmer bg-linear-to-r from-transparent via-white/5 to-transparent" />
</div>
);
}

View File

@@ -67,26 +67,22 @@ export default function Filter() {
const visibleSectionNumber = numberExpanded
? sizeData
: sizeData.slice(0, 10);
console.log("have suncategory: ", category.have_sub_category);
if (category.have_sub_category || subCategory.id !== 0) {
return null;
}
console.log("filter: ", filter);
return (
<div className="space-y-3 max-w-70 w-full text-white">
<div className="space-y-3 lg:max-w-70 lg:px-0 px-3 w-full text-white">
{/* Bo'lim filtri */}
<div className="bg-gray-500 rounded-lg">
{visibleSectionData && (
<div className="bg-gray-500 rounded-lg w-full">
<p className="bg-red-500 text-white p-2 font-semibold font-almarai text-lg rounded-t-lg">
Bo'lim
</p>
<div className="space-y-3 p-2">
<div className="lg:space-y-3 space-x-6 lg:p-2 p-5 flex lg:flex-col overflow-x-auto lg:overflow-x-hidden items-start justify-start w-full">
{visibleSectionData.map((item) => (
<div
key={item.id}
onClick={() => toggleFilter(item)}
className="hover:cursor-pointer flex items-center gap-2"
className="hover:cursor-pointer flex items-center gap-2 w-auto shrink-0"
>
<span
className={`flex h-5 w-5 items-center justify-center rounded border-2 transition ${
@@ -100,29 +96,31 @@ export default function Filter() {
<Check className="h-3 w-3 text-white" strokeWidth={3} />
)}
</span>
<p>{item.name}</p>
<p className="whitespace-nowrap">{item.name}</p>
</div>
))}
</div>
<button
className="p-2 text-lg underline hover:text-red-300 transition"
className="lg:flex hidden p-2 text-lg underline hover:text-red-300 transition"
onClick={() => setDataExpanded(!dataExpanded)}
>
{dataExpanded ? "Yashirish" : "Ko'proq ko'rish"}
</button>
</div>
)}
{/* O'lcham filtri */}
{visibleSectionNumber && (
<div className="bg-gray-500 rounded-lg">
<p className="bg-red-500 text-white p-2 font-semibold font-almarai text-lg rounded-t-lg">
O'lcham
</p>
<div className="grid grid-cols-2 gap-3 p-2">
<div className="lg:space-y-3 space-x-6 lg:p-2 p-5 flex lg:flex-col overflow-x-auto lg:overflow-x-hidden items-start justify-start w-full">
{visibleSectionNumber.map((item) => (
<div
key={item.id}
onClick={() => toggleFilter(item)}
className="hover:cursor-pointer flex items-center gap-2"
className="hover:cursor-pointer flex items-center gap-2 w-auto shrink-0"
>
<span
className={`flex h-5 w-5 items-center justify-center rounded border-2 transition ${
@@ -142,11 +140,12 @@ export default function Filter() {
</div>
<button
onClick={() => setNumberExpanded(!numberExpanded)}
className="p-2 text-lg underline hover:text-red-300 transition"
className="lg:flex hidden p-2 text-lg underline hover:text-red-300 transition"
>
{numberExpanded ? "Yashirish" : "Ko'proq ko'rish"}
</button>
</div>
)}
</div>
);
}

View File

@@ -4,9 +4,9 @@ import MainProduct from "./mianProduct";
export function Products() {
return (
<div className="bg-[#1e1d1c] py-20">
<div className="bg-[#1e1d1c] py-10">
<div className="max-w-300 mx-auto w-full z-20 relative">
<div className="flex items-start gap-5">
<div className="flex lg:flex-row flex-col lg:items-start items-center gap-5">
{/* filter part */}
<Filter />

View File

@@ -32,7 +32,7 @@ export default function Card({
image,
category,
});
router.push(`/${locale}/products/${slug}`);
router.push(`/${locale}/products`);
};
return (
<Link href="#" onClick={handleClick}>