Implement a comprehensive overhaul of the Filament admin dashboard, introducing a structured 12-column responsive grid layout and enhanced visual identity. Key changes include: - Redesigned Dashboard layout with a 4-layer progressive disclosure architecture (KPIs, Exchange Rates, Data Tables, and Trends). - Introduced custom IFNEX design tokens via CSS, including branded stat cards, status badges, and improved sidebar typography. - Enhanced FinanceOverviewWidget with real-time trend analysis and sparkline-ready data structures. - Refactored RecentShipments and RecentTransactions widgets to use custom Blade templates for a more polished, consistent UI. - Integrated brand assets including the company logo and custom authentication pages. - Added global number formatting helpers and integrated them into financial widgets. - Updated AdminPanelProvider to support custom login pages and brand-specific header/footer hooks.
86 lines
3.1 KiB
PHP
86 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Widgets;
|
|
|
|
use App\Models\Shipment;
|
|
use Filament\Widgets\Widget;
|
|
use Morilog\Jalali\Jalalian;
|
|
|
|
/**
|
|
* Layer 3 (left) — recent shipments table, spanning 6/12 of the body grid.
|
|
*/
|
|
class RecentShipmentsWidget extends Widget
|
|
{
|
|
protected static ?int $sort = 6;
|
|
|
|
protected static bool $isLazy = false;
|
|
|
|
protected int|string|array $columnSpan = 6;
|
|
|
|
protected static string $view = 'filament.widgets.recent-shipments';
|
|
|
|
protected function getViewData(): array
|
|
{
|
|
$recentShipments = Shipment::query()
|
|
->with(['fromCountry', 'toCountry'])
|
|
->orderBy('created_at', 'desc')
|
|
->limit(5)
|
|
->get()
|
|
->map(function ($s) {
|
|
return [
|
|
'awb' => $s->awb_no,
|
|
'route' => ($s->fromCountry?->name ?? '?') . ' ← ' . ($s->toCountry?->name ?? '?'),
|
|
'status' => $s->status?->value ?? '—',
|
|
'status_label' => $this->statusLabel($s->status?->value),
|
|
'status_color' => $this->statusBadgeClass($s->status?->value),
|
|
'date' => Jalalian::fromCarbon($s->created_at)->format('Y/m/d'),
|
|
'amount' => $s->total_fee ? ifnex_format_number($s->total_fee) : '—',
|
|
'url' => route('filament.admin.resources.shipments.view', $s),
|
|
];
|
|
});
|
|
|
|
return [
|
|
'recentShipments' => $recentShipments,
|
|
'viewAllUrl' => route('filament.admin.resources.shipments.index'),
|
|
];
|
|
}
|
|
|
|
private function statusLabel(?string $status): string
|
|
{
|
|
return match ($status) {
|
|
'pending_approval' => 'در انتظار تأیید',
|
|
'approved' => 'تأیید شده',
|
|
'pending_payment' => 'در انتظار پرداخت',
|
|
'cancelled' => 'لغو شده',
|
|
'processed' => 'در حال پردازش',
|
|
'picked_up' => 'تحویل به حملکننده',
|
|
'in_transit' => 'در حال حمل',
|
|
'out_for_delivery' => 'آماده تحویل',
|
|
'failed' => 'تحویل ناموفق',
|
|
'delivered' => 'تحویل شده',
|
|
'returned' => 'برگشتی',
|
|
'archived' => 'آرشیو',
|
|
default => '—',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Return the badge CSS class name — uses the new ifnex-badge-* styles
|
|
* defined in head.blade.php (success / warning / danger / info / gray).
|
|
*/
|
|
private function statusBadgeClass(?string $status): string
|
|
{
|
|
return match ($status) {
|
|
'pending_approval', 'pending_payment' => 'ifnex-badge-warning',
|
|
'approved' => 'ifnex-badge-info',
|
|
'picked_up', 'in_transit' => 'ifnex-badge-info',
|
|
'out_for_delivery' => 'ifnex-badge-info',
|
|
'delivered' => 'ifnex-badge-success',
|
|
'cancelled', 'failed' => 'ifnex-badge-danger',
|
|
'returned' => 'ifnex-badge-warning',
|
|
'processed' => 'ifnex-badge-info',
|
|
'archived' => 'ifnex-badge-gray',
|
|
default => 'ifnex-badge-gray',
|
|
};
|
|
}
|
|
} |