Dashboard Widgets: Stats, Table and Chart

Dashboard Widgets: Stats, Table and Chart

2024-10-16 وقت القراءه : 4 دقائق

في لوحة التحكم، في dashboard عاده ما يكون هناك بعض widgets التي تقوم بعرض إحصائيات عن إمور معينة، مثل عدد الرسائل الوارده، عدد المنتجات، عدد المستخدمين .... وبعض الجداول وبعض الخرائط والإحصائيات.

filament بشكل إفتراضي تحتوي على ثلاثة أنواع من widgets وهي Sats, Charts, Tables


كيفية إضافة Widget او Stats في Filament

Stats هي الكارد الخاصه بالإحصائيات، ولتثبيت حزمة Stats نستخدم الأمر التالي

php artisan make:filament-widget StatsOverview --stats-overview

بعد تثبيت الحزمة سيظهر لدينا الكلاس StatsOverview.php في المسار app/Filament/Widgets/StatsOverview.php

ويكون بالشكل التالي

<?php
namespace App\Filament\Widgets;

use App\Models\Payment;
use Filament\Forms\Components\Card;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;


class StatsOverview extends BaseWidget
{
    protected function getStats(): array
    {

    }
}

كما نرى أنه يأتي مع الدالة getStats ولإظهار ويدجيت معينة نقوم بإضافة Stack

class StatsOverview extends BaseWidget
{
    protected function getStats(): array
    {
        return [
            Stat::make('Payments This Month', 1),
        ];
    }
}

حيث نقوم بتمرير عنوان الـ Card وكذلك القيمة

الأن لو ذهبنا إلى dashboard سنرى أنه تم إضافة Card جديد


في هذه الدرس سوف نقوم بإظهار ويدجيت للدفعات التي تمت هذه الشهر، وكذلك ويدجيت لإجمالي المبيعات، وللحصول على القيمة نستخدم إستعلام eloquent

<?php
namespace App\Filament\Widgets;

use App\Models\Payment;
use Filament\Forms\Components\Card;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;


class StatsOverview extends BaseWidget
{
    protected function getStats(): array
    {
        return [
            Stat::make(
                'Payments This Month',
                Payment::where('created_at', '>=', now()->subDays(30))->count()
            ),
            Stat::make(
                'Income This Month',
                Payment::where('created_at', '>=', now()->subDays(30))->sum('total')
            ),
        ];
    }

}


كيفية إضافة Table في Filament

لإضافة جدول نستخدم الأمر

php artisan make:filament-widget LatestPayments --table  

مع الملاحظة أن LatestPayments هو إسم إختياري، وهو إسم الكلاس الذي سيتم إنشاؤه

namespace App\Filament\Widgets;


use Filament\Tables;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget as BaseWidget;


class LatestPayments extends BaseWidget
{
    public function table(Table $table): Table
    {
        return $table
            ->query(
                // ...
            )
            ->columns([
                // ...
            ]);
    }
}

حيث إنه بداخل Columns نحدد الحقول التي نريد إظهارها ، وفي query نقوم بكتابة جملة الإستعلام

class LatestPayments extends BaseWidget
{
    public function table(Table $table): Table
    {
        return $table
            ->query(
                 Payment::with('product')->latest()->take(5),
            )
            ->columns([
                Tables\Columns\TextColumn::make('created_at')->label('Time'),
                Tables\Columns\TextColumn::make('total')->money(),
                Tables\Columns\TextColumn::make('product.name'),
            ]);
    }
}

لكن كما نلاحظ أنه قمنا بتحديد أن تظهر أخر 5 نتائج، لكن ظهر في الجدول أكثر من ذلك، ولحل هذه المشكله يمكن لنا إضافة الدالة isTablePaginationEnabled

protected function isTablePaginationEnabled(): bool
{
    return false;
}


لكن كما نلاحظ أن cards تأتي تحت table وللتحكم في ترتيب هذه العناصر

هنا نستخدم الدالة sort حيث نقوم بإضافتها لل Stats و LatestPayment، كذلك نلاحظ أن  table لم يأخذ كامل الشاشة بل جزء منها لذلك يمكن لنا إستخدام $columnSpan


class StatsOverview extends BaseWidget
{
    protected static ?int $sort = 1;
    protected function getStats(): array
    {
        return [
            Stat::make(
                'Payments This Month',
                Payment::where('created_at', '>=', now()->subDays(30))->count()
            ),
            Stat::make(
                'Income This Month',
                Payment::where('created_at', '>=', now()->subDays(30))->sum('total')
            ),
        ];
    }
}


<?php
namespace App\Filament\Widgets;

use App\Models\Payment;
use Filament\Tables;
use Filament\Tables\Table;
use Filament\Widgets\TableWidget as BaseWidget;


class LatestPayments extends BaseWidget
{
    protected static ?int $sort = 2;
    protected int | string | array $columnSpan = 'full';

    public function table(Table $table): Table
    {
        return $table
            ->query(
                 Payment::with('product')->latest()->take(5),
            )
            ->columns([
                Tables\Columns\TextColumn::make('created_at')->label('Time'),
                Tables\Columns\TextColumn::make('total')->money(),
                Tables\Columns\TextColumn::make('product.name'),
            ]);
    }


    protected function isTablePaginationEnabled(): bool
    {
        return false;
    }
}


كيفية إضافة Charts في Filament

لإضافة Chart نستخدم الأمر 

php artisan make:filament-widget RevenueChart --chart  

مع الإنتباه أن RevenueChart هي إسم إختياري، وهو إسم الكلاس الذي سوف يتم إنشاؤه للتعامل معه.

<?php


namespace App\Filament\Widgets;


use Filament\Widgets\ChartWidget;


class RevenueChart extends ChartWidget
{
    protected static ?string $heading = 'Revenue Charts';


    protected function getData(): array
    {
        return [
            //
        ];
    }


    protected function getType(): string
    {
        return 'line';
    }
}


ولإظهار chart  بشكل dynamic فإنه يجب تثبيت حزمة FlowFrame

composer require flowframe/laravel-trend


ولكتابة جملة الإستعلام من جدول Payment وإظهار الخارطة

class RevenueChart extends ChartWidget
{
    protected static ?string $heading = 'Revenue Charts';
    protected int | string | array $columnSpan = 'full';


    protected static ?int $sort = 3;
    protected function getData(): array
    {
        $data = Trend::model(Payment::class)
            ->between(
                start: now()->subDays(30),
                end: now(),
            )
            ->perDay()
            ->sum('total');


        return [
            'datasets' => [
                [
                    'label' => 'Revenue ($)',
                    'data' => $data->map(fn (TrendValue $value) => $value->aggregate / 100),
                ],
            ],
            'labels' => $data->map(fn (TrendValue $value) => $value->date),
        ];
    }


    protected function getType(): string
    {
        return 'line';
    }
}

مع الملاحظة أن Trend هي من الحزمة التي قمنا بتثبيتها.

لتفاصيل أكثر يمكن قراءة الموقع الرسمي

https://filamentphp.com/docs/2.x/admin/dashboard/charts

إضافة تعليق
Loading...