79091387

Date: 2024-10-15 19:03:08
Score: 1
Natty:
Report link

compine all widgets in one widget and give it columnspan = 'full'

A friend told me how to fix this, I have created 6 widgets for each single stats overview and gave each one columnspan = 1; but he told me to do it like in the photo. I must put each 3 widgets or each row in the same stats overview widget and give it columnspan = 'full'; let me share my code with you

<?php

namespace App\Filament\Widgets;

use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;
use App\Models\Order;
use App\Models\PlaceOrder;
use Filament\Widgets\Concerns\InteractsWithPageFilters;
use Carbon\Carbon;

class OrderDeliveredWidget extends BaseWidget
{
    use InteractsWithPageFilters;

    protected int | string | array $columnSpan = 'full';

    protected function getStats(): array
    {
        $statuses = [
            ['model' => Order::class, 'status' => 'to_customer', 'label' => 'On Delivery Orders'],
            ['model' => Order::class, 'status' => 'delivered', 'label' => 'Delivered Orders'],
            ['model' => PlaceOrder::class, 'status' => 'pending', 'label' => 'Pending Orders'],
        ];

        $stats = [];

        foreach ($statuses as $statusInfo) {
            $query = $statusInfo['model']::query();
            
            if ($this->filters['Date']) {
                $query->where('created_at', '>=', $this->getFilterDate($this->filters['Date']));
            }

            $currentCount = $query->where('status', $statusInfo['status'])->count();
            
            $previousPeriodStart = $this->getPreviousPeriodStart($this->filters['Date']);
            $previousCount = $statusInfo['model']::where('status', $statusInfo['status'])
                ->where('created_at', '>=', $previousPeriodStart)
                ->where('created_at', '<', $this->getFilterDate($this->filters['Date']))
                ->count();

            $percentageChange = $this->calculatePercentageChange($previousCount, $currentCount);
            $description = $this->getDescription($percentageChange);
            $icon = $this->getDescriptionIcon($percentageChange);
            $color = $this->getColor($percentageChange);

            $stats[] = Stat::make($statusInfo['label'], $currentCount)
                ->description($description)
                ->descriptionIcon($icon)
                ->color($color);
        }

        return $stats;
    }

    private function getFilterDate(?string $filter): Carbon
    {
        return match($filter) {
            'today' => now()->startOfDay(),
            'week' => now()->startOfWeek(),
            'month' => now()->startOfMonth(),
            'year' => now()->startOfYear(),
            default => Carbon::createFromTimestamp(0),
        };
    }

    protected function getFilters(): ?array
    {
        return [
            'today' => 'Today',
            'week' => 'This week',
            'month' => 'This month',
            'year' => 'This year',
        ];
    }

    private function calculatePercentageChange($oldValue, $newValue): float
    {
        if ($oldValue == 0) {
            return $newValue > 0 ? 100 : 0;
        }
        return (($newValue - $oldValue) / $oldValue) * 100;
    }

    private function getDescription(float $percentageChange): string
    {
        $formattedChange = number_format(abs($percentageChange), 1);
        $direction = $percentageChange >= 0 ? 'increase' : 'decrease';
        return "{$formattedChange}% {$direction}";
    }

    private function getDescriptionIcon(float $percentageChange): string
    {
        return $percentageChange >= 0 
            ? 'heroicon-m-arrow-trending-up'
            : 'heroicon-m-arrow-trending-down';
    }

    private function getColor(float $percentageChange): string
    {
        if ($percentageChange > 10) {
            return 'success';
        } elseif ($percentageChange < -10) {
            return 'danger';
        } else {
            return 'warning';
        }
    }

    private function getPreviousPeriodStart(?string $filter): Carbon
    {
        return match($filter) {
            'today' => now()->subDay()->startOfDay(),
            'week' => now()->subWeek()->startOfWeek(),
            'month' => now()->subMonth()->startOfMonth(),
            'year' => now()->subYear()->startOfYear(),
            default => Carbon::createFromTimestamp(0),
        };
    }
}
Reasons:
  • Probably link only (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: Pierre Sameh