Skip to content

Commit 6116ca4

Browse files
committed
feat:(LAR-171) BO add Stat in dashboard
1 parent 36f1939 commit 6116ca4

19 files changed

+487
-424
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Resources\ArticleResource\Widgets;
6+
7+
use App\Models\Article;
8+
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
9+
use Filament\Widgets\StatsOverviewWidget\Stat;
10+
use Flowframe\Trend\Trend;
11+
use Flowframe\Trend\TrendValue;
12+
13+
final class ArticleStatsOverview extends BaseWidget
14+
{
15+
protected static ?string $pollingInterval = null;
16+
17+
protected ?string $heading = 'Posts';
18+
19+
protected function getColumns(): int
20+
{
21+
return 2;
22+
}
23+
24+
protected function getStats(): array
25+
{
26+
$currentWeekStart = now()->startOfWeek();
27+
$currentWeekEnd = now()->endOfWeek();
28+
29+
return [
30+
Stat::make('Total Post', Article::query()->published()->count())
31+
->icon('heroicon-o-newspaper')
32+
->chart(
33+
Trend::query(Article::query()->published())
34+
->between(
35+
start: $currentWeekStart,
36+
end: $currentWeekEnd,
37+
)->perDay()
38+
->count()
39+
->map(fn (TrendValue $value) => $value->aggregate)->toArray()
40+
)->description(__('Total Post')),
41+
42+
Stat::make(
43+
'Recent post',
44+
Article::query()
45+
->recent()
46+
->whereBetween('created_at', [
47+
$currentWeekStart,
48+
$currentWeekEnd,
49+
])->count()
50+
)
51+
->chart(
52+
Trend::query(Article::query())
53+
->between(
54+
start: $currentWeekStart,
55+
end: $currentWeekEnd,
56+
)
57+
->perDay()
58+
->count()
59+
->map(fn (TrendValue $value) => $value->aggregate)
60+
->toArray()
61+
)->icon('heroicon-o-newspaper')
62+
->color('primary')
63+
->description('Total Posts of the week'),
64+
];
65+
}
66+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Resources\ArticleResource\Widgets;
6+
7+
use App\Models\Article;
8+
use Filament\Widgets\ChartWidget;
9+
use Illuminate\Support\Str;
10+
11+
final class MostLikedPostsChart extends ChartWidget
12+
{
13+
protected static ?string $heading = 'Most Liked Posts';
14+
15+
protected static ?string $maxHeight = '200px';
16+
17+
protected int|string|array $columnSpan = 'full';
18+
19+
protected int $titleLength = 10;
20+
21+
protected function getData(): array
22+
{
23+
$articles = Article::published()
24+
->popular()
25+
->limit(10)
26+
->get();
27+
28+
return [
29+
'datasets' => [
30+
[
31+
'label' => 'Total Liked',
32+
'data' => $articles->pluck('reactions_count')->toArray(),
33+
],
34+
],
35+
'labels' => $articles->pluck('title')
36+
->map(fn ($title) => Str::limit($title, $this->titleLength, '...'))
37+
->toArray(),
38+
];
39+
}
40+
41+
protected function getType(): string
42+
{
43+
return 'bar';
44+
}
45+
46+
protected function getOptions(): array
47+
{
48+
return [
49+
'scales' => [
50+
'y' => [
51+
'beginAtZero' => true,
52+
],
53+
],
54+
];
55+
}
56+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Resources\ArticleResource\Widgets;
6+
7+
use App\Models\Article;
8+
use CyrildeWit\EloquentViewable\Support\Period;
9+
use Filament\Widgets\ChartWidget;
10+
use Illuminate\Support\Str;
11+
12+
final class MostViewedPostsChart extends ChartWidget
13+
{
14+
protected static ?string $heading = 'Most Viewed Posts';
15+
16+
protected static ?string $maxHeight = '200px';
17+
18+
protected int|string|array $columnSpan = 'full';
19+
20+
protected int $titleLength = 10;
21+
22+
protected function getData(): array
23+
{
24+
$articles = Article::withViewsCount(Period::create(now()->startOfWeek(), now()->endOfWeek())) // @phpstan-ignore-line
25+
->published()
26+
->orderByDesc('views_count')
27+
->orderByDesc('published_at')
28+
->limit(10)
29+
->get();
30+
31+
return [
32+
'datasets' => [
33+
[
34+
'label' => 'Most viewed post',
35+
'data' => $articles->pluck('views_count')->toArray(),
36+
],
37+
],
38+
'labels' => $articles->pluck('title')
39+
->map(fn ($title) => Str::limit($title, $this->titleLength, '...'))
40+
->toArray(),
41+
];
42+
}
43+
44+
protected function getType(): string
45+
{
46+
return 'bar';
47+
}
48+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Resources\UserResource\Widgets;
6+
7+
use App\Models\User;
8+
use Filament\Widgets\ChartWidget;
9+
use Illuminate\Database\Eloquent\Builder;
10+
11+
final class UserActivityWidget extends ChartWidget
12+
{
13+
protected static ?string $heading = 'Most active users this week';
14+
15+
protected int|string|array $columnSpan = 'full';
16+
17+
protected static ?string $maxHeight = '200px';
18+
19+
protected function getData(): array
20+
{
21+
$users = User::with('activities')
22+
->withCount('activities')
23+
->verifiedUsers()
24+
->whereHas('activities', fn (Builder $query) => $query->whereBetween('created_at', [
25+
now()->startOfWeek(),
26+
now()->endOfWeek(),
27+
]))
28+
->orderByDesc('activities_count')
29+
->limit(10)
30+
->get();
31+
32+
return [
33+
'datasets' => [
34+
[
35+
'label' => 'Total Activities',
36+
'data' => $users->pluck('activities_count')->toArray(),
37+
],
38+
],
39+
'labels' => $users->pluck('name')->toArray(),
40+
];
41+
}
42+
43+
protected function getType(): string
44+
{
45+
return 'bar';
46+
}
47+
48+
protected function getOptions(): array
49+
{
50+
return [
51+
'scales' => [
52+
'y' => [
53+
'beginAtZero' => true,
54+
],
55+
],
56+
];
57+
}
58+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Resources\UserResource\Widgets;
6+
7+
use App\Models\User;
8+
use Filament\Widgets\ChartWidget;
9+
use Flowframe\Trend\Trend;
10+
use Flowframe\Trend\TrendValue;
11+
12+
final class UserChartWidget extends ChartWidget
13+
{
14+
protected static ?string $heading = 'Account Creation';
15+
16+
protected int|string|array $columnSpan = 'full';
17+
18+
protected static ?string $maxHeight = '200px';
19+
20+
public ?string $filter = 'week';
21+
22+
protected function getColumns(): int
23+
{
24+
return 2;
25+
}
26+
27+
protected function getFilters(): array
28+
{
29+
return [
30+
'week' => 'Last Week',
31+
'month' => 'Last Month',
32+
'3months' => 'Last 3 Months',
33+
];
34+
}
35+
36+
protected function getData(): array
37+
{
38+
match ($this->filter) { // @phpstan-ignore-line
39+
'week' => $data = Trend::model(User::class)
40+
->between(
41+
start: now()->subWeeks(),
42+
end: now()
43+
)
44+
->perDay()
45+
->count(),
46+
47+
'month' => $data = Trend::model(User::class)
48+
->between(
49+
start: now()->subMonth(),
50+
end: now()
51+
)
52+
->perDay()
53+
->count(),
54+
55+
'3months' => $data = Trend::model(User::class)
56+
->between(
57+
start: now()->subMonths(3),
58+
end: now()
59+
)
60+
->perMonth()
61+
->count(),
62+
};
63+
64+
return [
65+
'datasets' => [
66+
[
67+
'label' => 'Account created',
68+
'data' => $data->map(fn (TrendValue $value) => $value->aggregate), // @phpstan-ignore-line
69+
],
70+
],
71+
'labels' => $data->map(fn (TrendValue $value) => $value->date), // @phpstan-ignore-line
72+
];
73+
}
74+
75+
protected function getType(): string
76+
{
77+
return 'line';
78+
}
79+
}

0 commit comments

Comments
 (0)