refactor: add type hinting to closures and fix logic errors in Filament codebase

- Added comprehensive parameter and return type hinting to closures across various Filament resources, actions, and relation managers to improve type safety and static analysis.
- Fixed logic in ReportRelationManager where report count was incorrectly compared, preventing the 'Buat Laporan' button from showing correctly.
- Corrected namespaces for RepeatableEntry and TextEntry in ViewCooperation (changed from Filament\Schemas to Filament\Infolists).
- Fixed component rendering in JournalistResource form by ensuring sections are correctly returned in the mapping.
- Added @var docblocks to resolve lint errors related to auth()->user() and verified query builder return types.
- Standardized file retrieval logic in PartnerResource and improved overall code reliability."
This commit is contained in:
Yoga Pangestu 2026-01-12 15:17:21 +07:00
parent 95dbcb1c75
commit 6fe5e81717
42 changed files with 323 additions and 253 deletions

View File

@ -162,7 +162,7 @@ public function approveAction(): Action
->modalHeading('Setujui Verifikasi Lengkap') ->modalHeading('Setujui Verifikasi Lengkap')
->modalDescription('Apakah Anda yakin ingin menyetujui verifikasi ini? Status akan diterapkan pada Perusahaan, Media, dan semua Jurnalis sekaligus.') ->modalDescription('Apakah Anda yakin ingin menyetujui verifikasi ini? Status akan diterapkan pada Perusahaan, Media, dan semua Jurnalis sekaligus.')
->modalSubmitActionLabel('Ya, Setujui') ->modalSubmitActionLabel('Ya, Setujui')
->action(function (array $arguments, array $data) { ->action(function (array $arguments, array $data): void {
$this->processReview($arguments['id'], DecisionAdmin::APPROVED, $data['note'] ?? null); $this->processReview($arguments['id'], DecisionAdmin::APPROVED, $data['note'] ?? null);
}); });
} }
@ -184,9 +184,11 @@ public function revisionAction(): Action
->label('Catatan Revisi') ->label('Catatan Revisi')
->required() ->required()
->placeholder('Jelaskan bagian yang perlu diperbaiki (Perusahaan, Media, atau Jurnalis)...') ->placeholder('Jelaskan bagian yang perlu diperbaiki (Perusahaan, Media, atau Jurnalis)...')
->helperText('Catatan ini akan ditampilkan kepada user.'), ->helperText('Catatan ini akan ditampilkan kepada user.')
->autocomplete(false)
->autofocus(),
]) ])
->action(function (array $arguments, array $data) { ->action(function (array $arguments, array $data): void {
$this->processReview($arguments['id'], DecisionAdmin::NEED_REVISION, $data['note']); $this->processReview($arguments['id'], DecisionAdmin::NEED_REVISION, $data['note']);
}); });
} }
@ -210,9 +212,11 @@ public function rejectAction(): Action
->label('Alasan Penolakan') ->label('Alasan Penolakan')
->required() ->required()
->placeholder('Jelaskan alasan pengajuan ditolak...') ->placeholder('Jelaskan alasan pengajuan ditolak...')
->helperText('Alasan ini akan ditampilkan kepada user.'), ->helperText('Alasan ini akan ditampilkan kepada user.')
->autocomplete(false)
->autofocus(),
]) ])
->action(function (array $arguments, array $data) { ->action(function (array $arguments, array $data): void {
$this->processReview($arguments['id'], DecisionAdmin::REJECTED, $data['note']); $this->processReview($arguments['id'], DecisionAdmin::REJECTED, $data['note']);
}); });
} }

View File

@ -224,8 +224,8 @@ public static function form(Schema $schema): Schema
], ],
collect($documents) collect($documents)
->map( ->map(function (array $doc): void {
fn ($doc) => Section::make($doc['title']) Section::make($doc['title'])
->schema([ ->schema([
TextInput::make($doc['text_name']) TextInput::make($doc['text_name'])
->hiddenLabel() ->hiddenLabel()
@ -241,8 +241,8 @@ public static function form(Schema $schema): Schema
->maxSize($doc['max_size']) ->maxSize($doc['max_size'])
->directory($doc['folder'].now()->toDateString()) ->directory($doc['folder'].now()->toDateString())
->required(), ->required(),
]) ]);
)->toArray() })->toArray()
) )
) )
->columns(2), ->columns(2),

View File

@ -170,8 +170,8 @@ public static function form(Schema $schema): Schema
->schema( ->schema(
collect($documents) collect($documents)
->map( ->map(function (array $doc): void {
fn ($doc) => Section::make($doc['title']) Section::make($doc['title'])
->schema([ ->schema([
TextInput::make($doc['text_name']) TextInput::make($doc['text_name'])
->hiddenLabel() ->hiddenLabel()
@ -187,8 +187,8 @@ public static function form(Schema $schema): Schema
->maxSize($doc['max_size']) ->maxSize($doc['max_size'])
->directory($doc['folder'].now()->toDateString()) ->directory($doc['folder'].now()->toDateString())
->required(), ->required(),
]) ]);
)->toArray() })->toArray()
) )
->columns(2), ->columns(2),
]) ])

View File

@ -64,13 +64,15 @@ public function form(Schema $schema): Schema
->placeholder('diskominfo@purwakartakab.go.id') ->placeholder('diskominfo@purwakartakab.go.id')
->email() ->email()
->required() ->required()
->maxLength(255), ->maxLength(255)
->autocomplete(false),
TextInput::make('site_phone') TextInput::make('site_phone')
->label('Nomor Telepon') ->label('Nomor Telepon')
->placeholder('(0264) 200222') ->placeholder('(0264) 200222')
->required() ->required()
->maxLength(255), ->maxLength(255)
->autocomplete(false),
RichEditor::make('about_us') RichEditor::make('about_us')
->label('Tentang Kami') ->label('Tentang Kami')

View File

@ -86,14 +86,14 @@ public function submitVerificationAction(): Action
$progress = $this->getVerificationProgress(); $progress = $this->getVerificationProgress();
return Action::make('submit_verification') return Action::make('submit_verification')
->label(fn () => $this->verificationRequest && $this->verificationRequest->status === VerificationStatus::NEED_REVISION ->label(fn (): string => $this->verificationRequest && $this->verificationRequest->status === VerificationStatus::NEED_REVISION
? 'Kirim Ulang' ? 'Kirim Ulang'
: 'Ajukan Verifikasi') : 'Ajukan Verifikasi')
->icon('heroicon-o-paper-airplane') ->icon('heroicon-o-paper-airplane')
->color('primary') ->color('primary')
->requiresConfirmation() ->requiresConfirmation()
->modalHeading('Ajukan Verifikasi Lengkap') ->modalHeading('Ajukan Verifikasi Lengkap')
->modalDescription(function () use ($progress) { ->modalDescription(function () use ($progress): string {
if (! $progress['isDataComplete']) { if (! $progress['isDataComplete']) {
return 'Data belum lengkap. Silakan lengkapi terlebih dahulu: '.implode(', ', $progress['missingData']); return 'Data belum lengkap. Silakan lengkapi terlebih dahulu: '.implode(', ', $progress['missingData']);
} }
@ -101,9 +101,9 @@ public function submitVerificationAction(): Action
return 'Apakah Anda yakin ingin mengajukan verifikasi untuk Perusahaan, Media, dan Jurnalis? Pastikan semua data sudah benar dan lengkap.'; return 'Apakah Anda yakin ingin mengajukan verifikasi untuk Perusahaan, Media, dan Jurnalis? Pastikan semua data sudah benar dan lengkap.';
}) })
->modalSubmitActionLabel('Ya, Ajukan') ->modalSubmitActionLabel('Ya, Ajukan')
->visible(fn () => $progress['canSubmit']) ->visible(fn (): bool => $progress['canSubmit'])
->disabled(fn () => ! $progress['isDataComplete']) ->disabled(fn (): bool => ! $progress['isDataComplete'])
->action(function () { ->action(function (): void {
$this->submitVerification(); $this->submitVerification();
}); });
} }

View File

