diff --git a/app/Filament/Resources/MyPosts/MyPostResource.php b/app/Filament/Resources/MyPosts/MyPostResource.php deleted file mode 100644 index f2b43f3..0000000 --- a/app/Filament/Resources/MyPosts/MyPostResource.php +++ /dev/null @@ -1,46 +0,0 @@ -where('author_id', auth()->id()); - } - - public static function form(Schema $form): Schema - { - return \App\Filament\Resources\MyPosts\Schemas\MyPostForm::configure($form); - } - - public static function table(Table $table): Table - { - return \App\Filament\Resources\MyPosts\Tables\MyPostsTable::configure($table); - } - - public static function getPages(): array - { - return [ - 'index' => ListMyPosts::route('/'), - 'create' => CreateMyPost::route('/create'), - 'edit' => EditMyPost::route('/{record}/edit'), - ]; - } -} diff --git a/app/Filament/Resources/MyPosts/Pages/CreateMyPost.php b/app/Filament/Resources/MyPosts/Pages/CreateMyPost.php deleted file mode 100644 index 500783c..0000000 --- a/app/Filament/Resources/MyPosts/Pages/CreateMyPost.php +++ /dev/null @@ -1,11 +0,0 @@ -components([ - TextInput::make('title')->label('Judul')->required() - ->live(onBlur: true) - ->afterStateUpdated(fn ($state, $set) => $set('slug', Str::slug($state))), - TextInput::make('slug')->required()->unique(ignoreRecord: true), - Select::make('category')->label('Kategori') - ->options([ - 'umum' => 'Umum', - 'pengumuman' => 'Pengumuman', - 'berita' => 'Berita', - ]) - ->default('umum')->required(), - RichEditor::make('content')->label('Konten')->required()->columnSpanFull(), - ]); - } -} diff --git a/app/Filament/Resources/MyPosts/Tables/MyPostsTable.php b/app/Filament/Resources/MyPosts/Tables/MyPostsTable.php deleted file mode 100644 index 6c3854b..0000000 --- a/app/Filament/Resources/MyPosts/Tables/MyPostsTable.php +++ /dev/null @@ -1,59 +0,0 @@ -columns([ - TextColumn::make('title')->label('Judul')->searchable()->sortable(), - TextColumn::make('category')->label('Kategori')->badge(), - TextColumn::make('status')->badge() - ->color(fn ($state) => match ($state) { - 'published' => 'success', - 'pending' => 'warning', - 'rejected' => 'danger', - default => 'gray', - }), - TextColumn::make('rejection_reason')->label('Alasan Penolakan') - ->visible(fn ($record) => $record?->status === 'rejected') - ->limit(40)->default('-'), - TextColumn::make('created_at')->label('Dibuat')->date('d M Y')->sortable(), - ]) - ->recordActions([ - // Hanya bisa edit jika masih draft atau rejected - EditAction::make() - ->visible(fn ($record) => in_array($record->status, ['draft', 'rejected'])), - // Ajukan untuk review - Action::make('submit') - ->label('Ajukan') - ->icon('heroicon-o-paper-airplane') - ->color('info') - ->requiresConfirmation() - ->visible(fn ($record) => in_array($record->status, ['draft', 'rejected'])) - ->action(fn ($record) => $record->update(['status' => 'pending', 'rejection_reason' => null])), - ]) - ->toolbarActions([ - BulkActionGroup::make([ - DeleteBulkAction::make() - ->before(function ($records) { - // Tidak bisa hapus yang sudah published - $records->each(function ($record) { - if ($record->status === 'published') { - throw new \Exception("Artikel yang sudah diterbitkan tidak dapat dihapus."); - } - }); - }), - ]), - ]); - } -} diff --git a/app/Filament/Resources/Posts/PostResource.php b/app/Filament/Resources/Posts/PostResource.php index efa85dc..74435af 100644 --- a/app/Filament/Resources/Posts/PostResource.php +++ b/app/Filament/Resources/Posts/PostResource.php @@ -11,13 +11,33 @@ use App\Models\Post; use Filament\Resources\Resource; use Filament\Schemas\Schema; use Filament\Tables\Table; +use Illuminate\Database\Eloquent\Builder; class PostResource extends Resource { protected static ?string $model = Post::class; protected static string|\BackedEnum|null $navigationIcon = 'heroicon-o-newspaper'; protected static string|\UnitEnum|null $navigationGroup = 'Konten'; - protected static ?string $modelLabel = 'Artikel'; + + // Label dinamis sesuai role + public static function getModelLabel(): string + { + return auth()->user()?->hasAnyRole(['super_admin', 'ketua', 'auditor']) + ? 'Artikel' + : 'Artikel Saya'; + } + + // Scope: ketua/super_admin/auditor lihat semua, lainnya hanya milik sendiri + public static function getEloquentQuery(): Builder + { + $query = parent::getEloquentQuery(); + + if (auth()->user()?->hasAnyRole(['super_admin', 'ketua', 'auditor'])) { + return $query; + } + + return $query->where('author_id', auth()->id()); + } public static function form(Schema $form): Schema { diff --git a/app/Filament/Resources/Posts/Schemas/PostForm.php b/app/Filament/Resources/Posts/Schemas/PostForm.php index aaa744c..1ece865 100644 --- a/app/Filament/Resources/Posts/Schemas/PostForm.php +++ b/app/Filament/Resources/Posts/Schemas/PostForm.php @@ -13,6 +13,8 @@ class PostForm { public static function configure(Schema $schema): Schema { + $isAdmin = auth()->user()?->hasAnyRole(['super_admin', 'ketua']); + return $schema->components([ TextInput::make('title')->label('Judul')->required() ->live(onBlur: true) @@ -20,12 +22,13 @@ class PostForm TextInput::make('slug')->required()->unique(ignoreRecord: true), Select::make('category')->label('Kategori') ->options([ - 'umum' => 'Umum', - 'pengumuman' => 'Pengumuman', - 'berita' => 'Berita', + 'umum' => 'Umum', + 'pengumuman' => 'Pengumuman', + 'berita' => 'Berita', ]) ->default('umum')->required(), DateTimePicker::make('published_at')->label('Tanggal Publikasi') + ->visible($isAdmin) ->helperText('Kosongkan untuk menyimpan sebagai draft'), RichEditor::make('content')->label('Konten')->required()->columnSpanFull(), ]); diff --git a/app/Filament/Resources/Posts/Tables/PostsTable.php b/app/Filament/Resources/Posts/Tables/PostsTable.php index a70b095..714ad28 100644 --- a/app/Filament/Resources/Posts/Tables/PostsTable.php +++ b/app/Filament/Resources/Posts/Tables/PostsTable.php @@ -15,6 +15,8 @@ class PostsTable { public static function configure(Table $table): Table { + $isAdmin = auth()->user()?->hasAnyRole(['super_admin', 'ketua']); + return $table ->columns([ TextColumn::make('title')->label('Judul')->searchable()->sortable(), @@ -31,7 +33,10 @@ class PostsTable 'rejected' => 'danger', default => 'gray', }), - TextColumn::make('author.name')->label('Penulis'), + TextColumn::make('author.name')->label('Penulis')->visible($isAdmin), + TextColumn::make('rejection_reason')->label('Alasan Penolakan') + ->limit(40)->default('-') + ->visible(fn ($record) => $record?->status === 'rejected'), TextColumn::make('published_at')->label('Dipublikasi') ->dateTime('d M Y')->default('-')->sortable(), ]) @@ -44,22 +49,34 @@ class PostsTable ]), ]) ->recordActions([ + // Untuk anggota/pengurus/bendahara: ajukan artikel + Action::make('submit') + ->label('Ajukan') + ->icon('heroicon-o-paper-airplane') + ->color('info') + ->requiresConfirmation() + ->visible(fn ($record) => ! $isAdmin && in_array($record->status, ['draft', 'rejected'])) + ->action(fn ($record) => $record->update(['status' => 'pending', 'rejection_reason' => null])), + + // Untuk admin: approve Action::make('publish') ->label('Terbitkan') ->icon('heroicon-o-check-circle') ->color('success') ->requiresConfirmation() - ->visible(fn ($record) => $record->status === 'pending') + ->visible(fn ($record) => $isAdmin && $record->status === 'pending') ->action(fn ($record) => $record->update([ - 'status' => 'published', + 'status' => 'published', 'published_at' => now(), - 'reviewed_by' => auth()->id(), + 'reviewed_by' => auth()->id(), ])), + + // Untuk admin: tolak Action::make('reject') ->label('Tolak') ->icon('heroicon-o-x-circle') ->color('danger') - ->visible(fn ($record) => $record->status === 'pending') + ->visible(fn ($record) => $isAdmin && $record->status === 'pending') ->form([ Textarea::make('rejection_reason')->label('Alasan Penolakan')->required(), ]) @@ -68,7 +85,9 @@ class PostsTable 'reviewed_by' => auth()->id(), 'rejection_reason' => $data['rejection_reason'], ])), - EditAction::make(), + + EditAction::make() + ->visible(fn ($record) => $isAdmin || in_array($record->status, ['draft', 'rejected'])), ]) ->toolbarActions([BulkActionGroup::make([DeleteBulkAction::make()])]); } diff --git a/database/seeders/PermissionSeeder.php b/database/seeders/PermissionSeeder.php index 628e1d9..a042635 100644 --- a/database/seeders/PermissionSeeder.php +++ b/database/seeders/PermissionSeeder.php @@ -23,24 +23,26 @@ class PermissionSeeder extends Seeder ->where('name', 'not like', '%Permission%') ->get()); - // Bendahara: hanya kas + // Bendahara: hanya kas + artikel sendiri $bendahara->syncPermissions(Permission::where('name', 'like', '%CashRecord%') ->orWhere('name', 'like', '%CashCategory%') + ->orWhereIn('name', ['ViewAny:Post', 'View:Post', 'Create:Post', 'Update:Post', 'Delete:Post']) ->get()); - // Pengurus: kegiatan + lihat anggota & divisi + // Pengurus: kegiatan + lihat anggota & divisi + artikel sendiri $pengurus->syncPermissions(Permission::where('name', 'like', '%Activity%') - ->orWhere('name', 'like', 'ViewAny:User') - ->orWhere('name', 'like', 'View:User') - ->orWhere('name', 'like', 'ViewAny:Division') - ->orWhere('name', 'like', 'View:Division') + ->orWhereIn('name', [ + 'ViewAny:User', 'View:User', + 'ViewAny:Division', 'View:Division', + 'ViewAny:Post', 'View:Post', 'Create:Post', 'Update:Post', 'Delete:Post', + ]) ->get()); - // Anggota: lihat kegiatan & voting + kelola artikel sendiri + // Anggota: lihat kegiatan & voting + artikel sendiri $anggota->syncPermissions(Permission::whereIn('name', [ 'ViewAny:Activity', 'View:Activity', 'ViewAny:Vote', 'View:Vote', - 'ViewAny:MyPost', 'View:MyPost', 'Create:MyPost', 'Update:MyPost', 'Delete:MyPost', + 'ViewAny:Post', 'View:Post', 'Create:Post', 'Update:Post', 'Delete:Post', ])->get()); // Auditor: read-only semua + akses audit