menu category mobile

This commit is contained in:
hamid zarghami
2025-10-25 17:57:18 +03:30
parent 8a1150d6eb
commit 7e31f55fb7
+136 -161
View File
@@ -2,6 +2,9 @@
import { FC, useState } from 'react' import { FC, useState } from 'react'
import { ArrowLeft2 } from 'iconsax-react' import { ArrowLeft2 } from 'iconsax-react'
import { useRouter } from 'next/navigation' import { useRouter } from 'next/navigation'
import Image from 'next/image'
import { useGetCategories } from '@/share/hooks/useShareData'
import { Category } from '@/share/types/SharedTypes'
type Props = { type Props = {
isOpen: boolean isOpen: boolean
@@ -10,202 +13,174 @@ type Props = {
const CategoryModal: FC<Props> = ({ isOpen, onClose }) => { const CategoryModal: FC<Props> = ({ isOpen, onClose }) => {
const router = useRouter() const router = useRouter()
const [selectedMainCategory, setSelectedMainCategory] = useState<number>(0) const { data, isLoading } = useGetCategories()
const [selectedMainCategory, setSelectedMainCategory] = useState<string | null>(null)
const [expandedSubcategory, setExpandedSubcategory] = useState<string | null>(null) const [expandedSubcategory, setExpandedSubcategory] = useState<string | null>(null)
// Main categories for the left column const parentCategories = data?.results?.data?.filter(cat => !cat.parent) || []
const mainCategories = [
{ icon: '🏪', title: 'سوپر مارکت ارگانیک' },
{ icon: '🍞', title: 'خانه نان و شیرینی سالم' },
{ icon: '🍎', title: 'بوفه رژیم‌های خاص' },
{ icon: '💪', title: 'بوفه سبک زندگی' },
{ icon: '🌿', title: 'عطاری سلامت' },
{ icon: '🎁', title: 'بوفه هدایا و سوغات' }
]
// Subcategories for each main category const handleMainCategoryClick = (categoryId: string) => {
const categorySubcategories = { setSelectedMainCategory(categoryId)
'سوپر مارکت ارگانیک': [
{ title: 'ارگانیک گواهی‌دار', hasChildren: false },
{ title: 'روغن های سالم', hasChildren: true },
{ title: 'چاشنی سلامت', hasChildren: true },
{ title: 'صبحانه سالم', hasChildren: false },
{ title: 'نوشیدنی سالم', hasChildren: false },
{ title: 'آرایشی', hasChildren: false },
{ title: 'بهداشتی', hasChildren: false },
{ title: 'تازه خوری', hasChildren: false },
{ title: 'حبوبات و غلات', hasChildren: false },
{ title: 'تنقلات', hasChildren: false },
{ title: 'چای و دمنوش', hasChildren: false },
{ title: 'قهوه', hasChildren: false },
{ title: 'قند و شکر', hasChildren: false }
],
'خانه نان و شیرینی سالم': [
{ title: 'نان سنتی', hasChildren: false },
{ title: 'نان صنعتی', hasChildren: false },
{ title: 'شیرینی', hasChildren: false },
{ title: 'کیک و کلوچه', hasChildren: false }
],
'بوفه رژیم‌های خاص': [
{ title: 'رژیم کتو', hasChildren: false },
{ title: 'رژیم وگان', hasChildren: false },
{ title: 'بدون گلوتن', hasChildren: false }
],
'بوفه سبک زندگی': [
{ title: 'ورزشی', hasChildren: false },
{ title: 'لاغری', hasChildren: false },
{ title: 'سالمندان', hasChildren: false }
],
'عطاری سلامت': [
{ title: 'گیاهان دارویی', hasChildren: false },
{ title: 'عسل طبیعی', hasChildren: false },
{ title: 'دمنوش', hasChildren: false }
],
'بوفه هدایا و سوغات': [
{ title: 'هدایا', hasChildren: false },
{ title: 'سوغات', hasChildren: false },
{ title: 'بسته بندی ویژه', hasChildren: false }
]
}
// Third level subcategories (for items that expand)
const thirdLevelCategories = {
'روغن های سالم': [
{ icon: '🫒', title: 'روغن زیتون پیوست و مو' },
{ icon: '🌻', title: 'روغن ماساژ' },
{ icon: '🥥', title: 'روغن های خوراکی' }
],
'چاشنی سلامت': [
{ icon: '🥒', title: 'ترشی' },
{ icon: '🥫', title: 'رب ها' },
{ icon: '🍯', title: 'سس ها' },
{ icon: '🥬', title: 'سبزیجات خشک' },
{ icon: '🌶️', title: 'ادویه' },
{ icon: '🍎', title: 'سرکه' },
{ icon: '🫒', title: 'زیتون' }
]
}
const handleMainCategoryClick = (index: number) => {
setSelectedMainCategory(index)
setExpandedSubcategory(null) setExpandedSubcategory(null)
} }
const handleSubcategoryClick = (subcategory: { title: string; hasChildren: boolean }) => { const handleSubcategoryClick = (category: Category) => {
if (subcategory.hasChildren && thirdLevelCategories[subcategory.title as keyof typeof thirdLevelCategories]) { if (category.children && category.children.length > 0) {
setExpandedSubcategory(expandedSubcategory === subcategory.title ? null : subcategory.title) setExpandedSubcategory(expandedSubcategory === category._id ? null : category._id)
} else { } else {
router.push(`/products/${subcategory.title}`) router.push(`/products/${category.title_en}`)
onClose() onClose()
} }
} }
const handleCategoryNavigate = (category: Category) => {
router.push(`/products/${category.title_en}`)
onClose()
}
if (!isOpen) return null if (!isOpen) return null
const currentMainCategory = mainCategories[selectedMainCategory] const currentMainCategoryData = selectedMainCategory
const currentSubcategories = categorySubcategories[currentMainCategory.title as keyof typeof categorySubcategories] || [] ? parentCategories.find(cat => cat._id === selectedMainCategory)
: parentCategories[0]
const currentSubcategories = currentMainCategoryData?.children || []
return ( return (
<div className="fixed top-[120px] left-0 right-0 bottom-0 bg-white z-40 md:hidden"> <div className="fixed top-[120px] left-0 right-0 bottom-0 bg-white z-40 md:hidden">
<div className="flex h-full overflow-hidden"> <div className="flex h-full overflow-hidden">
{/* Left Column - Main Categories */} {/* Left Column - Main Categories */}
<div className="w-28 bg-gray-100 overflow-y-auto"> <div className="w-28 bg-gray-100 overflow-y-auto">
<div className="p-2 space-y-2"> {isLoading ? (
{mainCategories.map((category, index) => ( <div className="flex items-center justify-center h-40">
<div key={index}> <div className="text-gray-500 text-xs">در حال بارگذاری...</div>
<div </div>
className={`flex flex-col items-center text-center p-2 cursor-pointer rounded-lg transition-colors ${index === selectedMainCategory ? 'bg-white shadow-sm' : 'hover:bg-gray-200' ) : (
}`} <div className="p-2 space-y-2">
onClick={() => handleMainCategoryClick(index)} {parentCategories.map((category, index) => (
> <div key={category._id}>
<div className="w-12 h-12 bg-white rounded-full flex items-center justify-center mb-1 shadow-sm"> <div
<span className="text-lg">{category.icon}</span> className={`flex flex-col items-center text-center p-2 cursor-pointer rounded-lg transition-colors ${(selectedMainCategory || parentCategories[0]?._id) === category._id
? 'bg-white shadow-sm'
: 'hover:bg-gray-200'
}`}
onClick={() => handleMainCategoryClick(category._id)}
>
<div className="w-12 h-12 bg-white rounded-full flex items-center justify-center mb-1 shadow-sm">
{category.icon ? (
<Image
src={category.icon}
alt={category.title_fa}
width={24}
height={24}
className="w-6 h-6 object-contain"
/>
) : (
<span className="text-lg">📦</span>
)}
</div>
<span className="text-xs text-gray-800 leading-tight text-center">
{category.title_fa}
</span>
</div> </div>
<span className="text-xs text-gray-800 leading-tight text-center"> {index < parentCategories.length - 1 && (
{category.title} <div className="border-b border-gray-200 mx-1" />
</span> )}
</div> </div>
{index < mainCategories.length - 1 && ( ))}
<div className="border-b border-gray-200 mx-1" /> </div>
)} )}
</div>
))}
</div>
</div> </div>
{/* Right Column - Subcategories */} {/* Right Column - Subcategories */}
<div className="flex-1 bg-white overflow-y-auto"> <div className="flex-1 bg-white overflow-y-auto">
<div className="px-4 py-4"> <div className="px-4 py-4">
{/* Special Categories */} {isLoading ? (
<div className="space-y-1 mb-4"> <div className="flex items-center justify-center h-40">
<div <div className="text-gray-500">در حال بارگذاری...</div>
className="py-3 cursor-pointer hover:bg-gray-50 transition-colors"
onClick={() => {
router.push('/products')
onClose()
}}
>
<span className="text-primary font-medium text-sm">همه محصولات سوپر مارکت ارگانیک</span>
</div> </div>
<div ) : (
className="py-3 cursor-pointer hover:bg-gray-50 transition-colors" <>
onClick={() => { {/* Main Category Link */}
router.push('/products/organic') {currentMainCategoryData && (
onClose() <div className="space-y-1 mb-4">
}} <div
> className="py-3 cursor-pointer hover:bg-gray-50 transition-colors"
<span className="text-gray-800 font-medium text-sm">ارگانیک گواهیدار</span> onClick={() => handleCategoryNavigate(currentMainCategoryData)}
</div> >
</div> <span className="text-primary font-medium text-sm">
همه محصولات {currentMainCategoryData.title_fa}
{/* Subcategories List */} </span>
<div> </div>
{currentSubcategories.map((subcategory, index) => (
<div key={index}>
<div
className="flex items-center justify-between py-3 cursor-pointer hover:bg-gray-50 transition-colors"
onClick={() => handleSubcategoryClick(subcategory)}
>
<span className="text-gray-800 text-sm">{subcategory.title}</span>
{subcategory.hasChildren && (
<ArrowLeft2 size={16} color="#666" />
)}
</div> </div>
)}
{/* Expanded third level categories */} {/* Subcategories List */}
{expandedSubcategory === subcategory.title && thirdLevelCategories[subcategory.title as keyof typeof thirdLevelCategories] && ( <div>
<div className="mt-2 mb-4 p-4 bg-gray-50 rounded-lg"> {currentSubcategories.length > 0 ? (
<div className="text-sm text-primary mb-3 font-medium"> currentSubcategories.map((subcategory, index) => (
همه محصولات {subcategory.title} <div key={subcategory._id}>
</div> <div
<div className="grid grid-cols-2 gap-4"> className="flex items-center justify-between py-3 cursor-pointer hover:bg-gray-50 transition-colors"
{thirdLevelCategories[subcategory.title as keyof typeof thirdLevelCategories].map((item, itemIndex) => ( onClick={() => handleSubcategoryClick(subcategory)}
<div >
key={itemIndex} <span className="text-gray-800 text-sm">{subcategory.title_fa}</span>
className="flex flex-col items-center p-4 bg-white rounded-lg cursor-pointer hover:bg-gray-100 transition-colors" {subcategory.children && subcategory.children.length > 0 && (
onClick={() => { <ArrowLeft2 size={16} color="#666" />
router.push(`/products/${item.title}`) )}
onClose() </div>
}}
> {/* Expanded third level categories */}
<div className="w-14 h-14 bg-white rounded-full flex items-center justify-center mb-3 border border-gray-200"> {expandedSubcategory === subcategory._id && subcategory.children && subcategory.children.length > 0 && (
<span className="text-xl">{item.icon}</span> <div className="mt-2 mb-4 p-4 bg-gray-50 rounded-lg">
<div
className="text-sm text-primary mb-3 font-medium cursor-pointer"
onClick={() => handleCategoryNavigate(subcategory)}
>
همه محصولات {subcategory.title_fa}
</div>
<div className="grid grid-cols-2 gap-4">
{subcategory.children.map((item) => (
<div
key={item._id}
className="flex flex-col items-center p-4 bg-white rounded-lg cursor-pointer hover:bg-gray-100 transition-colors"
onClick={() => handleCategoryNavigate(item)}
>
<div className="w-14 h-14 bg-white rounded-full flex items-center justify-center mb-3 border border-gray-200">
{item.icon ? (
<Image
src={item.icon}
alt={item.title_fa}
width={28}
height={28}
className="w-7 h-7 object-contain"
/>
) : (
<span className="text-xl">📦</span>
)}
</div>
<span className="text-sm text-gray-800 text-center leading-tight font-medium">
{item.title_fa}
</span>
</div>
))}
</div> </div>
<span className="text-sm text-gray-800 text-center leading-tight font-medium">
{item.title}
</span>
</div> </div>
))} )}
{index < currentSubcategories.length - 1 && (
<div className="border-b border-gray-100" />
)}
</div> </div>
))
) : (
<div className="text-center text-gray-500 py-8">
زیردستهای یافت نشد
</div> </div>
)} )}
{index < currentSubcategories.length - 1 && (
<div className="border-b border-gray-100" />
)}
</div> </div>
))} </>
</div> )}
</div> </div>
</div> </div>
</div> </div>