@ -104,7 +104,7 @@ public static function infolist(Schema $schema): Schema
->placeholder('Belum dibalas'), ->placeholder('Belum dibalas'),
]) ])
->columnSpanFull() ->columnSpanFull()
->visible(fn ($record) => $record->replied_at !== null), ->visible(fn (Contact $record): bool => $record->replied_at !== null),
]) ])
->columns(2); ->columns(2);
} }
@ -128,7 +128,7 @@ public static function table(Table $table): Table
IconColumn::make('replied_at') IconColumn::make('replied_at')
->label('Dibalas') ->label('Dibalas')
->boolean() ->boolean()
->getStateUsing(fn ($record) => $record->replied_at !== null), ->getStateUsing(fn (Contact $record): bool => $record->replied_at !== null),
TextColumn::make('repliedBy.name') TextColumn::make('repliedBy.name')
->label('Dibalas Oleh') ->label('Dibalas Oleh')
@ -157,11 +157,13 @@ public static function table(Table $table): Table
->schema([ ->schema([
Textarea::make('reply_message') Textarea::make('reply_message')
->label('Pesan Balasan') ->label('Pesan Balasan')
->placeholder(fn ($record) => "Halo {$record->name}, ...") ->placeholder(fn (Contact $record): string => "Halo {$record->name}, ...")
->required() ->required()
->rows(5), ->rows(5)
->autocomplete(false)
->autofocus(),
]) ])
->action(function (Contact $record, array $data) { ->action(function (Contact $record, array $data): void {
Mail::to($record->email)->send(new ContactReplyMail($record, $data['reply_message'])); Mail::to($record->email)->send(new ContactReplyMail($record, $data['reply_message']));
$record->update([ $record->update([
@ -175,7 +177,7 @@ public static function table(Table $table): Table
->success() ->success()
->send(); ->send();
}) })
->visible(fn ($record) => $record->replied_at === null), ->visible(fn (Contact $record): bool => $record->replied_at === null),
DeleteAction::make() DeleteAction::make()
->label('Hapus'), ->label('Hapus'),

View File

@ -16,10 +16,10 @@ protected function setUp(): void
$this->label('Terima') $this->label('Terima')
->icon(Heroicon::OutlinedCheck) ->icon(Heroicon::OutlinedCheck)
->color('success') ->color('success')
->action(function ($record) { ->action(function (\App\Models\Cooperation $record): void {
$cooperationMedia = $record->cooperationMedia() $cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) { ->whereHas('partnerMedia', function (\Illuminate\Database\Eloquent\Builder $query): void {
$query->whereHas('company', function ($subQuery) { $query->whereHas('company', function (\Illuminate\Database\Eloquent\Builder $subQuery): void {
$subQuery->where('user_id', auth()->id()); $subQuery->where('user_id', auth()->id());
}); });
}) })
@ -33,14 +33,14 @@ protected function setUp(): void
->send(); ->send();
} }
}) })
->visible(function ($record) { ->visible(function (\App\Models\Cooperation $record): bool {
if (! auth()->user()->hasRole('Perusahaan')) { if (! auth()->user()->hasRole('Perusahaan')) {
return false; return false;
} }
$cooperationMedia = $record->cooperationMedia() $cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) { ->whereHas('partnerMedia', function (\Illuminate\Database\Eloquent\Builder $query): void {
$query->whereHas('company', function ($subQuery) { $query->whereHas('company', function (\Illuminate\Database\Eloquent\Builder $subQuery): void {
$subQuery->where('user_id', auth()->id()); $subQuery->where('user_id', auth()->id());
}); });
}) })

View File

@ -22,36 +22,45 @@ protected function setUp(): void
$this->label('Buat Penugasan') $this->label('Buat Penugasan')
->icon(Heroicon::Plus) ->icon(Heroicon::Plus)
->color('primary') ->color('primary')
->schema([ ->schema(function (Cooperation $record): array {
DatePicker::make('start_date') return [
->label('Tanggal Mulai') DatePicker::make('start_date')
->placeholder(fn () => now()->translatedFormat('l, d F Y')) ->label('Tanggal Mulai')
->native(false) ->placeholder(fn (): string => now()->translatedFormat('l, d F Y'))
->displayFormat('l, d F Y') ->native(false)
->locale('id') ->displayFormat('l, d F Y')
->required(), ->locale('id')
->required()
->minDate($record->final_submission_date)
->autocomplete(false)
->autofocus(),
DatePicker::make('end_date') DatePicker::make('end_date')
->label('Tanggal Seleisa') ->label('Tanggal Selesai')
->placeholder(fn () => now()->addDays(30)->translatedFormat('l, d F Y')) ->placeholder(fn (): string => now()->addDays(30)->translatedFormat('l, d F Y'))
->native(false) ->native(false)
->displayFormat('l, d F Y') ->displayFormat('l, d F Y')
->required() ->required()
->after('start_date'), ->after('start_date')
->minDate($record->final_submission_date)
->autocomplete(false),
TextInput::make('report_amount') TextInput::make('report_amount')
->label('Jumlah Laporan') ->label('Jumlah Laporan')
->placeholder(10) ->placeholder(10)
->numeric() ->numeric()
->minValue(1) ->minValue(1)
->required(), ->required()
Textarea::make('task_description') ->autocomplete(false),
->label('Deskripsi Tugas') Textarea::make('task_description')
->required() ->label('Deskripsi Tugas')
->rows(4) ->required()
->placeholder('...'), ->rows(4)
]) ->placeholder('...')
->action(function (array $data, Cooperation $record) { ->autocomplete(false),
];
})
->action(function (array $data, Cooperation $record): void {
$taskAssignment = $record->taskAssignments()->create([ $taskAssignment = $record->taskAssignments()->create([
'start_date' => $data['start_date'], 'start_date' => $data['start_date'],
'end_date' => $data['end_date'], 'end_date' => $data['end_date'],
@ -77,11 +86,11 @@ protected function setUp(): void
}) })
->modalHeading('Buat Penugasan') ->modalHeading('Buat Penugasan')
->modalSubmitActionLabel('Simpan') ->modalSubmitActionLabel('Simpan')
->visible( ->visible(function (Cooperation $record): bool {
fn (Cooperation $record): bool => ! auth()->user()->hasRole('Perusahaan') return ! auth()->user()->hasRole('Perusahaan')
&& ! $record->taskAssignments()->exists() && ! $record->taskAssignments()->exists()
&& $record->status === CooperationStatus::ASSIGNMENT && $record->status === CooperationStatus::ASSIGNMENT;
) })
->modalWidth(Width::Large); ->modalWidth(Width::Large);
} }
} }

View File

@ -16,7 +16,7 @@ protected function setUp(): void
$this->label('Tolak') $this->label('Tolak')
->icon(Heroicon::XMark) ->icon(Heroicon::XMark)
->color('danger') ->color('danger')
->action(function ($record) { ->action(function (\App\Models\Cooperation $record): void {
$cooperationMedia = $record->cooperationMedia() $cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) { ->whereHas('partnerMedia', function ($query) {
$query->whereHas('company', function ($subQuery) { $query->whereHas('company', function ($subQuery) {
@ -33,7 +33,7 @@ protected function setUp(): void
->send(); ->send();
} }
}) })
->visible(function ($record) { ->visible(function (\App\Models\Cooperation $record): bool {
if (! auth()->user()->hasRole('Perusahaan')) { if (! auth()->user()->hasRole('Perusahaan')) {
return false; return false;
} }

View File

@ -42,13 +42,13 @@ protected function setUp(): void
->disk(config('filesystems.default')) ->disk(config('filesystems.default'))
->acceptedFileTypes(['application/pdf']) ->acceptedFileTypes(['application/pdf'])
->maxSize(1024 * 10) ->maxSize(1024 * 10)
->directory(fn () => 'cooperations/proposal-attachment/'.now()->toDateString()) ->directory(fn (): string => 'cooperations/proposal-attachment/'.now()->toDateString())
->required(), ->required(),
]) ])
->action(function ($record, array $data) { ->action(function (\App\Models\Cooperation $record, array $data): void {
$cooperationMedia = $record->cooperationMedia() $cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) { ->whereHas('partnerMedia', function (\Illuminate\Database\Eloquent\Builder $query): void {
$query->whereHas('company', function ($subQuery) { $query->whereHas('company', function (\Illuminate\Database\Eloquent\Builder $subQuery): void {
$subQuery->where('user_id', auth()->id()); $subQuery->where('user_id', auth()->id());
}); });
}) })
@ -86,14 +86,14 @@ protected function setUp(): void
}) })
->modalHeading('Proposal Kerja Sama') ->modalHeading('Proposal Kerja Sama')
->modalSubmitActionLabel('Kirim Proposal') ->modalSubmitActionLabel('Kirim Proposal')
->visible(function ($record) { ->visible(function (\App\Models\Cooperation $record): bool {
if (! auth()->user()->hasRole('Perusahaan')) { if (! auth()->user()->hasRole('Perusahaan')) {
return false; return false;
} }
$cooperationMedia = $record->cooperationMedia() $cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) { ->whereHas('partnerMedia', function (\Illuminate\Database\Eloquent\Builder $query): void {
$query->whereHas('company', function ($subQuery) { $query->whereHas('company', function (\Illuminate\Database\Eloquent\Builder $subQuery): void {
$subQuery->where('user_id', auth()->id()); $subQuery->where('user_id', auth()->id());
}); });
}) })
@ -101,9 +101,10 @@ protected function setUp(): void
return $cooperationMedia return $cooperationMedia
&& $cooperationMedia->status === ApprovalStatus::ACCEPTED && $cooperationMedia->status === ApprovalStatus::ACCEPTED
&& $record->initial_submission_date->toDateString() === now()->toDateString()
&& ! $record->proposals() && ! $record->proposals()
->where('partner_media_id', $cooperationMedia->partner_media_id) ->where('partner_media_id', $cooperationMedia->partner_media_id)
->where(fn ($q) => $q->accepted()->orWhere(fn ($q) => $q->pending())) ->where(fn (\Illuminate\Database\Eloquent\Builder $q): \Illuminate\Database\Eloquent\Builder => $q->accepted()->orWhere(fn (\Illuminate\Database\Eloquent\Builder $q): \Illuminate\Database\Eloquent\Builder => $q->pending()))
->exists(); ->exists();
}) })
->modalWidth(Width::Large); ->modalWidth(Width::Large);

View File

@ -17,7 +17,7 @@ protected function setUp(): void
$this->label('Terima') $this->label('Terima')
->icon(Heroicon::OutlinedCheck) ->icon(Heroicon::OutlinedCheck)
->color('success') ->color('success')
->action(function (CooperationProposal $record) { ->action(function (CooperationProposal $record): void {
$record->update([ $record->update([
'status' => ApprovalStatus::ACCEPTED, 'status' => ApprovalStatus::ACCEPTED,
'responded_at' => now(), 'responded_at' => now(),
@ -29,6 +29,6 @@ protected function setUp(): void
->success() ->success()
->send(); ->send();
}) })
->visible(fn (CooperationProposal $record) => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING); ->visible(fn (CooperationProposal $record): bool => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING);
} }
} }

View File

@ -25,7 +25,7 @@ protected function setUp(): void
->placeholder('...') ->placeholder('...')
->required(), ->required(),
]) ])
->action(function (CooperationProposal $record, array $data) { ->action(function (CooperationProposal $record, array $data): void {
$record->update([ $record->update([
'status' => ApprovalStatus::REJECTED, 'status' => ApprovalStatus::REJECTED,
'responded_at' => now(), 'responded_at' => now(),
@ -39,7 +39,7 @@ protected function setUp(): void
->warning() ->warning()
->send(); ->send();
}) })
->visible(fn (CooperationProposal $record) => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING) ->visible(fn (CooperationProposal $record): bool => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING)
->modalWidth(Width::Large); ->modalWidth(Width::Large);
} }
} }

