diff --git a/src/App.tsx b/src/App.tsx index 3965b19..e406f79 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -11,7 +11,7 @@ import { useAuth } from './contexts/AuthContext'; import { Login } from './pages/Login'; import { Dashboard } from './pages/Dashboard'; import { Users } from './pages/Users'; -import Products from './pages/Products'; + import { Orders } from './pages/Orders'; import { Reports } from './pages/Reports'; import { Notifications } from './pages/Notifications'; @@ -26,6 +26,7 @@ import RolePermissionsPage from './pages/roles/role-permissions/RolePermissionsP // Admin Users Pages import AdminUsersListPage from './pages/admin-users/admin-users-list/AdminUsersListPage'; import AdminUserFormPage from './pages/admin-users/admin-user-form/AdminUserFormPage'; +import AdminUserDetailPage from './pages/admin-users/admin-user-detail/AdminUserDetailPage'; // Permissions Pages import PermissionsListPage from './pages/permissions/permissions-list/PermissionsListPage'; @@ -84,6 +85,7 @@ const AppRoutes = () => { {/* Admin Users Routes */} } /> } /> + } /> } /> {/* Permissions Routes */} diff --git a/src/components/forms/UserForm.tsx b/src/components/forms/UserForm.tsx index 3b4d884..940aca6 100644 --- a/src/components/forms/UserForm.tsx +++ b/src/components/forms/UserForm.tsx @@ -1,7 +1,7 @@ import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; import * as yup from 'yup'; -import { User, Mail, Phone } from 'lucide-react'; + import { Button } from '../ui/Button'; import { Input } from '../ui/Input'; import { UserFormData } from '../../utils/validationSchemas'; @@ -10,24 +10,30 @@ const userSchema = yup.object({ name: yup.string().required('نام الزامی است'), email: yup.string().email('ایمیل معتبر نیست').required('ایمیل الزامی است'), phone: yup.string().required('شماره تلفن الزامی است'), + role: yup.string().required('نقش الزامی است'), + password: yup.string().notRequired(), }); interface UserFormProps { onSubmit: (data: UserFormData) => void; defaultValues?: Partial; + initialData?: any; + onCancel?: () => void; + loading?: boolean; + isEdit?: boolean; isLoading?: boolean; } -export const UserForm = ({ onSubmit, defaultValues, isLoading }: UserFormProps) => { +export const UserForm = ({ onSubmit, defaultValues, initialData, onCancel, loading, isEdit, isLoading }: UserFormProps) => { const { register, handleSubmit, formState: { errors, isValid } - } = useForm({ + } = useForm({ resolver: yupResolver(userSchema), - defaultValues, + defaultValues: defaultValues || initialData, mode: 'onChange' - }); + }) as any; return (
@@ -40,7 +46,7 @@ export const UserForm = ({ onSubmit, defaultValues, isLoading }: UserFormProps)

