feat: tambah seeder roles & super_admin, widget dashboard stats
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Filament\Widgets;
|
||||
|
||||
use App\Models\Activity;
|
||||
use App\Models\CashRecord;
|
||||
use App\Models\User;
|
||||
use Filament\Widgets\StatsOverviewWidget;
|
||||
use Filament\Widgets\StatsOverviewWidget\Stat;
|
||||
|
||||
class StatsOverview extends StatsOverviewWidget
|
||||
{
|
||||
protected function getStats(): array
|
||||
{
|
||||
$totalKas = CashRecord::join('cash_categories', 'cash_records.category_id', '=', 'cash_categories.id')
|
||||
->selectRaw("SUM(CASE WHEN cash_categories.name = 'pemasukan' THEN amount ELSE -amount END) as saldo")
|
||||
->value('saldo') ?? 0;
|
||||
|
||||
return [
|
||||
Stat::make('Anggota Aktif', User::where('status', 'aktif')->count())
|
||||
->icon('heroicon-o-users')
|
||||
->color('success'),
|
||||
|
||||
Stat::make('Total Kas', 'Rp ' . number_format($totalKas, 0, ',', '.'))
|
||||
->icon('heroicon-o-banknotes')
|
||||
->color($totalKas >= 0 ? 'success' : 'danger'),
|
||||
|
||||
Stat::make('Kegiatan Berjalan', Activity::where('status', 'approved')
|
||||
->whereNull('executed_at')->count())
|
||||
->icon('heroicon-o-calendar-days')
|
||||
->color('info'),
|
||||
|
||||
Stat::make('Kegiatan Pending', Activity::where('status', 'pending')->count())
|
||||
->icon('heroicon-o-clock')
|
||||
->color('warning'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\Activity;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class ActivityPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:Activity');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, Activity $activity): bool
|
||||
{
|
||||
return $authUser->can('View:Activity');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:Activity');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, Activity $activity): bool
|
||||
{
|
||||
return $authUser->can('Update:Activity');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, Activity $activity): bool
|
||||
{
|
||||
return $authUser->can('Delete:Activity');
|
||||
}
|
||||
|
||||
public function deleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('DeleteAny:Activity');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, Activity $activity): bool
|
||||
{
|
||||
return $authUser->can('Restore:Activity');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, Activity $activity): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:Activity');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:Activity');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:Activity');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, Activity $activity): bool
|
||||
{
|
||||
return $authUser->can('Replicate:Activity');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:Activity');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\Approval;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class ApprovalPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:Approval');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, Approval $approval): bool
|
||||
{
|
||||
return $authUser->can('View:Approval');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:Approval');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, Approval $approval): bool
|
||||
{
|
||||
return $authUser->can('Update:Approval');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, Approval $approval): bool
|
||||
{
|
||||
return $authUser->can('Delete:Approval');
|
||||
}
|
||||
|
||||
public function deleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('DeleteAny:Approval');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, Approval $approval): bool
|
||||
{
|
||||
return $authUser->can('Restore:Approval');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, Approval $approval): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:Approval');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:Approval');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:Approval');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, Approval $approval): bool
|
||||
{
|
||||
return $authUser->can('Replicate:Approval');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:Approval');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\Audit;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class AuditPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:Audit');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, Audit $audit): bool
|
||||
{
|
||||
return $authUser->can('View:Audit');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:Audit');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, Audit $audit): bool
|
||||
{
|
||||
return $authUser->can('Update:Audit');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, Audit $audit): bool
|
||||
{
|
||||
return $authUser->can('Delete:Audit');
|
||||
}
|
||||
|
||||
public function deleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('DeleteAny:Audit');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, Audit $audit): bool
|
||||
{
|
||||
return $authUser->can('Restore:Audit');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, Audit $audit): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:Audit');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:Audit');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:Audit');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, Audit $audit): bool
|
||||
{
|
||||
return $authUser->can('Replicate:Audit');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:Audit');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\CashCategory;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class CashCategoryPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:CashCategory');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, CashCategory $cashCategory): bool
|
||||
{
|
||||
return $authUser->can('View:CashCategory');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:CashCategory');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, CashCategory $cashCategory): bool
|
||||
{
|
||||
return $authUser->can('Update:CashCategory');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, CashCategory $cashCategory): bool
|
||||
{
|
||||
return $authUser->can('Delete:CashCategory');
|
||||
}
|
||||
|
||||
public function deleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('DeleteAny:CashCategory');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, CashCategory $cashCategory): bool
|
||||
{
|
||||
return $authUser->can('Restore:CashCategory');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, CashCategory $cashCategory): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:CashCategory');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:CashCategory');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:CashCategory');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, CashCategory $cashCategory): bool
|
||||
{
|
||||
return $authUser->can('Replicate:CashCategory');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:CashCategory');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\CashRecord;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class CashRecordPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:CashRecord');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, CashRecord $cashRecord): bool
|
||||
{
|
||||
return $authUser->can('View:CashRecord');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:CashRecord');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, CashRecord $cashRecord): bool
|
||||
{
|
||||
return $authUser->can('Update:CashRecord');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, CashRecord $cashRecord): bool
|
||||
{
|
||||
return $authUser->can('Delete:CashRecord');
|
||||
}
|
||||
|
||||
public function deleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('DeleteAny:CashRecord');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, CashRecord $cashRecord): bool
|
||||
{
|
||||
return $authUser->can('Restore:CashRecord');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, CashRecord $cashRecord): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:CashRecord');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:CashRecord');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:CashRecord');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, CashRecord $cashRecord): bool
|
||||
{
|
||||
return $authUser->can('Replicate:CashRecord');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:CashRecord');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\Division;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class DivisionPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:Division');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, Division $division): bool
|
||||
{
|
||||
return $authUser->can('View:Division');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:Division');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, Division $division): bool
|
||||
{
|
||||
return $authUser->can('Update:Division');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, Division $division): bool
|
||||
{
|
||||
return $authUser->can('Delete:Division');
|
||||
}
|
||||
|
||||
public function deleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('DeleteAny:Division');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, Division $division): bool
|
||||
{
|
||||
return $authUser->can('Restore:Division');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, Division $division): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:Division');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:Division');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:Division');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, Division $division): bool
|
||||
{
|
||||
return $authUser->can('Replicate:Division');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:Division');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class UserPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:User');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('View:User');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:User');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Update:User');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Delete:User');
|
||||
}
|
||||
|
||||
public function deleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('DeleteAny:User');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Restore:User');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:User');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:User');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:User');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Replicate:User');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:User');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Foundation\Auth\User as AuthUser;
|
||||
use App\Models\Vote;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
|
||||
class VotePolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
public function viewAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ViewAny:Vote');
|
||||
}
|
||||
|
||||
public function view(AuthUser $authUser, Vote $vote): bool
|
||||
{
|
||||
return $authUser->can('View:Vote');
|
||||
}
|
||||
|
||||
public function create(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Create:Vote');
|
||||
}
|
||||
|
||||
public function update(AuthUser $authUser, Vote $vote): bool
|
||||
{
|
||||
return $authUser->can('Update:Vote');
|
||||
}
|
||||
|
||||
public function delete(AuthUser $authUser, Vote $vote): bool
|
||||
{
|
||||
return $authUser->can('Delete:Vote');
|
||||
}
|
||||
|
||||
public function deleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('DeleteAny:Vote');
|
||||
}
|
||||
|
||||
public function restore(AuthUser $authUser, Vote $vote): bool
|
||||
{
|
||||
return $authUser->can('Restore:Vote');
|
||||
}
|
||||
|
||||
public function forceDelete(AuthUser $authUser, Vote $vote): bool
|
||||
{
|
||||
return $authUser->can('ForceDelete:Vote');
|
||||
}
|
||||
|
||||
public function forceDeleteAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('ForceDeleteAny:Vote');
|
||||
}
|
||||
|
||||
public function restoreAny(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('RestoreAny:Vote');
|
||||
}
|
||||
|
||||
public function replicate(AuthUser $authUser, Vote $vote): bool
|
||||
{
|
||||
return $authUser->can('Replicate:Vote');
|
||||
}
|
||||
|
||||
public function reorder(AuthUser $authUser): bool
|
||||
{
|
||||
return $authUser->can('Reorder:Vote');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,7 +40,7 @@ class AdminPanelProvider extends PanelProvider
|
||||
->discoverWidgets(in: app_path('Filament/Widgets'), for: 'App\Filament\Widgets')
|
||||
->widgets([
|
||||
AccountWidget::class,
|
||||
FilamentInfoWidget::class,
|
||||
\App\Filament\Widgets\StatsOverview::class,
|
||||
])
|
||||
->middleware([
|
||||
EncryptCookies::class,
|
||||
|
||||
@@ -2,24 +2,14 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
{
|
||||
use WithoutModelEvents;
|
||||
|
||||
/**
|
||||
* Seed the application's database.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// User::factory(10)->create();
|
||||
|
||||
User::factory()->create([
|
||||
'name' => 'Test User',
|
||||
'email' => 'test@example.com',
|
||||
$this->call([
|
||||
RolesAndPermissionsSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
class RolesAndPermissionsSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions();
|
||||
|
||||
$roles = ['super_admin', 'ketua', 'bendahara', 'pengurus', 'anggota', 'auditor'];
|
||||
|
||||
foreach ($roles as $role) {
|
||||
Role::firstOrCreate(['name' => $role, 'guard_name' => 'web']);
|
||||
}
|
||||
|
||||
// super_admin mendapat semua permission via Shield config
|
||||
$superAdmin = User::firstOrCreate(
|
||||
['email' => 'admin@persegi.id'],
|
||||
[
|
||||
'name' => 'Super Admin',
|
||||
'password' => bcrypt('password'),
|
||||
'phone' => '08123456789',
|
||||
'status' => 'aktif',
|
||||
]
|
||||
);
|
||||
|
||||
$superAdmin->assignRole('super_admin');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user