Skip to content

Commit 67b1863

Browse files
committed
wip
1 parent a23372d commit 67b1863

8 files changed

Lines changed: 195 additions & 12 deletions

File tree

composer.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"require": {
2323
"php": "^8.1",
2424
"filament/filament": "^3.0",
25-
"spatie/laravel-package-tools": "^1.15.0"
25+
"spatie/laravel-package-tools": "^1.15.0",
26+
"spatie/laravel-permission": "*"
2627
},
2728
"require-dev": {
2829
"laravel/pint": "^1.0",
@@ -77,4 +78,4 @@
7778
},
7879
"minimum-stability": "dev",
7980
"prefer-stable": true
80-
}
81+
}

config/backstage/user-management.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
'eloquent' => [
99
'users' => [
1010
'model' => \App\Models\User::class,
11+
'observer' => \Backstage\UserManagement\Observers\UserObserver::class
1112
],
1213

1314
'user_logins' => [
1415
'model' => UserLogin::class,
1516
'table' => 'user_logins',
16-
'primary_key' => 'id',
1717
],
1818
],
1919

src/Exports/UserExporter.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace Backstage\UserManagement\Exports;
4+
5+
use Filament\Actions\Exports\Exporter;
6+
use Filament\Actions\Exports\ExportColumn;
7+
use Filament\Actions\Exports\Models\Export;
8+
9+
class UserExporter extends Exporter
10+
{
11+
public static function getModel(): string
12+
{
13+
return config('backstage.user-management.eloquent.users.model', \App\Models\User::class);
14+
}
15+
16+
public static function getColumns(): array
17+
{
18+
return [
19+
ExportColumn::make('name')
20+
->label(__('Name')),
21+
22+
ExportColumn::make('email')
23+
->label(__('Email')),
24+
25+
ExportColumn::make('password')
26+
->label(__('Password')),
27+
28+
ExportColumn::make('email_verified_at')
29+
->label(__('Email Verified At')),
30+
31+
ExportColumn::make('created_at')
32+
->label(__('Created At')),
33+
34+
ExportColumn::make('updated_at')
35+
->label(__('Updated At')),
36+
];
37+
}
38+
39+
public static function getCompletedNotificationBody(Export $export): string
40+
{
41+
$body = 'Your user export has completed and ' . number_format($export->successful_rows) . ' ' . str('row')->plural($export->successful_rows) . ' exported.';
42+
43+
if ($failedRowsCount = $export->getFailedRowsCount()) {
44+
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to export.';
45+
}
46+
47+
return $body;
48+
}
49+
}

src/Imports/UserImporter.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
namespace Backstage\UserManagement\Imports;
4+
5+
use Filament\Actions\Exports\Exporter;
6+
use Filament\Actions\Exports\ExportColumn;
7+
use Filament\Actions\Exports\Models\Export;
8+
use Filament\Actions\Imports\ImportColumn;
9+
use Filament\Actions\Imports\Importer;
10+
use Filament\Actions\Imports\Models\Import;
11+
use App\Models\User;
12+
13+
14+
class UserImporter extends Importer
15+
{
16+
public static function getModel(): string
17+
{
18+
return config('backstage.user-management.eloquent.users.model', \App\Models\User::class);
19+
}
20+
21+
public static function getColumns(): array
22+
{
23+
return [
24+
ImportColumn::make('name')
25+
->label(__('Name'))
26+
->requiredMapping()
27+
->rules(['required', 'max:255']),
28+
29+
ImportColumn::make('email')
30+
->label(__('Email'))
31+
->requiredMapping()
32+
->rules(['required', 'email', 'max:255']),
33+
34+
ImportColumn::make('email_verified_at')
35+
->label(__('Email Verified At'))
36+
->rules(['email', 'datetime']),
37+
38+
ImportColumn::make('password')
39+
->label(__('Password'))
40+
->requiredMapping()
41+
->rules(['required', 'max:255']),
42+
43+
ImportColumn::make('created_at')
44+
->label(__('Created At'))
45+
->rules(['date']),
46+
ImportColumn::make('updated_at')
47+
->label(__('Updated At'))
48+
->rules(['date']),
49+
];
50+
}
51+
52+
public function resolveRecord(): ?User
53+
{
54+
// return User::firstOrNew([
55+
// // Update existing records, matching them by `$this->data['column_name']`
56+
// 'email' => $this->data['email'],
57+
// ]);
58+
59+
return new User();
60+
}
61+
62+
public static function getCompletedNotificationBody(Import $import): string
63+
{
64+
$body = 'Your user import has completed and ' . number_format($import->successful_rows) . ' ' . str('row')->plural($import->successful_rows) . ' imported.';
65+
66+
if ($failedRowsCount = $import->getFailedRowsCount()) {
67+
$body .= ' ' . number_format($failedRowsCount) . ' ' . str('row')->plural($failedRowsCount) . ' failed to import.';
68+
}
69+
70+
return $body;
71+
}
72+
}