View File

@ -17,7 +17,7 @@ protected function setUp(): void
$this->label('Terima') $this->label('Terima')
->icon(Heroicon::OutlinedCheck) ->icon(Heroicon::OutlinedCheck)
->color('success') ->color('success')
->action(function (Report $record) { ->action(function (Report $record): void {
$record->update([ $record->update([
'status' => ApprovalStatus::ACCEPTED, 'status' => ApprovalStatus::ACCEPTED,
]); ]);
@ -28,6 +28,6 @@ protected function setUp(): void
->success() ->success()
->send(); ->send();
}) })
->visible(fn (Report $record) => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING); ->visible(fn (Report $record): bool => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING);
} }
} }

View File

@ -25,7 +25,7 @@ protected function setUp(): void
->placeholder('...') ->placeholder('...')
->required(), ->required(),
]) ])
->action(function (Report $record, array $data) { ->action(function (Report $record, array $data): void {
$record->update([ $record->update([
'status' => ApprovalStatus::REJECTED, 'status' => ApprovalStatus::REJECTED,
]); ]);
@ -38,7 +38,7 @@ protected function setUp(): void
->warning() ->warning()
->send(); ->send();
}) })
->visible(fn (Report $record) => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING) ->visible(fn (Report $record): bool => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING)
->modalWidth(Width::Large); ->modalWidth(Width::Large);
} }
} }

View File

