From c46fd2ba0eca64a63f47eedc4c584b9808ab39d2 Mon Sep 17 00:00:00 2001 From: hosseintaromi Date: Thu, 8 Jan 2026 18:08:25 +0330 Subject: [PATCH] Refactor: Consolidate duplicate code patterns across 20+ pages - Replace local ToggleSwitch components with shared component (3 pages) - Consolidate formatDate/formatCurrency functions to formatters.ts (11 pages) - Replace direct toLocaleDateString calls with formatDate utility (5 pages) - Standardize PageHeader usage across 8 pages - Extract ReportSkeleton component for Reports pages (4 pages) All changes maintain existing functionality and Persian locale formatting. --- src/App.tsx | 6 +- src/components/common/ReportSkeleton.tsx | 126 ++++++++++++++ src/components/ui/ToggleSwitch.tsx | 41 +++++ src/pages/Settings.tsx | 15 +- src/pages/UsersNew.tsx | 3 +- .../admin-user-detail/AdminUserDetailPage.tsx | 5 +- .../categories-list/CategoriesListPage.tsx | 38 ++--- .../DiscountCodeFormPage.tsx | 17 +- .../DiscountCodesListPage.tsx | 38 ++--- .../payment-card/card-form/CardFormPage.tsx | 68 ++------ .../payment-ipg/ipg-list/IPGListPage.tsx | 68 ++------ .../permissions-list/PermissionsListPage.tsx | 30 ++-- .../ProductOptionsListPage.tsx | 38 ++--- .../comments-list/ProductCommentsListPage.tsx | 14 +- .../product-detail/ProductDetailPage.tsx | 9 +- .../products-list/ProductsListPage.tsx | 160 +++++++++--------- .../CustomerDiscountUsagePage.tsx | 67 +------- .../DiscountUsageReportPage.tsx | 69 +------- .../PaymentMethodsReportPage.tsx | 102 +---------- .../ShipmentsByMethodReportPage.tsx | 88 +--------- .../roles/role-detail/RoleDetailPage.tsx | 5 +- src/pages/roles/roles-list/RolesListPage.tsx | 44 ++--- .../ShippingMethodFormPage.tsx | 11 +- .../ShippingMethodsListPage.tsx | 31 ++-- .../ticket-config/TicketConfigPage.tsx | 13 +- .../user-admin-detail/UserAdminDetailPage.tsx | 5 +- .../user-admin-form/UserAdminFormPage.tsx | 15 +- .../users-admin-list/UsersAdminListPage.tsx | 70 ++++---- .../wallet/wallet-list/WalletListPage.tsx | 68 ++------ src/utils/formatters.ts | 19 +++ 30 files changed, 499 insertions(+), 784 deletions(-) create mode 100644 src/components/common/ReportSkeleton.tsx create mode 100644 src/components/ui/ToggleSwitch.tsx diff --git a/src/App.tsx b/src/App.tsx index f3f87b0..8aba761 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -204,9 +204,9 @@ const App = () => { - - +
+ +
}>
diff --git a/src/components/common/ReportSkeleton.tsx b/src/components/common/ReportSkeleton.tsx new file mode 100644 index 0000000..323196b --- /dev/null +++ b/src/components/common/ReportSkeleton.tsx @@ -0,0 +1,126 @@ +import React from 'react'; + +interface ReportSkeletonProps { + summaryCardCount?: number; + tableColumnCount?: number; + tableRowCount?: number; + showMethodSummaries?: boolean; + showChart?: boolean; + showPaymentTypeCards?: boolean; +} + +export const ReportSkeleton: React.FC = ({ + summaryCardCount = 4, + tableColumnCount = 7, + tableRowCount = 5, + showMethodSummaries = false, + showChart = false, + showPaymentTypeCards = false, +}) => { + return ( + <> + {/* Summary Cards Skeleton */} +
+ {[...Array(summaryCardCount)].map((_, i) => ( +
+
+
+
+
+
+
+
+
+ ))} +
+ + {/* Method Summaries Skeleton */} + {showMethodSummaries && ( +
+
+
+ {[...Array(3)].map((_, i) => ( +
+
+
+ {[...Array(6)].map((_, j) => ( +
+
+
+
+ ))} +
+
+ ))} +
+
+ )} + + {/* Pie Chart and Total Amount Skeleton */} + {showChart && ( +
+
+
+
+
+
+
+
+
+
+
+ )} + + {/* Payment Type Cards Skeleton */} + {showPaymentTypeCards && ( +
+
+
+ {[...Array(5)].map((_, i) => ( +
+
+
+ {[...Array(5)].map((_, j) => ( +
+
+
+
+ ))} +
+
+ ))} +
+
+ )} + + {/* Table Skeleton */} +
+
+ + + + {[...Array(tableColumnCount)].map((_, i) => ( + + ))} + + + + {[...Array(tableRowCount)].map((_, i) => ( + + {[...Array(tableColumnCount)].map((_, j) => ( + + ))} + + ))} + +
+
+
+
+
+
+
+ + ); +}; + diff --git a/src/components/ui/ToggleSwitch.tsx b/src/components/ui/ToggleSwitch.tsx new file mode 100644 index 0000000..d6ad1fb --- /dev/null +++ b/src/components/ui/ToggleSwitch.tsx @@ -0,0 +1,41 @@ +import React from 'react'; + +interface ToggleSwitchProps { + checked: boolean; + onChange: (checked: boolean) => void; + disabled?: boolean; + className?: string; +} + +export const ToggleSwitch: React.FC = ({ + checked, + onChange, + disabled = false, + className = '', +}) => { + return ( +