diff --git a/src/pages/admin-users/admin-users-list/AdminUsersListPage.tsx b/src/pages/admin-users/admin-users-list/AdminUsersListPage.tsx
index 8dcaa5e..026dc37 100644
--- a/src/pages/admin-users/admin-users-list/AdminUsersListPage.tsx
+++ b/src/pages/admin-users/admin-users-list/AdminUsersListPage.tsx
@@ -4,84 +4,14 @@ import { useAdminUsers, useDeleteAdminUser } from '../core/_hooks';
import { AdminUserInfo } from '../core/_models';
import { Button } from "@/components/ui/Button";
-import { Trash2, Edit3, Plus, Eye, Users, UserPlus } from "lucide-react";
-import { Modal } from "@/components/ui/Modal";
-import { PageContainer, PageTitle, SectionSubtitle } from '../../../components/ui/Typography';
-
-// Skeleton Loading Component
-const AdminUserTableSkeleton = () => (
-
- {/* Desktop Table Skeleton */}
-
-
-
-
-
-
- نام و نام خانوادگی
-
-
- نام کاربری
-
-
- وضعیت
-
-
- تاریخ ایجاد
-
-
- عملیات
-
-
-
-
- {[...Array(5)].map((_, index) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ))}
-
-
-
-
-
- {/* Mobile Cards Skeleton */}
-
- {[...Array(3)].map((_, index) => (
-
- ))}
-
-
-);
+import { Users, UserPlus, Plus } from "lucide-react";
+import { PageContainer, SectionSubtitle } from '../../../components/ui/Typography';
+import { TableSkeleton } from '@/components/common/TableSkeleton';
+import { PageHeader } from '@/components/layout/PageHeader';
+import { EmptyState } from '@/components/common/EmptyState';
+import { ActionButtons } from '@/components/common/ActionButtons';
+import { DeleteConfirmModal } from '@/components/common/DeleteConfirmModal';
+import { formatDate } from '@/utils/formatters';
const AdminUsersListPage = () => {
const navigate = useNavigate();
@@ -136,24 +66,20 @@ const AdminUsersListPage = () => {
return (
- {/* Header */}
-
-
-
-
-
مدیریت کاربران ادمین
-
-
مدیریت کاربران دسترسی به پنل ادمین
-
-
-
-
-
-
+
+
+
+ }
+ />
{/* Filters */}
فیلترها
@@ -190,25 +116,24 @@ const AdminUsersListPage = () => {
{/* Users Table */}
{isLoading ? (
-
+
) : (users || []).length === 0 ? (
-
-
-
- هیچ کاربر ادمین یافت نشد
-
-
- {filters.search || filters.status
- ? "نتیجهای برای جستجوی شما یافت نشد"
- : "شما هنوز هیچ کاربر ادمین ایجاد نکردهاید"
- }
-
-
-
- اولین کاربر ادمین را ایجاد کنید
-
-
+
+
+ اولین کاربر ادمین را ایجاد کنید
+ >
+ }
+ onAction={handleCreate}
+ />
) : (
@@ -253,32 +178,14 @@ const AdminUsersListPage = () => {
- {new Date(user.created_at).toLocaleDateString('fa-IR')}
+ {formatDate(user.created_at)}
-
- handleView(user.id)}
- className="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300"
- title="مشاهده"
- >
-
-
- handleEdit(user.id)}
- className="text-indigo-600 hover:text-indigo-900 dark:text-indigo-400 dark:hover:text-indigo-300"
- title="ویرایش"
- >
-
-
- setDeleteUserId(user.id.toString())}
- className="text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300"
- title="حذف"
- >
-
-
-
+ handleView(user.id)}
+ onEdit={() => handleEdit(user.id)}
+ onDelete={() => setDeleteUserId(user.id.toString())}
+ />
))}
@@ -308,65 +215,27 @@ const AdminUsersListPage = () => {
- تاریخ ایجاد: {new Date(user.created_at).toLocaleDateString('fa-IR')}
-
-
- handleView(user.id)}
- className="flex items-center gap-1 px-2 py-1 text-xs text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300"
- >
-
- مشاهده
-
- handleEdit(user.id)}
- className="flex items-center gap-1 px-2 py-1 text-xs text-indigo-600 hover:text-indigo-900 dark:text-indigo-400 dark:hover:text-indigo-300"
- >
-
- ویرایش
-
- setDeleteUserId(user.id.toString())}
- className="flex items-center gap-1 px-2 py-1 text-xs text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300"
- >
-
- حذف
-
+ تاریخ ایجاد: {formatDate(user.created_at)}
+ handleView(user.id)}
+ onEdit={() => handleEdit(user.id)}
+ onDelete={() => setDeleteUserId(user.id.toString())}
+ />
))}
)}
- {/* Delete Confirmation Modal */}
- setDeleteUserId(null)}
+ onConfirm={handleDeleteConfirm}
title="حذف کاربر ادمین"
- >
-
-
- آیا از حذف این کاربر ادمین اطمینان دارید؟ این عمل قابل بازگشت نیست.
-
-
- setDeleteUserId(null)}
- disabled={isDeleting}
- >
- انصراف
-
-
- حذف
-
-
-
-
+ message="آیا از حذف این کاربر ادمین اطمینان دارید؟ این عمل قابل بازگشت نیست."
+ isLoading={isDeleting}
+ />
);
};
diff --git a/src/pages/orders/order-detail/OrderDetailPage.tsx b/src/pages/orders/order-detail/OrderDetailPage.tsx
index eb27d38..ff79567 100644
--- a/src/pages/orders/order-detail/OrderDetailPage.tsx
+++ b/src/pages/orders/order-detail/OrderDetailPage.tsx
@@ -21,6 +21,7 @@ import {
} from 'lucide-react';
import { englishToPersian } from '@/utils/numberUtils';
import { API_GATE_WAY } from '@/constant/routes';
+import { formatCurrency, formatDateTime } from '@/utils/formatters';
const resolveImageUrl = (imageUrl?: string): string => {
if (!imageUrl) return '';
@@ -55,19 +56,6 @@ const getStatusText = (status: OrderStatus) => {
return text[status] || status;
};
-const formatCurrency = (amount: number) => {
- return new Intl.NumberFormat('fa-IR').format(amount) + ' تومان';
-};
-
-const formatDate = (dateString: string) => {
- return new Date(dateString).toLocaleDateString('fa-IR', {
- year: 'numeric',
- month: 'long',
- day: 'numeric',
- hour: '2-digit',
- minute: '2-digit'
- });
-};
const formatPaymentType = (type?: string) => {
if (!type) return '';
@@ -171,7 +159,7 @@ const OrderDetailPage = () => {
سفارش #{order?.order_number || 'نامشخص'}
- تاریخ ثبت: {order?.created_at ? formatDate(order.created_at) : 'نامشخص'}
+ تاریخ ثبت: {order?.created_at ? formatDateTime(order.created_at) : 'نامشخص'}
@@ -367,7 +355,7 @@ const OrderDetailPage = () => {
تاریخ ثبت
-
{order?.created_at ? formatDate(order.created_at) : 'نامشخص'}
+
{order?.created_at ? formatDateTime(order.created_at) : 'نامشخص'}
شناسه فاکتور
@@ -379,7 +367,7 @@ const OrderDetailPage = () => {
تاریخ آخرین بروزرسانی
-
{order?.updated_at ? formatDate(order.updated_at) : 'نامشخص'}
+
{order?.updated_at ? formatDateTime(order.updated_at) : 'نامشخص'}
{/* روش حمل و نقل در دادههای فعلی وجود ندارد */}
{order?.tracking_number && (
@@ -391,7 +379,7 @@ const OrderDetailPage = () => {
{order?.estimated_delivery && (
تاریخ تحویل تخمینی
-
{formatDate(order.estimated_delivery)}
+
{formatDateTime(order.estimated_delivery)}
)}
{order?.shipping_method_id !== undefined && order?.shipping_method_id !== null && (
diff --git a/src/pages/permissions/permissions-list/PermissionsListPage.tsx b/src/pages/permissions/permissions-list/PermissionsListPage.tsx
index 9f68112..c269096 100644
--- a/src/pages/permissions/permissions-list/PermissionsListPage.tsx
+++ b/src/pages/permissions/permissions-list/PermissionsListPage.tsx
@@ -1,72 +1,12 @@
import React, { useState } from 'react';
import { usePermissions } from '../core/_hooks';
import { Permission } from '../core/_models';
-
-import { Shield, Plus } from "lucide-react";
-
-// Skeleton Loading Component
-const PermissionsTableSkeleton = () => (
-
- {/* Desktop Table Skeleton */}
-
-
-
-
-
-
- عنوان
-
-
- توضیحات
-
-
- تاریخ ایجاد
-
-
-
-
- {[...Array(5)].map((_, index) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ))}
-
-
-
-
-
- {/* Mobile Cards Skeleton */}
-
- {[...Array(3)].map((_, index) => (
-
- ))}
-
-
-);
+import { Shield } from "lucide-react";
+import { TableSkeleton } from '@/components/common/TableSkeleton';
+import { PageHeader } from '@/components/layout/PageHeader';
+import { EmptyState } from '@/components/common/EmptyState';
+import { FiltersSection } from '@/components/common/FiltersSection';
+import { formatDate } from '@/utils/formatters';
const PermissionsListPage = () => {
const [filters, setFilters] = useState({
@@ -91,54 +31,40 @@ const PermissionsListPage = () => {
return (
- {/* Header */}
-
-
-
-
- لیست دسترسیها
-
-
- نمایش دسترسیهای سیستم
-
-
-
+
- {/* Filters */}
-
-
+
{/* Permissions Table */}
{isLoading ? (
-
+
) : (permissions || []).length === 0 ? (
-
-
-
- هیچ دسترسی یافت نشد
-
-
- {filters.search
- ? "نتیجهای برای جستجوی شما یافت نشد"
- : "دسترسیهای سیستم در اینجا نمایش داده میشوند"
- }
-
-
+
) : (
@@ -172,7 +98,7 @@ const PermissionsListPage = () => {
{permission.description}
- {new Date(permission.created_at).toLocaleDateString('fa-IR')}
+ {formatDate(permission.created_at)}
))}
@@ -196,7 +122,7 @@ const PermissionsListPage = () => {
- تاریخ ایجاد: {new Date(permission.created_at).toLocaleDateString('fa-IR')}
+ تاریخ ایجاد: {formatDate(permission.created_at)}
))}
diff --git a/src/pages/product-options/product-options-list/ProductOptionsListPage.tsx b/src/pages/product-options/product-options-list/ProductOptionsListPage.tsx
index 9498044..d4d05f0 100644
--- a/src/pages/product-options/product-options-list/ProductOptionsListPage.tsx
+++ b/src/pages/product-options/product-options-list/ProductOptionsListPage.tsx
@@ -2,58 +2,14 @@ import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useProductOptions, useDeleteProductOption } from '../core/_hooks';
import { ProductOption } from '../core/_models';
-import { Button } from "@/components/ui/Button";
-
-import { Trash2, Edit3, Plus, Settings, Tag } from "lucide-react";
-import { Modal } from "@/components/ui/Modal";
-
-const ProductOptionsTableSkeleton = () => (
-
-
-
-
-
-
-
- نام گزینه
-
-
- مقادیر
-
-
- تاریخ ایجاد
-
-
- عملیات
-
-
-
-
- {[...Array(5)].map((_, i) => (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ))}
-
-
-
-
-
-);
+import { Settings, Tag, Plus } from "lucide-react";
+import { TableSkeleton } from '@/components/common/TableSkeleton';
+import { PageHeader } from '@/components/layout/PageHeader';
+import { EmptyState } from '@/components/common/EmptyState';
+import { ActionButtons } from '@/components/common/ActionButtons';
+import { DeleteConfirmModal } from '@/components/common/DeleteConfirmModal';
+import { FiltersSection } from '@/components/common/FiltersSection';
+import { formatDate } from '@/utils/formatters';
const ProductOptionsListPage = () => {
const navigate = useNavigate();
@@ -99,47 +55,39 @@ const ProductOptionsListPage = () => {
return (
- {/* Header */}
-
-
-
-
- مدیریت گزینههای محصول
-
-
- تنظیمات گزینههای قابل انتخاب برای محصولات
-
-
-
-
-
-
+
+
+
+ }
+ />
- {/* Filters */}
-
-
+
{/* Product Options Table */}
{isLoading ? (
-
+
) : (
{/* Desktop Table */}
@@ -187,25 +135,13 @@ const ProductOptionsListPage = () => {
- {new Date(option.created_at).toLocaleDateString('fa-IR')}
+ {formatDate(option.created_at)}
-
- handleEdit(option.id)}
- className="text-indigo-600 hover:text-indigo-900 dark:text-indigo-400 dark:hover:text-indigo-300"
- title="ویرایش"
- >
-
-
- setDeleteOptionId(option.id.toString())}
- className="text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300"
- title="حذف"
- >
-
-
-
+ handleEdit(option.id)}
+ onDelete={() => setDeleteOptionId(option.id.toString())}
+ />
))}
@@ -242,77 +178,26 @@ const ProductOptionsListPage = () => {
- تاریخ ایجاد: {new Date(option.created_at).toLocaleDateString('fa-IR')}
-
-
- handleEdit(option.id)}
- className="flex items-center gap-1 px-2 py-1 text-xs text-indigo-600 hover:text-indigo-900 dark:text-indigo-400 dark:hover:text-indigo-300"
- >
-
- ویرایش
-
- setDeleteOptionId(option.id.toString())}
- className="flex items-center gap-1 px-2 py-1 text-xs text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300"
- >
-
- حذف
-
+ تاریخ ایجاد: {formatDate(option.created_at)}
+ handleEdit(option.id)}
+ onDelete={() => setDeleteOptionId(option.id.toString())}
+ />
))}
-
- {/* Empty State */}
- {(!productOptions || productOptions.length === 0) && !isLoading && (
-
-
-
- گزینهای موجود نیست
-
-
- برای شروع، اولین گزینه محصول خود را ایجاد کنید.
-
-
-
-
- ایجاد گزینه جدید
-
-
-
- )}
)}
- {/* Delete Confirmation Modal */}
- setDeleteOptionId(null)}
+ onConfirm={handleDeleteConfirm}
title="حذف گزینه محصول"
- >
-
-
- آیا از حذف این گزینه محصول اطمینان دارید؟ این عمل قابل بازگشت نیست و ممکن است بر محصولاتی که از این گزینه استفاده میکنند تأثیر بگذارد.
-
-
- setDeleteOptionId(null)}
- disabled={isDeleting}
- >
- انصراف
-
-
- حذف
-
-
-
-
+ message="آیا از حذف این گزینه محصول اطمینان دارید؟ این عمل قابل بازگشت نیست و ممکن است بر محصولاتی که از این گزینه استفاده میکنند تأثیر بگذارد."
+ isLoading={isDeleting}
+ />
);
};