From 8ad555c0ab55820b9ea36f41f4e2e193136be6e0 Mon Sep 17 00:00:00 2001 From: Nisse Lommerde Date: Wed, 20 Nov 2024 15:53:46 -0500 Subject: [PATCH] Improving Order table front-end --- .../Resources/CustomerReportResource.php | 2 +- app/Filament/Resources/InvoiceResource.php | 22 +++---- app/Filament/Resources/OrderResource.php | 19 +++++- .../OrderResource/Pages/ListOrders.php | 66 +++++++++++++++++++ app/Models/Order.php | 16 +++++ database/seeders/OrderSeeder.php | 2 +- 6 files changed, 111 insertions(+), 16 deletions(-) diff --git a/app/Filament/Resources/CustomerReportResource.php b/app/Filament/Resources/CustomerReportResource.php index d0e0ca2..7a86555 100644 --- a/app/Filament/Resources/CustomerReportResource.php +++ b/app/Filament/Resources/CustomerReportResource.php @@ -95,7 +95,7 @@ class CustomerReportResource extends Resource DatePicker::make('created_until') ->label('Until date'), ]), - ], layout: Tables\Enums\FiltersLayout::AboveContentCollapsible) + ]) ->actions([ ]) ->bulkActions([ diff --git a/app/Filament/Resources/InvoiceResource.php b/app/Filament/Resources/InvoiceResource.php index aeda0fa..8c29bf7 100644 --- a/app/Filament/Resources/InvoiceResource.php +++ b/app/Filament/Resources/InvoiceResource.php @@ -102,9 +102,6 @@ class InvoiceResource extends Resource ->sortable() ->extraHeaderAttributes(['class' => 'w-full']) ->searchable(), - Tables\Columns\TextColumn::make('status') - ->badge(InvoiceStatus::class) - ->sortable(), Tables\Columns\TextColumn::make('created_at') ->label('Created') ->date() @@ -126,17 +123,18 @@ class InvoiceResource extends Resource ->money('USD') ->weight('bold') ->alignRight(), + Tables\Columns\TextColumn::make('status') + ->badge(InvoiceStatus::class) + ->sortable(), ]) ->filters([ Tables\Filters\Filter::make('created_at') ->form([ - Split::make([ - DatePicker::make('created_from') - ->label('From date'), - DatePicker::make('created_until') - ->label('Until date'), - ]), + DatePicker::make('created_from') + ->label('From date'), + DatePicker::make('created_until') + ->label('Until date'), ]) ->query(function (Builder $query, array $data): Builder { return $query @@ -151,11 +149,9 @@ class InvoiceResource extends Resource }), Tables\Filters\SelectFilter::make('status') - ->options(InvoiceStatus::class) - ->columnSpan(1), + ->options(InvoiceStatus::class), - ], layout: Tables\Enums\FiltersLayout::AboveContentCollapsible) - ->filtersFormColumns(3) + ], ) ->groups([ 'status', diff --git a/app/Filament/Resources/OrderResource.php b/app/Filament/Resources/OrderResource.php index 13e307b..880a776 100644 --- a/app/Filament/Resources/OrderResource.php +++ b/app/Filament/Resources/OrderResource.php @@ -223,15 +223,25 @@ class OrderResource extends Resource { return $table ->columns([ + Tables\Columns\IconColumn::make('alert') + ->getStateUsing(fn ($record) => $record->is_alert_danger || $record->is_alert_warning) + ->label('') + ->color(fn ($record) => $record->is_alert_danger ? 'danger' : 'warning' + ) + ->icon(fn ($state) => $state ? OrderAttributes::rush->getIcon() : null) + ->size(Tables\Columns\IconColumn\IconColumnSize::Small), + TextColumn::make('internal_po') ->label('Internal PO') ->fontFamily('mono') ->color('info') ->searchable() ->sortable(), + TextColumn::make('customer.company_name') ->searchable() ->sortable(), + TextColumn::make('customer_po') ->label('PO') ->wrap() @@ -242,18 +252,23 @@ class OrderResource extends Resource ->extraHeaderAttributes([ 'class' => 'w-full', ]), + TextColumn::make('order_date') ->searchable() ->sortable(), + TextColumn::make('due_date') ->searchable() ->sortable(), + TextColumn::make('status') ->badge() ->searchable() ->sortable(), ]) + ->defaultSort('order_date', 'desc') + ->filters([ Tables\Filters\Filter::make('order_date') ->form([ @@ -271,10 +286,12 @@ class OrderResource extends Resource fn (Builder $query, $date): Builder => $query->whereDate('order_date', '<=', $date), ); }), - ], layout: Tables\Enums\FiltersLayout::AboveContentCollapsible) + ], ) + ->actions([ Tables\Actions\EditAction::make(), ]) + ->bulkActions([ Tables\Actions\BulkActionGroup::make([ Tables\Actions\DeleteBulkAction::make(), diff --git a/app/Filament/Resources/OrderResource/Pages/ListOrders.php b/app/Filament/Resources/OrderResource/Pages/ListOrders.php index dc19c41..0765829 100644 --- a/app/Filament/Resources/OrderResource/Pages/ListOrders.php +++ b/app/Filament/Resources/OrderResource/Pages/ListOrders.php @@ -2,8 +2,12 @@ namespace App\Filament\Resources\OrderResource\Pages; +use App\Enums\OrderAttributes; +use App\Enums\OrderStatus; use App\Filament\Resources\OrderResource; +use App\Models\Order; use Filament\Actions; +use Filament\Resources\Components\Tab; use Filament\Resources\Pages\ListRecords; class ListOrders extends ListRecords @@ -16,4 +20,66 @@ class ListOrders extends ListRecords Actions\CreateAction::make(), ]; } + + public function getTabs(): array + { + return [ + null => Tab::make('All') + ->icon('lucide-layout-grid'), + + 'overdue' => Tab::make() + ->query(function ($query) { + return $query->whereDate('due_date', '<=', today()) + ->whereNot('status', OrderStatus::INVOICED) + ->whereNot('status', ORderStatus::SHIPPED); + }) + ->icon('lucide-calendar-clock') + ->badge(function () { + $count = Order::whereDate('due_date', '<=', today()) + ->whereNot('status', OrderStatus::INVOICED) + ->whereNot('status', ORderStatus::SHIPPED) + ->count(); + + return $count > 0 ? $count : null; + }) + ->badgeColor('danger'), + + 'rush' => Tab::make() + ->query(function ($query) { + return $query->where('rush', true) + ->whereNot('status', OrderStatus::INVOICED) + ->whereNot('status', OrderStatus::SHIPPED); + }) + ->icon(OrderAttributes::rush->getIcon()) + ->badge(function () { + $count = Order::where('rush', true) + ->whereNot('status', OrderStatus::INVOICED) + ->whereNot('status', OrderStatus::SHIPPED) + ->count(); + + return $count > 0 ? $count : null; + }) + ->badgeColor('warning'), + + 'draft' => Tab::make() + ->query(fn ($query) => $query->where('status', OrderStatus::DRAFT->value)) + ->icon(OrderStatus::DRAFT->getIcon()), + + 'approved' => Tab::make() + ->query(fn ($query) => $query->where('status', OrderStatus::APPROVED->value)) + ->icon(OrderStatus::APPROVED->getIcon()), + + 'production' => Tab::make() + ->query(fn ($query) => $query->where('status', OrderStatus::PRODUCTION->value)) + ->icon(OrderStatus::PRODUCTION->getIcon()), + + 'shipped' => Tab::make() + ->query(fn ($query) => $query->where('status', OrderStatus::SHIPPED->value)) + ->icon(OrderStatus::SHIPPED->getIcon()), + + 'invoiced' => Tab::make() + ->query(fn ($query) => $query->where('status', OrderStatus::INVOICED->value)) + ->icon(OrderStatus::INVOICED->getIcon()), + ]; + } } diff --git a/app/Models/Order.php b/app/Models/Order.php index 08f17a3..9113375 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -45,6 +45,8 @@ class Order extends Model protected $appends = [ 'total_service_price', 'total_product_quantity', + 'is_alert_warning', + 'is_alert_danger', ]; protected $casts = [ @@ -80,6 +82,20 @@ class Order extends Model return 'TN'.$year.'-'.$po; } + public function getIsAlertWarningAttribute(): bool + { + if ($this->rush) { + return ! ($this->status === OrderStatus::INVOICED || $this->status === OrderStatus::SHIPPED); + } + + return false; + } + + public function getIsAlertDangerAttribute(): bool + { + return $this->due_date <= today() && $this->status !== OrderStatus::INVOICED && $this->status !== OrderStatus::SHIPPED; + } + public function getTotalProductQuantityAttribute(): int { $total = 0; diff --git a/database/seeders/OrderSeeder.php b/database/seeders/OrderSeeder.php index 9bc5503..813f3de 100644 --- a/database/seeders/OrderSeeder.php +++ b/database/seeders/OrderSeeder.php @@ -14,7 +14,7 @@ class OrderSeeder extends Seeder public function run(): void { foreach (Customer::all() as $customer) { - Order::factory(rand(2, 50), ['customer_id' => $customer])->create(); + Order::factory(rand(10, 50), ['customer_id' => $customer])->create(); } } }