mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-08-17 20:52:14 +01:00
Updated dependencies; Added widgets and charts
This commit is contained in:
committed by
Constantin Graf
parent
b5a240cb2f
commit
2862033321
@@ -101,8 +101,7 @@ class UserResource extends Resource
|
||||
->boolean(),
|
||||
Tables\Columns\TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
->toggleable(isToggledHiddenByDefault: true),
|
||||
->sortable(),
|
||||
Tables\Columns\TextColumn::make('updated_at')
|
||||
->dateTime()
|
||||
->sortable()
|
||||
|
||||
42
app/Filament/Widgets/ActiveUserOverview.php
Normal file
42
app/Filament/Widgets/ActiveUserOverview.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\User;
|
||||
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
|
||||
use Filament\Widgets\StatsOverviewWidget\Stat;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ActiveUserOverview extends BaseWidget
|
||||
{
|
||||
protected static ?string $heading = 'A Registrations';
|
||||
|
||||
protected function getCards(): array
|
||||
{
|
||||
$usersCount = User::query()->where('is_placeholder', '=', false)->count();
|
||||
$placeholderUserCount = User::query()->where('is_placeholder', '=', true)->count();
|
||||
$activeInLastWeek = User::query()
|
||||
->where('is_placeholder', '=', false)
|
||||
->whereHas('timeEntries', function (Builder $query) {
|
||||
$query->where('created_at', '>=', now()->subWeek())
|
||||
->orWhere('updated_at', '>=', now()->subWeek());
|
||||
})
|
||||
->count();
|
||||
|
||||
return [
|
||||
Stat::make('Total', $usersCount)
|
||||
->color('primary')
|
||||
->description('Total real users'),
|
||||
|
||||
Stat::make('Placeholder', $placeholderUserCount)
|
||||
->color('danger')
|
||||
->description('Placeholder users'),
|
||||
|
||||
Stat::make('Active', $activeInLastWeek)
|
||||
->color('success')
|
||||
->description('Active users in the last seven days'),
|
||||
];
|
||||
}
|
||||
}
|
||||
73
app/Filament/Widgets/TimeEntriesCreated.php
Normal file
73
app/Filament/Widgets/TimeEntriesCreated.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\TimeEntry;
|
||||
use Filament\Widgets\ChartWidget;
|
||||
use Flowframe\Trend\Trend;
|
||||
use Flowframe\Trend\TrendValue;
|
||||
|
||||
class TimeEntriesCreated extends ChartWidget
|
||||
{
|
||||
protected static ?string $heading = 'Time Entries Created';
|
||||
|
||||
public ?string $filter = 'week';
|
||||
|
||||
protected function getData(): array
|
||||
{
|
||||
$filter = $this->filter;
|
||||
if ($filter === 'week') {
|
||||
$start = now()->subWeek();
|
||||
} elseif ($filter === 'month') {
|
||||
$start = now()->subMonth();
|
||||
} elseif ($filter === 'year') {
|
||||
$start = now()->subYear();
|
||||
} else {
|
||||
$start = now()->subWeek();
|
||||
}
|
||||
$trend = Trend::model(TimeEntry::class)
|
||||
->between(
|
||||
start: $start,
|
||||
end: now(),
|
||||
)
|
||||
->perDay();
|
||||
|
||||
if ($filter === 'week') {
|
||||
$trend->perDay();
|
||||
} elseif ($filter === 'month') {
|
||||
$trend->perDay();
|
||||
} elseif ($filter === 'year') {
|
||||
$trend->perMonth();
|
||||
} else {
|
||||
$trend->perDay();
|
||||
}
|
||||
|
||||
$data = $trend->count();
|
||||
|
||||
return [
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => self::$heading,
|
||||
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
|
||||
],
|
||||
],
|
||||
'labels' => $data->map(fn (TrendValue $value) => $value->date),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getFilters(): ?array
|
||||
{
|
||||
return [
|
||||
'week' => 'Last week',
|
||||
'month' => 'Last month',
|
||||
'year' => 'Last year',
|
||||
];
|
||||
}
|
||||
|
||||
protected function getType(): string
|
||||
{
|
||||
return 'line';
|
||||
}
|
||||
}
|
||||
76
app/Filament/Widgets/UserRegistrations.php
Normal file
76
app/Filament/Widgets/UserRegistrations.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\User;
|
||||
use Filament\Widgets\ChartWidget;
|
||||
use Flowframe\Trend\Trend;
|
||||
use Flowframe\Trend\TrendValue;
|
||||
|
||||
class UserRegistrations extends ChartWidget
|
||||
{
|
||||
protected static ?string $heading = 'User Registrations';
|
||||
|
||||
public ?string $filter = 'week';
|
||||
|
||||
protected function getData(): array
|
||||
{
|
||||
$filter = $this->filter;
|
||||
if ($filter === 'week') {
|
||||
$start = now()->subWeek();
|
||||
} elseif ($filter === 'month') {
|
||||
$start = now()->subMonth();
|
||||
} elseif ($filter === 'year') {
|
||||
$start = now()->subYear();
|
||||
} else {
|
||||
$start = now()->subWeek();
|
||||
}
|
||||
$trend = Trend::query(
|
||||
User::query()
|
||||
->where('is_placeholder', '=', false)
|
||||
)
|
||||
->between(
|
||||
start: $start,
|
||||
end: now(),
|
||||
)
|
||||
->perDay();
|
||||
|
||||
if ($filter === 'week') {
|
||||
$trend->perDay();
|
||||
} elseif ($filter === 'month') {
|
||||
$trend->perDay();
|
||||
} elseif ($filter === 'year') {
|
||||
$trend->perMonth();
|
||||
} else {
|
||||
$trend->perDay();
|
||||
}
|
||||
|
||||
$data = $trend->count();
|
||||
|
||||
return [
|
||||
'datasets' => [
|
||||
[
|
||||
'label' => self::$heading,
|
||||
'data' => $data->map(fn (TrendValue $value) => $value->aggregate),
|
||||
],
|
||||
],
|
||||
'labels' => $data->map(fn (TrendValue $value) => $value->date),
|
||||
];
|
||||
}
|
||||
|
||||
protected function getFilters(): ?array
|
||||
{
|
||||
return [
|
||||
'week' => 'Last week',
|
||||
'month' => 'Last month',
|
||||
'year' => 'Last year',
|
||||
];
|
||||
}
|
||||
|
||||
protected function getType(): string
|
||||
{
|
||||
return 'line';
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,9 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Providers\Filament;
|
||||
|
||||
use App\Filament\Widgets\ActiveUserOverview;
|
||||
use App\Filament\Widgets\TimeEntriesCreated;
|
||||
use App\Filament\Widgets\UserRegistrations;
|
||||
use Filament\Http\Middleware\Authenticate;
|
||||
use Filament\Http\Middleware\DisableBladeIconComponents;
|
||||
use Filament\Http\Middleware\DispatchServingFilamentEvent;
|
||||
@@ -12,7 +15,6 @@ use Filament\Pages;
|
||||
use Filament\Panel;
|
||||
use Filament\PanelProvider;
|
||||
use Filament\Support\Colors\Color;
|
||||
use Filament\Widgets;
|
||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies;
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
||||
@@ -41,7 +43,9 @@ class AdminPanelProvider extends PanelProvider
|
||||
])
|
||||
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\\Filament\\Widgets')
|
||||
->widgets([
|
||||
Widgets\AccountWidget::class,
|
||||
ActiveUserOverview::class,
|
||||
UserRegistrations::class,
|
||||
TimeEntriesCreated::class,
|
||||
])
|
||||
->plugins([
|
||||
EnvironmentIndicatorPlugin::make()
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"brick/money": "^0.8.1",
|
||||
"dedoc/scramble": "dev-main",
|
||||
"filament/filament": "^3.2",
|
||||
"flowframe/laravel-trend": "^0.2.0",
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"inertiajs/inertia-laravel": "^1.0",
|
||||
"korridor/laravel-computed-attributes": "^3.1",
|
||||
@@ -30,6 +31,7 @@
|
||||
"wikimedia/composer-merge-plugin": "^2.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-ide-helper": "^3.0",
|
||||
"brianium/paratest": "^7.3",
|
||||
"fakerphp/faker": "^1.9.1",
|
||||
"fumeapp/modeltyper": "^2.2",
|
||||
@@ -93,6 +95,10 @@
|
||||
],
|
||||
"fix": [
|
||||
"@php pint"
|
||||
],
|
||||
"ide-helper": [
|
||||
"@php artisan ide-helper:generate",
|
||||
"@php artisan ide-helper:meta"
|
||||
]
|
||||
},
|
||||
"extra": {
|
||||
|
||||
849
composer.lock
generated
849
composer.lock
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user