From 1683cb9ffe10519aee2b10eab25b27de037cdd72 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sat, 25 Oct 2025 15:38:12 +0330 Subject: [PATCH] delete and edit category attribute --- src/pages/category/Attributes.tsx | 32 ++++---- .../category/components/AttributesModal.tsx | 8 +- .../category/hooks/useAttributesLogic.tsx | 81 +++++++++++++++---- src/pages/category/hooks/useCategoryData.tsx | 13 +++ src/pages/category/service/CategoryService.ts | 10 +++ 5 files changed, 110 insertions(+), 34 deletions(-) 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