ifnex/04_Laravel/app/Filament/Widgets/ExchangeRateWidget.php
Kazem Alghasi c54530d8da refactor(admin): optimize dashboard layout and enhance sidebar UX
Refactor the Filament admin dashboard by decoupling the recent shipments
logic into a dedicated widget and improving the sidebar navigation
experience. Additionally, implement several improvements to the
WordPress theme for better client-side usability.

Laravel/Filament:
- Extract `RecentShipmentsWidget` from `DashboardInfoWidget` to improve
  modularization and dashboard performance.
- Update widget sorting and layout to accommodate the new structure.
- Inject custom CSS and Alpine.js logic into the admin head to provide
  sidebar group toggling and a "collapse all" utility.
- Improve sidebar group label visibility and hover states.

WordPress:
- Implement `ifnex_login_url()` to support Polylang-aware, language-specific
  login pages.
- Hide the WordPress admin bar for non-administrator users to provide a
  cleaner client interface.
- Add conditional rendering for the registration link in the login
  template based on WordPress user registration settings.
2026-10-03 07:01:54 +03:30

71 lines
3.2 KiB
PHP

<?php
namespace App\Filament\Widgets;
use App\Services\ExchangeRateService;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;
use App\Models\ExchangeRateHistory;
class ExchangeRateWidget extends BaseWidget
{
protected static ?int $sort = 3;
protected static bool $isLazy = false;
protected int | string | array $columnSpan = 'full';
protected function getStats(): array
{
$service = app(ExchangeRateService::class);
$aedInfo = $service->getLatestRateInfo('AED', 'IRR');
$usdInfo = $service->getLatestRateInfo('USD', 'IRR');
$aedChangePercent = $aedInfo['change_percent'];
$usdChangePercent = $usdInfo['change_percent'];
$aedChart = $service->getRateChart('AED', 'IRR', 7);
$usdChart = $service->getRateChart('USD', 'IRR', 7);
return [
Stat::make('نرخ درهم (AED)', number_format($aedInfo['current_rate']) . ' ریال')
->description($aedChangePercent !== null
? 'تغییر: ' . number_format($aedChangePercent, 2) . '% — توسط ' . ($aedInfo['changed_by'] ?? 'سیستم')
: 'آخرین تغییر: ' . ($aedInfo['last_updated']?->format('Y/m/d H:i') ?? '—'))
->descriptionIcon(
$aedChangePercent > 0 ? 'heroicon-m-arrow-trending-up' :
($aedChangePercent < 0 ? 'heroicon-m-arrow-trending-down' : 'heroicon-m-minus')
)
->color(
$aedChangePercent > 0 ? 'danger' :
($aedChangePercent < 0 ? 'success' : 'gray')
)
->chart(!empty($aedChart) ? $aedChart : [0]),
Stat::make('نرخ دلار (USD)', number_format($usdInfo['current_rate']) . ' ریال')
->description($usdChangePercent !== null
? 'تغییر: ' . number_format($usdChangePercent, 2) . '% — توسط ' . ($usdInfo['changed_by'] ?? 'سیستم')
: 'آخرین تغییر: ' . ($usdInfo['last_updated']?->format('Y/m/d H:i') ?? '—'))
->descriptionIcon(
$usdChangePercent > 0 ? 'heroicon-m-arrow-trending-up' :
($usdChangePercent < 0 ? 'heroicon-m-arrow-trending-down' : 'heroicon-m-minus')
)
->color(
$usdChangePercent > 0 ? 'danger' :
($usdChangePercent < 0 ? 'success' : 'gray')
)
->chart(!empty($usdChart) ? $usdChart : [0]),
Stat::make('تغییرات امروز',
ExchangeRateHistory::whereDate('created_at', today())->count()
)
->description('تغییرات نرخ ثبت‌شده در امروز')
->descriptionIcon('heroicon-m-arrow-path')
->color('info'),
Stat::make('در انتظار تأیید', $service->getPendingCount())
->description('نرخ‌های پیشنهادی API — منتظر تأیید مدیر')
->descriptionIcon('heroicon-m-clock')
->color('warning'),
];
}
}