refactor(admin): reorganize filament navigation and layout

Refactor the Filament admin panel structure by adjusting navigation sorting
across various resources to improve usability and logical grouping.

- Reorder navigation items in 'مالی' (Finance), 'تنظیمات' (Settings),
  and 'عملیات' (Operations) groups.
- Hide `PriceTestPage` from the main navigation sidebar.
- Adjust sidebar width and max content width in `AdminPanelProvider`.
- Add custom CSS asset for Filament styling.
This commit is contained in:
Kazem Alghasi 2026-08-08 04:11:03 +03:30
parent b605b689fd
commit 0d04c89e91
12 changed files with 301 additions and 7 deletions

View File

@ -1 +1 @@
{"version":2,"defects":{"Tests\\Feature\\Api\\PricingControllerTest::it_can_calculate_pricing_with_valid_data":5,"Tests\\Feature\\Api\\PricingControllerTest::it_returns_validation_errors_for_invalid_data":7,"Tests\\Feature\\Services\\PriceCalculatorServiceTest::it_calculates_price_correctly_for_standard_package":8,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_returns_active_discount_codes":8,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_validates_discount_code_successfully":8,"Tests\\Feature\\Api\\PaymentControllerTest::it_completes_mock_payment_successfully":7,"Tests\\Feature\\Services\\WalletServiceTest::it_creates_deposit_transaction":8,"Tests\\Feature\\Services\\WalletServiceTest::it_completes_deposit_and_updates_balance":8,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_deposit":8,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_withdrawal":8,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_withdrawal_when_balance_is_insufficient":7,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_order_payment":8,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_order_payment_when_balance_is_insufficient":7,"Tests\\Feature\\Services\\WalletServiceTest::it_fails_transaction":8},"times":{"Tests\\Feature\\Api\\PricingControllerTest::it_can_calculate_pricing_with_valid_data":0.055,"Tests\\Feature\\Api\\PricingControllerTest::it_returns_validation_errors_for_invalid_data":0.052,"Tests\\Feature\\Services\\PriceCalculatorServiceTest::it_calculates_price_correctly_for_standard_package":0.009,"Tests\\Unit\\ExampleTest::test_that_true_is_true":0.006,"Tests\\Feature\\ExampleTest::test_the_application_returns_a_successful_response":0.056,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_returns_active_discount_codes":0.09,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_validates_discount_code_successfully":0.059,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_invalid_discount_code":0.052,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_expired_discount_code":0.055,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_code_below_minimum_order_amount":0.048,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_calculates_fixed_discount_correctly":0.048,"Tests\\Feature\\Api\\PaymentControllerTest::it_redirects_to_gateway_for_payment":0.067,"Tests\\Feature\\Api\\PaymentControllerTest::it_validates_minimum_deposit_amount":0.054,"Tests\\Feature\\Api\\PaymentControllerTest::it_prevents_payment_for_frozen_wallet":0.05,"Tests\\Feature\\Api\\PaymentControllerTest::it_completes_mock_payment_successfully":0.079,"Tests\\Feature\\Api\\PaymentControllerTest::it_checks_transaction_status":0.051,"Tests\\Feature\\Services\\WalletServiceTest::it_creates_deposit_transaction":0.005,"Tests\\Feature\\Services\\WalletServiceTest::it_completes_deposit_and_updates_balance":0.008,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_deposit":0.004,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_withdrawal":0.004,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_withdrawal_when_balance_is_insufficient":0.002,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_order_payment":0.004,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_order_payment_when_balance_is_insufficient":0.001,"Tests\\Feature\\Services\\WalletServiceTest::it_fails_transaction":0.006}}
{"version":2,"defects":{"Tests\\Feature\\Api\\PricingControllerTest::it_can_calculate_pricing_with_valid_data":5,"Tests\\Feature\\Api\\PricingControllerTest::it_returns_validation_errors_for_invalid_data":7,"Tests\\Feature\\Services\\PriceCalculatorServiceTest::it_calculates_price_correctly_for_standard_package":8,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_returns_active_discount_codes":8,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_validates_discount_code_successfully":8,"Tests\\Feature\\Api\\PaymentControllerTest::it_completes_mock_payment_successfully":7,"Tests\\Feature\\Services\\WalletServiceTest::it_creates_deposit_transaction":8,"Tests\\Feature\\Services\\WalletServiceTest::it_completes_deposit_and_updates_balance":8,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_deposit":8,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_withdrawal":8,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_withdrawal_when_balance_is_insufficient":7,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_order_payment":8,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_order_payment_when_balance_is_insufficient":7,"Tests\\Feature\\Services\\WalletServiceTest::it_fails_transaction":8},"times":{"Tests\\Feature\\Api\\PricingControllerTest::it_can_calculate_pricing_with_valid_data":0.056,"Tests\\Feature\\Api\\PricingControllerTest::it_returns_validation_errors_for_invalid_data":0.052,"Tests\\Feature\\Services\\PriceCalculatorServiceTest::it_calculates_price_correctly_for_standard_package":0.011,"Tests\\Unit\\ExampleTest::test_that_true_is_true":0.008,"Tests\\Feature\\ExampleTest::test_the_application_returns_a_successful_response":0.06,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_returns_active_discount_codes":0.09,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_validates_discount_code_successfully":0.055,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_invalid_discount_code":0.047,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_expired_discount_code":0.05,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_rejects_code_below_minimum_order_amount":0.048,"Tests\\Feature\\Api\\DiscountCodeControllerTest::it_calculates_fixed_discount_correctly":0.047,"Tests\\Feature\\Api\\PaymentControllerTest::it_redirects_to_gateway_for_payment":0.068,"Tests\\Feature\\Api\\PaymentControllerTest::it_validates_minimum_deposit_amount":0.051,"Tests\\Feature\\Api\\PaymentControllerTest::it_prevents_payment_for_frozen_wallet":0.05,"Tests\\Feature\\Api\\PaymentControllerTest::it_completes_mock_payment_successfully":0.072,"Tests\\Feature\\Api\\PaymentControllerTest::it_checks_transaction_status":0.052,"Tests\\Feature\\Services\\WalletServiceTest::it_creates_deposit_transaction":0.004,"Tests\\Feature\\Services\\WalletServiceTest::it_completes_deposit_and_updates_balance":0.009,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_deposit":0.003,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_manual_withdrawal":0.008,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_withdrawal_when_balance_is_insufficient":0.003,"Tests\\Feature\\Services\\WalletServiceTest::it_processes_order_payment":0.003,"Tests\\Feature\\Services\\WalletServiceTest::it_prevents_order_payment_when_balance_is_insufficient":0.002,"Tests\\Feature\\Services\\WalletServiceTest::it_fails_transaction":0.022}}

View File

@ -18,7 +18,8 @@ class PriceTestPage extends Page
protected static ?string $navigationIcon = 'heroicon-o-calculator';
protected static string $view = 'filament.pages.price-test-page';
protected static ?string $navigationLabel = 'تست محاسبه قیمت';
protected static ?int $navigationSort = 101;
protected static ?int $navigationSort = 999;
protected static bool $shouldRegisterNavigation = false;
public ?array $data = [];
public ?array $result = null;

View File

@ -18,6 +18,7 @@ class CountryResource extends Resource
protected static ?string $navigationLabel = 'کشورها';
protected static ?string $navigationGroup = 'تنظیمات';
protected static ?int $navigationSort = 2;
public static function form(Form $form): Form
{

View File

@ -18,7 +18,7 @@ class DiscountCodeResource extends Resource
protected static ?string $navigationLabel = 'کدهای تخفیف';
protected static ?string $navigationGroup = 'مالی';
protected static ?int $navigationSort = 1;
protected static ?int $navigationSort = 4;
public static function form(Form $form): Form
{

View File

@ -18,7 +18,7 @@ class PaymentResource extends Resource
protected static ?string $navigationLabel = 'پرداخت‌ها';
protected static ?string $navigationGroup = 'مالی';
protected static ?int $navigationSort = 4;
protected static ?int $navigationSort = 3;
public static function form(Form $form): Form
{

View File

@ -18,6 +18,7 @@ class ShipmentItemResource extends Resource
protected static ?string $navigationLabel = 'اقلام مرسوله';
protected static ?string $navigationGroup = 'عملیات';
protected static ?int $navigationSort = 2;
public static function form(Form $form): Form
{

View File

@ -18,6 +18,7 @@ class ShipmentResource extends Resource
protected static ?string $navigationLabel = 'مرسولات';
protected static ?string $navigationGroup = 'عملیات';
protected static ?int $navigationSort = 1;
public static function form(Form $form): Form
{

View File

@ -18,6 +18,7 @@ class ShippingRateResource extends Resource
protected static ?string $navigationLabel = 'نرخ‌های حمل';
protected static ?string $navigationGroup = 'تنظیمات';
protected static ?int $navigationSort = 3;
public static function form(Form $form): Form
{

View File

@ -19,7 +19,7 @@ class WalletResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-wallet';
protected static ?string $navigationLabel = 'کیف پول کاربران';
protected static ?string $navigationGroup = 'مالی';
protected static ?int $navigationSort = 2;
protected static ?int $navigationSort = 1;
public static function form(Form $form): Form
{

View File

@ -19,7 +19,7 @@ class WalletTransactionResource extends Resource
protected static ?string $navigationIcon = 'heroicon-o-arrows-right-left';
protected static ?string $navigationLabel = 'تراکنش‌ها';
protected static ?string $navigationGroup = 'مالی';
protected static ?int $navigationSort = 3;
protected static ?int $navigationSort = 2;
public static function form(Form $form): Form
{

View File

@ -40,6 +40,8 @@ class AdminPanelProvider extends PanelProvider
])
->authMiddleware([
Authenticate::class,
]);
])
->sidebarWidth('18rem')
->maxContentWidth('xl');
}
}

View File

@ -0,0 +1,287 @@
@import 'tailwindcss';
/* Custom IFNEX Filament Theme */
/* Sidebar Styling */
.fi-sidebar {
background: linear-gradient(180deg, #1a1a2e 0%, #16213e 100%) !important;
border-left: 1px solid rgba(245, 158, 11, 0.2) !important;
}
.fi-sidebar-header {
background: transparent !important;
border-bottom: 1px solid rgba(245, 158, 11, 0.15) !important;
padding: 1.25rem !important;
}
.fi-sidebar-nav {
padding: 0.75rem !important;
}
/* Navigation Groups */
.fi-sidebar-nav-group {
margin-bottom: 0.5rem !important;
border-radius: 0.5rem !important;
overflow: hidden !important;
}
.fi-sidebar-nav-group-header {
background: rgba(245, 158, 11, 0.08) !important;
border-bottom: 1px solid rgba(245, 158, 11, 0.1) !important;
transition: all 0.2s ease !important;
}
.fi-sidebar-nav-group-header:hover {
background: rgba(245, 158, 11, 0.15) !important;
}
.fi-sidebar-nav-group-item {
padding: 0.5rem 0.75rem !important;
font-weight: 500 !important;
color: rgba(255, 255, 255, 0.7) !important;
transition: all 0.2s ease !important;
}
.fi-sidebar-nav-group-item:hover {
color: #fbbf24 !important;
}
/* Navigation Items */
.fi-sidebar-nav-item {
margin: 0.15rem 0 !important;
border-radius: 0.5rem !important;
transition: all 0.2s ease !important;
position: relative !important;
overflow: hidden !important;
}
.fi-sidebar-nav-item::before {
content: '' !important;
position: absolute !important;
right: 0 !important;
top: 50% !important;
transform: translateY(-50%) !important;
width: 3px !important;
height: 0 !important;
background: #fbbf24 !important;
border-radius: 3px 0 0 3px !important;
transition: height 0.2s ease !important;
}
.fi-sidebar-nav-item:hover::before,
.fi-sidebar-nav-item.active::before {
height: 60% !important;
}
.fi-sidebar-nav-item:hover {
background: rgba(245, 158, 11, 0.1) !important;
}
.fi-sidebar-nav-item.active {
background: rgba(245, 158, 11, 0.15) !important;
box-shadow: inset 0 0 0 1px rgba(245, 158, 11, 0.2) !important;
}
.fi-sidebar-nav-item.active .fi-sidebar-nav-item-label {
color: #fbbf24 !important;
font-weight: 600 !important;
}
/* Icons */
.fi-sidebar-nav-item-icon {
color: rgba(255, 255, 255, 0.6) !important;
transition: color 0.2s ease !important;
}
.fi-sidebar-nav-item:hover .fi-sidebar-nav-item-icon,
.fi-sidebar-nav-item.active .fi-sidebar-nav-item-icon {
color: #fbbf24 !important;
}
/* Labels */
.fi-sidebar-nav-item-label {
color: rgba(255, 255, 255, 0.85) !important;
font-size: 0.875rem !important;
transition: color 0.2s ease !important;
}
.fi-sidebar-nav-group-item {
color: rgba(255, 255, 255, 0.5) !important;
font-size: 0.75rem !important;
text-transform: uppercase !important;
letter-spacing: 0.05em !important;
}
/* Badges */
.fi-badge {
font-weight: 600 !important;
border-radius: 9999px !important;
font-size: 0.75rem !important;
padding: 0.125rem 0.5rem !important;
}
/* Cards and Panels */
.fi-card {
border-radius: 0.75rem !important;
border: 1px solid #e5e7eb !important;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05) !important;
transition: all 0.2s ease !important;
}
.fi-card:hover {
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1) !important;
}
/* Buttons */
.fi-btn {
border-radius: 0.5rem !important;
font-weight: 500 !important;
transition: all 0.2s ease !important;
}
.fi-btn-primary {
background: #f59e0b !important;
border-color: #f59e0b !important;
}
.fi-btn-primary:hover {
background: #d97706 !important;
border-color: #d97706 !important;
transform: translateY(-1px) !important;
box-shadow: 0 4px 6px -1px rgba(245, 158, 11, 0.3) !important;
}
/* Tables */
.fi-ta-table {
border-radius: 0.75rem !important;
overflow: hidden !important;
}
.fi-ta-header-cell {
background: #f9fafb !important;
font-weight: 600 !important;
color: #374151 !important;
font-size: 0.75rem !important;
text-transform: uppercase !important;
letter-spacing: 0.05em !important;
}
.fi-ta-row {
transition: background-color 0.15s ease !important;
}
.fi-ta-row:hover {
background-color: #fffbeb !important;
}
/* Forms */
.fi-input {
border-radius: 0.5rem !important;
border-color: #d1d5db !important;
transition: all 0.2s ease !important;
}
.fi-input:focus {
border-color: #fbbf24 !important;
box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.1) !important;
}
.fi-select {
border-radius: 0.5rem !important;
}
/* Widgets */
.fi-wi-stats-overview {
gap: 1rem !important;
}
.fi-wi-stats-overview-card {
border-radius: 0.75rem !important;
border: 1px solid #e5e7eb !important;
transition: all 0.2s ease !important;
}
.fi-wi-stats-overview-card:hover {
transform: translateY(-2px) !important;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1) !important;
}
/* Dashboard */
.fi-page-header {
border-bottom: 2px solid #fbbf24 !important;
margin-bottom: 1.5rem !important;
padding-bottom: 1rem !important;
}
/* Top Navigation */
.fi-topbar {
border-bottom: 1px solid #f3f4f6 !important;
background: #ffffff !important;
}
/* Notifications */
.fi-notification {
border-radius: 0.75rem !important;
border-right: 4px solid #fbbf24 !important;
}
/* Modals */
.fi-modal {
border-radius: 0.75rem !important;
overflow: hidden !important;
}
/* Dropdowns */
.fi-dropdown {
border-radius: 0.5rem !important;
border: 1px solid #e5e7eb !important;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1) !important;
}
/* Tabs */
.fi-tabs {
border-bottom: 2px solid #f3f4f6 !important;
}
.fi-tab {
border-bottom: 2px solid transparent !important;
margin-bottom: -2px !important;
transition: all 0.2s ease !important;
}
.fi-tab:hover {
border-bottom-color: #fbbf24 !important;
color: #d97706 !important;
}
.fi-tab.active {
border-bottom-color: #fbbf24 !important;
color: #d97706 !important;
font-weight: 600 !important;
}
/* Scrollbar */
::-webkit-scrollbar {
width: 8px !important;
height: 8px !important;
}
::-webkit-scrollbar-track {
background: #f1f5f9 !important;
}
::-webkit-scrollbar-thumb {
background: #cbd5e1 !important;
border-radius: 4px !important;
}
::-webkit-scrollbar-thumb:hover {
background: #94a3b8 !important;
}
/* Dark mode adjustments */
@media (prefers-color-scheme: dark) {
.fi-sidebar {
background: linear-gradient(180deg, #0f172a 0%, #1e293b 100%) !important;
}
}