From c2f938bda8fd0ba53275482e002022433bc58fb8 Mon Sep 17 00:00:00 2001 From: hossein taromi Date: Mon, 28 Jul 2025 13:22:30 +0330 Subject: [PATCH] fix: improve category form functionality - Fix loading button state in category form (use Button loading prop instead of manual spinner) - Fix redirect after successful category create/update (move navigation to mutation callbacks) - Remove duplicate toast messages - Ensure proper navigation only after successful API calls --- .../categories-list/CategoriesListPage.tsx | 29 ++- .../category-form/CategoryFormPage.tsx | 232 +++++++----------- src/pages/categories/core/_hooks.ts | 5 + 3 files changed, 115 insertions(+), 151 deletions(-) diff --git a/src/pages/categories/categories-list/CategoriesListPage.tsx b/src/pages/categories/categories-list/CategoriesListPage.tsx index ae7c366..1bef2e3 100644 --- a/src/pages/categories/categories-list/CategoriesListPage.tsx +++ b/src/pages/categories/categories-list/CategoriesListPage.tsx @@ -6,6 +6,7 @@ import { Button } from "@/components/ui/Button"; import { LoadingSpinner } from "@/components/ui/LoadingSpinner"; import { Trash2, Edit3, Plus, FolderOpen, Folder } from "lucide-react"; import { Modal } from "@/components/ui/Modal"; +import { PageContainer, PageTitle, SectionSubtitle } from "../../../components/ui/Typography"; const CategoriesTableSkeleton = () => (
@@ -98,22 +99,24 @@ const CategoriesListPage = () => { } return ( -
+ {/* Header */} -
+
-

+
- مدیریت دسته‌بندی‌ها -

-

- مدیریت دسته‌بندی‌های محصولات -

+ مدیریت دسته‌بندی‌ها +
+

مدیریت دسته‌بندی‌های محصولات

- + +
{/* Filters */} @@ -288,7 +291,7 @@ const CategoriesListPage = () => {
- + ); }; diff --git a/src/pages/categories/category-form/CategoryFormPage.tsx b/src/pages/categories/category-form/CategoryFormPage.tsx index 533feee..c811972 100644 --- a/src/pages/categories/category-form/CategoryFormPage.tsx +++ b/src/pages/categories/category-form/CategoryFormPage.tsx @@ -1,75 +1,64 @@ -import React, { useEffect } from 'react'; +import { useState, useEffect } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; -import { useForm } from 'react-hook-form'; -import { yupResolver } from '@hookform/resolvers/yup'; -import * as yup from 'yup'; +import { ArrowRight, FolderOpen } from 'lucide-react'; +import { Button } from '../../../components/ui/Button'; +import { Input } from '../../../components/ui/Input'; +import { LoadingSpinner } from '../../../components/ui/LoadingSpinner'; +import { useToast } from '../../../contexts/ToastContext'; import { useCategory, useCreateCategory, useUpdateCategory } from '../core/_hooks'; -import { CategoryFormData } from '../core/_models'; -import { Button } from "@/components/ui/Button"; -import { Input } from "@/components/ui/Input"; -import { LoadingSpinner } from "@/components/ui/LoadingSpinner"; -import { ArrowRight, FolderOpen } from "lucide-react"; - -const categorySchema = yup.object({ - name: yup.string().required('نام دسته‌بندی الزامی است').min(2, 'نام دسته‌بندی باید حداقل 2 کاراکتر باشد'), - description: yup.string().optional(), -}); +import { FormHeader, PageContainer, Label } from '../../../components/ui/Typography'; const CategoryFormPage = () => { const navigate = useNavigate(); - const { id } = useParams<{ id: string }>(); - const isEdit = !!id; + const { id } = useParams(); + const { showToast } = useToast(); + const isEdit = Boolean(id); - const { data: category, isLoading: isLoadingCategory } = useCategory(id || '', isEdit); - const { mutate: createCategory, isPending: isCreating } = useCreateCategory(); - const { mutate: updateCategory, isPending: isUpdating } = useUpdateCategory(); - - const isLoading = isCreating || isUpdating; - - const { - register, - handleSubmit, - formState: { errors, isValid, isDirty }, - setValue, - watch - } = useForm({ - resolver: yupResolver(categorySchema) as any, - mode: 'onChange', - defaultValues: { - name: '', - description: '' - } + const [formData, setFormData] = useState({ + name: '', + description: '', + parent_id: null as number | null, }); - const formValues = watch(); + const { data: category, isLoading: isLoadingCategory } = useCategory( + id || '0', + isEdit + ); + + const createMutation = useCreateCategory(); + const updateMutation = useUpdateCategory(); useEffect(() => { - if (isEdit && category) { - setValue('name', category.name, { shouldValidate: true }); - setValue('description', category.description || '', { shouldValidate: true }); + if (category && isEdit) { + setFormData({ + name: category.name || '', + description: category.description || '', + parent_id: category.parent_id || null, + }); } - }, [isEdit, category, setValue]); + }, [category, isEdit]); - const onSubmit = (data: CategoryFormData) => { - if (isEdit && id) { - updateCategory({ - id: parseInt(id), - name: data.name, - description: data.description || undefined - }, { - onSuccess: () => { - navigate('/categories'); - } - }); - } else { - createCategory({ - name: data.name, - description: data.description || undefined - }, { - onSuccess: () => { - navigate('/categories'); - } - }); + const handleChange = (field: string, value: any) => { + setFormData(prev => ({ + ...prev, + [field]: value + })); + }; + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + try { + if (isEdit) { + await updateMutation.mutateAsync({ + id: parseInt(id!), + ...formData + }); + } else { + await createMutation.mutateAsync(formData); + } + } catch (error) { + console.error('Error saving category:', error); } }; @@ -85,106 +74,73 @@ const CategoryFormPage = () => { ); } + const backButton = ( + + ); + return ( -
- {/* Header */} -
- -
-

- - {isEdit ? 'ویرایش دسته‌بندی' : 'ایجاد دسته‌بندی جدید'} -

-

- {isEdit ? 'ویرایش اطلاعات دسته‌بندی' : 'اطلاعات دسته‌بندی جدید را وارد کنید'} -

-
-
+ + {/* Form */} -
-
- - +
+
- -