Skip to content

Commit a1087ac

Browse files
authored
Filament admin panel (alexjustesen#27)
1 parent 1ded5d2 commit a1087ac

File tree

22 files changed

+4794
-1377
lines changed

22 files changed

+4794
-1377
lines changed

.phpstorm.meta.php

Lines changed: 110 additions & 22 deletions
Large diffs are not rendered by default.

_ide_helper.php

Lines changed: 2090 additions & 317 deletions
Large diffs are not rendered by default.

app/Console/Commands/InstallCommand.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,15 @@ public function handle()
4747

4848
$this->checkAppKey();
4949

50-
$this->line('⏳ Optimizing the cache');
50+
$this->line('⏳ Optimizing the cache...');
5151

5252
Artisan::call('optimize:clear');
5353

5454
$this->line('✅ Optimized cache');
5555

5656
$this->newLine();
5757

58-
$this->line('⏳ Migrating the database');
58+
$this->line('⏳ Migrating the database...');
5959

6060
try {
6161
Artisan::call('migrate:fresh', [
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<?php
2+
3+
namespace App\Filament\Resources;
4+
5+
use App\Filament\Resources\ResultResource\Pages;
6+
use App\Filament\Resources\ResultResource\Widgets\StatsOverview;
7+
use App\Models\Result;
8+
use Filament\Resources\Resource;
9+
use Filament\Resources\Table;
10+
use Filament\Tables;
11+
use Filament\Tables\Columns\TextColumn;
12+
use Filament\Tables\Columns\ViewColumn;
13+
14+
class ResultResource extends Resource
15+
{
16+
protected static ?string $model = Result::class;
17+
18+
protected static ?string $navigationGroup = 'Data';
19+
20+
protected static ?string $navigationIcon = 'heroicon-o-table';
21+
22+
protected static ?string $navigationLabel = 'Speedtest Results';
23+
24+
public static function table(Table $table): Table
25+
{
26+
return $table
27+
->columns([
28+
TextColumn::make('id')
29+
->label('ID'),
30+
ViewColumn::make('download')
31+
->view('tables.columns.bytes-column'),
32+
ViewColumn::make('upload')
33+
->view('tables.columns.bytes-column'),
34+
TextColumn::make('ping'),
35+
TextColumn::make('created_at')
36+
->dateTime(),
37+
])
38+
->filters([
39+
//
40+
])
41+
->actions([
42+
// Tables\Actions\ViewAction::make(),
43+
Tables\Actions\DeleteAction::make(),
44+
])
45+
->bulkActions([
46+
Tables\Actions\DeleteBulkAction::make(),
47+
]);
48+
}
49+
50+
public static function getRelations(): array
51+
{
52+
return [
53+
//
54+
];
55+
}
56+
57+
public static function getPages(): array
58+
{
59+
return [
60+
'index' => Pages\ListResults::route('/'),
61+
];
62+
}
63+
64+
public static function getWidgets(): array
65+
{
66+
return [
67+
StatsOverview::class,
68+
];
69+
}
70+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
namespace App\Filament\Resources\ResultResource\Pages;
4+
5+
use App\Filament\Resources\ResultResource;
6+
use Filament\Resources\Pages\ListRecords;
7+
8+
class ListResults extends ListRecords
9+
{
10+
protected static string $resource = ResultResource::class;
11+
12+
protected function getHeaderWidgets(): array
13+
{
14+
return ResultResource::getWidgets();
15+
}
16+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace App\Filament\Resources\ResultResource\Widgets;
4+
5+
use App\Models\Result;
6+
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
7+
use Filament\Widgets\StatsOverviewWidget\Card;
8+
9+
class StatsOverview extends BaseWidget
10+
{
11+
protected static ?string $pollingInterval = null;
12+
13+
protected function getCards(): array
14+
{
15+
return [
16+
Card::make('Latest download', formatBytes(Result::latest()->first()->download)),
17+
Card::make('Latest upload', formatBytes(Result::latest()->first()->upload)),
18+
Card::make('Latest ping', round(Result::latest()->first()->ping, 2)),
19+
];
20+
}
21+
}

app/Http/Middleware/Authenticate.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Authenticate extends Middleware
1515
protected function redirectTo($request)
1616
{
1717
if (! $request->expectsJson()) {
18-
return route('login');
18+
return route('admin/login');
1919
}
2020
}
2121
}

app/Models/User.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class User extends Authenticatable
2020
protected $fillable = [
2121
'name',
2222
'email',
23+
'email_verified_at',
2324
'password',
2425
];
2526

@@ -41,4 +42,12 @@ class User extends Authenticatable
4142
protected $casts = [
4243
'email_verified_at' => 'datetime',
4344
];
45+
46+
/**
47+
* Any user can access the Filament admin panel.
48+
*/
49+
public function canAccessFilament(): bool
50+
{
51+
return true;
52+
}
4453
}

app/Policies/ResultPolicy.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
namespace App\Policies;
4+
5+
use App\Models\Result;
6+
use App\Models\User;
7+
use Illuminate\Auth\Access\HandlesAuthorization;
8+
9+
class ResultPolicy
10+
{
11+
use HandlesAuthorization;
12+
13+
/**
14+
* Determine whether the user can view any models.
15+
*
16+
* @param \App\Models\User $user
17+
* @return \Illuminate\Auth\Access\Response|bool
18+
*/
19+
public function viewAny(User $user)
20+
{
21+
return true;
22+
}
23+
24+
/**
25+
* Determine whether the user can view the model.
26+
*
27+
* @param \App\Models\User $user
28+
* @param \App\Models\Result $result
29+
* @return \Illuminate\Auth\Access\Response|bool
30+
*/
31+
public function view(User $user, Result $result)
32+
{
33+
return true;
34+
}
35+
36+
/**
37+
* Determine whether the user can create models.
38+
*
39+
* @param \App\Models\User $user
40+
* @return \Illuminate\Auth\Access\Response|bool
41+
*/
42+
public function create(User $user)
43+
{
44+
//
45+
}
46+
47+
/**
48+
* Determine whether the user can update the model.
49+
*
50+
* @param \App\Models\User $user
51+
* @param \App\Models\Result $result
52+
* @return \Illuminate\Auth\Access\Response|bool
53+
*/
54+
public function update(User $user, Result $result)
55+
{
56+
//
57+
}
58+
59+
/**
60+
* Determine whether the user can delete the model.
61+
*
62+
* @param \App\Models\User $user
63+
* @param \App\Models\Result $result
64+
* @return \Illuminate\Auth\Access\Response|bool
65+
*/
66+
public function delete(User $user, Result $result)
67+
{
68+
return true;
69+
}
70+
71+
/**
72+
* Determine whether the user can restore the model.
73+
*
74+
* @param \App\Models\User $user
75+
* @param \App\Models\Result $result
76+
* @return \Illuminate\Auth\Access\Response|bool
77+
*/
78+
public function restore(User $user, Result $result)
79+
{
80+
//
81+
}
82+
83+
/**
84+
* Determine whether the user can permanently delete the model.
85+
*
86+
* @param \App\Models\User $user
87+
* @param \App\Models\Result $result
88+
* @return \Illuminate\Auth\Access\Response|bool
89+
*/
90+
public function forceDelete(User $user, Result $result)
91+
{
92+
//
93+
}
94+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace App\Providers;
4+
5+
use Filament\Facades\Filament;
6+
use Filament\Navigation\NavigationItem;
7+
use Illuminate\Support\ServiceProvider;
8+
9+
class FilamentServiceProvider extends ServiceProvider
10+
{
11+
/**
12+
* Register services.
13+
*
14+
* @return void
15+
*/
16+
public function register()
17+
{
18+
//
19+
}
20+
21+
/**
22+
* Bootstrap services.
23+
*
24+
* @return void
25+
*/
26+
public function boot()
27+
{
28+
Filament::serving(function () {
29+
Filament::registerNavigationGroups([
30+
'Data',
31+
'Links',
32+
]);
33+
34+
Filament::registerNavigationItems([
35+
NavigationItem::make('Documenation')
36+
->url('https://docs.speedtest-tracker.dev/', shouldOpenInNewTab: true)
37+
->icon('heroicon-o-external-link')
38+
->group('Links')
39+
->sort(0),
40+
NavigationItem::make('Donate')
41+
->url('https://github.com/sponsors/alexjustesen', shouldOpenInNewTab: true)
42+
->icon('heroicon-o-external-link')
43+
->group('Links')
44+
->sort(1),
45+
NavigationItem::make('Source Code')
46+
->url('https://github.com/alexjustesen/speedtest-tracker', shouldOpenInNewTab: true)
47+
->icon('heroicon-o-external-link')
48+
->group('Links')
49+
->sort(2),
50+
]);
51+
});
52+
}
53+
}

0 commit comments

Comments
 (0)