simedkom/app/Filament/Resources/Manage/Journalists/JournalistResource.php

253 lines
9.4 KiB
PHP

<?php
namespace App\Filament\Resources\Manage\Journalists;
use App\Enums\RoleEnum;
use App\Enums\VerificationStatus;
use App\Filament\Actions\Cheerful\ForceDeleteAction;
use App\Filament\Actions\Cheerful\RestoreAction;
use App\Filament\Columns\TimestampColumns;
use App\Filament\Pages\Media;
use App\Filament\Resources\Manage\Journalists\Actions\DeleteJournalistAction;
use App\Filament\Resources\Manage\Journalists\Actions\EditJournalistAction;
use App\Filament\Resources\Manage\Journalists\Pages\ManageJournalists;
use App\Models\Journalist;
use Asmit\FilamentUpload\Forms\Components\AdvancedFileUpload;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\RestoreBulkAction;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
use Filament\Resources\Resource;
use Filament\Schemas\Components\Group;
use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\TrashedFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use UnitEnum;
class JournalistResource extends Resource
{
protected static ?string $model = Journalist::class;
protected static string|UnitEnum|null $navigationGroup = 'Kelola';
protected static string|BackedEnum|null $navigationIcon = Heroicon::Identification;
protected static ?string $navigationLabel = 'Jurnalis';
protected static ?int $navigationSort = 4;
protected static ?string $recordTitleAttribute = 'name';
protected static ?string $slug = 'manage/journalists';
public static function getNavigationBadge(): ?string
{
return static::getModel()::pending()
->when(auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value), function (Builder $query): void {
$query->whereHas('partnerMedia.company', function (Builder $q): void {
$q->where('user_id', auth()->id());
});
})
->count() ?: null;
}
public static function form(Schema $schema): Schema
{
$documents = [
[
'title' => 'Dokumen Pers',
'text_name' => 'press_card',
'placeholder' => '*****',
'max' => 100,
'max_size' => 1024 * 10,
'file_name' => 'press_card_docs',
'accept' => ['application/pdf'],
'folder' => 'press-card/',
],
[
'title' => 'Sertifikat UKW',
'text_name' => 'ukw_certificate',
'placeholder' => '*****',
'max' => 100,
'max_size' => 1024 * 10,
'file_name' => 'ukw_certificate_docs',
'accept' => ['application/pdf'],
'folder' => 'ukw-certificate/',
],
];
return $schema
->components([
TextInput::make('name')
->label('Nama')
->placeholder('John Doe')
->autocomplete(false)
->autofocus()
->required()
->maxLength(100),
TextInput::make('email')
->label('Alamat Surel')
->placeholder('johndoe@example.com')
->autocomplete(false)
->required()
->maxLength(254)
->unique('journalists', 'email', ignoreRecord: true)
->email(),
TextInput::make('phone_number')
->label('Nomor Telepon')
->placeholder('08xx xxxx xxxx')
->autocomplete(false)
->required()
->maxLength(20)
->tel(),
Group::make()
->schema(
collect($documents)
->map(function (array $doc): Section {
return Section::make($doc['title'])
->schema([
TextInput::make($doc['text_name'])
->hiddenLabel()
->placeholder($doc['placeholder'])
->autocomplete(false)
->required()
->maxLength($doc['max']),
AdvancedFileUpload::make($doc['file_name'])
->hiddenLabel()
->disk(config('filesystems.default'))
->acceptedFileTypes($doc['accept'])
->directory(fn (): string => 'journalists/'.$doc['folder'].now()->toDateString())
->maxSize($doc['max_size'])
->required(),
]);
})
->toArray()
),
Section::make('Alasan Perubahan')
->schema([
Textarea::make('change_reason')
->label('Alasan')
->placeholder('Jelaskan alasan perubahan data ini...')
->rows(3)
->required(),
])
->visible(fn () => auth()->user()->company?->status === VerificationStatus::APPROVED && auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value)),
])
->columns(1);
}
public static function table(Table $table): Table
{
return $table
->columns([
TextColumn::make('name')
->label('Nama')
->searchable()
->sortable(),
TextColumn::make('email')
->label('Alamat Surel')
->searchable()
->sortable(),
TextColumn::make('phone_number')
->label('Nomor Telepon')
->searchable()
->sortable(),
TextColumn::make('press_card')
->label('Dokumen Pers')
->searchable()
->sortable()
->wrap(),
TextColumn::make('ukw_certificate')
->label('Sertifikat UKW')
->searchable()
->sortable()
->wrap(),
...TimestampColumns::make(),
])
->filters([
TrashedFilter::make()
->native(false)
->visible(fn () => auth()->user()?->hasRole('Developer')),
])
->recordActions([
EditJournalistAction::make('edit'),
DeleteJournalistAction::make('delete'),
ForceDeleteAction::make(),
RestoreAction::make(),
])
->toolbarActions([
BulkActionGroup::make([
DeleteBulkAction::make(),
ForceDeleteBulkAction::make(),
RestoreBulkAction::make(),
]),
])
->emptyStateIcon(Heroicon::Identification)
->emptyStateDescription('Setelah Anda membubat data pertama, maka akan muncul disini.')
->defaultSort('created_at', 'desc')
->deferFilters(false)
->modifyQueryUsing(function (Builder $query): void {
if (auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value) && ! auth()->user()->company?->partnerMedia) {
$query->whereRaw('1 = 0');
}
$query->when(auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value), function (Builder $q): Builder {
return $q->whereHas('partnerMedia.company', function (Builder $q): void {
$q->where('user_id', auth()->id());
});
});
})
->when(auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value) && ! auth()->user()->company?->partnerMedia, function (Table $table): Table {
return $table
->emptyStateHeading('Akses Dibatasi')
->emptyStateDescription('Silakan lengkapi data media Anda terlebih dahulu untuk dapat mengelola informasi jurnalis.')
->emptyStateIcon(Heroicon::LockClosed)
->emptyStateActions([
Action::make('complete_media')
->label('Lengkapi Data Media')
->url(Media::getUrl())
->button(),
]);
});
}
public static function getPages(): array
{
return [
'index' => ManageJournalists::route('/'),
];
}
public static function getRecordRouteBindingEloquentQuery(): Builder
{
return parent::getRecordRouteBindingEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}