NotificationEngagementStats   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 86
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
wmc 10
eloc 55
c 1
b 0
f 1
dl 0
loc 86
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getClicksChartData() 0 10 2
A getOpensChartData() 0 10 2
A getStats() 0 51 5
A canView() 0 3 1
1
<?php
2
3
namespace Usamamuneerchaudhary\Notifier\Filament\Widgets;
4
5
use Filament\Facades\Filament;
6
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
7
use Filament\Widgets\StatsOverviewWidget\Stat;
8
use Usamamuneerchaudhary\Notifier\Models\Notification;
9
use Usamamuneerchaudhary\Notifier\Models\NotificationSetting;
10
11
class NotificationEngagementStats extends BaseWidget
12
{
13
    protected ?string $pollingInterval = '30s';
14
    protected static ?int $sort = 2;
15
16
    public static function canView(): bool
17
    {
18
        return false;
19
    }
20
21
    protected function getStats(): array
22
    {
23
        $analytics = NotificationSetting::getAnalytics();
24
25
        if (!($analytics['enabled'] ?? config('notifier.settings.analytics.enabled', true))) {
26
            return [
27
                Stat::make('Analytics Disabled', '')
28
                    ->description('Enable analytics in settings to view engagement metrics')
29
                    ->color('gray'),
30
            ];
31
        }
32
33
        $totalSent = Notification::where('status', 'sent')->count();
34
        $totalOpened = Notification::whereNotNull('opened_at')->count();
35
        $totalClicked = Notification::whereNotNull('clicked_at')->count();
36
37
        $totalOpens = Notification::sum('opens_count');
38
        $totalClicks = Notification::sum('clicks_count');
39
40
        // Calculate engagement rates
41
        $openRate = $totalSent > 0 ? round(($totalOpened / $totalSent) * 100, 1) : 0;
42
        $clickRate = $totalSent > 0 ? round(($totalClicked / $totalSent) * 100, 1) : 0;
43
        $clickThroughRate = $totalOpened > 0 ? round(($totalClicked / $totalOpened) * 100, 1) : 0;
44
45
        return [
46
            Stat::make('Total Opens', number_format($totalOpens))
0 ignored issues
show
Bug introduced by
It seems like $totalOpens can also be of type Illuminate\Database\Eloq...gHasThroughRelationship; however, parameter $num of number_format() does only seem to accept double, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

46
            Stat::make('Total Opens', number_format(/** @scrutinizer ignore-type */ $totalOpens))
Loading history...
47
                ->description($totalOpened . ' unique opens')
48
                ->descriptionIcon('heroicon-m-eye')
49
                ->color('info')
50
                ->chart($this->getOpensChartData()),
51
52
            Stat::make('Open Rate', $openRate . '%')
53
                ->description($totalOpened . ' of ' . $totalSent . ' emails opened')
54
                ->descriptionIcon('heroicon-m-arrow-trending-up')
55
                ->color('success'),
56
57
            Stat::make('Total Clicks', number_format($totalClicks))
58
                ->description($totalClicked . ' unique clicks')
59
                ->descriptionIcon('heroicon-m-cursor-arrow-rays')
60
                ->color('warning')
61
                ->chart($this->getClicksChartData()),
62
63
            Stat::make('Click Rate', $clickRate . '%')
64
                ->description($totalClicked . ' of ' . $totalSent . ' emails clicked')
65
                ->descriptionIcon('heroicon-m-arrow-trending-up')
66
                ->color('warning'),
67
68
            Stat::make('Click-Through Rate', $clickThroughRate . '%')
69
                ->description('Clicks per open')
70
                ->descriptionIcon('heroicon-m-arrow-path')
71
                ->color('success'),
72
        ];
73
    }
74
75
    private function getOpensChartData(): array
76
    {
77
        $data = [];
78
        for ($i = 6; $i >= 0; $i--) {
79
            $date = now()->subDays($i);
80
            $count = Notification::whereDate('opened_at', $date)
81
                ->sum('opens_count');
82
            $data[] = $count;
83
        }
84
        return $data;
85
    }
86
87
    private function getClicksChartData(): array
88
    {
89
        $data = [];
90
        for ($i = 6; $i >= 0; $i--) {
91
            $date = now()->subDays($i);
92
            $count = Notification::whereDate('clicked_at', $date)
93
                ->sum('clicks_count');
94
            $data[] = $count;
95
        }
96
        return $data;
97
    }
98
}
99
100