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 @@
+
+