diff --git a/app/Filament/Resources/Users/Pages/EditUser.php b/app/Filament/Resources/Users/Pages/EditUser.php index 4c7c132..36ccc8e 100644 --- a/app/Filament/Resources/Users/Pages/EditUser.php +++ b/app/Filament/Resources/Users/Pages/EditUser.php @@ -5,6 +5,7 @@ namespace App\Filament\Resources\Users\Pages; use App\Filament\Resources\Users\UserResource; use Filament\Actions\DeleteAction; use Filament\Resources\Pages\EditRecord; +use STS\FilamentImpersonate\Actions\Impersonate; class EditUser extends EditRecord { @@ -13,6 +14,7 @@ class EditUser extends EditRecord protected function getHeaderActions(): array { return [ + Impersonate::make()->record($this->getRecord()), DeleteAction::make(), ]; } diff --git a/app/Filament/Resources/Users/Tables/UsersTable.php b/app/Filament/Resources/Users/Tables/UsersTable.php index c06dec2..b28f59c 100644 --- a/app/Filament/Resources/Users/Tables/UsersTable.php +++ b/app/Filament/Resources/Users/Tables/UsersTable.php @@ -9,6 +9,7 @@ use Filament\Actions\EditAction; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Filters\SelectFilter; use Filament\Tables\Table; +use STS\FilamentImpersonate\Actions\Impersonate; class UsersTable { @@ -30,7 +31,7 @@ class UsersTable SelectFilter::make('division_id')->label('Divisi') ->options(Division::pluck('name', 'id')), ]) - ->recordActions([EditAction::make()]) + ->recordActions([EditAction::make(), Impersonate::make()]) ->toolbarActions([BulkActionGroup::make([DeleteBulkAction::make()])]); } } diff --git a/app/Models/User.php b/app/Models/User.php index 09381ad..50b10dd 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -50,4 +50,14 @@ class User extends Authenticatable { return $this->hasMany(CashRecord::class, 'created_by'); } + + public function canImpersonate(): bool + { + return $this->hasRole('super_admin'); + } + + public function canBeImpersonated(): bool + { + return ! $this->hasRole('super_admin'); + } } diff --git a/composer.json b/composer.json index 466a49d..515e1da 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,8 @@ "bezhansalleh/filament-shield": "^4.2", "filament/filament": "^5.0", "laravel/framework": "^13.0", - "laravel/tinker": "^3.0" + "laravel/tinker": "^3.0", + "stechstudio/filament-impersonate": "^5.1" }, "require-dev": { "fakerphp/faker": "^1.23", diff --git a/composer.lock b/composer.lock index 6ffb00e..0374d3d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "7a9a4aed22d7f07e62ca1d857d07028d", + "content-hash": "ce9545832c2804984d01bf019a61cec1", "packages": [ { "name": "bezhansalleh/filament-plugin-essentials", @@ -5392,6 +5392,52 @@ ], "time": "2026-02-01T09:30:04+00:00" }, + { + "name": "stechstudio/filament-impersonate", + "version": "v5.1.0", + "source": { + "type": "git", + "url": "https://github.com/stechstudio/filament-impersonate.git", + "reference": "c5d5b8b5150fad02db18c4479eafb9dc2f537ffc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/stechstudio/filament-impersonate/zipball/c5d5b8b5150fad02db18c4479eafb9dc2f537ffc", + "reference": "c5d5b8b5150fad02db18c4479eafb9dc2f537ffc", + "shasum": "" + }, + "require": { + "filament/filament": "^4.0|^5.0" + }, + "require-dev": { + "orchestra/testbench": "^10.0", + "pestphp/pest": "^3.0", + "pestphp/pest-plugin-laravel": "^3.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "STS\\FilamentImpersonate\\FilamentImpersonateServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "STS\\FilamentImpersonate\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A Filament package to impersonate your users.", + "support": { + "issues": "https://github.com/stechstudio/filament-impersonate/issues", + "source": "https://github.com/stechstudio/filament-impersonate/tree/v5.1.0" + }, + "time": "2026-02-22T15:57:37+00:00" + }, { "name": "symfony/clock", "version": "v8.0.8", diff --git a/config/filament-impersonate.php b/config/filament-impersonate.php new file mode 100644 index 0000000..f87fa46 --- /dev/null +++ b/config/filament-impersonate.php @@ -0,0 +1,40 @@ + env('FILAMENT_IMPERSONATE_REDIRECT', '/'), + + // We wire up a route for the "leave" button. You can change the middleware stack here if needed. + 'leave_middleware' => env('FILAMENT_IMPERSONATE_LEAVE_MIDDLEWARE', 'web'), + + // Add a prefix for routes - Useful for apps installed with a subdirectory + 'route_prefix' => env('FILAMENT_IMPERSONATE_ROUTE_PREFIX', null), + + 'allow_soft_deleted' => env('FILAMENT_IMPERSONATE_ALLOW_SOFT_DELETED', false), + + 'banner' => [ + // Available hooks: https://filamentphp.com/docs/3.x/support/render-hooks#available-render-hooks + 'render_hook' => env('FILAMENT_IMPERSONATE_BANNER_RENDER_HOOK', 'panels::body.start'), + + // Currently supports 'dark', 'light' and 'auto'. + 'style' => env('FILAMENT_IMPERSONATE_BANNER_STYLE', 'dark'), + + // Turn this off if you want `absolute` positioning, so the banner scrolls out of view + 'fixed' => env('FILAMENT_IMPERSONATE_BANNER_FIXED', true), + + // Currently supports 'top' and 'bottom'. + 'position' => env('FILAMENT_IMPERSONATE_BANNER_POSITION', 'top'), + + 'styles' => [ + 'light' => [ + 'text' => '#1f2937', + 'background' => '#f3f4f6', + 'border' => '#e8eaec', + ], + 'dark' => [ + 'text' => '#f3f4f6', + 'background' => '#1f2937', + 'border' => '#374151', + ], + ] + ], +]; diff --git a/resources/views/public/layout.blade.php b/resources/views/public/layout.blade.php index 09b4d4d..997547d 100644 --- a/resources/views/public/layout.blade.php +++ b/resources/views/public/layout.blade.php @@ -58,6 +58,9 @@ + + +
@yield('content')