-
+ { - const { user, logout, hasPermission } = useAuth(); + const { user, logout } = useAuth(); const [expandedItems, setExpandedItems] = React.useState([]); const toggleExpanded = (title: string) => { diff --git a/src/components/ui/Modal.tsx b/src/components/ui/Modal.tsx index 9b06e82..9331be9 100644 --- a/src/components/ui/Modal.tsx +++ b/src/components/ui/Modal.tsx @@ -1,6 +1,5 @@ import React, { useEffect } from 'react'; import { X } from 'lucide-react'; -import { Button } from './Button'; import { SectionSubtitle } from './Typography'; interface ModalProps { diff --git a/src/components/ui/MultiSelectAutocomplete.tsx b/src/components/ui/MultiSelectAutocomplete.tsx index d870ae1..e157836 100644 --- a/src/components/ui/MultiSelectAutocomplete.tsx +++ b/src/components/ui/MultiSelectAutocomplete.tsx @@ -1,5 +1,5 @@ import React, { useState, useRef, useEffect } from 'react'; -import { ChevronDown, X, Search } from 'lucide-react'; +import { ChevronDown, X } from 'lucide-react'; export interface Option { id: number; diff --git a/src/components/ui/VariantManager.tsx b/src/components/ui/VariantManager.tsx index 99224e0..f6a5eaa 100644 --- a/src/components/ui/VariantManager.tsx +++ b/src/components/ui/VariantManager.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { Plus, Trash2, Edit3, Package } from 'lucide-react'; import { ProductVariantFormData, ProductImage } from '../../pages/products/core/_models'; import { Button } from './Button'; -import { Input } from './Input'; + import { FileUploader } from './FileUploader'; import { useFileUpload, useFileDelete } from '../../hooks/useFileUpload'; diff --git a/src/contexts/AuthContext.tsx b/src/contexts/AuthContext.tsx index c909f0e..974b8f3 100644 --- a/src/contexts/AuthContext.tsx +++ b/src/contexts/AuthContext.tsx @@ -1,5 +1,5 @@ import React, { createContext, useContext, useReducer, useEffect } from 'react'; -import { AuthState, AdminUser, Permission, LoginRequest } from '../types/auth'; +import { AuthState, AdminUser, Permission } from '../types/auth'; import toast from 'react-hot-toast'; interface AuthContextType { diff --git a/src/lib/queryClient.ts b/src/lib/queryClient.ts index e027f71..91f7a25 100644 --- a/src/lib/queryClient.ts +++ b/src/lib/queryClient.ts @@ -1,5 +1,4 @@ import { QueryClient } from "@tanstack/react-query"; -import toast from "react-hot-toast"; export const queryClient = new QueryClient({ defaultOptions: { diff --git a/src/pages/Products.tsx b/src/pages/Products.tsx index 466b394..0ba1ae6 100644 --- a/src/pages/Products.tsx +++ b/src/pages/Products.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { Package, Plus, Search, Filter, Eye, Edit, Trash2, Grid, List } from 'lucide-react'; import { Table } from '../components/ui/Table'; diff --git a/src/pages/admin-users/admin-user-form/AdminUserFormPage.tsx b/src/pages/admin-users/admin-user-form/AdminUserFormPage.tsx index b012408..361312f 100644 --- a/src/pages/admin-users/admin-user-form/AdminUserFormPage.tsx +++ b/src/pages/admin-users/admin-user-form/AdminUserFormPage.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import { useEffect } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; @@ -80,8 +80,8 @@ const AdminUserFormPage = () => { setValue('last_name', user.last_name, { shouldValidate: true }); setValue('username', user.username, { shouldValidate: true }); setValue('status', user.status, { shouldValidate: true }); - setValue('permissions', user.permissions?.map(p => p.id) || [], { shouldValidate: true }); - setValue('roles', user.roles?.map(r => r.id) || [], { shouldValidate: true }); + setValue('permissions', user.permissions?.map((p: any) => p.id) || [], { shouldValidate: true }); + setValue('roles', user.roles?.map((r: any) => r.id) || [], { shouldValidate: true }); setValue('isEdit', true, { shouldValidate: true }); } }, [isEdit, user, setValue]); diff --git a/src/pages/admin-users/admin-users-list/AdminUsersListPage.tsx b/src/pages/admin-users/admin-users-list/AdminUsersListPage.tsx index dc2cc6c..c51a27e 100644 --- a/src/pages/admin-users/admin-users-list/AdminUsersListPage.tsx +++ b/src/pages/admin-users/admin-users-list/AdminUsersListPage.tsx @@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom'; import { useAdminUsers, useDeleteAdminUser } from '../core/_hooks'; import { AdminUserInfo } from '../core/_models'; import { Button } from "@/components/ui/Button"; -import { LoadingSpinner } from "@/components/ui/LoadingSpinner"; + import { Trash2, Edit3, Plus, Eye, Users, UserPlus } from "lucide-react"; import { Modal } from "@/components/ui/Modal"; import { PageContainer, PageTitle, SectionSubtitle } from '../../../components/ui/Typography'; diff --git a/src/pages/categories/categories-list/CategoriesListPage.tsx b/src/pages/categories/categories-list/CategoriesListPage.tsx index 1bef2e3..1d27ff6 100644 --- a/src/pages/categories/categories-list/CategoriesListPage.tsx +++ b/src/pages/categories/categories-list/CategoriesListPage.tsx @@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom'; import { useCategories, useDeleteCategory } from '../core/_hooks'; import { Category } from '../core/_models'; 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"; diff --git a/src/pages/permissions/permission-form/PermissionFormPage.tsx b/src/pages/permissions/permission-form/PermissionFormPage.tsx index 701a373..ae646dd 100644 --- a/src/pages/permissions/permission-form/PermissionFormPage.tsx +++ b/src/pages/permissions/permission-form/PermissionFormPage.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import { useEffect } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; diff --git a/src/pages/permissions/permissions-list/PermissionsListPage.tsx b/src/pages/permissions/permissions-list/PermissionsListPage.tsx index 73d3b45..9f68112 100644 --- a/src/pages/permissions/permissions-list/PermissionsListPage.tsx +++ b/src/pages/permissions/permissions-list/PermissionsListPage.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { usePermissions } from '../core/_hooks'; import { Permission } from '../core/_models'; -import { LoadingSpinner } from "@/components/ui/LoadingSpinner"; + import { Shield, Plus } from "lucide-react"; // Skeleton Loading Component @@ -102,13 +102,6 @@ const PermissionsListPage = () => { نمایش دسترسی‌های سیستم

- {/* Filters */} @@ -139,16 +132,12 @@ const PermissionsListPage = () => {

هیچ دسترسی یافت نشد

-

+

{filters.search ? "نتیجه‌ای برای جستجوی شما یافت نشد" - : "شما هنوز هیچ دسترسی ایجاد نکرده‌اید" + : "دسترسی‌های سیستم در اینجا نمایش داده می‌شوند" }

- ) : ( diff --git a/src/pages/product-options/product-option-form/ProductOptionFormPage.tsx b/src/pages/product-options/product-option-form/ProductOptionFormPage.tsx index b966f68..9c8d573 100644 --- a/src/pages/product-options/product-option-form/ProductOptionFormPage.tsx +++ b/src/pages/product-options/product-option-form/ProductOptionFormPage.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import { useEffect } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { useForm, useFieldArray } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; diff --git a/src/pages/product-options/product-options-list/ProductOptionsListPage.tsx b/src/pages/product-options/product-options-list/ProductOptionsListPage.tsx index 98d4f15..9498044 100644 --- a/src/pages/product-options/product-options-list/ProductOptionsListPage.tsx +++ b/src/pages/product-options/product-options-list/ProductOptionsListPage.tsx @@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom'; import { useProductOptions, useDeleteProductOption } from '../core/_hooks'; import { ProductOption } from '../core/_models'; import { Button } from "@/components/ui/Button"; -import { LoadingSpinner } from "@/components/ui/LoadingSpinner"; + import { Trash2, Edit3, Plus, Settings, Tag } from "lucide-react"; import { Modal } from "@/components/ui/Modal"; diff --git a/src/pages/products/product-form/ProductFormPage.tsx b/src/pages/products/product-form/ProductFormPage.tsx index ae0cdb6..af85763 100644 --- a/src/pages/products/product-form/ProductFormPage.tsx +++ b/src/pages/products/product-form/ProductFormPage.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; diff --git a/src/pages/products/products-list/ProductsListPage.tsx b/src/pages/products/products-list/ProductsListPage.tsx index ba6ed10..c273ca5 100644 --- a/src/pages/products/products-list/ProductsListPage.tsx +++ b/src/pages/products/products-list/ProductsListPage.tsx @@ -4,7 +4,7 @@ import { useProducts, useDeleteProduct } from '../core/_hooks'; import { useCategories } from '../../categories/core/_hooks'; import { Product } from '../core/_models'; import { Button } from "@/components/ui/Button"; -import { LoadingSpinner } from "@/components/ui/LoadingSpinner"; + import { Trash2, Edit3, Plus, Package, Eye, Image } from "lucide-react"; import { Modal } from "@/components/ui/Modal"; @@ -73,7 +73,12 @@ const ProductsListPage = () => { max_price: '' }); - const { data: productsData, isLoading, error } = useProducts(filters); + const { data: productsData, isLoading, error } = useProducts({ + ...filters, + category_id: filters.category_id ? Number(filters.category_id) : undefined, + min_price: filters.min_price ? Number(filters.min_price) : undefined, + max_price: filters.max_price ? Number(filters.max_price) : undefined + }); const { data: categories } = useCategories(); const { mutate: deleteProduct, isPending: isDeleting } = useDeleteProduct(); @@ -292,13 +297,13 @@ const ProductsListPage = () => { - {formatPrice(product.price)} + {formatPrice(product.price || 0)} {product.category?.name || 'بدون دسته‌بندی'} - {getStatusBadge(product.status)} + {getStatusBadge(product.status || '')}
@@ -355,10 +360,10 @@ const ProductsListPage = () => { {product.name}

- {formatPrice(product.price)} + {formatPrice(product.price || 0)}

- {getStatusBadge(product.status)} + {getStatusBadge(product.status || '')} {product.category && ( {product.category.name} diff --git a/src/pages/roles/role-form/RoleFormPage.tsx b/src/pages/roles/role-form/RoleFormPage.tsx index f14496d..c5ec1f8 100644 --- a/src/pages/roles/role-form/RoleFormPage.tsx +++ b/src/pages/roles/role-form/RoleFormPage.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import { useEffect } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { useForm } from 'react-hook-form'; import { yupResolver } from '@hookform/resolvers/yup'; diff --git a/src/pages/roles/roles-list/RolesListPage.tsx b/src/pages/roles/roles-list/RolesListPage.tsx index 5661a65..821af7f 100644 --- a/src/pages/roles/roles-list/RolesListPage.tsx +++ b/src/pages/roles/roles-list/RolesListPage.tsx @@ -3,7 +3,7 @@ import { useNavigate } from 'react-router-dom'; import { useRoles, useDeleteRole } from '../core/_hooks'; import { Role } from '@/types/auth'; import { Button } from "@/components/ui/Button"; -import { LoadingSpinner } from "@/components/ui/LoadingSpinner"; + import { Trash2, Edit3, Plus, UserCog, Shield, Eye, Settings } from "lucide-react"; import { Modal } from "@/components/ui/Modal"; import { PageContainer, PageTitle, SectionSubtitle } from '../../../components/ui/Typography';