Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Simple Stats Laravel Package

spatie/filament-simple-stats

Opinionated, prebuilt stat widgets for Filament dashboards. Quickly add daily counts and sums using Flowframe/laravel-trend, with helpers like last 30 days to generate clean, consistent stats cards with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/filament-simple-stats
    

    Ensure your project uses Filament v2+ and Laravel 10+ (or newer, as per changelog).

  2. First Widget: Create a Filament widget (e.g., app/Filament/Widgets/DashboardStats.php):

    use Spatie\FilamentSimpleStats\SimpleStat;
    use Filament\Widgets\Widget;
    
    class DashboardStats extends Widget
    {
        protected static string $view = 'filament.widgets.dashboard-stats';
    
        public function getStats(): array
        {
            return [
                SimpleStat::make('Users')->model(\App\Models\User::class)->count(),
                SimpleStat::make('Revenue')->model(\App\Models\Order::class)->sum('amount'),
            ];
        }
    }
    
  3. Register Widget: Add the widget to your Filament dashboard in app/Providers/Filament/AdminPanelProvider.php:

    public function panel(Panel $panel): Panel
    {
        return $panel
            ->widgets([
                \App\Filament\Widgets\DashboardStats::class,
            ]);
    }
    
  4. Run Migrations (if needed): Ensure your models have the required columns (e.g., created_at for time-based queries).


First Use Case: Quick Dashboard Metrics

Use SimpleStat to display counts, sums, averages, or minimums/maximums of Eloquent models with minimal boilerplate. Example:

SimpleStat::make('Active Users')
    ->model(\App\Models\User::class)
    ->where('active', true)
    ->last7Days()
    ->dailyCount(),

Implementation Patterns

Core Workflows

  1. Model-Based Stats:

    SimpleStat::make('Total Orders')
        ->model(\App\Models\Order::class)
        ->count(); // or sum('amount'), avg('price'), etc.
    
  2. Time-Based Aggregations:

    // Daily/weekly/monthly trends
    SimpleStat::make('Daily Orders')
        ->model(\App\Models\Order::class)
        ->last30Days()
        ->dailySum('amount');
    
    // Custom periods
    SimpleStat::make('Monthly Revenue')
        ->model(\App\Models\Order::class)
        ->last12Months()
        ->monthlySum('amount');
    
  3. Query Modifiers:

    SimpleStat::make('User Orders')
        ->model(\App\Models\Order::class)
        ->where('user_id', auth()->id())
        ->where('status', 'completed')
        ->lastWeek()
        ->count();
    
  4. Trend Customization:

    // Disable trends (show raw values only)
    SimpleStat::make('Errors')->model(\App\Models\Error::class)->count()->withoutTrend();
    
    // Invert colors (e.g., for error rates)
    SimpleStat::make('Errors')->model(\App\Models\Error::class)->count()->invertTrendColors();
    

Integration Tips

  1. Dynamic Data Sources: Use closures for dynamic queries (e.g., scoped to the current user or tenant):

    SimpleStat::make('My Orders')
        ->query(fn () => \App\Models\Order::where('user_id', auth()->id()))
        ->count();
    
  2. Custom Views: Extend the default view (resources/views/filament/widgets/dashboard-stats.blade.php) to override styling or add tooltips:

    <div class="filament-stats-card">
        <x-filament::section>
            <div class="flex items-center gap-4">
                <div class="text-3xl font-bold">{{ $stat->value }}</div>
                <div class="text-sm text-gray-500">{{ $stat->description }}</div>
            </div>
        </x-filament::section>
    </div>
    
  3. Caching: Cache expensive queries in your widget’s update() method or use Laravel’s cache middleware:

    public function update(): void
    {
        Cache::remember('dashboard_stats', now()->addHours(1), fn () => $this->getStats());
    }
    
  4. Localization: Translate stat labels and descriptions using Filament’s localization:

    SimpleStat::make(__('filament::resources/users.title'))
        ->model(\App\Models\User::class)
        ->count();
    

Advanced Patterns

  1. Composite Stats: Combine multiple stats into a single widget for related metrics:

    public function getStats(): array
    {
        return [
            SimpleStat::make('Users')->model(\App\Models\User::class)->count(),
            SimpleStat::make('Active Users')->model(\App\Models\User::class)->where('last_seen_at', '>', now()->subDay())->count(),
            SimpleStat::make('Avg. Session')->model(\App\Models\User::class)->avg('session_duration'),
        ];
    }
    
  2. Conditional Stats: Show/hide stats based on user roles or permissions:

    public function getStats(): array
    {
        $stats = [
            SimpleStat::make('Admin Dashboard')->count(),
        ];
    
        if (auth()->user()->isAdmin()) {
            $stats[] = SimpleStat::make('Admin Users')->model(\App\Models\User::class)->where('role', 'admin')->count();
        }
    
        return $stats;
    }
    
  3. API-Driven Stats: Fetch data from external APIs and format it for SimpleStat:

    SimpleStat::make('API Calls')
        ->value(fn () => Http::get('https://api.example.com/metrics')->json()['count'])
        ->description('Last 24h');
    

Gotchas and Tips

Pitfalls

  1. Performance:

    • Issue: Time-based queries (e.g., last30Days()) can be slow without proper database indexing.
    • Fix: Ensure created_at (or your date column) is indexed:
      Schema::table('orders', function (Blueprint $table) {
          $table->index('created_at');
      });
      
    • Tip: Use select() to limit columns:
      SimpleStat::make('Orders')->model(\App\Models\Order::class)->select('id', 'amount')->sum('amount');
      
  2. Trend Calculation:

    • Issue: Trends may appear incorrect if data is sparse or irregular (e.g., missing days in last30Days()).
    • Fix: Use endOfDay() to include today’s data:
      SimpleStat::make('Daily Orders')->last30Days()->endOfDay()->dailySum('amount');
      
    • Workaround: Pad missing periods with 0 using a custom query:
      SimpleStat::make('Orders')->query(fn () => \App\Models\Order::selectRaw('
          COUNT(*) as count,
          DATE(created_at) as date
      )->groupBy('date')
      ->union([
          \DB::raw("SELECT 0 as count, DATE(CURRENT_DATE) as date ON CONFLICT(date) DO NOTHING")
      ]))
      ->last30Days();
      
  3. Model Ambiguity:

    • Issue: If multiple models share the same table name, SimpleStat::make() may fail.
    • Fix: Use the query() method instead of model():
      SimpleStat::make('Orders')->query(\App\Models\Order::query())->count();
      
  4. Filament Version Mismatch:

    • Issue: The package may break if Filament updates its widget API.
    • Fix: Pin the package version in composer.json or check the changelog for compatibility notes.

Debugging

  1. Query Inspection: Use Laravel’s query logging to debug slow or incorrect queries:

    \DB::enableQueryLog();
    $stats = $this->getStats();
    \Log::debug(\DB::getQueryLog());
    
  2. Stat Value Overrides: Temporarily override stat values for testing:

    SimpleStat::make('Test Stat')->value(42)->description('Hardcoded for testing');
    
  3. Trend Debugging: Check the raw trend data by inspecting the getTrend() method output:

    $stat = SimpleStat::make('Orders')->last7Days()->dailySum('amount');
    \Log::debug($stat->getTrend());
    

Configuration Quirks

  1. Default Time Periods:
    • The package uses last7Days() by default for daily stats and last12Months() for monthly stats. Override explicitly if needed:
      SimpleStat::make('Monthly Orders')->last12Month
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai