diff --git a/src/pages/category/Attributes.tsx b/src/pages/category/Attributes.tsx
index 3da0ceb..c4af140 100644
--- a/src/pages/category/Attributes.tsx
+++ b/src/pages/category/Attributes.tsx
@@ -6,7 +6,8 @@ import { AttributesModal } from './components'
import { useAttributesLogic } from './hooks/useAttributesLogic'
import { useGetCategoryAttributes } from './hooks/useCategoryData'
import { type CategoryAttributeType } from './types/Types'
-import { Add, Edit, Trash } from 'iconsax-react'
+import { Add, Edit } from 'iconsax-react'
+import TrashWithConfrim from '../../components/TrashWithConfrim'
const Attributes: FC = () => {
const { id } = useParams()
@@ -16,13 +17,17 @@ const Attributes: FC = () => {
isLoading,
isModalOpen,
newAttribute,
+ editingAttributeId,
openModal,
closeModal,
+ openEditModal,
setNewAttribute,
addAttribute,
+ deleteAttribute,
addValueToAttribute,
removeValueFromAttribute,
- isAddingLoading
+ isAddingLoading,
+ isDeletingLoading
} = useAttributesLogic({ id })
const attributes = attributesData?.results?.data?.category?.attributes || []
@@ -83,7 +88,7 @@ const Attributes: FC = () => {
}
return (
-
+
@@ -157,20 +162,12 @@ const Attributes: FC = () => {
)}
-
-
+
+ openEditModal(attribute)} color='#8C90A3' size={16} />
+ deleteAttribute(attribute._id)}
+ isLoading={isDeletingLoading}
+ />
{attribute.hint && (
@@ -204,6 +201,7 @@ const Attributes: FC = () => {
onAddValue={addValueToAttribute}
onRemoveValue={removeValueFromAttribute}
isLoading={isAddingLoading}
+ isEditing={!!editingAttributeId}
/>
)
diff --git a/src/pages/category/components/AttributesModal.tsx b/src/pages/category/components/AttributesModal.tsx
index 6ffe9aa..f95a977 100644
--- a/src/pages/category/components/AttributesModal.tsx
+++ b/src/pages/category/components/AttributesModal.tsx
@@ -17,6 +17,7 @@ interface AttributesModalProps {
onAddValue: (text: string) => void
onRemoveValue: (index: number) => void
isLoading?: boolean
+ isEditing?: boolean
}
const AttributesModal: FC
= ({
@@ -27,7 +28,8 @@ const AttributesModal: FC = ({
onAdd,
onAddValue,
onRemoveValue,
- isLoading = false
+ isLoading = false,
+ isEditing = false
}) => {
const [newValue, setNewValue] = useState('')
@@ -55,7 +57,7 @@ const AttributesModal: FC = ({
open={isOpen}
close={onClose}
isHeader={true}
- title_header="اضافه کردن ویژگی جدید"
+ title_header={isEditing ? "ویرایش ویژگی" : "اضافه کردن ویژگی جدید"}
width={600}
>
@@ -150,7 +152,7 @@ const AttributesModal: FC
= ({
onClick={onAdd}
disabled={!isFormValid() || isLoading}
>
- {isLoading ? 'در حال اضافه کردن...' : 'اضافه کردن'}
+ {isLoading ? (isEditing ? 'در حال ویرایش...' : 'در حال اضافه کردن...') : (isEditing ? 'ویرایش' : 'اضافه کردن')}
diff --git a/src/pages/category/hooks/useAttributesLogic.tsx b/src/pages/category/hooks/useAttributesLogic.tsx
index 14b4755..c36e393 100644
--- a/src/pages/category/hooks/useAttributesLogic.tsx
+++ b/src/pages/category/hooks/useAttributesLogic.tsx
@@ -1,6 +1,6 @@
import { useState } from 'react'
import { useQueryClient } from '@tanstack/react-query'
-import { useGetCategoryById, useCreateCategoryAttribute } from './useCategoryData'
+import { useGetCategoryById, useCreateCategoryAttribute, useUpdateCategoryAttribute, useDeleteCategoryAttribute } from './useCategoryData'
import { type CreateCategoryAttributeType } from '../types/Types'
import { toast } from 'react-toastify'
import { extractErrorMessage } from '../../../helpers/utils'
@@ -13,8 +13,11 @@ export const useAttributesLogic = ({ id }: UseAttributesLogicProps) => {
const queryClient = useQueryClient()
const { data, isLoading } = useGetCategoryById(id!)
const createAttributeMutation = useCreateCategoryAttribute()
+ const updateAttributeMutation = useUpdateCategoryAttribute()
+ const deleteAttributeMutation = useDeleteCategoryAttribute()
const [isModalOpen, setIsModalOpen] = useState(false)
+ const [editingAttributeId, setEditingAttributeId] = useState(null)
const [newAttribute, setNewAttribute] = useState({
title: '',
type: 'text',
@@ -27,6 +30,7 @@ export const useAttributesLogic = ({ id }: UseAttributesLogicProps) => {
const resetModal = () => {
setIsModalOpen(false)
+ setEditingAttributeId(null)
setNewAttribute({
title: '',
type: 'text',
@@ -38,23 +42,68 @@ export const useAttributesLogic = ({ id }: UseAttributesLogicProps) => {
const openModal = () => setIsModalOpen(true)
const closeModal = () => resetModal()
+ const openEditModal = (attribute: any) => {
+ setEditingAttributeId(attribute._id)
+ setNewAttribute({
+ title: attribute.title,
+ type: attribute.type,
+ multiple: attribute.multiple,
+ hint: attribute.hint || '',
+ required: attribute.required,
+ values: attribute.values.map((v: any) => ({ text: v.text }))
+ })
+ setIsModalOpen(true)
+ }
+
const addAttribute = async () => {
if (!id || !newAttribute.title.trim()) return
- createAttributeMutation.mutate(
- { id, data: newAttribute },
- {
- onSuccess: () => {
- toast.success('ویژگی با موفقیت اضافه شد')
- resetModal()
- queryClient.invalidateQueries({ queryKey: ['category', id] })
- queryClient.invalidateQueries({ queryKey: ['category', 'attributes', id] })
- },
- onError: (error) => {
- toast.error(extractErrorMessage(error))
+ if (editingAttributeId) {
+ // ویرایش ویژگی
+ updateAttributeMutation.mutate(
+ { attrId: editingAttributeId, ...newAttribute },
+ {
+ onSuccess: () => {
+ toast.success('ویژگی با موفقیت ویرایش شد')
+ resetModal()
+ queryClient.invalidateQueries({ queryKey: ['category', id] })
+ queryClient.invalidateQueries({ queryKey: ['category', 'attributes', id] })
+ },
+ onError: (error) => {
+ toast.error(extractErrorMessage(error))
+ }
}
+ )
+ } else {
+ // ایجاد ویژگی جدید
+ createAttributeMutation.mutate(
+ { id, data: newAttribute },
+ {
+ onSuccess: () => {
+ toast.success('ویژگی با موفقیت اضافه شد')
+ resetModal()
+ queryClient.invalidateQueries({ queryKey: ['category', id] })
+ queryClient.invalidateQueries({ queryKey: ['category', 'attributes', id] })
+ },
+ onError: (error) => {
+ toast.error(extractErrorMessage(error))
+ }
+ }
+ )
+ }
+ }
+
+ const deleteAttribute = async (attributeId: number) => {
+ deleteAttributeMutation.mutate(attributeId, {
+ onSuccess: () => {
+ toast.success('ویژگی با موفقیت حذف شد')
+ queryClient.invalidateQueries({ queryKey: ['category', id] })
+ queryClient.invalidateQueries({ queryKey: ['category', 'attributes', id] })
+ },
+ onError: (error) => {
+ toast.error(extractErrorMessage(error))
}
- )
+ })
}
const updateNewAttribute = (field: keyof CreateCategoryAttributeType, value: any) => {
@@ -87,16 +136,20 @@ export const useAttributesLogic = ({ id }: UseAttributesLogicProps) => {
// Modal state
isModalOpen,
newAttribute,
+ editingAttributeId,
// Actions
openModal,
closeModal,
+ openEditModal,
setNewAttribute: updateNewAttribute,
addAttribute,
+ deleteAttribute,
addValueToAttribute,
removeValueFromAttribute,
// Loading states
- isAddingLoading: createAttributeMutation.isPending
+ isAddingLoading: createAttributeMutation.isPending || updateAttributeMutation.isPending,
+ isDeletingLoading: deleteAttributeMutation.isPending
}
}
diff --git a/src/pages/category/hooks/useCategoryData.tsx b/src/pages/category/hooks/useCategoryData.tsx
index b4d8726..e655281 100644
--- a/src/pages/category/hooks/useCategoryData.tsx
+++ b/src/pages/category/hooks/useCategoryData.tsx
@@ -83,4 +83,17 @@ export const useGetCategoryAttributes = (id: string) => {
queryFn: () => api.getCategoryAttributes(id),
enabled: !!id,
});
+};
+
+export const useUpdateCategoryAttribute = () => {
+ return useMutation({
+ mutationFn: (params: CreateCategoryAttributeType & { attrId: number }) =>
+ api.updateCategoryAttribute(params),
+ });
+};
+
+export const useDeleteCategoryAttribute = () => {
+ return useMutation({
+ mutationFn: (id: number) => api.deleteCategoryAttribute(id),
+ });
};
\ No newline at end of file
diff --git a/src/pages/category/service/CategoryService.ts b/src/pages/category/service/CategoryService.ts
index 1117cd9..0d6a49b 100644
--- a/src/pages/category/service/CategoryService.ts
+++ b/src/pages/category/service/CategoryService.ts
@@ -66,4 +66,14 @@ export const createCategoryAttribute = async (id: string, params: CreateCategory
export const getCategoryAttributes = async (id: string): Promise => {
const { data } = await axios.get(`/category/${id}/attributes`);
return data;
+};
+
+export const updateCategoryAttribute = async (params: CreateCategoryAttributeType & { attrId: number }) => {
+ const { data } = await axios.patch(`/admin/category/attributes`, params);
+ return data;
+};
+
+export const deleteCategoryAttribute = async (id: number) => {
+ const { data } = await axios.delete(`/admin/category/attributes/${id}/delete`);
+ return data;
};
\ No newline at end of file