feat: Implement a new Analytic dashboard page with several data visualization widgets, add Company Status Chart, and expand Filament dashboard color options.
This commit is contained in:
parent
3dd098759c
commit
c493d066f4
114
app/Filament/Pages/Analytic.php
Normal file
114
app/Filament/Pages/Analytic.php
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
|
use App\Enums\RoleEnum;
|
||||||
|
use App\Filament\Widgets\CooperationStatusChart;
|
||||||
|
use App\Filament\Widgets\IssueLocationChart;
|
||||||
|
use App\Filament\Widgets\JournalistRegistrationChart;
|
||||||
|
use App\Filament\Widgets\MediaClassificationChart;
|
||||||
|
use App\Filament\Widgets\MediaCooperationRankingChart;
|
||||||
|
use App\Filament\Widgets\MediaRegistrationChart;
|
||||||
|
use App\Filament\Widgets\MediaTypeChart;
|
||||||
|
use App\Filament\Widgets\PopularNewsChart;
|
||||||
|
use App\Filament\Widgets\TaskRealizationChart;
|
||||||
|
use App\Filament\Widgets\TopMediaJournalistChart;
|
||||||
|
use App\Filament\Widgets\VerificationPerformanceChart;
|
||||||
|
use App\Filament\Widgets\VisitorTrafficChart;
|
||||||
|
use BackedEnum;
|
||||||
|
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
|
||||||
|
use Filament\Actions\Action;
|
||||||
|
use Filament\Forms\Components\DatePicker;
|
||||||
|
use Filament\Pages\Dashboard as BaseDashboard;
|
||||||
|
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
||||||
|
use Filament\Schemas\Components\Fieldset;
|
||||||
|
use Filament\Schemas\Schema;
|
||||||
|
use Filament\Support\Icons\Heroicon;
|
||||||
|
|
||||||
|
class Analytic extends BaseDashboard
|
||||||
|
{
|
||||||
|
use HasFiltersForm, HasPageShield;
|
||||||
|
|
||||||
|
protected static string $routePath = '/analytic';
|
||||||
|
|
||||||
|
protected static ?string $slug = 'analytic';
|
||||||
|
|
||||||
|
protected static ?string $title = 'Statistik';
|
||||||
|
|
||||||
|
protected static ?string $navigationLabel = 'Statistik';
|
||||||
|
|
||||||
|
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedChartBar;
|
||||||
|
|
||||||
|
protected static ?int $navigationSort = 2;
|
||||||
|
|
||||||
|
protected static ?string $pollingInterval = null;
|
||||||
|
|
||||||
|
public function getColumns(): int|array
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filtersForm(Schema $schema): Schema
|
||||||
|
{
|
||||||
|
return $schema
|
||||||
|
->schema([
|
||||||
|
Fieldset::make('Filter')
|
||||||
|
->schema([
|
||||||
|
DatePicker::make('startDate')
|
||||||
|
->label('Tanggal Mulai')
|
||||||
|
->placeholder('Pilih tanggal mulai')
|
||||||
|
->native(false)
|
||||||
|
->displayFormat('l, d F Y'),
|
||||||
|
|
||||||
|
DatePicker::make('endDate')
|
||||||
|
->label('Tanggal Selesai')
|
||||||
|
->placeholder('Pilih tanggal selesai')
|
||||||
|
->native(false)
|
||||||
|
->displayFormat('l, d F Y'),
|
||||||
|
])
|
||||||
|
->columns(2)
|
||||||
|
->columnSpanFull()
|
||||||
|
->visible(fn () => auth()->user()->hasRole(RoleEnum::DEVELOPER->value) || auth()->user()->hasRole(RoleEnum::ADMINISTRATOR->value)),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getHeaderActions(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
Action::make('reset')
|
||||||
|
->label('Reset Filter')
|
||||||
|
->icon(Heroicon::OutlinedXMark)
|
||||||
|
->color('danger')
|
||||||
|
->action(fn () => $this->resetFilters())
|
||||||
|
->visible(fn () => ! empty($this->filters['startDate']) || ! empty($this->filters['endDate'])),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resetFilters(): void
|
||||||
|
{
|
||||||
|
$this->filters['startDate'] = null;
|
||||||
|
$this->filters['endDate'] = null;
|
||||||
|
|
||||||
|
if (method_exists($this, 'getFiltersSessionKey')) {
|
||||||
|
session()->forget($this->getFiltersSessionKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getWidgets(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
CooperationStatusChart::class,
|
||||||
|
IssueLocationChart::class,
|
||||||
|
JournalistRegistrationChart::class,
|
||||||
|
MediaClassificationChart::class,
|
||||||
|
MediaCooperationRankingChart::class,
|
||||||
|
MediaRegistrationChart::class,
|
||||||
|
MediaTypeChart::class,
|
||||||
|
PopularNewsChart::class,
|
||||||
|
TaskRealizationChart::class,
|
||||||
|
TopMediaJournalistChart::class,
|
||||||
|
VerificationPerformanceChart::class,
|
||||||
|
VisitorTrafficChart::class,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,68 +2,27 @@
|
|||||||
|
|
||||||
namespace App\Filament\Pages;
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
use App\Enums\RoleEnum;
|
use App\Filament\Widgets\CompanyStatusChart;
|
||||||
|
use App\Filament\Widgets\OverviewStats;
|
||||||
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
|
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
|
||||||
use Filament\Actions\Action;
|
|
||||||
use Filament\Forms\Components\DatePicker;
|
|
||||||
use Filament\Pages\Dashboard as BaseDashboard;
|
use Filament\Pages\Dashboard as BaseDashboard;
|
||||||
use Filament\Pages\Dashboard\Concerns\HasFiltersForm;
|
|
||||||
use Filament\Schemas\Components\Fieldset;
|
|
||||||
use Filament\Schemas\Schema;
|
|
||||||
use Filament\Support\Icons\Heroicon;
|
|
||||||
|
|
||||||
class Dashboard extends BaseDashboard
|
class Dashboard extends BaseDashboard
|
||||||
{
|
{
|
||||||
use HasFiltersForm, HasPageShield;
|
use HasPageShield;
|
||||||
|
|
||||||
|
protected static ?string $pollingInterval = null;
|
||||||
|
|
||||||
public function getColumns(): int|array
|
public function getColumns(): int|array
|
||||||
{
|
{
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function filtersForm(Schema $schema): Schema
|
public function getWidgets(): array
|
||||||
{
|
|
||||||
return $schema
|
|
||||||
->schema([
|
|
||||||
Fieldset::make('Filter')
|
|
||||||
->schema([
|
|
||||||
DatePicker::make('startDate')
|
|
||||||
->label('Tanggal Mulai')
|
|
||||||
->placeholder('Pilih tanggal mulai')
|
|
||||||
->native(false)
|
|
||||||
->displayFormat('l, d F Y'),
|
|
||||||
|
|
||||||
DatePicker::make('endDate')
|
|
||||||
->label('Tanggal Selesai')
|
|
||||||
->placeholder('Pilih tanggal selesai')
|
|
||||||
->native(false)
|
|
||||||
->displayFormat('l, d F Y'),
|
|
||||||
])
|
|
||||||
->columns(2)
|
|
||||||
->columnSpanFull()
|
|
||||||
->visible(fn () => auth()->user()->hasRole(RoleEnum::DEVELOPER->value) || auth()->user()->hasRole(RoleEnum::ADMINISTRATOR->value)),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getHeaderActions(): array
|
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
Action::make('reset')
|
OverviewStats::class,
|
||||||
->label('Reset Filter')
|
CompanyStatusChart::class,
|
||||||
->icon(Heroicon::OutlinedXMark)
|
|
||||||
->color('danger')
|
|
||||||
->action(fn () => $this->resetFilters())
|
|
||||||
->visible(fn () => ! empty($this->filters['startDate']) || ! empty($this->filters['endDate'])),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resetFilters(): void
|
|
||||||
{
|
|
||||||
$this->filters['startDate'] = null;
|
|
||||||
$this->filters['endDate'] = null;
|
|
||||||
|
|
||||||
if (method_exists($this, 'getFiltersSessionKey')) {
|
|
||||||
session()->forget($this->getFiltersSessionKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
61
app/Filament/Widgets/CompanyStatusChart.php
Normal file
61
app/Filament/Widgets/CompanyStatusChart.php
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Filament\Widgets;
|
||||||
|
|
||||||
|
use App\Enums\VerificationStatus;
|
||||||
|
use App\Models\Company;
|
||||||
|
use App\Models\VerificationRequest;
|
||||||
|
use BezhanSalleh\FilamentShield\Traits\HasWidgetShield;
|
||||||
|
use Filament\Widgets\ChartWidget;
|
||||||
|
|
||||||
|
class CompanyStatusChart extends ChartWidget
|
||||||
|
{
|
||||||
|
use HasWidgetShield;
|
||||||
|
|
||||||
|
protected ?string $heading = 'Status Verifikasi Perusahaan';
|
||||||
|
|
||||||
|
protected static ?int $sort = 2;
|
||||||
|
|
||||||
|
protected int|string|array $columnSpan = 1;
|
||||||
|
|
||||||
|
protected function getData(): array
|
||||||
|
{
|
||||||
|
$data = VerificationRequest::query()
|
||||||
|
->selectRaw('status, count(*) as total')
|
||||||
|
->groupBy('status')
|
||||||
|
->get();
|
||||||
|
|
||||||
|
$notSubmittedCount = Company::doesntHave('verificationRequest')->count();
|
||||||
|
|
||||||
|
$labels = ['Belum Mengajukan'];
|
||||||
|
$counts = [$notSubmittedCount];
|
||||||
|
$colors = ['#94a3b8']; // Slate 400
|
||||||
|
|
||||||
|
foreach (VerificationStatus::cases() as $status) {
|
||||||
|
$labels[] = $status->getLabel();
|
||||||
|
$counts[] = $data->where('status', $status)->first()?->total ?? 0;
|
||||||
|
$colors[] = match ($status) {
|
||||||
|
VerificationStatus::PENDING => '#f59e0b', // Amber 500
|
||||||
|
VerificationStatus::APPROVED => '#10b981', // Emerald 500
|
||||||
|
VerificationStatus::NEED_REVISION => '#0ea5e9', // Sky 500
|
||||||
|
VerificationStatus::REJECTED => '#f43f5e', // Rose 500
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
'datasets' => [
|
||||||
|
[
|
||||||
|
'label' => 'Jumlah Perusahaan',
|
||||||
|
'data' => $counts,
|
||||||
|
'backgroundColor' => $colors,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'labels' => $labels,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getType(): string
|
||||||
|
{
|
||||||
|
return 'pie';
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,93 +2,111 @@
|
|||||||
|
|
||||||
namespace App\Filament\Widgets;
|
namespace App\Filament\Widgets;
|
||||||
|
|
||||||
use App\Models\Company;
|
use App\Enums\IsActive;
|
||||||
|
use App\Models\Classification;
|
||||||
use App\Models\DataChangeRequest;
|
use App\Models\DataChangeRequest;
|
||||||
|
use App\Models\Department;
|
||||||
use App\Models\Journalist;
|
use App\Models\Journalist;
|
||||||
|
use App\Models\Location;
|
||||||
use App\Models\PartnerMedia;
|
use App\Models\PartnerMedia;
|
||||||
|
use App\Models\Theme;
|
||||||
use App\Models\VerificationRequest;
|
use App\Models\VerificationRequest;
|
||||||
use App\Models\Visitor;
|
use App\Models\Visitor;
|
||||||
use BezhanSalleh\FilamentShield\Traits\HasWidgetShield;
|
use BezhanSalleh\FilamentShield\Traits\HasWidgetShield;
|
||||||
use Filament\Support\Icons\Heroicon;
|
use Filament\Support\Icons\Heroicon;
|
||||||
use Filament\Widgets\Concerns\InteractsWithPageFilters;
|
|
||||||
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
|
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
|
||||||
use Filament\Widgets\StatsOverviewWidget\Stat;
|
use Filament\Widgets\StatsOverviewWidget\Stat;
|
||||||
|
|
||||||
class OverviewStats extends BaseWidget
|
class OverviewStats extends BaseWidget
|
||||||
{
|
{
|
||||||
use HasWidgetShield, InteractsWithPageFilters;
|
use HasWidgetShield;
|
||||||
|
|
||||||
protected static ?int $sort = 1;
|
protected static ?int $sort = 1;
|
||||||
|
|
||||||
protected int|string|array $columnSpan = 'full';
|
protected int|string|array $columnSpan = 'full';
|
||||||
|
|
||||||
|
protected ?string $pollingInterval = null;
|
||||||
|
|
||||||
protected function getStats(): array
|
protected function getStats(): array
|
||||||
{
|
{
|
||||||
$startDate = $this->filters['startDate'] ?? null;
|
$totalJournalists = Journalist::count();
|
||||||
$endDate = $this->filters['endDate'] ?? null;
|
$totalMedia = PartnerMedia::count();
|
||||||
|
|
||||||
$totalJournalists = Journalist::when($startDate, fn ($q) => $q->whereDate('created_at', '>=', $startDate))
|
|
||||||
->when($endDate, fn ($q) => $q->whereDate('created_at', '<=', $endDate))
|
|
||||||
->count();
|
|
||||||
|
|
||||||
$totalMedia = PartnerMedia::when($startDate, fn ($q) => $q->whereDate('created_at', '>=', $startDate))
|
|
||||||
->when($endDate, fn ($q) => $q->whereDate('created_at', '<=', $endDate))
|
|
||||||
->count();
|
|
||||||
|
|
||||||
$average = $totalMedia > 0 ? round($totalJournalists / $totalMedia, 1) : 0;
|
$average = $totalMedia > 0 ? round($totalJournalists / $totalMedia, 1) : 0;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
Stat::make('Total Perusahaan', Company::when($startDate, fn ($q) => $q->whereDate('created_at', '>=', $startDate))
|
Stat::make('Total Klasifikasi', Classification::active()->count())
|
||||||
->when($endDate, fn ($q) => $q->whereDate('created_at', '<=', $endDate))
|
->description('Klasifikasi aktif')
|
||||||
->count())
|
->descriptionIcon(Heroicon::OutlinedBookOpen)
|
||||||
->description('Perusahaan terdaftar')
|
->color($this->getRandomColor()),
|
||||||
->descriptionIcon(Heroicon::OutlinedBuildingOffice2)
|
|
||||||
->color('primary'),
|
Stat::make('Total Lokus', Location::active()->count())
|
||||||
|
->description('Lokus aktif')
|
||||||
|
->descriptionIcon(Heroicon::OutlinedMapPin)
|
||||||
|
->color($this->getRandomColor()),
|
||||||
|
|
||||||
|
Stat::make('Total OPD', Department::where('is_active', IsActive::ACTIVE)->count())
|
||||||
|
->description('OPD aktif')
|
||||||
|
->descriptionIcon(Heroicon::OutlinedBuildingLibrary)
|
||||||
|
->color($this->getRandomColor()),
|
||||||
|
|
||||||
|
Stat::make('Total Tema', Theme::active()->count())
|
||||||
|
->description('Tema aktif')
|
||||||
|
->descriptionIcon(Heroicon::OutlinedPuzzlePiece)
|
||||||
|
->color($this->getRandomColor()),
|
||||||
|
|
||||||
Stat::make('Media Terverifikasi', PartnerMedia::whereHas('company.verificationRequest', function ($q) {
|
Stat::make('Media Terverifikasi', PartnerMedia::whereHas('company.verificationRequest', function ($q) {
|
||||||
$q->approved();
|
$q->approved();
|
||||||
})
|
})->count())
|
||||||
->when($startDate, fn ($q) => $q->whereDate('created_at', '>=', $startDate))
|
|
||||||
->when($endDate, fn ($q) => $q->whereDate('created_at', '<=', $endDate))
|
|
||||||
->count())
|
|
||||||
->description('Media aktif')
|
->description('Media aktif')
|
||||||
->descriptionIcon(Heroicon::OutlinedCheckBadge)
|
->descriptionIcon(Heroicon::OutlinedCheckBadge)
|
||||||
->color('success'),
|
->color($this->getRandomColor()),
|
||||||
|
|
||||||
Stat::make('Total Jurnalis', Journalist::when($startDate, fn ($q) => $q->whereDate('created_at', '>=', $startDate))
|
Stat::make('Total Jurnalis', $totalJournalists)
|
||||||
->when($endDate, fn ($q) => $q->whereDate('created_at', '<=', $endDate))
|
|
||||||
->count())
|
|
||||||
->description('Jurnalis terdaftar')
|
->description('Jurnalis terdaftar')
|
||||||
->descriptionIcon(Heroicon::OutlinedIdentification)
|
->descriptionIcon(Heroicon::OutlinedIdentification)
|
||||||
->color('info'),
|
->color($this->getRandomColor()),
|
||||||
|
|
||||||
Stat::make('Antrean Verifikasi', VerificationRequest::pending()
|
Stat::make('Antrean Verifikasi', VerificationRequest::pending()->count())
|
||||||
->when($startDate, fn ($q) => $q->whereDate('created_at', '>=', $startDate))
|
|
||||||
->when($endDate, fn ($q) => $q->whereDate('created_at', '<=', $endDate))
|
|
||||||
->count())
|
|
||||||
->description('Butuh tindakan')
|
->description('Butuh tindakan')
|
||||||
->descriptionIcon(Heroicon::OutlinedPencilSquare)
|
->descriptionIcon(Heroicon::OutlinedPencilSquare)
|
||||||
->color('warning'),
|
->color($this->getRandomColor()),
|
||||||
|
|
||||||
Stat::make('Antrean Perubahan', DataChangeRequest::pending()
|
Stat::make('Antrean Perubahan', DataChangeRequest::pending()->count())
|
||||||
->when($startDate, fn ($q) => $q->whereDate('created_at', '>=', $startDate))
|
|
||||||
->when($endDate, fn ($q) => $q->whereDate('created_at', '<=', $endDate))
|
|
||||||
->count())
|
|
||||||
->description('Perubahan data')
|
->description('Perubahan data')
|
||||||
->descriptionIcon(Heroicon::OutlinedDocumentText)
|
->descriptionIcon(Heroicon::OutlinedDocumentText)
|
||||||
->color('warning'),
|
->color($this->getRandomColor()),
|
||||||
|
|
||||||
Stat::make('Total Pengunjung', Visitor::when($startDate, fn ($q) => $q->whereDate('date', '>=', $startDate))
|
Stat::make('Total Pengunjung', Visitor::count())
|
||||||
->when($endDate, fn ($q) => $q->whereDate('date', '<=', $endDate))
|
|
||||||
->count())
|
|
||||||
->description('Total traffic')
|
->description('Total traffic')
|
||||||
->descriptionIcon(Heroicon::OutlinedChartBar)
|
->descriptionIcon(Heroicon::OutlinedChartBar)
|
||||||
->color('info'),
|
->color($this->getRandomColor()),
|
||||||
|
|
||||||
Stat::make('Rata-rata Jurnalis / Media', $average)
|
Stat::make('Rata-rata Jurnalis / Media', $average)
|
||||||
->description('Rasio sebaran jurnalis')
|
->description('Rasio sebaran jurnalis')
|
||||||
->descriptionIcon(Heroicon::OutlinedUsers)
|
->descriptionIcon(Heroicon::OutlinedUsers)
|
||||||
->color('primary'),
|
->color($this->getRandomColor()),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private array $availableColors = [
|
||||||
|
'primary',
|
||||||
|
'success',
|
||||||
|
'warning',
|
||||||
|
'danger',
|
||||||
|
'info',
|
||||||
|
'fuchsia',
|
||||||
|
'indigo',
|
||||||
|
'violet',
|
||||||
|
'orange',
|
||||||
|
'cyan',
|
||||||
|
'emerald',
|
||||||
|
'amber',
|
||||||
|
'rose',
|
||||||
|
'lime',
|
||||||
|
];
|
||||||
|
|
||||||
|
private function getRandomColor(): string
|
||||||
|
{
|
||||||
|
return $this->availableColors[array_rand($this->availableColors)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -60,7 +60,20 @@ public function panel(Panel $panel): Panel
|
|||||||
->emailVerification(EmailVerification::class)
|
->emailVerification(EmailVerification::class)
|
||||||
->colors([
|
->colors([
|
||||||
'primary' => Color::Blue,
|
'primary' => Color::Blue,
|
||||||
|
'success' => Color::Emerald,
|
||||||
|
'warning' => Color::Amber,
|
||||||
|
'danger' => Color::Rose,
|
||||||
|
'info' => Color::Sky,
|
||||||
'slate' => Color::Slate,
|
'slate' => Color::Slate,
|
||||||
|
'fuchsia' => Color::Fuchsia,
|
||||||
|
'indigo' => Color::Indigo,
|
||||||
|
'violet' => Color::Violet,
|
||||||
|
'orange' => Color::Orange,
|
||||||
|
'cyan' => Color::Cyan,
|
||||||
|
'emerald' => Color::Emerald,
|
||||||
|
'amber' => Color::Amber,
|
||||||
|
'rose' => Color::Rose,
|
||||||
|
'lime' => Color::Lime,
|
||||||
])
|
])
|
||||||
->breadcrumbs(false)
|
->breadcrumbs(false)
|
||||||
->maxContentWidth(Width::Full)
|
->maxContentWidth(Width::Full)
|
||||||
|
|||||||
@ -18,6 +18,8 @@ public function run(): void
|
|||||||
"name": "Developer",
|
"name": "Developer",
|
||||||
"guard_name": "web",
|
"guard_name": "web",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
"View:Analytic",
|
||||||
|
|
||||||
"View:AdminVerification",
|
"View:AdminVerification",
|
||||||
|
|
||||||
"ViewAny:Announcement",
|
"ViewAny:Announcement",
|
||||||
@ -44,6 +46,8 @@ public function run(): void
|
|||||||
"Replicate:Category",
|
"Replicate:Category",
|
||||||
"Reorder:Category",
|
"Reorder:Category",
|
||||||
|
|
||||||
|
"View:CompanyStatusChart",
|
||||||
|
|
||||||
"ViewAny:Classification",
|
"ViewAny:Classification",
|
||||||
"View:Classification",
|
"View:Classification",
|
||||||
"Create:Classification",
|
"Create:Classification",
|
||||||
@ -277,6 +281,8 @@ public function run(): void
|
|||||||
"name": "Administrator",
|
"name": "Administrator",
|
||||||
"guard_name": "web",
|
"guard_name": "web",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
"View:Analytic",
|
||||||
|
|
||||||
"View:AdminVerification",
|
"View:AdminVerification",
|
||||||
|
|
||||||
"ViewAny:Announcement",
|
"ViewAny:Announcement",
|
||||||
@ -303,6 +309,8 @@ public function run(): void
|
|||||||
"Replicate:Category",
|
"Replicate:Category",
|
||||||
"Reorder:Category",
|
"Reorder:Category",
|
||||||
|
|
||||||
|
"View:CompanyStatusChart",
|
||||||
|
|
||||||
"ViewAny:Classification",
|
"ViewAny:Classification",
|
||||||
"View:Classification",
|
"View:Classification",
|
||||||
"Create:Classification",
|
"Create:Classification",
|
||||||
@ -522,6 +530,8 @@ public function run(): void
|
|||||||
"name": "Admin Monitoring",
|
"name": "Admin Monitoring",
|
||||||
"guard_name": "web",
|
"guard_name": "web",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
"View:Analytic",
|
||||||
|
|
||||||
"ViewAny:Classification",
|
"ViewAny:Classification",
|
||||||
"View:Classification",
|
"View:Classification",
|
||||||
"Create:Classification",
|
"Create:Classification",
|
||||||
@ -625,6 +635,8 @@ public function run(): void
|
|||||||
"name": "Admin Konten",
|
"name": "Admin Konten",
|
||||||
"guard_name": "web",
|
"guard_name": "web",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
"View:Analytic",
|
||||||
|
|
||||||
"ViewAny:Category",
|
"ViewAny:Category",
|
||||||
|
|
||||||
"View:Category",
|
"View:Category",
|
||||||
@ -681,6 +693,8 @@ public function run(): void
|
|||||||
"name": "Admin Keuangan",
|
"name": "Admin Keuangan",
|
||||||
"guard_name": "web",
|
"guard_name": "web",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
"View:Analytic",
|
||||||
|
|
||||||
"ViewAny:Cooperation",
|
"ViewAny:Cooperation",
|
||||||
"View:Cooperation",
|
"View:Cooperation",
|
||||||
|
|
||||||
@ -691,6 +705,8 @@ public function run(): void
|
|||||||
"name": "Perusahaan",
|
"name": "Perusahaan",
|
||||||
"guard_name": "web",
|
"guard_name": "web",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
"View:Analytic",
|
||||||
|
|
||||||
"ViewAny:Cooperation",
|
"ViewAny:Cooperation",
|
||||||
"View:Cooperation",
|
"View:Cooperation",
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user