user()?->can('Publish:Post') ?? false; $canPublish = $canReview; return $table ->columns([ TextColumn::make('title')->label('Judul')->searchable()->sortable(), TextColumn::make('category')->label('Kategori')->badge() ->color(fn ($state) => match ($state) { 'pengumuman' => 'warning', 'berita' => 'info', default => 'gray', }), TextColumn::make('status')->badge() ->color(fn ($state) => match ($state) { 'published' => 'success', 'approved' => 'info', 'pending' => 'warning', 'rejected' => 'danger', default => 'gray', }) ->formatStateUsing(fn ($state) => match ($state) { 'draft' => 'Draft', 'pending' => 'Menunggu', 'approved' => 'Disetujui', 'published' => 'Diterbitkan', 'rejected' => 'Ditolak', default => $state, }), TextColumn::make('author.name')->label('Penulis')->visible($canReview), TextColumn::make('published_at')->label('Dipublikasi') ->dateTime('d M Y')->placeholder('-')->sortable(), ]) ->filters([ SelectFilter::make('status')->options([ 'draft' => 'Draft', 'pending' => 'Menunggu', 'approved' => 'Disetujui', 'published' => 'Diterbitkan', 'rejected' => 'Ditolak', ]), ]) ->recordActions([ // Member: ajukan artikel Action::make('submit') ->label('Ajukan') ->icon('heroicon-o-paper-airplane') ->color('info') ->requiresConfirmation() ->visible(fn ($record) => ! $canReview && in_array($record->status, ['draft', 'rejected'])) ->action(function ($record): void { $record->update(['status' => 'pending', 'rejection_reason' => null]); NotificationService::toRole('editor', 'Artikel Menunggu Persetujuan', "\"{$record->title}\" oleh {$record->author->name} menunggu persetujuan.", 'warning', route('filament.admin.resources.posts.edit', $record)); }), // Editor: approve Action::make('approve') ->label('Setujui') ->icon('heroicon-o-check-circle') ->color('success') ->requiresConfirmation() ->visible(fn ($record) => $canReview && $record->status === 'pending') ->action(fn ($record) => tap($record->update([ 'status' => 'approved', 'approved_by' => auth()->id(), 'approved_at' => now(), 'reviewed_by' => auth()->id(), ]), fn () => NotificationService::send( $record->author, 'Artikel Disetujui', "Artikel \"{$record->title}\" Anda telah disetujui dan akan segera diterbitkan.", 'success', route('filament.admin.resources.posts.edit', $record) ))), // Editor: tolak Action::make('reject') ->label('Tolak') ->icon('heroicon-o-x-circle') ->color('danger') ->visible(fn ($record) => $canReview && $record->status === 'pending') ->form([Textarea::make('rejection_reason')->label('Alasan Penolakan')->required()]) ->action(fn ($record, array $data) => tap($record->update([ 'status' => 'draft', 'reviewed_by' => auth()->id(), 'rejection_reason' => $data['rejection_reason'], ]), fn () => NotificationService::send( $record->author, 'Artikel Ditolak', "Artikel \"{$record->title}\" ditolak: {$data['rejection_reason']}", 'danger', route('filament.admin.resources.posts.edit', $record) ))), // Editor: publish (approved → published) Action::make('publish') ->label('Terbitkan') ->icon('heroicon-o-globe-alt') ->color('success') ->visible(fn ($record) => $canPublish && $record->status === 'approved') ->form([ DateTimePicker::make('published_at')->label('Tanggal Publikasi') ->default(now())->required(), ]) ->action(fn ($record, array $data) => $record->update([ 'status' => 'published', 'published_at' => $data['published_at'], ])), // Editor: unpublish Action::make('unpublish') ->label('Batalkan Publikasi') ->icon('heroicon-o-eye-slash') ->color('warning') ->requiresConfirmation() ->visible(fn ($record) => $canPublish && $record->status === 'published') ->action(fn ($record) => $record->update([ 'status' => 'approved', 'published_at' => null, ])), EditAction::make() ->visible(fn ($record) => $canReview || in_array($record->status, ['draft', 'rejected'])), ]) ->toolbarActions([BulkActionGroup::make([DeleteBulkAction::make()])]); } }