diff --git a/app/[locale]/cart/page.tsx b/app/[locale]/cart/page.tsx index 537b7ff..91b2bb9 100644 --- a/app/[locale]/cart/page.tsx +++ b/app/[locale]/cart/page.tsx @@ -18,11 +18,12 @@ import type { DeliveryType, PaymentType } from "@/lib/types/api"; export default function CartPage() { const [isClient, setIsClient] = useState(false); const [paymentType, setPaymentType] = useState(null); - const [deliveryType, setDeliveryType] = useState("SELECTED_DELIVERY"); + const [deliveryType, setDeliveryType] = + useState("SELECTED_DELIVERY"); const [selectedRegion, setSelectedRegion] = useState(""); const [selectedProvince, setSelectedProvince] = useState(null); const [note, setNote] = useState(""); - + const [phone, setPhone] = useState(""); const router = useRouter(); const t = useTranslations(); @@ -48,7 +49,10 @@ export default function CartPage() { }, {} as Record); }, [provinces]); - const availableRegions = useMemo(() => Object.keys(regionGroups), [regionGroups]); + const availableRegions = useMemo( + () => Object.keys(regionGroups), + [regionGroups] + ); // Memoize items grouped by seller const itemsBySeller = useMemo(() => { @@ -86,7 +90,9 @@ export default function CartPage() { return; } - const selectedProvinceData = provinces.find((p) => p.id === selectedProvince); + const selectedProvinceData = provinces.find( + (p) => p.id === selectedProvince + ); if (!selectedProvinceData) return; const orderData = userStore.getOrderData(); @@ -99,7 +105,7 @@ export default function CartPage() { createOrder( { customer_name: orderData.customer_name, - customer_phone: orderData.customer_phone, + customer_phone: phone, customer_address: selectedProvinceData.name, shipping_method: deliveryType === "PICK_UP" ? "pickup" : "standart", payment_type_id: paymentType.id, @@ -141,48 +147,52 @@ export default function CartPage() {
- {Object.entries(itemsBySeller).map(([sellerId, { seller, items }]) => ( -
-

{seller.name}

-
- {items.map((item) => { - const price = parseFloat(item.product.price_amount || "0"); - const quantity = item.product_quantity; - const total = price * quantity; + {Object.entries(itemsBySeller).map( + ([sellerId, { seller, items }]) => ( +
+

{seller.name}

+
+ {items.map((item) => { + const price = parseFloat( + item.product.price_amount || "0" + ); + const quantity = item.product_quantity; + const total = price * quantity; - return ( - m.images_800x800 || m.thumbnail - ) || [], - }, - }} - /> - ); - })} + return ( + m.images_800x800 || m.thumbnail + ) || [], + }, + }} + /> + ); + })} +
+ {Object.entries(itemsBySeller).length > 1 && ( + + )}
- {Object.entries(itemsBySeller).length > 1 && ( - - )} -
- ))} + ) + )}
@@ -217,8 +227,10 @@ export default function CartPage() { onNoteChange={setNote} onCompleteOrder={handleCompleteOrder} isLoading={isCreatingOrder} + phone={phone} + onPhoneChange={setPhone} />
); -} \ No newline at end of file +} diff --git a/app/[locale]/favorites/page.tsx b/app/[locale]/favorites/page.tsx index 595f993..e8d2143 100644 --- a/app/[locale]/favorites/page.tsx +++ b/app/[locale]/favorites/page.tsx @@ -1,76 +1,17 @@ "use client"; -import { - useFavorites, - useAddToCart, - useRemoveFromFavorites, -} from "@/lib/hooks"; -import { useState, useCallback, useMemo } from "react"; -import Image from "next/image"; -import Link from "next/link"; -import { Heart, ShoppingCart } from "lucide-react"; -import { Button } from "@/components/ui/button"; -import { Card } from "@/components/ui/card"; -import { Badge } from "@/components/ui/badge"; + +import { useFavorites } from "@/lib/hooks"; import { Skeleton } from "@/components/ui/skeleton"; -import { useToast } from "@/hooks/use-toast"; import { useTranslations } from "next-intl"; +import ProductCard from "@/features/home/components/ProductCard"; import type { Favorite } from "@/lib/types/api"; export default function FavoritesPage() { - const [isHovered, setIsHovered] = useState(null); - const { toast } = useToast(); const t = useTranslations(); - const { data: favorites, isLoading, isError } = useFavorites(); - const { mutate: removeFromFavorites, isPending: isRemoving } = - useRemoveFromFavorites(); - const { mutate: addToCart, isPending: isAddingToCart } = useAddToCart(); - const handleRemoveFromFavorites = useCallback( - (productId: number) => { - removeFromFavorites(productId, { - onSuccess: () => { - toast({ - title: t("removed_from_favorites"), - }); - }, - onError: (error) => { - toast({ - title: t("error"), - description: error.message, - variant: "destructive", - }); - }, - }); - }, - [removeFromFavorites, toast, t] - ); - - const handleAddToCart = useCallback( - (productId: number) => { - addToCart( - { productId }, - { - onSuccess: () => { - toast({ - title: t("added_to_cart"), - }); - }, - onError: (error) => { - toast({ - title: t("error"), - description: error.message, - variant: "destructive", - }); - }, - } - ); - }, - [addToCart, toast, t] - ); - - const loadingSkeleton = useMemo( - () => ( + if (isLoading) { + return (

{t("favorite_products")}

@@ -79,17 +20,12 @@ export default function FavoritesPage() { ))}
- ), - [t] - ); - - if (isLoading) { - return loadingSkeleton; + ); } if (isError || !favorites || favorites.length === 0) { return ( -
+

{t("favorite_products")}

{t("empty_favorites")}

@@ -99,145 +35,48 @@ export default function FavoritesPage() { } return ( -
-

{t("favorite_products")}

-
- {favorites.map((favorite: Favorite) => ( - handleRemoveFromFavorites(favorite.product.id)} - onAddToCart={() => handleAddToCart(favorite.product.id)} - onHover={setIsHovered} - isHovered={isHovered === favorite.product.id} - isRemoving={isRemoving} - isAddingToCart={isAddingToCart} - /> - ))} +
+

{t("favorite_products")}

+
+ {favorites.map((favorite: Favorite) => { + const product = favorite.product; + + const allImages = product.media + ?.map( + (media) => + media.images_800x800 || + media.images_720x720 || + media.images_400x400 || + media.thumbnail + ) + .filter(Boolean) || ["/placeholder-product.jpg"]; + + const formattedPrice = product.price_amount + ? `${parseFloat(product.price_amount).toFixed(2)} TMT` + : "Price not available"; + + return ( + + ); + })}
); } - -interface Product { - id: number; - name: string; - slug: string; - price_amount: string; - old_price_amount?: string | null; - media: Array<{ - thumbnail: string; - images_400x400: string; - images_720x720: string; - images_800x800: string; - images_1200x1200: string; - }>; - stock: number; -} - -interface ProductCardProps { - productId: number; - product: Product; - onRemove: () => void; - onAddToCart: () => void; - onHover: (id: number | null) => void; - isHovered: boolean; - isRemoving: boolean; - isAddingToCart: boolean; -} - -function ProductCard({ - productId, - product, - onRemove, - onAddToCart, - onHover, - isHovered, - isRemoving, - isAddingToCart, -}: ProductCardProps) { - const t = useTranslations(); - - if (!product) return null; - - const imageUrl = - product.media?.[0]?.images_800x800 || - product.media?.[0]?.thumbnail || - "/placeholder.svg"; - - const price = `${parseFloat(product.price_amount).toFixed(2)} TMT`; - const oldPrice = product.old_price_amount - ? `${parseFloat(product.old_price_amount).toFixed(2)} TMT` - : null; - - return ( - onHover(productId)} - onMouseLeave={() => onHover(null)} - > - -
- - - {product.name} - - {product.stock === 0 && ( -
- - {t("out_of_stock")} - -
- )} -
- -
-

- {product.name} -

-
- {oldPrice && ( -

{oldPrice}

- )} -

{price}

-
-
- - - {isHovered && product.stock > 0 && ( -
- -
- )} -
- ); -} diff --git a/app/[locale]/openStore/page.tsx b/app/[locale]/openStore/page.tsx index 667729b..bf14c8c 100644 --- a/app/[locale]/openStore/page.tsx +++ b/app/[locale]/openStore/page.tsx @@ -1,65 +1,74 @@ -"use client" +"use client"; -import type React from "react" -import { useState } from "react" -import { Upload } from "lucide-react" -import { Button } from "@/components/ui/button" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" -import { useOpenStore } from "@/lib/hooks" -import { useToast } from "@/hooks/use-toast" +import type React from "react"; +import { useState } from "react"; +import { Upload } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { useOpenStore } from "@/lib/hooks"; +import { useToast } from "@/hooks/use-toast"; interface OpenStorePageProps { - locale?: string + locale?: string; translations?: { - title: string - firstName: string - lastName: string - email: string - phone: string - uploadPatent: string - submit: string - selectedFile: string - firstNameRequired: string - lastNameRequired: string - emailInvalid: string - phoneInvalid: string - fileRequired: string - fileSizeError: string - fileTypeError: string - } + title: string; + firstName: string; + lastName: string; + email: string; + phone: string; + uploadPatent: string; + submit: string; + selectedFile: string; + firstNameRequired: string; + lastNameRequired: string; + emailInvalid: string; + phoneInvalid: string; + fileRequired: string; + fileSizeError: string; + fileTypeError: string; + }; } interface FormData { - firstName: string - lastName: string - email: string - phone: string - file: File | null + firstName: string; + lastName: string; + email: string; + phone: string; + file: File | null; } interface FormErrors { - firstName?: string - lastName?: string - email?: string - phone?: string - file?: string + firstName?: string; + lastName?: string; + email?: string; + phone?: string; + file?: string; } -export default function OpenStorePage({ locale = "ru", translations }: OpenStorePageProps) { +export default function OpenStorePage({ + locale = "ru", + translations, +}: OpenStorePageProps) { const [formData, setFormData] = useState({ firstName: "", lastName: "", email: "", phone: "+993", file: null, - }) - const [errors, setErrors] = useState({}) - const [fileName, setFileName] = useState("") + }); + const [errors, setErrors] = useState({}); + const [fileName, setFileName] = useState(""); - const { mutate: submitOpenStore, isPending: loading } = useOpenStore() - const { toast } = useToast() + const { mutate: submitOpenStore, isPending: loading } = useOpenStore(); + const { toast } = useToast(); const t = translations || { title: "Форма подачи заявления на открытие магазина", @@ -77,68 +86,68 @@ export default function OpenStorePage({ locale = "ru", translations }: OpenStore fileRequired: "Патент обязателен", fileSizeError: "Файл слишком большой (макс. 25MB)", fileTypeError: "Только PDF и JPG документы", - } + }; const validateForm = (): boolean => { - const newErrors: FormErrors = {} + const newErrors: FormErrors = {}; if (!formData.firstName.trim()) { - newErrors.firstName = t.firstNameRequired + newErrors.firstName = t.firstNameRequired; } if (!formData.lastName.trim()) { - newErrors.lastName = t.lastNameRequired + newErrors.lastName = t.lastNameRequired; } - const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(formData.email)) { - newErrors.email = t.emailInvalid + newErrors.email = t.emailInvalid; } - const phoneRegex = /^\+?[0-9]{6,15}$/ + const phoneRegex = /^\+?[0-9]{6,15}$/; if (!phoneRegex.test(formData.phone)) { - newErrors.phone = t.phoneInvalid + newErrors.phone = t.phoneInvalid; } if (!formData.file) { - newErrors.file = t.fileRequired + newErrors.file = t.fileRequired; } else { - const allowedTypes = ["image/jpeg", "image/jpg", "application/pdf"] + const allowedTypes = ["image/jpeg", "image/jpg", "application/pdf"]; if (!allowedTypes.includes(formData.file.type)) { - newErrors.file = t.fileTypeError + newErrors.file = t.fileTypeError; } if (formData.file.size > 25 * 1024 * 1024) { - newErrors.file = t.fileSizeError + newErrors.file = t.fileSizeError; } } - setErrors(newErrors) - return Object.keys(newErrors).length === 0 - } + setErrors(newErrors); + return Object.keys(newErrors).length === 0; + }; const handleInputChange = (e: React.ChangeEvent) => { - const { name, value } = e.target - setFormData((prev) => ({ ...prev, [name]: value })) + const { name, value } = e.target; + setFormData((prev) => ({ ...prev, [name]: value })); if (errors[name as keyof FormErrors]) { - setErrors((prev) => ({ ...prev, [name]: undefined })) + setErrors((prev) => ({ ...prev, [name]: undefined })); } - } + }; const handleFileChange = (e: React.ChangeEvent) => { - const file = e.target.files?.[0] + const file = e.target.files?.[0]; if (file) { - setFormData((prev) => ({ ...prev, file })) - setFileName(file.name) + setFormData((prev) => ({ ...prev, file })); + setFileName(file.name); if (errors.file) { - setErrors((prev) => ({ ...prev, file: undefined })) + setErrors((prev) => ({ ...prev, file: undefined })); } } - } + }; const handleSubmit = (e: React.FormEvent) => { - e.preventDefault() + e.preventDefault(); - if (!validateForm()) return + if (!validateForm()) return; if (formData.file) { submitOpenStore( @@ -154,34 +163,36 @@ export default function OpenStorePage({ locale = "ru", translations }: OpenStore toast({ title: "Success", description: "Your store request has been submitted successfully", - }) + }); setFormData({ firstName: "", lastName: "", email: "", phone: "+993", file: null, - }) - setFileName("") + }); + setFileName(""); }, onError: (error: any) => { toast({ title: "Error", description: error?.message || "Failed to submit store request", variant: "destructive", - }) + }); }, - }, - ) + } + ); } - } + }; return ( -
+
{t.title} - Заполните форму для подачи заявления + + Заполните форму для подачи заявления +
@@ -195,7 +206,9 @@ export default function OpenStorePage({ locale = "ru", translations }: OpenStore onChange={handleInputChange} className={errors.firstName ? "border-red-500" : ""} /> - {errors.firstName &&

{errors.firstName}

} + {errors.firstName && ( +

{errors.firstName}

+ )}
{/* Last Name */} @@ -208,7 +221,9 @@ export default function OpenStorePage({ locale = "ru", translations }: OpenStore onChange={handleInputChange} className={errors.lastName ? "border-red-500" : ""} /> - {errors.lastName &&

{errors.lastName}

} + {errors.lastName && ( +

{errors.lastName}

+ )}
{/* Email */} @@ -222,7 +237,9 @@ export default function OpenStorePage({ locale = "ru", translations }: OpenStore onChange={handleInputChange} className={errors.email ? "border-red-500" : ""} /> - {errors.email &&

{errors.email}

} + {errors.email && ( +

{errors.email}

+ )}
{/* Phone */} @@ -236,14 +253,22 @@ export default function OpenStorePage({ locale = "ru", translations }: OpenStore placeholder="+99361111111" className={errors.phone ? "border-red-500" : ""} /> - {errors.phone &&

{errors.phone}

} + {errors.phone && ( +

{errors.phone}

+ )}
{/* File Upload */}
- +
{/* Submit Button */} -
- ) + ); } diff --git a/components/layout/Header.tsx b/components/layout/Header.tsx index 32fe162..f072c1a 100644 --- a/components/layout/Header.tsx +++ b/components/layout/Header.tsx @@ -3,14 +3,8 @@ import { useState, useEffect, useCallback } from "react"; import Link from "next/link"; import Image from "next/image"; -import { X, Menu, Search, Store, LogOut, User as UserIcon } from "lucide-react"; +import { X, Search, Store, User as UserIcon } from "lucide-react"; import { Button } from "@/components/ui/button"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu"; import Logo from "@/public/logo.webp"; import CategoryMenu from "./ui/CategoryMenu"; import SearchBar from "./ui/SearchBar"; @@ -65,10 +59,16 @@ export default function Header({ locale = "ru" }: HeaderProps) { <>
-
+
- Logo + Logo
@@ -77,12 +77,16 @@ export default function Header({ locale = "ru" }: HeaderProps) { className="hidden gap-2 rounded-xl font-bold sm:flex hover:bg-[#005bff] bg-[#005bff] text-white" size="lg" > - {isCategoryOpen ? : } + {isCategoryOpen ? : } {t("common.catalog")}
- @@ -99,20 +103,13 @@ export default function Header({ locale = "ru" }: HeaderProps) { locale={locale} /> - +
- - - -
@@ -126,10 +123,7 @@ export default function Header({ locale = "ru" }: HeaderProps) { locale={locale} /> - setIsLoginOpen(false)} - /> + setIsLoginOpen(false)} /> ); -} \ No newline at end of file +} diff --git a/components/layout/ui/ActionButtons.tsx b/components/layout/ui/ActionButtons.tsx index cf870ae..2bcd9f0 100644 --- a/components/layout/ui/ActionButtons.tsx +++ b/components/layout/ui/ActionButtons.tsx @@ -3,7 +3,7 @@ import { useMemo } from "react"; import type React from "react"; import Link from "next/link"; -import { User, Truck, Heart, ShoppingCart, LogOut } from "lucide-react"; +import { User, Truck, Heart, Store, LogOut } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { @@ -16,7 +16,12 @@ import { useCart, useFavorites, useOrders } from "@/lib/hooks"; import { Skeleton } from "@/components/ui/skeleton"; import { useTranslations } from "next-intl"; import { useLogout } from "@/lib/hooks/useAuth"; -import { CartIcon, FavoriteIcon, OrderIcon, ProfileIcon } from "@/components/icons"; +import { + CartIcon, + FavoriteIcon, + OrderIcon, + ProfileIcon, +} from "@/components/icons"; interface ActionButtonsProps { isAuthenticated: boolean; @@ -34,15 +39,15 @@ interface ActionButtonData { isLoading?: boolean; } -export default function ActionButtons({ - isAuthenticated, - onAuthClick, +export default function ActionButtons({ + isAuthenticated, + onAuthClick, isLoading: authLoading, - locale = "ru" + locale = "ru", }: ActionButtonsProps) { const t = useTranslations(); const { mutate: logout, isPending: isLoggingOut } = useLogout(); - + const { data: cartData, isLoading: cartLoading } = useCart(); const { data: favoritesData, isLoading: favoritesLoading } = useFavorites(); const { data: ordersData, isLoading: ordersLoading } = useOrders(); @@ -69,29 +74,46 @@ export default function ActionButtons({ logout(); }; - const buttons: ActionButtonData[] = useMemo(() => [ - { - icon: , - label: t("common.orders"), - href: "/orders", - badgeCount: ordersCount, - isLoading: ordersLoading, - }, - { - icon: , - label: t("common.favorites"), - href: "/favorites", - badgeCount: favoritesCount, - isLoading: favoritesLoading, - }, - { - icon: , - label: t("common.cart"), - href: "/cart", - badgeCount: cartCount, - isLoading: cartLoading, - }, - ], [ordersCount, ordersLoading, favoritesCount, favoritesLoading, cartCount, cartLoading, t]); + const buttons: ActionButtonData[] = useMemo( + () => [ + { + icon: , + label: t("common.openStore"), + href: "/openStore", + }, + { + icon: , + label: t("common.orders"), + href: "/orders", + badgeCount: ordersCount, + isLoading: ordersLoading, + }, + { + icon: , + label: t("common.favorites"), + href: "/favorites", + badgeCount: favoritesCount, + isLoading: favoritesLoading, + }, + { + icon: , + label: t("common.cart"), + href: "/cart", + badgeCount: cartCount, + isLoading: cartLoading, + } + + ], + [ + ordersCount, + ordersLoading, + favoritesCount, + favoritesLoading, + cartCount, + cartLoading, + t, + ] + ); return (
@@ -101,13 +123,19 @@ export default function ActionButtons({ ) : isAuthenticated ? ( - - (window.location.href = `/${locale}/me`)}> + (window.location.href = `/${locale}/me`)} + > {t("profile")} @@ -118,7 +146,12 @@ export default function ActionButtons({ ) : ( - @@ -132,9 +165,21 @@ export default function ActionButtons({ ); } -function ActionButton({ icon, label, href, onClick, badgeCount, isLoading }: ActionButtonData) { +function ActionButton({ + icon, + label, + href, + onClick, + badgeCount, + isLoading, +}: ActionButtonData) { const buttonContent = ( - @@ -368,11 +366,11 @@ export default function CartItemCard({ item, onUpdate }: CartItemCardProps) { size="icon" onClick={handleQuantityIncrease} disabled={localQuantity >= availableStock} - className={`rounded-xl bg-blue-50 ${isSyncing ? 'opacity-70' : ''} ${ + className={`rounded-xl cursor-pointer bg-blue-50 ${isSyncing ? 'opacity-70' : ''} ${ localQuantity >= availableStock ? 'opacity-50 cursor-not-allowed' : '' }`} > - +
diff --git a/features/cart/components/OrderSummary.tsx b/features/cart/components/OrderSummary.tsx index 38dcf0b..98d2192 100644 --- a/features/cart/components/OrderSummary.tsx +++ b/features/cart/components/OrderSummary.tsx @@ -15,6 +15,7 @@ import { import DeliveryTypeSelector from "./DeliveryTypeSelector"; import { useTranslations } from "next-intl"; import type { DeliveryType, PaymentType, Province } from "@/lib/types/api"; +import { Input } from "@/components/ui/input"; interface OrderBillingItem { title: string; @@ -42,6 +43,8 @@ interface OrderSummaryProps { regionGroups: Record; availableRegions: string[]; paymentTypes: PaymentType[]; + phone: string; + onPhoneChange: (phone: string) => void; onPaymentTypeChange: (type: PaymentType) => void; onDeliveryTypeChange: (type: DeliveryType) => void; onRegionChange: (regionCode: string) => void; @@ -61,6 +64,7 @@ export default function OrderSummary({ regionGroups, availableRegions, paymentTypes, + phone, onPhoneChange, onPaymentTypeChange, onDeliveryTypeChange, onRegionChange, @@ -74,7 +78,7 @@ export default function OrderSummary({ const provincesForSelectedRegion = selectedRegion ? regionGroups[selectedRegion] || [] : []; - const isFormValid = selectedRegion && selectedProvince && paymentType; + const isFormValid = selectedRegion && selectedProvince && paymentType && phone; return ( @@ -167,6 +171,17 @@ export default function OrderSummary({
)} +{/* Phone Number */} +
+ + onPhoneChange(e.target.value)} + placeholder={t("phone")} + className="rounded-xl" + /> +
{/* Note */}
diff --git a/features/cart/hooks/useCart.ts b/features/cart/hooks/useCart.ts index 30d1e54..05cded9 100644 --- a/features/cart/hooks/useCart.ts +++ b/features/cart/hooks/useCart.ts @@ -224,7 +224,7 @@ export function useCreateOrder() { return useMutation({ mutationFn: async (payload: { customer_name?: string - customer_phone?: string + customer_phone: string customer_address: string shipping_method: string payment_type_id: number diff --git a/features/category/components/CategoryClient.tsx b/features/category/components/CategoryClient.tsx index 1f44b33..76aae31 100644 --- a/features/category/components/CategoryClient.tsx +++ b/features/category/components/CategoryClient.tsx @@ -23,7 +23,7 @@ import { useCategoryFilters, useFilteredCategoryProducts, } from "@/features/category/hooks/useCategories"; -import { notFound } from "next/navigation"; + import { useTranslations } from "next-intl"; import type { Category, Product } from "@/lib/types/api"; @@ -232,50 +232,14 @@ export default function CategoryPageClient({ [] ); - const renderBreadcrumbs = useCallback(() => { - if (!categoriesData || !selectedCategory) return null; - - const breadcrumbs: Category[] = []; - let currentCategory = selectedCategory; - let parentId = currentCategory.parent_id; - - breadcrumbs.unshift(currentCategory); - - while (parentId) { - const parentCategory = findCategoryById(categoriesData, parentId); - if (parentCategory) { - breadcrumbs.unshift(parentCategory); - parentId = parentCategory.parent_id; - } else { - break; - } - } - - return ( -
- {breadcrumbs.map((category, index) => ( -
- - {index < breadcrumbs.length - 1 && /} -
- ))} -
- ); - }, [categoriesData, selectedCategory, findCategoryById, locale, router]); + const FiltersContent = useCallback( () => (
{filtersData?.categories && filtersData.categories.length > 0 && (
-

{t("categories")}

+

{t("category")}

{filtersData.categories.map((category) => (