@ -47,9 +47,9 @@ class CooperationResource extends Resource
public static function getNavigationBadge(): ?string public static function getNavigationBadge(): ?string
{ {
return static::getModel()::when(auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value), function ($query) { return static::getModel()::when(auth()->user()->hasRole(RoleEnum::PERUSAHAAN->value), function (Builder $query): void {
$query->whereHas('partnerMedia', function ($partnerMediaQuery) { $query->whereHas('partnerMedia', function (Builder $partnerMediaQuery): void {
$partnerMediaQuery->whereHas('company', function ($companyQuery) { $partnerMediaQuery->whereHas('company', function (Builder $companyQuery): void {
$companyQuery->where('user_id', auth()->id()); $companyQuery->where('user_id', auth()->id());
}); });
}); });
@ -65,11 +65,11 @@ public static function form(Schema $schema): Schema
public static function table(Table $table): Table public static function table(Table $table): Table
{ {
return CooperationsTable::configure($table) return CooperationsTable::configure($table)
->modifyQueryUsing(function (Builder $query) { ->modifyQueryUsing(function (Builder $query): Builder {
if (auth()->user()->hasRole('Perusahaan')) { if (auth()->user()->hasRole('Perusahaan')) {
$query->whereHas('cooperationMedia', function ($subQuery) { $query->whereHas('cooperationMedia', function (Builder $subQuery): void {
$subQuery->whereHas('partnerMedia', function ($mediaQuery) { $subQuery->whereHas('partnerMedia', function (Builder $mediaQuery): void {
$mediaQuery->whereHas('company', function ($companyQuery) { $mediaQuery->whereHas('company', function (Builder $companyQuery): void {
$companyQuery->where('user_id', auth()->id()); $companyQuery->where('user_id', auth()->id());
}); });
}); });
@ -87,9 +87,9 @@ public static function infolist(Schema $schema): Schema
Section::make('Informasi Kerja Sama') Section::make('Informasi Kerja Sama')
->headerActions([ ->headerActions([
Action::make('status') Action::make('status')
->label(fn ($record) => $record->status->getLabel()) ->label(fn (Cooperation $record): ?string => $record->status->getLabel())
->badge() ->badge()
->color(fn ($record) => $record->status->getColor()) ->color(fn (Cooperation $record): string|array|null => $record->status->getColor())
->disabled(), ->disabled(),
]) ])
->schema([ ->schema([
@ -131,15 +131,15 @@ public static function infolist(Schema $schema): Schema
->schema([ ->schema([
PdfViewerEntry::make('proposal_template') PdfViewerEntry::make('proposal_template')
->label('Template Proposal') ->label('Template Proposal')
->getStateUsing(fn ($record) => optional($record->getMedia('cooperations')->where('custom_properties.doc_type', 'proposal-template')->sortByDesc('created_at')->first())->getPathRelativeToRoot()) ->getStateUsing(fn (Cooperation $record): ?string => optional($record->getMedia('cooperations')->where('custom_properties.doc_type', 'proposal-template')->sortByDesc('created_at')->first())->getPathRelativeToRoot())
->disk(config('filesystems.default')) ->disk(config('filesystems.default'))
->columnSpan(2), ->columnSpan(2),
ImageEntry::make('banner') ImageEntry::make('banner')
->label('Banner') ->label('Banner')
->getStateUsing(fn ($record) => optional($record->getMedia('cooperations')->where('custom_properties.doc_type', 'banner')->sortByDesc('created_at')->first())->getPathRelativeToRoot()) ->getStateUsing(fn (Cooperation $record): ?string => optional($record->getMedia('cooperations')->where('custom_properties.doc_type', 'banner')->sortByDesc('created_at')->first())->getPathRelativeToRoot())
->disk(config('filesystems.default')) ->disk(config('filesystems.default'))
->visible(fn ($record) => $record->getMedia('cooperations')->isNotEmpty()), ->visible(fn (Cooperation $record): bool => $record->getMedia('cooperations')->isNotEmpty()),
]), ]),
TextEntry::make('description') TextEntry::make('description')

View File

@ -5,10 +5,10 @@
use App\Enums\ApprovalStatus; use App\Enums\ApprovalStatus;
use App\Filament\Resources\Manage\Cooperations\CooperationResource; use App\Filament\Resources\Manage\Cooperations\CooperationResource;
use Filament\Actions\Action; use Filament\Actions\Action;
use Filament\Infolists\Components\RepeatableEntry;
use Filament\Infolists\Components\TextEntry;
use Filament\Notifications\Notification; use Filament\Notifications\Notification;
use Filament\Resources\Pages\ViewRecord; use Filament\Resources\Pages\ViewRecord;
use Filament\Schemas\Components\RepeatableEntry;
use Filament\Schemas\Components\TextEntry;
use Filament\Support\Enums\FontWeight; use Filament\Support\Enums\FontWeight;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
@ -77,7 +77,7 @@ protected function getWorkflowSteps()
->schema([ ->schema([
TextEntry::make('step') TextEntry::make('step')
->label('Langkah') ->label('Langkah')
->formatStateUsing(fn ($state) => "Langkah {$state}") ->formatStateUsing(fn (int $state): string => "Langkah {$state}")
->weight(FontWeight::Bold), ->weight(FontWeight::Bold),
TextEntry::make('title') TextEntry::make('title')
@ -250,19 +250,19 @@ protected function getHeaderActions(): array
->label('Tandai Selesai') ->label('Tandai Selesai')
->icon('heroicon-o-check-circle') ->icon('heroicon-o-check-circle')
->color('success') ->color('success')
->action(function () { ->action(function (): void {
// Logic to mark cooperation as completed // Logic to mark cooperation as completed
Notification::make() Notification::make()
->title('Kerja Sama Ditandai Selesai') ->title('Kerja Sama Ditandai Selesai')
->success() ->success()
->send(); ->send();
}) })
->visible(fn () => $this->canMarkAsCompleted()); ->visible(fn (): bool => $this->canMarkAsCompleted());
} else { } else {
// For Perusahaan users, add accept/reject actions if they have a cooperation media record // For Perusahaan users, add accept/reject actions if they have a cooperation media record
$cooperationMedia = $record->cooperationMedia() $cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) { ->whereHas('partnerMedia', function (\Illuminate\Database\Eloquent\Builder $query): void {
$query->whereHas('company', function ($subQuery) { $query->whereHas('company', function (\Illuminate\Database\Eloquent\Builder $subQuery): void {
$subQuery->where('user_id', Auth::id()); $subQuery->where('user_id', Auth::id());
}); });
}) })
@ -273,7 +273,7 @@ protected function getHeaderActions(): array
->label('Terima Kerja Sama') ->label('Terima Kerja Sama')
->icon('heroicon-o-check-circle') ->icon('heroicon-o-check-circle')
->color('success') ->color('success')
->action(function () use ($cooperationMedia) { ->action(function () use ($cooperationMedia): void {
$cooperationMedia->update(['status' => ApprovalStatus::ACCEPTED]); $cooperationMedia->update(['status' => ApprovalStatus::ACCEPTED]);
Notification::make() Notification::make()
->title('Kerja Sama Diterima') ->title('Kerja Sama Diterima')
@ -285,7 +285,7 @@ protected function getHeaderActions(): array
->label('Tolak Kerja Sama') ->label('Tolak Kerja Sama')
->icon('heroicon-o-x-circle') ->icon('heroicon-o-x-circle')
->color('danger') ->color('danger')
->action(function () use ($cooperationMedia) { ->action(function () use ($cooperationMedia): void {
$cooperationMedia->update(['status' => ApprovalStatus::REJECTED]); $cooperationMedia->update(['status' => ApprovalStatus::REJECTED]);
Notification::make() Notification::make()
->title('Kerja Sama Ditolak') ->title('Kerja Sama Ditolak')

View File

@ -22,6 +22,11 @@ public static function canViewForRecord(Model $ownerRecord, string $pageClass):
return ! auth()->user()->hasRole('Perusahaan'); return ! auth()->user()->hasRole('Perusahaan');
} }
public static function getBadge(Model $ownerRecord, string $pageClass): ?string
{
return $ownerRecord->cooperationMedia()->count();
}
public function table(Table $table): Table public function table(Table $table): Table
{ {
return $table return $table
@ -41,11 +46,11 @@ public function table(Table $table): Table
Action::make('view') Action::make('view')
->label('Lihat') ->label('Lihat')
->icon(Heroicon::Eye) ->icon(Heroicon::Eye)
->url( ->url(function (CooperationMedia $record): string {
fn (CooperationMedia $record): string => PartnerResource::getUrl('view', [ return PartnerResource::getUrl('view', [
'record' => $record->partnerMedia->company->user_id, 'record' => $record->partnerMedia->company->user_id,
]) ]);
), }),
]) ])
->recordAction(null); ->recordAction(null);
} }

View File

@ -14,7 +14,6 @@
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
use Joaopaulolndev\FilamentPdfViewer\Infolists\Components\PdfViewerEntry; use Joaopaulolndev\FilamentPdfViewer\Infolists\Components\PdfViewerEntry;
class CooperationProposalRelationManager extends RelationManager class CooperationProposalRelationManager extends RelationManager
@ -23,15 +22,10 @@ class CooperationProposalRelationManager extends RelationManager
protected static ?string $title = 'Proposal'; protected static ?string $title = 'Proposal';
public static function getBadge(Model $ownerRecord, string $pageClass): ?string
{
return $ownerRecord->proposals()->count();
}
public function table(Table $table): Table public function table(Table $table): Table
{ {
return $table return $table
->recordTitleAttribute('description') ->recordTitleAttribute('e_catalog')
->columns([ ->columns([
TextColumn::make('partnerMedia.name') TextColumn::make('partnerMedia.name')
->label('Media') ->label('Media')
@ -40,7 +34,7 @@ public function table(Table $table): Table
TextColumn::make('e_catalog') TextColumn::make('e_catalog')
->label('E-Catalog') ->label('E-Catalog')
->url(fn ($record) => $record->e_catalog) ->url(fn (\App\Models\CooperationProposal $record): ?string => $record->e_catalog)
->openUrlInNewTab() ->openUrlInNewTab()
->color('primary'), ->color('primary'),
@ -69,7 +63,9 @@ public function table(Table $table): Table
->headerActions([]) ->headerActions([])
->recordActions([ ->recordActions([
ViewAction::make(), ViewAction::make(),
AcceptAction::make('accept'), AcceptAction::make('accept'),
RejectAction::make('reject'), RejectAction::make('reject'),
]) ])
->toolbarActions([ ->toolbarActions([
@ -104,10 +100,10 @@ public function infolist(Schema $infolist): Schema
TextEntry::make('e_catalog') TextEntry::make('e_catalog')
->label('E-Catalog') ->label('E-Catalog')
->url(fn ($record) => $record->e_catalog) ->url(fn (\App\Models\CooperationProposal $record): ?string => $record->e_catalog)
->openUrlInNewTab() ->openUrlInNewTab()
->color('primary') ->color('primary')
->visible(fn ($record) => $record->e_catalog), ->visible(fn (\App\Models\CooperationProposal $record): ?string => $record->e_catalog),
TextEntry::make('description') TextEntry::make('description')
->label('Deskripsi') ->label('Deskripsi')
@ -115,13 +111,13 @@ public function infolist(Schema $infolist): Schema
PdfViewerEntry::make('proposal_attachment') PdfViewerEntry::make('proposal_attachment')
->label('Lampiran Proposal') ->label('Lampiran Proposal')
->getStateUsing(fn ($record) => optional($record->getMedia('cooperations')->where('custom_properties.doc_type', 'proposal-attachment')->sortByDesc('created_at')->first())->getPathRelativeToRoot()) ->getStateUsing(fn (\App\Models\CooperationProposal $record): ?string => optional($record->getMedia('cooperations')->where('custom_properties.doc_type', 'proposal-attachment')->sortByDesc('created_at')->first())->getPathRelativeToRoot())
->disk(config('filesystems.default')), ->disk(config('filesystems.default')),
TextEntry::make('rejectionReasons.reason') TextEntry::make('rejectionReasons.reason')
->label('Alasan Penolakan') ->label('Alasan Penolakan')
->listWithLineBreaks() ->listWithLineBreaks()
->visible(fn ($record) => $record->status === ApprovalStatus::REJECTED && $record->rejectionReasons->isNotEmpty()) ->visible(fn (\App\Models\CooperationProposal $record): bool => $record->status === ApprovalStatus::REJECTED && $record->rejectionReasons->isNotEmpty())
->columnSpanFull(), ->columnSpanFull(),
]) ])
->columns(1); ->columns(1);

View File

@ -33,11 +33,13 @@ public function form(Schema $schema): Schema
TextInput::make('title') TextInput::make('title')
->placeholder('Dirgahayu Purwakarta') ->placeholder('Dirgahayu Purwakarta')
->required() ->required()
->maxLength(200), ->maxLength(200)
->autocomplete(false)
->autofocus(),
DatePicker::make('publication_date') DatePicker::make('publication_date')
->label('Tanggal Publikasi') ->label('Tanggal Publikasi')
->placeholder(fn () => now()->format('l, d F Y')) ->placeholder(fn (): string => now()->format('l, d F Y'))
->native(false) ->native(false)
->displayFormat('l, d F Y') ->displayFormat('l, d F Y')
->required(), ->required(),
@ -47,12 +49,14 @@ public function form(Schema $schema): Schema
->placeholder('https://example.com') ->placeholder('https://example.com')
->maxLength(50) ->maxLength(50)
->url() ->url()
->required(), ->required()
->autocomplete(false),
Textarea::make('description') Textarea::make('description')
->label('Deskripsi') ->label('Deskripsi')
->placeholder('....') ->placeholder('....')
->required(), ->required()
->autocomplete(false),
SpatieMediaLibraryFileUpload::make('image') SpatieMediaLibraryFileUpload::make('image')
->label('Gambar') ->label('Gambar')
@ -82,7 +86,7 @@ public function table(Table $table): Table
TextColumn::make('link') TextColumn::make('link')
->label('Link') ->label('Link')
->limit(30) ->limit(30)
->url(fn ($record) => $record->link) ->url(fn (\App\Models\Report $record): string => $record->link)
->openUrlInNewTab(), ->openUrlInNewTab(),
TextColumn::make('status') TextColumn::make('status')
@ -96,6 +100,7 @@ public function table(Table $table): Table
->filters([]) ->filters([])
->recordActions([ ->recordActions([
AcceptAction::make('accept'), AcceptAction::make('accept'),
RejectAction::make('reject'), RejectAction::make('reject'),
]) ])
->headerActions([ ->headerActions([
@ -107,6 +112,15 @@ public function table(Table $table): Table
$data['task_assignment_id'] = $this->getOwnerRecord()->taskAssignments()->first()?->id; $data['task_assignment_id'] = $this->getOwnerRecord()->taskAssignments()->first()?->id;
return $data; return $data;
})
->visible(function (): bool {
$taskAssignment = $this->getOwnerRecord()->taskAssignments()->first();
if (! $taskAssignment) {
return false;
}
return $taskAssignment->reports()->count() < $taskAssignment->report_amount;
}), }),
]) ])
->toolbarActions([]); ->toolbarActions([]);

View File

@ -31,33 +31,39 @@ public function form(Schema $schema): Schema
DatePicker::make('start_date') DatePicker::make('start_date')
->label('Tanggal Mulai') ->label('Tanggal Mulai')
->required() ->required()
->native(false), ->native(false)
->autocomplete(false)
->autofocus(),
DatePicker::make('end_date') DatePicker::make('end_date')
->label('Tanggal Selesai') ->label('Tanggal Selesai')
->required() ->required()
->native(false) ->native(false)
->after('start_date'), ->after('start_date')
->autocomplete(false),
Textarea::make('task_description') Textarea::make('task_description')
->label('Deskripsi Tugas') ->label('Deskripsi Tugas')
->required() ->required()
->rows(4) ->rows(4)
->maxLength(65535), ->maxLength(65535)
->autocomplete(false),
TextInput::make('report_amount') TextInput::make('report_amount')
->label('Jumlah Laporan') ->label('Jumlah Laporan')
->numeric() ->numeric()
->required() ->required()
->minValue(1) ->minValue(1)
->default(1), ->default(1)
->autocomplete(false),
Select::make('partner_media_ids') Select::make('partner_media_ids')
->label('Media yang Ditugaskan') ->label('Media yang Ditugaskan')
->relationship('partnerMedia', 'name') ->relationship('partnerMedia', 'name')
->multiple() ->multiple()
->preload() ->preload()
->required(), ->required()
->autocomplete(false),
Select::make('status') Select::make('status')
->options(ApprovalStatus::options()) ->options(ApprovalStatus::options())
@ -67,7 +73,8 @@ public function form(Schema $schema): Schema
Textarea::make('rejection_reason') Textarea::make('rejection_reason')
->label('Alasan Penolakan') ->label('Alasan Penolakan')
->rows(3) ->rows(3)
->columnSpanFull(), ->columnSpanFull()
->autocomplete(false),
]); ]);
} }
@ -90,9 +97,10 @@ public function table(Table $table): Table
TextColumn::make('report_amount') TextColumn::make('report_amount')
->label('Jumlah Laporan'), ->label('Jumlah Laporan'),
TextColumn::make('report_count') TextColumn::make('report_count')
->label('Laporan Diterima') ->label('Laporan Diterima')
->getStateUsing(function (TaskAssignment $record) { ->getStateUsing(function (TaskAssignment $record): string {
return $record->reports()->count().' / '.($record->report_amount * $record->partnerMedia()->count()); return $record->reports()->count().' / '.($record->report_amount * $record->partnerMedia()->count());
}), }),
]) ])
@ -102,7 +110,11 @@ public function table(Table $table): Table
->headerActions([ ->headerActions([
CreateAction::make() CreateAction::make()
->label('Buat Penugasan') ->label('Buat Penugasan')
->visible(fn () => $this->canCreateTaskAssignment()), ->visible(function (): bool {
$cooperation = $this->getOwnerRecord();
return $cooperation->proposals()->accepted()->exists();
}),
]) ])
->recordActions([ ->recordActions([
EditAction::make(), EditAction::make(),
@ -115,12 +127,4 @@ public function table(Table $table): Table
]), ]),
]); ]);
} }
protected function canCreateTaskAssignment(): bool
{
$cooperation = $this->getOwnerRecord();
// Can create task assignment only if there are accepted proposals
return $cooperation->proposals()->accepted()->exists();
}
} }

View File

@ -35,23 +35,25 @@ public static function configure(Schema $schema): Schema
->schema([ ->schema([
DatePicker::make('initial_submission_date') DatePicker::make('initial_submission_date')
->label('Tanggal Pengajuan Awal') ->label('Tanggal Pengajuan Awal')
->placeholder(fn () => now()->format('Y-m-d')) ->placeholder(fn (): string => now()->format('Y-m-d'))
->native(false)
->displayFormat('l, d F Y')
->required(),
DatePicker::make('final_submission_date')
->label('Tanggal Pengajuan Akhir')
->placeholder(fn () => now()->addDays(30)->format('Y-m-d'))
->native(false) ->native(false)
->displayFormat('l, d F Y') ->displayFormat('l, d F Y')
->required() ->required()
->after('initial_submission_date'), ->autocomplete(false),
DatePicker::make('final_submission_date')
->label('Tanggal Pengajuan Akhir')
->placeholder(fn (): string => now()->addDays(30)->format('Y-m-d'))
->native(false)
->displayFormat('l, d F Y')
->required()
->after('initial_submission_date')
->autocomplete(false),
]), ]),
Select::make('partner_media_ids') Select::make('partner_media_ids')
->label('Media') ->label('Media')
->relationship('partnerMedia', 'name', fn (Builder $query) => $query->verified()) ->relationship('partnerMedia', 'name', fn (Builder $query): Builder => $query->verified())
->multiple() ->multiple()
->preload() ->preload()
->searchable() ->searchable()
@ -59,11 +61,12 @@ public static function configure(Schema $schema): Schema
->required() ->required()
->selectablePlaceholder(false) ->selectablePlaceholder(false)
->helperText('Pilih media yang akan diajak kerja sama.') ->helperText('Pilih media yang akan diajak kerja sama.')
->autocomplete(false)
->suffixAction( ->suffixAction(
Action::make('select_all') Action::make('select_all')
->label('Select All') ->label('Select All')
->icon(Heroicon::OutlinedCheckCircle) ->icon(Heroicon::OutlinedCheckCircle)
->action(function ($set, $livewire) { ->action(function (\Filament\Schemas\Components\Utilities\Set $set): void {
$allMediaIds = PartnerMedia::verified()->pluck('id')->toArray(); $allMediaIds = PartnerMedia::verified()->pluck('id')->toArray();
$set('partner_media_ids', $allMediaIds); $set('partner_media_ids', $allMediaIds);
}) })
@ -74,7 +77,8 @@ public static function configure(Schema $schema): Schema
->placeholder('...') ->placeholder('...')
->required() ->required()
->rows(5) ->rows(5)
->maxLength(65535), ->maxLength(65535)
->autocomplete(false),
]) ])
->columnSpan(2), ->columnSpan(2),
@ -85,7 +89,7 @@ public static function configure(Schema $schema): Schema
->acceptedFileTypes(['image/*']) ->acceptedFileTypes(['image/*'])
->maxSize(1024 * 3) ->maxSize(1024 * 3)
->collection('cooperations') ->collection('cooperations')
->customProperties(fn () => [ ->customProperties(fn (): array => [
'feature' => 'cooperations', 'feature' => 'cooperations',
'doc_type' => 'banner', 'doc_type' => 'banner',
'date' => now()->toDateString(), 'date' => now()->toDateString(),
@ -97,7 +101,7 @@ public static function configure(Schema $schema): Schema
->disk(config('filesystems.default')) ->disk(config('filesystems.default'))
->acceptedFileTypes(['application/pdf']) ->acceptedFileTypes(['application/pdf'])
->maxSize(1024 * 10) ->maxSize(1024 * 10)
->directory(fn () => 'cooperations/proposal-template/'.now()->toDateString()) ->directory(fn (): string => 'cooperations/proposal-template/'.now()->toDateString())
->required(), ->required(),
]), ]),
]) ])

View File

@ -2,6 +2,7 @@
namespace App\Filament\Resources\Manage\Cooperations\Tables; namespace App\Filament\Resources\Manage\Cooperations\Tables;
use App\Enums\ApprovalStatus;
use App\Filament\Actions\DefaultBulkActions; use App\Filament\Actions\DefaultBulkActions;
use App\Filament\Columns\TimestampColumns; use App\Filament\Columns\TimestampColumns;
use App\Filament\Resources\Manage\Cooperations\Actions\Cooperation\AcceptAction; use App\Filament\Resources\Manage\Cooperations\Actions\Cooperation\AcceptAction;
@ -18,6 +19,7 @@
use Filament\Tables\Columns\TextColumn; use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\TrashedFilter; use Filament\Tables\Filters\TrashedFilter;
use Filament\Tables\Table; use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
class CooperationsTable class CooperationsTable
{ {
@ -83,11 +85,11 @@ public static function configure(Table $table): Table
TextColumn::make('media_count') TextColumn::make('media_count')
->label('Tanggapan Media') ->label('Tanggapan Media')
->html() ->html()
->getStateUsing(function (Cooperation $record) { ->getStateUsing(function (Cooperation $record): string {
$record->loadCount([ $record->loadCount([
'partnerMedia as approved_count' => fn ($query) => $query->wherePivotAccepted(), 'partnerMedia as approved_count' => fn (Builder $query): Builder => $query->wherePivotAccepted(),
'partnerMedia as rejected_count' => fn ($query) => $query->wherePivotRejected(), 'partnerMedia as rejected_count' => fn (Builder $query): Builder => $query->wherePivotRejected(),
'partnerMedia as pending_count' => fn ($query) => $query->wherePivotPending(), 'partnerMedia as pending_count' => fn (Builder $query): Builder => $query->wherePivotPending(),
]); ]);
$totalCount = $record->partnerMedia()->count(); $totalCount = $record->partnerMedia()->count();
@ -101,11 +103,11 @@ public static function configure(Table $table): Table
TextColumn::make('status_tanggapan') TextColumn::make('status_tanggapan')
->label('Tanggapan') ->label('Tanggapan')
->getStateUsing(function ($record) { ->getStateUsing(function (Cooperation $record): ?ApprovalStatus {
if (auth()->user()->hasRole('Perusahaan')) { if (auth()->user()->hasRole('Perusahaan')) {
$cooperationMedia = $record->cooperationMedia() $cooperationMedia = $record->cooperationMedia()
->whereHas('partnerMedia', function ($query) { ->whereHas('partnerMedia', function (Builder $query): void {
$query->whereHas('company', function ($subQuery) { $query->whereHas('company', function (Builder $subQuery): void {
$subQuery->where('user_id', auth()->id()); $subQuery->where('user_id', auth()->id());
}); });
}) })
@ -157,10 +159,10 @@ public static function configure(Table $table): Table
CreateTaskAssignmentAction::make('create_task_assignment'), CreateTaskAssignmentAction::make('create_task_assignment'),
EditAction::make() EditAction::make()
->visible(fn () => ! auth()->user()->hasRole('Perusahaan')), ->visible(fn (): bool => ! auth()->user()->hasRole('Perusahaan')),
DeleteAction::make() DeleteAction::make()
->visible(fn () => ! auth()->user()->hasRole('Perusahaan')), ->visible(fn (): bool => ! auth()->user()->hasRole('Perusahaan')),
]) ])
->toolbarActions([ ->toolbarActions([
BulkActionGroup::make([ BulkActionGroup::make([

View File

@ -11,7 +11,7 @@ protected function setUp(): void
{ {
parent::setUp(); parent::setUp();
$this->visible(function () { $this->visible(function (): bool {
$user = auth()->user(); $user = auth()->user();
if (! $user->hasRole('Perusahaan')) { if (! $user->hasRole('Perusahaan')) {

View File

@ -16,7 +16,7 @@ protected function setUp(): void
parent::setUp(); parent::setUp();
$this->modalWidth(Width::Large) $this->modalWidth(Width::Large)
->fillForm(function (Journalist $journalist) { ->fillForm(function (Journalist $journalist): array {
$data = [ $data = [
'name' => $journalist->name, 'name' => $journalist->name,
'email' => $journalist->email, 'email' => $journalist->email,
@ -87,7 +87,8 @@ protected function setUp(): void
return $record; return $record;
}) })
->visible(function () { ->visible(function (): bool {
/** @var \App\Models\User $user */
$user = auth()->user(); $user = auth()->user();
if (! $user->hasRole('Perusahaan')) { if (! $user->hasRole('Perusahaan')) {

View File

@ -85,7 +85,6 @@ public static function form(Schema $schema): Schema
->label('Alamat Surel') ->label('Alamat Surel')
->placeholder('johndoe@example.com') ->placeholder('johndoe@example.com')
->autocomplete(false) ->autocomplete(false)
->autofocus()
->required() ->required()
->maxLength(254) ->maxLength(254)
->unique('journalists', 'email', ignoreRecord: true) ->unique('journalists', 'email', ignoreRecord: true)
@ -102,8 +101,8 @@ public static function form(Schema $schema): Schema
Group::make() Group::make()
->schema( ->schema(
collect($documents) collect($documents)
->map( ->map(function (array $doc): Section {
fn ($doc) => Section::make($doc['title']) return Section::make($doc['title'])
->schema([ ->schema([
TextInput::make($doc['text_name']) TextInput::make($doc['text_name'])
->hiddenLabel() ->hiddenLabel()
@ -116,11 +115,11 @@ public static function form(Schema $schema): Schema
->hiddenLabel() ->hiddenLabel()
->disk(config('filesystems.default')) ->disk(config('filesystems.default'))
->acceptedFileTypes($doc['accept']) ->acceptedFileTypes($doc['accept'])
->directory(fn () => 'journalists/'.$doc['folder'].now()->toDateString()) ->directory(fn (): string => 'journalists/'.$doc['folder'].now()->toDateString())
->maxSize($doc['max_size']) ->maxSize($doc['max_size'])
->required(), ->required(),
]) ]);
) })
->toArray() ->toArray()
), ),
]) ])
@ -187,18 +186,18 @@ public static function table(Table $table): Table
->emptyStateDescription('Setelah Anda membubat data pertama, maka akan muncul disini.') ->emptyStateDescription('Setelah Anda membubat data pertama, maka akan muncul disini.')
->defaultSort('created_at', 'desc') ->defaultSort('created_at', 'desc')
->deferFilters(false) ->deferFilters(false)
->modifyQueryUsing(function (Builder $query) { ->modifyQueryUsing(function (Builder $query): void {
if (auth()->user()->hasRole('Perusahaan') && ! auth()->user()->company?->partnerMedia) { if (auth()->user()->hasRole('Perusahaan') && ! auth()->user()->company?->partnerMedia) {
$query->whereRaw('1 = 0'); $query->whereRaw('1 = 0');
} }
$query->when(auth()->user()->hasRole('Perusahaan'), function (Builder $q) { $query->when(auth()->user()->hasRole('Perusahaan'), function (Builder $q): Builder {
return $q->whereHas('partnerMedia.company', function (Builder $q) { return $q->whereHas('partnerMedia.company', function (Builder $q): void {
$q->where('user_id', auth()->id()); $q->where('user_id', auth()->id());
}); });
}); });
}) })
->when(auth()->user()->hasRole('Perusahaan') && ! auth()->user()->company?->partnerMedia, function (Table $table) { ->when(auth()->user()->hasRole('Perusahaan') && ! auth()->user()->company?->partnerMedia, function (Table $table): Table {
return $table return $table
->emptyStateHeading('Akses Dibatasi') ->emptyStateHeading('Akses Dibatasi')
->emptyStateDescription('Mohon lengkapi data Media Anda terlebih dahulu.') ->emptyStateDescription('Mohon lengkapi data Media Anda terlebih dahulu.')

View File

@ -91,7 +91,7 @@ public static function infolist(Schema $schema): Schema
TextEntry::make('company.rejection_reason') TextEntry::make('company.rejection_reason')
->label('Alasan Penolakan') ->label('Alasan Penolakan')
->visible(fn ($record) => $record->company?->rejection_reason), ->visible(fn (User $record): ?string => $record->company?->rejection_reason),
]), ]),
Grid::make(3) Grid::make(3)
@ -104,7 +104,7 @@ public static function infolist(Schema $schema): Schema
TextEntry::make('company.director_nik_docs') TextEntry::make('company.director_nik_docs')
->hiddenLabel() ->hiddenLabel()
->html() ->html()
->getStateUsing(function ($record) { ->getStateUsing(function (User $record): string {
$media = $record->company $media = $record->company
?->getMedia('companies') ?->getMedia('companies')
->where('custom_properties.doc_type', 'director-nik') ->where('custom_properties.doc_type', 'director-nik')
@ -197,7 +197,7 @@ public static function infolist(Schema $schema): Schema
TextEntry::make('company.partnerMedia.link') TextEntry::make('company.partnerMedia.link')
->label('Tautan') ->label('Tautan')
->url(fn ($record) => $record->company?->partnerMedia?->link, true), ->url(fn (User $record): ?string => $record->company?->partnerMedia?->link, true),
TextEntry::make('company.partnerMedia.type') TextEntry::make('company.partnerMedia.type')
->label('Jenis') ->label('Jenis')
@ -281,7 +281,7 @@ public static function table(Table $table): Table
->label('Perusahaan') ->label('Perusahaan')
->searchable() ->searchable()
->sortable() ->sortable()
->description(fn (User $record) => 'Direktur: '.$record->company?->director_name), ->description(fn (User $record): string => 'Direktur: '.$record->company?->director_name),
TextColumn::make('company.partnerMedia.name') TextColumn::make('company.partnerMedia.name')
->label('Media') ->label('Media')
@ -323,7 +323,7 @@ public static function table(Table $table): Table
->defaultSort('created_at', 'desc') ->defaultSort('created_at', 'desc')
->deferFilters(false) ->deferFilters(false)
->reorderable('sort_order') ->reorderable('sort_order')
->modifyQueryUsing(function (Builder $query) { ->modifyQueryUsing(function (Builder $query): void {
$query->role('Perusahaan') $query->role('Perusahaan')
->whereHas('company'); ->whereHas('company');
}); });
@ -344,7 +344,7 @@ private static function fileEntry(
): PdfViewerEntry { ): PdfViewerEntry {
return PdfViewerEntry::make($name) return PdfViewerEntry::make($name)
->hiddenLabel() ->hiddenLabel()
->getStateUsing(function ($record) use ($name, $mediaOwner, $collection) { ->getStateUsing(function (\Illuminate\Database\Eloquent\Model $record) use ($name, $mediaOwner, $collection): ?string {
$owner = data_get($record, $mediaOwner); $owner = data_get($record, $mediaOwner);
if (! $owner) { if (! $owner) {
@ -356,7 +356,7 @@ private static function fileEntry(
->slug('-'); ->slug('-');
return $owner->getMedia($collection) return $owner->getMedia($collection)
->where('custom_properties.doc_type', $docType) ->where('custom_properties.doc_type', (string) $docType)
->sortByDesc('created_at') ->sortByDesc('created_at')
->first() ->first()
?->getUrl(); ?->getUrl();

View File

@ -70,8 +70,8 @@ public static function table(Table $table): Table
ToggleColumn::make('is_active') ToggleColumn::make('is_active')
->label('Aktif?') ->label('Aktif?')
->sortable() ->sortable()
->getStateUsing(fn (Category $record) => $record->is_active === IsActive::ACTIVE) ->getStateUsing(fn (Category $record): bool => $record->is_active === IsActive::ACTIVE)
->updateStateUsing(function (Category $record, bool $state) { ->updateStateUsing(function (Category $record, bool $state): void {
$record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE; $record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE;
$record->save(); $record->save();
}), }),

View File

@ -70,8 +70,8 @@ public static function table(Table $table): Table
ToggleColumn::make('is_active') ToggleColumn::make('is_active')
->label('Aktif?') ->label('Aktif?')
->sortable() ->sortable()
->getStateUsing(fn (Classification $record) => $record->is_active === IsActive::ACTIVE) ->getStateUsing(fn (Classification $record): bool => $record->is_active === IsActive::ACTIVE)
->updateStateUsing(function (Classification $record, bool $state) { ->updateStateUsing(function (Classification $record, bool $state): void {
$record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE; $record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE;
$record->save(); $record->save();
}), }),

View File

@ -57,7 +57,6 @@ public static function form(Schema $schema): Schema
TextInput::make('alias') TextInput::make('alias')
->placeholder('Diskominfo') ->placeholder('Diskominfo')
->autocomplete(false) ->autocomplete(false)
->autofocus()
->required() ->required()
->maxLength(20), ->maxLength(20),
]) ])
@ -81,8 +80,8 @@ public static function table(Table $table): Table
ToggleColumn::make('is_active') ToggleColumn::make('is_active')
->label('Aktif?') ->label('Aktif?')
->sortable() ->sortable()
->getStateUsing(fn (Department $record) => $record->is_active === IsActive::ACTIVE) ->getStateUsing(fn (Department $record): bool => $record->is_active === IsActive::ACTIVE)
->updateStateUsing(function (Department $record, bool $state) { ->updateStateUsing(function (Department $record, bool $state): void {
$record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE; $record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE;
$record->save(); $record->save();
}), }),

View File

@ -70,8 +70,8 @@ public static function table(Table $table): Table
ToggleColumn::make('is_active') ToggleColumn::make('is_active')
->label('Aktif?') ->label('Aktif?')
->sortable() ->sortable()
->getStateUsing(fn (Location $record) => $record->is_active === IsActive::ACTIVE) ->getStateUsing(fn (Location $record): bool => $record->is_active === IsActive::ACTIVE)
->updateStateUsing(function (Location $record, bool $state) { ->updateStateUsing(function (Location $record, bool $state): void {
$record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE; $record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE;
$record->save(); $record->save();
}), }),

View File

@ -54,13 +54,14 @@ public static function form(Schema $schema): Schema
->searchable() ->searchable()
->native(false) ->native(false)
->required() ->required()
->rules(['exists:classifications,id']), ->rules(['exists:classifications,id'])
->autocomplete(false)
->autofocus(),
TextInput::make('name') TextInput::make('name')
->label('Nama') ->label('Nama')
->placeholder('Korupsi') ->placeholder('Korupsi')
->autocomplete(false) ->autocomplete(false)
->autofocus()
->required() ->required()
->maxLength(50), ->maxLength(50),
]) ])
@ -85,8 +86,8 @@ public static function table(Table $table): Table
ToggleColumn::make('is_active') ToggleColumn::make('is_active')
->label('Aktif?') ->label('Aktif?')
->sortable() ->sortable()
->getStateUsing(fn (SubClassification $record) => $record->is_active === IsActive::ACTIVE) ->getStateUsing(fn (SubClassification $record): bool => $record->is_active === IsActive::ACTIVE)
->updateStateUsing(function (SubClassification $record, bool $state) { ->updateStateUsing(function (SubClassification $record, bool $state): void {
$record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE; $record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE;
$record->save(); $record->save();
}), }),

View File

@ -54,13 +54,14 @@ public static function form(Schema $schema): Schema
->searchable() ->searchable()
->native(false) ->native(false)
->required() ->required()
->rules(['exists:locations,id']), ->rules(['exists:locations,id'])
->autocomplete(false)
->autofocus(),
TextInput::make('name') TextInput::make('name')
->label('Nama') ->label('Nama')
->placeholder('Nagri Kaler') ->placeholder('Nagri Kaler')
->autocomplete(false) ->autocomplete(false)
->autofocus()
->required() ->required()
->maxLength(50), ->maxLength(50),
]) ])
@ -85,8 +86,8 @@ public static function table(Table $table): Table
ToggleColumn::make('is_active') ToggleColumn::make('is_active')
->label('Aktif?') ->label('Aktif?')
->sortable() ->sortable()
->getStateUsing(fn (SubLocation $record) => $record->is_active === IsActive::ACTIVE) ->getStateUsing(fn (SubLocation $record): bool => $record->is_active === IsActive::ACTIVE)
->updateStateUsing(function (SubLocation $record, bool $state) { ->updateStateUsing(function (SubLocation $record, bool $state): void {
$record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE; $record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE;
$record->save(); $record->save();
}), }),

View File

@ -70,8 +70,8 @@ public static function table(Table $table): Table
ToggleColumn::make('is_active') ToggleColumn::make('is_active')
->label('Aktif?') ->label('Aktif?')
->sortable() ->sortable()
->getStateUsing(fn (Theme $record) => $record->is_active === IsActive::ACTIVE) ->getStateUsing(fn (Theme $record): bool => $record->is_active === IsActive::ACTIVE)
->updateStateUsing(function (Theme $record, bool $state) { ->updateStateUsing(function (Theme $record, bool $state): void {
$record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE; $record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE;
$record->save(); $record->save();
}), }),

View File

@ -80,13 +80,16 @@ public static function form(Schema $schema): Schema
Select::make('roles') Select::make('roles')
->label('Peran') ->label('Peran')
->required() ->required()
->relationship('roles', 'name', fn ($query) => $query->whereNotIn('name', [RoleEnum::DEVELOPER, RoleEnum::PERUSAHAAN])) ->relationship('roles', 'name', function (Builder $query): Builder {
return $query->whereNotIn('name', [RoleEnum::DEVELOPER, RoleEnum::PERUSAHAAN]);
})
->multiple() ->multiple()
->preload() ->preload()
->searchable(), ->searchable()
->autocomplete(false),
Hidden::make('password') Hidden::make('password')
->default(fn ($record) => $record ? null : config('auth.password_default')), ->default(fn (?User $record): ?string => $record ? null : config('auth.password_default')),
]) ])
->columns(1); ->columns(1);
} }
@ -114,8 +117,8 @@ public static function table(Table $table): Table
ToggleColumn::make('is_active') ToggleColumn::make('is_active')
->label('Status') ->label('Status')
->sortable() ->sortable()
->getStateUsing(fn (User $record) => $record->is_active === IsActive::ACTIVE) ->getStateUsing(fn (User $record): bool => $record->is_active === IsActive::ACTIVE)
->updateStateUsing(function (User $record, bool $state) { ->updateStateUsing(function (User $record, bool $state): void {
$record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE; $record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE;
$record->save(); $record->save();
@ -125,14 +128,14 @@ public static function table(Table $table): Table
->delete(); ->delete();
} }
}) })
->disabled(fn (User $record) => $record->hasRole(RoleEnum::PERUSAHAAN->value)), ->disabled(fn (User $record): bool => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
TextColumn::make('roles.name') TextColumn::make('roles.name')
->label('Peran') ->label('Peran')
->searchable() ->searchable()
->sortable() ->sortable()
->badge() ->badge()
->getStateUsing(fn (User $record) => $record->roles->pluck('name', 'id')->toArray()), ->getStateUsing(fn (User $record): array => $record->roles->pluck('name', 'id')->toArray()),
...TimestampColumns::make(), ...TimestampColumns::make(),
]) ])
@ -143,16 +146,16 @@ public static function table(Table $table): Table
->recordActions([ ->recordActions([
EditAction::make() EditAction::make()
->modalWidth(Width::Large) ->modalWidth(Width::Large)
->hidden(fn (User $record) => $record->hasRole(RoleEnum::PERUSAHAAN->value)), ->hidden(fn (User $record): bool => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
DeleteAction::make() DeleteAction::make()
->hidden(fn (User $record) => $record->hasRole(RoleEnum::PERUSAHAAN->value)), ->hidden(fn (User $record): bool => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
ForceDeleteAction::make() ForceDeleteAction::make()
->hidden(fn (User $record) => $record->hasRole(RoleEnum::PERUSAHAAN->value)), ->hidden(fn (User $record): bool => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
RestoreAction::make() RestoreAction::make()
->hidden(fn (User $record) => $record->hasRole(RoleEnum::PERUSAHAAN->value)), ->hidden(fn (User $record): bool => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
]) ])
->toolbarActions([ ->toolbarActions([
BulkActionGroup::make([ BulkActionGroup::make([

View File

@ -12,6 +12,7 @@
use Filament\Schemas\Components\Grid; use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section; use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Illuminate\Database\Eloquent\Builder;
class ContentRecapForm class ContentRecapForm
{ {
@ -61,7 +62,7 @@ public static function configure(Schema $schema): Schema
DatePicker::make('posting_date') DatePicker::make('posting_date')
->label('Tanggal Posting') ->label('Tanggal Posting')
->placeholder(fn () => now()->format('Y-m-d')) ->placeholder(fn (): string => now()->format('Y-m-d'))
->native(false) ->native(false)
->displayFormat('l, d F Y') ->displayFormat('l, d F Y')
->required(), ->required(),
@ -71,7 +72,9 @@ public static function configure(Schema $schema): Schema
Section::make([ Section::make([
Select::make('classification_id') Select::make('classification_id')
->label('Klasifikasi') ->label('Klasifikasi')
->relationship('classification', 'name', fn ($query) => $query->active()) ->relationship('classification', 'name', function (Builder $query): Builder {
return $query->active();
})
->native(false) ->native(false)
->preload() ->preload()
->required(), ->required(),
@ -82,7 +85,7 @@ public static function configure(Schema $schema): Schema
->acceptedFileTypes(['image/*']) ->acceptedFileTypes(['image/*'])
->maxSize(1024 * 3) ->maxSize(1024 * 3)
->collection('content-recpaps') ->collection('content-recpaps')
->customProperties(fn () => [ ->customProperties(fn (): array => [
'feature' => 'content-recaps', 'feature' => 'content-recaps',
'date' => now()->toDateString(), 'date' => now()->toDateString(),
]) ])

View File

@ -24,7 +24,9 @@ public static function configure(Schema $schema): Schema
->relationship('mediaMonitoring', 'title') ->relationship('mediaMonitoring', 'title')
->searchable() ->searchable()
->preload() ->preload()
->required(), ->required()
->autocomplete(false)
->autofocus(),
Grid::make(2) Grid::make(2)
->schema([ ->schema([
@ -34,15 +36,19 @@ public static function configure(Schema $schema): Schema
->searchable() ->searchable()
->preload() ->preload()
->live() ->live()
->afterStateUpdated(fn (Set $set) => $set('sub_location_id', null)) ->afterStateUpdated(function (Set $set): void {
->required(), $set('sub_location_id', null);
})
->required()
->autocomplete(false),
Select::make('sub_location_id') Select::make('sub_location_id')
->label('Sub Lokasi') ->label('Sub Lokasi')
->relationship('subLocation', 'name', fn (Builder $query, Get $get) => $query->where('location_id', $get('location_id'))) ->relationship('subLocation', 'name', fn (Builder $query, Get $get): Builder => $query->where('location_id', $get('location_id')))
->searchable() ->searchable()
->preload() ->preload()
->required(), ->required()
->autocomplete(false),
]), ]),
RichEditor::make('description') RichEditor::make('description')
@ -57,30 +63,36 @@ public static function configure(Schema $schema): Schema
->options(IssueSentiment::options()) ->options(IssueSentiment::options())
->required() ->required()
->native(false) ->native(false)
->in(implode(',', array_column(IssueSentiment::cases(), 'value'))), ->in(implode(',', array_column(IssueSentiment::cases(), 'value')))
->autocomplete(false),
Select::make('response') Select::make('response')
->label('Respon') ->label('Respon')
->options(IssueSentiment::options()) ->options(IssueSentiment::options())
->required() ->required()
->native(false) ->native(false)
->in(implode(',', array_column(IssueSentiment::cases(), 'value'))), ->in(implode(',', array_column(IssueSentiment::cases(), 'value')))
->autocomplete(false),
Select::make('classification_id') Select::make('classification_id')
->label('Klasifikasi') ->label('Klasifikasi')
->relationship('classification', 'name', fn ($query) => $query->active()) ->relationship('classification', 'name', fn (Builder $query): Builder => $query->active())
->searchable() ->searchable()
->preload() ->preload()
->live() ->live()
->afterStateUpdated(fn (Set $set) => $set('sub_classification_id', null)) ->afterStateUpdated(function (Set $set): void {
->required(), $set('sub_classification_id', null);
})
->required()
->autocomplete(false),
Select::make('sub_classification_id') Select::make('sub_classification_id')
->label('Sub Klasifikasi') ->label('Sub Klasifikasi')
->relationship('subClassification', 'name', fn (Builder $query, Get $get) => $query->where('classification_id', $get('classification_id'))->active()) ->relationship('subClassification', 'name', fn (Builder $query, Get $get): Builder => $query->where('classification_id', $get('classification_id'))->active())
->searchable() ->searchable()
->preload() ->preload()
->required(), ->required()
->autocomplete(false),
])->columnSpan(1), ])->columnSpan(1),
]) ])
->columns(3); ->columns(3);

View File

@ -24,8 +24,8 @@ protected function setUp(): void
TextInput::make('keyword') TextInput::make('keyword')
->label('Kata Kunci') ->label('Kata Kunci')
->placeholder('Pendidikan, UMKM, Pariwisata') ->placeholder('Pendidikan, UMKM, Pariwisata')
->autocomplete(false)
->autofocus() ->autofocus()
->autocomplete('off')
->required() ->required()
->helperText('Jika kata kunci nya lebih dari 1, pisahkan dengan koma.'), ->helperText('Jika kata kunci nya lebih dari 1, pisahkan dengan koma.'),
@ -41,10 +41,11 @@ protected function setUp(): void
->placeholder(10) ->placeholder(10)
->numeric() ->numeric()
->required() ->required()
->default(10), ->default(10)
->autocomplete(false),
]) ])
->action(function (array $data, NewsCrawlerService $service) { ->action(function (array $data, NewsCrawlerService $service): void {
$count = $service->crawlFromGoogleNews($data['keyword'], $data['limit'], $data['theme_id'] ?? []); $count = $service->crawlFromGoogleNews($data['keyword'], $data['limit'], (array) ($data['theme_id'] ?? []));
if ($count > 0) { if ($count > 0) {
Notification::make() Notification::make()

View File

@ -11,6 +11,7 @@
use Filament\Schemas\Components\Grid; use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section; use Filament\Schemas\Components\Section;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Illuminate\Database\Eloquent\Builder;
class MediaMonitoringForm class MediaMonitoringForm
{ {
@ -80,7 +81,9 @@ public static function configure(Schema $schema): Schema
Select::make('themes') Select::make('themes')
->label('Tema') ->label('Tema')
->relationship('themes', 'name', fn ($query) => $query->active()) ->relationship('themes', 'name', function (Builder $query): Builder {
return $query->active();
})
->native(false) ->native(false)
->multiple() ->multiple()
->preload() ->preload()
@ -88,7 +91,7 @@ public static function configure(Schema $schema): Schema
DatePicker::make('release_date') DatePicker::make('release_date')
->label('Tanggal Rilis') ->label('Tanggal Rilis')
->placeholder(fn () => now()->format('Y-m-d')) ->placeholder(fn (): string => now()->format('Y-m-d'))
->native(false) ->native(false)
->displayFormat('l, d F Y') ->displayFormat('l, d F Y')
->required(), ->required(),
@ -113,7 +116,7 @@ public static function configure(Schema $schema): Schema
->acceptedFileTypes(['image/*']) ->acceptedFileTypes(['image/*'])
->maxSize(1024 * 3) ->maxSize(1024 * 3)
->collection('media-monitorings') ->collection('media-monitorings')
->customProperties(fn () => [ ->customProperties(fn (): array => [
'feature' => 'media-monitorings', 'feature' => 'media-monitorings',
'date' => now()->toDateString(), 'date' => now()->toDateString(),
]) ])

View File

@ -74,16 +74,16 @@ public static function form(Schema $schema): Schema
CheckboxList::make('partnerMedia') CheckboxList::make('partnerMedia')
->label('Kirim Kepada') ->label('Kirim Kepada')
->relationship('partnerMedia', 'name', fn (Builder $query) => $query->verified()) ->relationship('partnerMedia', 'name', fn (Builder $query): Builder => $query->verified())
->visible(fn ($get) => in_array($get('type'), [AnnouncementType::COMPANY, AnnouncementType::COMPANY->value])) ->visible(fn (\Filament\Schemas\Components\Utilities\Get $get): bool => in_array($get('type'), [AnnouncementType::COMPANY, AnnouncementType::COMPANY->value]))
->required(fn ($get) => in_array($get('type'), [AnnouncementType::COMPANY, AnnouncementType::COMPANY->value])) ->required(fn (\Filament\Schemas\Components\Utilities\Get $get): bool => in_array($get('type'), [AnnouncementType::COMPANY, AnnouncementType::COMPANY->value]))
->searchable() ->searchable()
->noSearchResultsMessage('Tidak ada media yang ditemukan.') ->noSearchResultsMessage('Tidak ada media yang ditemukan.')
->helperText('Pilih media yang akan menerima pengumuman ini') ->helperText('Pilih media yang akan menerima pengumuman ini')
->columnSpanFull() ->columnSpanFull()
->bulkToggleable() ->bulkToggleable()
->selectAllAction( ->selectAllAction(
fn (Action $action) => $action->label('Pilih Semua Media'), fn (Action $action): Action => $action->label('Pilih Semua Media'),
) )
->dehydrated(), ->dehydrated(),
@ -121,7 +121,7 @@ public static function table(Table $table): Table
->listWithLineBreaks() ->listWithLineBreaks()
->limitList(3) ->limitList(3)
->expandableLimitedList() ->expandableLimitedList()
->placeholder(fn ($record) => $record->type === AnnouncementType::PUBLIC ? 'Publik' : 'Tidak ada penerima'), ->placeholder(fn (Announcement $record): string => $record->type === AnnouncementType::PUBLIC ? 'Publik' : 'Tidak ada penerima'),
...TimestampColumns::make(), ...TimestampColumns::make(),
]) ])
@ -131,7 +131,7 @@ public static function table(Table $table): Table
->recordActions([ ->recordActions([
EditAction::make() EditAction::make()
->modalWidth(Width::TwoExtraLarge) ->modalWidth(Width::TwoExtraLarge)
->visible(fn ($record) => $record->type === AnnouncementType::PUBLIC), ->visible(fn (Announcement $record): bool => $record->type === AnnouncementType::PUBLIC),
DeleteAction::make(), DeleteAction::make(),

View File

@ -14,6 +14,7 @@
use Filament\Schemas\Components\Section; use Filament\Schemas\Components\Section;
use Filament\Schemas\Components\Utilities\Set; use Filament\Schemas\Components\Utilities\Set;
use Filament\Schemas\Schema; use Filament\Schemas\Schema;
use Illuminate\Database\Eloquent\Builder;
class NewsForm class NewsForm
{ {
@ -54,7 +55,9 @@ public static function configure(Schema $schema): Schema
Section::make([ Section::make([
Select::make('categories') Select::make('categories')
->label('Kategori') ->label('Kategori')
->relationship('categories', 'name', fn ($query) => $query->active()) ->relationship('categories', 'name', function (Builder $query): Builder {
return $query->active();
})
->native(false) ->native(false)
->multiple() ->multiple()
->preload() ->preload()
@ -62,14 +65,15 @@ public static function configure(Schema $schema): Schema
TagsInput::make('tags') TagsInput::make('tags')
->reactive() ->reactive()
->afterStateHydrated(function ($component, $state, $record) { ->afterStateHydrated(function ($component, $state, $record): void {
if (! $record) { if (! $record) {
return; return;
} }
$component->state( $component->state(
$record->tags->pluck('name')->toArray() $record->tags->pluck('name')->toArray()
); );
}), })
->autocomplete(false),
Radio::make('status') Radio::make('status')
->label('Status') ->label('Status')
@ -78,7 +82,7 @@ public static function configure(Schema $schema): Schema
->default(NewsStatus::PUBLISHED->value) ->default(NewsStatus::PUBLISHED->value)
->inline() ->inline()
->live() ->live()
->afterStateUpdated(function (Set $set, ?string $state, ?News $news) { ->afterStateUpdated(function (Set $set, ?string $state, ?News $news): void {
if ($state == NewsStatus::PUBLISHED->value && ! $news?->published_at) { if ($state == NewsStatus::PUBLISHED->value && ! $news?->published_at) {
$set('published_at', now()); $set('published_at', now());
} elseif ($state != NewsStatus::PUBLISHED->value && ! $news) { } elseif ($state != NewsStatus::PUBLISHED->value && ! $news) {
@ -96,7 +100,7 @@ public static function configure(Schema $schema): Schema
->acceptedFileTypes(['image/*']) ->acceptedFileTypes(['image/*'])
->maxSize(1024 * 3) ->maxSize(1024 * 3)
->collection('news') ->collection('news')
->customProperties(fn () => [ ->customProperties(fn (): array => [
'feature' => 'news', 'feature' => 'news',
'date' => now()->toDateString(), 'date' => now()->toDateString(),
]) ])

View File

@ -69,8 +69,8 @@ public static function configure(Table $table): Table
->searchable() ->searchable()
->sortable() ->sortable()
->badge() ->badge()
->formatStateUsing(fn ($state) => $state->getLabel()) ->formatStateUsing(fn (\App\Enums\NewsStatus $state): string => $state->getLabel())
->color(fn ($state) => $state->getColor()), ->color(fn (\App\Enums\NewsStatus $state): string => $state->getColor()),
TextColumn::make('published_at') TextColumn::make('published_at')
->label('Tgl Publish') ->label('Tgl Publish')

View File

@ -79,13 +79,13 @@ public static function table(Table $table): Table
Filter::make('date') Filter::make('date')
->schema([ ->schema([
DatePicker::make('from')->time(), DatePicker::make('from')->time()->autocomplete(false),
DatePicker::make('until')->time(), DatePicker::make('until')->time()->autocomplete(false),
]) ])
->query(function ($query, array $data) { ->query(function (Builder $query, array $data): Builder {
return $query return $query
->when($data['from'], fn ($q) => $q->whereDate('date', '>=', $data['from'])) ->when($data['from'], fn (Builder $q): Builder => $q->whereDate('date', '>=', $data['from']))
->when($data['until'], fn ($q) => $q->whereDate('date', '<=', $data['until'])); ->when($data['until'], fn (Builder $q): Builder => $q->whereDate('date', '<=', $data['until']));
}), }),
]) ])
->recordActions([]) ->recordActions([])