src/Observers/UserObserver.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
namespace Backstage\UserManagement\Observers;
4+
5+
use Filament\Facades\Filament;
6+
use Filament\Notifications\Auth\VerifyEmail;
7+
8+
class UserObserver
9+
{
10+
/**
11+
* Handle the User "created" event.
12+
*
13+
* @param \Backstage\UserManagement\Models\User $user
14+
* @return void
15+
*/
16+
public function created($user)
17+
{
18+
$notification = new VerifyEmail;
19+
$notification->url = Filament::getVerifyEmailUrl($user);
20+
$user->notify($notification);
21+
}
22+
23+
/**
24+
* Handle the User "updated" event.
25+
*
26+
* @param \Backstage\UserManagement\Models\User $user
27+
* @return void
28+
*/
29+
public function updated($user)
30+
{
31+
// Logic to handle after a user is updated
32+
}
33+
34+
/**
35+
* Handle the User "deleted" event.
36+
*
37+
* @param \Backstage\UserManagement\Models\User $user
38+
* @return void
39+
*/
40+
public function deleted($user)
41+
{
42+
// Logic to handle after a user is deleted
43+
}
44+
}

src/Resources/UserResource.php

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@
22

33
namespace Backstage\UserManagement\Resources;
44

5-
use Backstage\UserManagement\Resources\UserResource\Pages;
6-
use Backstage\UserManagement\Widgets\StatsOverviewWidget;
7-
use Filament\Facades\Filament;
85
use Filament\Forms;
9-
use Filament\Forms\Form;
10-
use Filament\Resources\Resource;
116
use Filament\Tables;
7+
use Filament\Forms\Form;
128
use Filament\Tables\Table;
9+
use Filament\Facades\Filament;
10+
use Filament\Resources\Resource;
1311
use Illuminate\Support\Facades\Hash;
12+
use Filament\Tables\Actions\ExportAction;
13+
use Filament\Tables\Actions\ImportAction;
1414
use Illuminate\Validation\Rules\Password;
15+
use Backstage\UserManagement\Exports\UserExporter;
16+
use Backstage\UserManagement\Imports\UserImporter;
17+
use Backstage\UserManagement\Widgets\StatsOverviewWidget;
18+
use Backstage\UserManagement\Resources\UserResource\Pages;
1519

1620
class UserResource extends Resource
1721
{
@@ -42,15 +46,23 @@ public static function form(Form $form): Form
4246
->revealable(Filament::arePasswordsRevealable())
4347
->rule(Password::default())
4448
->autocomplete('new-password')
45-
->dehydrated(fn ($state): bool => filled($state))
46-
->dehydrateStateUsing(fn ($state): string => Hash::make($state))
49+
->dehydrated(fn($state): bool => filled($state))
50+
->dehydrateStateUsing(fn($state): string => Hash::make($state))
4751
->live(debounce: 500),
4852
]);
4953
}
5054

5155
public static function table(Table $table): Table
5256
{
5357
return $table
58+
->headerActions([
59+
Tables\Actions\ImportAction::make('import')
60+
->importer(UserImporter::class)
61+
->color('primary'),
62+
63+
Tables\Actions\ExportAction::make()
64+
->exporter(UserExporter::class),
65+
])
5466
->columns([
5567
Tables\Columns\TextColumn::make('name')
5668
->searchable(),

src/Resources/UserResource/Pages/ViewUser.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Backstage\UserManagement\Resources\UserResource;
66
use Filament\Actions;
7+
use Filament\Facades\Filament;
78
use Filament\Notifications\Auth\VerifyEmail;
89
use Filament\Resources\Pages\ViewRecord;
910
use Illuminate\Contracts\Support\Htmlable;
@@ -18,11 +19,11 @@ protected function getHeaderActions(): array
1819
{
1920
return [
2021
Actions\Action::make('send_verify_user_email')
21-
->visible(fn ($record) => $record->isVerified() === false)
22+
->visible(fn($record) => $record->isVerified() === false)
2223
->label(__('Send Verification Email'))
2324
->action(function ($record) {
2425
$notification = new VerifyEmail;
25-
$notification->url = filament()->getVerifyEmailUrl($record);
26+
$notification->url = Filament::getVerifyEmailUrl($record);
2627
$record->notify($notification);
2728
}),
2829

src/UserManagementServiceProvider.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ public function packageBooted(): void
9999
Event::listen(Login::class, UserLogin::class);
100100
Event::listen(Logout::class, UserLogout::class);
101101
Event::listen(WebTrafficDetected::class, RecordUserMovements::class);
102+
103+
config('backstage.user-management.users.model', \App\Models\User::class)::observe(
104+
config('backstage.user-management.eloquent.users.observer', \Backstage\UserManagement\Observers\UserObserver::class)
105+
);
102106
}
103107

104108
protected function getAssetPackageName(): ?string

0 commit comments

Comments
 (0)