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

303 lines
11 KiB
PHP

<?php
namespace App\Filament\Resources\Manage\Journalists;
use App\Filament\Columns\TimestampColumns;
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\DeleteAction;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Actions\ForceDeleteAction;
use Filament\Actions\ForceDeleteBulkAction;
use Filament\Actions\RestoreAction;
use Filament\Actions\RestoreBulkAction;
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\Enums\Width;
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\Model;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Illuminate\Support\Facades\Storage;
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 = 11;
protected static ?string $recordTitleAttribute = 'name';
protected static ?string $slug = 'manage/journalists';
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' => 'journalists/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' => 'journalists/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)
->autofocus()
->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(
fn ($doc) => 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'])
->maxSize($doc['max_size'])
->required(),
])
)
->toArray()
),
])
->columns(1);
}
public static function table(Table $table): Table
{
return $table
->recordTitleAttribute('name')
->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),
])
->recordActions([
EditAction::make()
->modalWidth(Width::Large)
->fillForm(function (Journalist $journalist) {
$data = [
'name' => $journalist->name,
'email' => $journalist->email,
'phone_number' => $journalist->phone_number,
'press_card' => $journalist->press_card,
'ukw_certificate' => $journalist->ukw_certificate,
];
$documents = [
'press_card',
'ukw_certificate',
];
$mediaItems = $journalist->getMedia('journalists');
foreach ($documents as $docType) {
$media = $mediaItems
->where('custom_properties.doc_type', str($docType)->replace('_docs', '')->slug('-'))
->sortByDesc('created_at')
->first();
if ($media) {
$data["{$docType}_docs"] = [$media->getPathRelativeToRoot()];
}
}
return $data;
})
->using(function (Model $record, array $data): Model {
$record->update([
'name' => $data['name'],
'email' => $data['email'],
'phone_number' => $data['phone_number'],
'press_card' => $data['press_card'],
'ukw_certificate' => $data['ukw_certificate'],
]);
$documents = [
'press_card_docs',
'ukw_certificate_docs',
];
foreach ($documents as $field) {
if (empty($data[$field])) {
continue;
}
foreach ((array) $data[$field] as $filePath) {
$fullPath = Storage::disk(config('filesystems.default'))->path($filePath);
if (! file_exists($fullPath)) {
continue;
}
$record
->addMediaFromDisk($filePath, config('filesystems.default'))
->preservingOriginal()
->withCustomProperties([
'feature' => 'journalists',
'date' => now()->toDateString(),
'doc_type' => str($field)
->replace('_docs', '')
->slug('-'),
])
->toMediaCollection('journalists');
}
}
return $record;
}),
DeleteAction::make(),
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) {
if (auth()->user()->hasRole('Perusahaan') && ! auth()->user()->company?->partnerMedia) {
$query->whereRaw('1 = 0');
}
$query->when(auth()->user()->hasRole('Perusahaan'), function (Builder $q) {
return $q->whereHas('partnerMedia.company', function (Builder $q) {
$q->where('user_id', auth()->id());
});
});
})
->when(auth()->user()->hasRole('Perusahaan') && ! auth()->user()->company?->partnerMedia, function (Table $table) {
return $table
->emptyStateHeading('Akses Dibatasi')
->emptyStateDescription('Mohon lengkapi data Media Anda terlebih dahulu.')
->emptyStateIcon(Heroicon::LockClosed)
->emptyStateActions([
Action::make('completeMedia')
->label('Lengkapi Data Media')
->url(route('filament.dashboard.pages.manage.media'))
->button(),
]);
});
}
public static function getPages(): array
{
return [
'index' => ManageJournalists::route('/'),
];
}
public static function getRecordRouteBindingEloquentQuery(): Builder
{
return parent::getRecordRouteBindingEloquentQuery()
->withoutGlobalScopes([
SoftDeletingScope::class,
]);
}
}