vreadCrumb added
This commit is contained in:
195
components/breadCrumb.tsx
Normal file
195
components/breadCrumb.tsx
Normal file
@@ -0,0 +1,195 @@
|
||||
"use client";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { ChevronRight, Home } from "lucide-react";
|
||||
import { useTranslations } from "next-intl";
|
||||
import { useCategory } from "@/store/useCategory";
|
||||
import { useSubCategory } from "@/store/useSubCategory";
|
||||
import { useProductPageInfo } from "@/store/useProduct";
|
||||
|
||||
interface BreadcrumbProps {
|
||||
customLabels?: Record<string, string>;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function Breadcrumb({
|
||||
customLabels = {},
|
||||
className = "",
|
||||
}: BreadcrumbProps) {
|
||||
const pathname = usePathname();
|
||||
const t = useTranslations();
|
||||
const category = useCategory((state) => state.category);
|
||||
const subCategory = useSubCategory((state) => state.subCategory);
|
||||
const product = useProductPageInfo((state) => state.product);
|
||||
console.log("sub category: ", subCategory);
|
||||
|
||||
// Pathdan segments olish
|
||||
const segments = pathname.split("/").filter((segment) => segment !== "");
|
||||
|
||||
// Agar locale bo'lsa, uni olib tashlash (uz, en, ru)
|
||||
const locales = ["uz", "en", "ru"];
|
||||
const filteredSegments = segments.filter(
|
||||
(segment) => !locales.includes(segment),
|
||||
);
|
||||
|
||||
// Agar faqat home page bo'lsa, breadcrumb ko'rsatmaslik
|
||||
if (filteredSegments.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Breadcrumb items yaratish
|
||||
const breadcrumbItems: Array<{
|
||||
label: string;
|
||||
href: string;
|
||||
isLast: boolean;
|
||||
}> = [];
|
||||
|
||||
// Home qo'shish (har doim birinchi)
|
||||
breadcrumbItems.push({
|
||||
label: t("breadcrumb.home") || "Home",
|
||||
href: "/",
|
||||
isLast: false,
|
||||
});
|
||||
|
||||
// Locale olish
|
||||
const locale = segments.find((seg) => locales.includes(seg)) || "";
|
||||
const localePrefix = locale ? `/${locale}` : "";
|
||||
|
||||
// Segmentlarni tahlil qilish
|
||||
filteredSegments.forEach((segment, index) => {
|
||||
const isLast = index === filteredSegments.length - 1;
|
||||
|
||||
if (segment === "catalog_page") {
|
||||
// Catalog_page - asosiy kategoriyalar sahifasi
|
||||
breadcrumbItems.push({
|
||||
label: t("breadcrumb.catalog_page") || "Katalog",
|
||||
href: `${localePrefix}/catalog_page`,
|
||||
isLast: isLast,
|
||||
});
|
||||
} else if (segment === "subCategory") {
|
||||
// SubCategory - kategoriya nomi ko'rsatiladi
|
||||
if (category?.name) {
|
||||
breadcrumbItems.push({
|
||||
label: category.name,
|
||||
href: `${localePrefix}/catalog_page/subCategory`,
|
||||
isLast: isLast,
|
||||
});
|
||||
}
|
||||
} else if (segment === "products") {
|
||||
if (subCategory?.name) {
|
||||
// Agar subCategory orqali kelgan bo'lsa
|
||||
// 1. Kategoriya
|
||||
if (category?.name) {
|
||||
const categoryInBreadcrumb = breadcrumbItems.find(
|
||||
(item) => item.label === category.name,
|
||||
);
|
||||
if (!categoryInBreadcrumb) {
|
||||
breadcrumbItems.push({
|
||||
label: category.name,
|
||||
href: `${localePrefix}/catalog_page/subCategory`,
|
||||
isLast: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 2. SubKategoriya
|
||||
breadcrumbItems.push({
|
||||
label: subCategory.name,
|
||||
href: `${localePrefix}/catalog_page/subCategory`,
|
||||
isLast: false,
|
||||
});
|
||||
} else if (category?.name) {
|
||||
// To'g'ridan-to'g'ri kategoriyadan products ga kelgan
|
||||
breadcrumbItems.push({
|
||||
label: category.name,
|
||||
href: `${localePrefix}/catalog_page`,
|
||||
isLast: false,
|
||||
});
|
||||
}
|
||||
} else if (segment.startsWith("[") && segment.endsWith("]")) {
|
||||
// Dynamic route (masalan, [slug])
|
||||
// Custom label yoki default
|
||||
const slugValue = segment.replace(/\[|\]/g, "");
|
||||
const label = customLabels[slugValue] || slugValue;
|
||||
|
||||
breadcrumbItems.push({
|
||||
label: label,
|
||||
href: `${localePrefix}/${filteredSegments.slice(0, index + 1).join("/")}`,
|
||||
isLast: isLast,
|
||||
});
|
||||
} else {
|
||||
// Boshqa segmentlar
|
||||
const label = getLabel(segment);
|
||||
breadcrumbItems.push({
|
||||
label: label,
|
||||
href: `${localePrefix}/${filteredSegments.slice(0, index + 1).join("/")}`,
|
||||
isLast: isLast,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Default label translator
|
||||
function getLabel(segment: string): string {
|
||||
// Agar custom label berilgan bo'lsa
|
||||
if (customLabels[segment]) {
|
||||
return customLabels[segment];
|
||||
}
|
||||
|
||||
// Agar translation mavjud bo'lsa
|
||||
try {
|
||||
if (segment === "special_product") {
|
||||
return product.name;
|
||||
}
|
||||
return t(`breadcrumb.${segment}`);
|
||||
} catch {
|
||||
// Aks holda, segment nomini formatlash
|
||||
return segment
|
||||
.replace(/-/g, " ")
|
||||
.replace(/_/g, " ")
|
||||
.split(" ")
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
||||
.join(" ");
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<nav aria-label="Breadcrumb" className={`py-4 ${className}`}>
|
||||
<ol className="flex items-center flex-wrap gap-2 text-sm">
|
||||
{breadcrumbItems.map((item, index) => (
|
||||
<li
|
||||
key={`${item.label}-${index}`}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
{index > 0 && (
|
||||
<ChevronRight className="w-4 h-4 text-gray-400 dark:text-gray-600" />
|
||||
)}
|
||||
|
||||
{index === 0 ? (
|
||||
// Home link with icon
|
||||
<Link
|
||||
href={item.href}
|
||||
className="flex items-center gap-1.5 text-gray-600 hover:text-red-600 dark:text-gray-400 dark:hover:text-red-500 transition-colors duration-200"
|
||||
>
|
||||
<Home className="w-4 h-4" />
|
||||
<span className="hidden sm:inline">{item.label}</span>
|
||||
</Link>
|
||||
) : item.isLast ? (
|
||||
// Last item (current page)
|
||||
<span className="text-gray-900 dark:text-white font-medium line-clamp-1">
|
||||
{item.label}
|
||||
</span>
|
||||
) : (
|
||||
// Regular link
|
||||
<Link
|
||||
href={item.href}
|
||||
className="text-gray-600 hover:text-red-600 dark:text-gray-400 dark:hover:text-red-500 transition-colors duration-200 line-clamp-1"
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
@@ -2,14 +2,13 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import httpClient from "@/request/api";
|
||||
import { endPoints } from "@/request/links";
|
||||
import { useEffect } from "react";
|
||||
import CatalogCard from "../../products/catalog";
|
||||
import CatalogCardSkeleton from "@/components/loadingSkleton";
|
||||
import EmptyData from "@/components/EmptyData";
|
||||
import { getRouteLang } from "@/request/getLang";
|
||||
import { CategoryType } from "@/lib/types";
|
||||
|
||||
export default function Catalog() {
|
||||
export default function Catalog() {
|
||||
const language = getRouteLang();
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ["category", language],
|
||||
|
||||
@@ -84,8 +84,8 @@ export default function CatalogCard({
|
||||
};
|
||||
|
||||
const navigateLink = have_sub_category
|
||||
? `/${locale}/subCategory?category=${id}`
|
||||
: `/${locale}/products?category=${id}`;
|
||||
? `/${locale}/catalog_page/subCategory?category=${id}`
|
||||
: `/${locale}/catalog_page/products?category=${id}`;
|
||||
|
||||
return (
|
||||
<Link
|
||||
|
||||
@@ -18,7 +18,7 @@ export default function ProductCard({
|
||||
const locale = useLocale();
|
||||
|
||||
return (
|
||||
<Link href={`/${locale}/products/${slug}`} onClick={getProduct}>
|
||||
<Link href={`/${locale}/catalog_page/products/${slug}`} onClick={getProduct}>
|
||||
<article className="group transition-all duration-300 hover:cursor-pointer max-sm:max-w-100 max-sm:mx-auto max-sm:w-full">
|
||||
{/* Image Container */}
|
||||
<div className="relative rounded-2xl h-45 sm:h-55 md:h-65 lg:w-[95%] w-[90%] mx-auto overflow-hidden">
|
||||
|
||||
@@ -32,7 +32,7 @@ export default function Card({
|
||||
image,
|
||||
category,
|
||||
});
|
||||
router.push(`/${locale}/products`);
|
||||
router.push(`/${locale}/catalog_page/products`);
|
||||
};
|
||||
return (
|
||||
<Link href="#" onClick={handleClick}>
|
||||
|
||||
Reference in New Issue
Block a user