Skip to content

Commit 970a351

Browse files
authored
feat:(LAR-171) BO add Stat in dashboard (#306)
2 parents 94f0a7c + 2640c3c commit 970a351

19 files changed

+485
-424
lines changed
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 = 'Article';
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 Article', 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 des articles postés')),
41+
42+
Stat::make(
43+
'Article récent publié',
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 des articles Postés de la semaine'),
64+
];
65+
}
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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 = 'Article le plus aimé';
14+
15+
protected static ?string $maxHeight = '200px';
16+
17+
protected int|string|array $columnSpan = 'full';
18+
19+
protected int $titleLength = 30;
20+
21+
protected function getData(): array
22+
{
23+
$articles = Article::published()
24+
->popular()
25+
->get();
26+
27+
return [
28+
'datasets' => [
29+
[
30+
'label' => 'Total aimé',
31+
'data' => $articles->pluck('reactions_count')->toArray(),
32+
],
33+
],
34+
'labels' => $articles->pluck('title')
35+
->map(fn ($title) => Str::limit($title, $this->titleLength, '...'))
36+
->toArray(),
37+
];
38+
}
39+
40+
protected function getType(): string
41+
{
42+
return 'bar';
43+
}
44+
45+
protected function getOptions(): array
46+
{
47+
return [
48+
'scales' => [
49+
'y' => [
50+
'beginAtZero' => true,
51+
],
52+
],
53+
];
54+
}
55+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
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 = 'Article le plus vu cette semaine';
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+
->get();
29+
30+
return [
31+
'datasets' => [
32+
[
33+
'label' => 'Article le plus vu',
34+
'data' => $articles->pluck('views_count')->toArray(),
35+
],
36+
],
37+
'labels' => $articles->pluck('title')
38+
->map(fn ($title) => Str::limit($title, $this->titleLength, '...'))
39+
->toArray(),
40+
];
41+
}
42+
43+
protected function getType(): string
44+
{
45+
return 'bar';
46+
}
47+
}
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 = 'Les utilisateurs les plus actifs cette semaine';
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 des activités',
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+
}
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 = 'Création de compte';
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' => 'Compte créé',
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)