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')
->modalDescription('Apakah Anda yakin ingin menyetujui verifikasi ini? Status akan diterapkan pada Perusahaan, Media, dan semua Jurnalis sekaligus.')
->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);
});
}
@ -184,9 +184,11 @@ public function revisionAction(): Action
->label('Catatan Revisi')
->required()
->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']);
});
}
@ -210,9 +212,11 @@ public function rejectAction(): Action
->label('Alasan Penolakan')
->required()
->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']);
});
}

View File

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

View File

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

View File

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

View File

@ -86,14 +86,14 @@ public function submitVerificationAction(): Action
$progress = $this->getVerificationProgress();
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'
: 'Ajukan Verifikasi')
->icon('heroicon-o-paper-airplane')
->color('primary')
->requiresConfirmation()
->modalHeading('Ajukan Verifikasi Lengkap')
->modalDescription(function () use ($progress) {
->modalDescription(function () use ($progress): string {
if (! $progress['isDataComplete']) {
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.';
})
->modalSubmitActionLabel('Ya, Ajukan')
->visible(fn () => $progress['canSubmit'])
->disabled(fn () => ! $progress['isDataComplete'])
->action(function () {
->visible(fn (): bool => $progress['canSubmit'])
->disabled(fn (): bool => ! $progress['isDataComplete'])
->action(function (): void {
$this->submitVerification();
});
}

View File

@ -104,7 +104,7 @@ public static function infolist(Schema $schema): Schema
->placeholder('Belum dibalas'),
])
->columnSpanFull()
->visible(fn ($record) => $record->replied_at !== null),
->visible(fn (Contact $record): bool => $record->replied_at !== null),
])
->columns(2);
}
@ -128,7 +128,7 @@ public static function table(Table $table): Table
IconColumn::make('replied_at')
->label('Dibalas')
->boolean()
->getStateUsing(fn ($record) => $record->replied_at !== null),
->getStateUsing(fn (Contact $record): bool => $record->replied_at !== null),
TextColumn::make('repliedBy.name')
->label('Dibalas Oleh')
@ -157,11 +157,13 @@ public static function table(Table $table): Table
->schema([
Textarea::make('reply_message')
->label('Pesan Balasan')
->placeholder(fn ($record) => "Halo {$record->name}, ...")
->placeholder(fn (Contact $record): string => "Halo {$record->name}, ...")
->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']));
$record->update([
@ -175,7 +177,7 @@ public static function table(Table $table): Table
->success()
->send();
})
->visible(fn ($record) => $record->replied_at === null),
->visible(fn (Contact $record): bool => $record->replied_at === null),
DeleteAction::make()
->label('Hapus'),

View File

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

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@ protected function setUp(): void
$this->label('Terima')
->icon(Heroicon::OutlinedCheck)
->color('success')
->action(function (CooperationProposal $record) {
->action(function (CooperationProposal $record): void {
$record->update([
'status' => ApprovalStatus::ACCEPTED,
'responded_at' => now(),
@ -29,6 +29,6 @@ protected function setUp(): void
->success()
->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('...')
->required(),
])
->action(function (CooperationProposal $record, array $data) {
->action(function (CooperationProposal $record, array $data): void {
$record->update([
'status' => ApprovalStatus::REJECTED,
'responded_at' => now(),
@ -39,7 +39,7 @@ protected function setUp(): void
->warning()
->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);
}
}

View File

@ -17,7 +17,7 @@ protected function setUp(): void
$this->label('Terima')
->icon(Heroicon::OutlinedCheck)
->color('success')
->action(function (Report $record) {
->action(function (Report $record): void {
$record->update([
'status' => ApprovalStatus::ACCEPTED,
]);
@ -28,6 +28,6 @@ protected function setUp(): void
->success()
->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('...')
->required(),
])
->action(function (Report $record, array $data) {
->action(function (Report $record, array $data): void {
$record->update([
'status' => ApprovalStatus::REJECTED,
]);
@ -38,7 +38,7 @@ protected function setUp(): void
->warning()
->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);
}
}

View File

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

View File

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

View File

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

View File

@ -14,7 +14,6 @@
use Filament\Schemas\Schema;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
use Joaopaulolndev\FilamentPdfViewer\Infolists\Components\PdfViewerEntry;
class CooperationProposalRelationManager extends RelationManager
@ -23,15 +22,10 @@ class CooperationProposalRelationManager extends RelationManager
protected static ?string $title = 'Proposal';
public static function getBadge(Model $ownerRecord, string $pageClass): ?string
{
return $ownerRecord->proposals()->count();
}
public function table(Table $table): Table
{
return $table
->recordTitleAttribute('description')
->recordTitleAttribute('e_catalog')
->columns([
TextColumn::make('partnerMedia.name')
->label('Media')
@ -40,7 +34,7 @@ public function table(Table $table): Table
TextColumn::make('e_catalog')
->label('E-Catalog')
->url(fn ($record) => $record->e_catalog)
->url(fn (\App\Models\CooperationProposal $record): ?string => $record->e_catalog)
->openUrlInNewTab()
->color('primary'),
@ -69,7 +63,9 @@ public function table(Table $table): Table
->headerActions([])
->recordActions([
ViewAction::make(),
AcceptAction::make('accept'),
RejectAction::make('reject'),
])
->toolbarActions([
@ -104,10 +100,10 @@ public function infolist(Schema $infolist): Schema
TextEntry::make('e_catalog')
->label('E-Catalog')
->url(fn ($record) => $record->e_catalog)
->url(fn (\App\Models\CooperationProposal $record): ?string => $record->e_catalog)
->openUrlInNewTab()
->color('primary')
->visible(fn ($record) => $record->e_catalog),
->visible(fn (\App\Models\CooperationProposal $record): ?string => $record->e_catalog),
TextEntry::make('description')
->label('Deskripsi')
@ -115,13 +111,13 @@ public function infolist(Schema $infolist): Schema
PdfViewerEntry::make('proposal_attachment')
->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')),
TextEntry::make('rejectionReasons.reason')
->label('Alasan Penolakan')
->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(),
])
->columns(1);

View File

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

View File

@ -31,33 +31,39 @@ public function form(Schema $schema): Schema
DatePicker::make('start_date')
->label('Tanggal Mulai')
->required()
->native(false),
->native(false)
->autocomplete(false)
->autofocus(),
DatePicker::make('end_date')
->label('Tanggal Selesai')
->required()
->native(false)
->after('start_date'),
->after('start_date')
->autocomplete(false),
Textarea::make('task_description')
->label('Deskripsi Tugas')
->required()
->rows(4)
->maxLength(65535),
->maxLength(65535)
->autocomplete(false),
TextInput::make('report_amount')
->label('Jumlah Laporan')
->numeric()
->required()
->minValue(1)
->default(1),
->default(1)
->autocomplete(false),
Select::make('partner_media_ids')
->label('Media yang Ditugaskan')
->relationship('partnerMedia', 'name')
->multiple()
->preload()
->required(),
->required()
->autocomplete(false),
Select::make('status')
->options(ApprovalStatus::options())
@ -67,7 +73,8 @@ public function form(Schema $schema): Schema
Textarea::make('rejection_reason')
->label('Alasan Penolakan')
->rows(3)
->columnSpanFull(),
->columnSpanFull()
->autocomplete(false),
]);
}
@ -90,9 +97,10 @@ public function table(Table $table): Table
TextColumn::make('report_amount')
->label('Jumlah Laporan'),
TextColumn::make('report_count')
->label('Laporan Diterima')
->getStateUsing(function (TaskAssignment $record) {
->getStateUsing(function (TaskAssignment $record): string {
return $record->reports()->count().' / '.($record->report_amount * $record->partnerMedia()->count());
}),
])
@ -102,7 +110,11 @@ public function table(Table $table): Table
->headerActions([
CreateAction::make()
->label('Buat Penugasan')
->visible(fn () => $this->canCreateTaskAssignment()),
->visible(function (): bool {
$cooperation = $this->getOwnerRecord();
return $cooperation->proposals()->accepted()->exists();
}),
])
->recordActions([
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([
DatePicker::make('initial_submission_date')
->label('Tanggal Pengajuan Awal')
->placeholder(fn () => 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'))
->placeholder(fn (): string => now()->format('Y-m-d'))
->native(false)
->displayFormat('l, d F Y')
->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')
->label('Media')
->relationship('partnerMedia', 'name', fn (Builder $query) => $query->verified())
->relationship('partnerMedia', 'name', fn (Builder $query): Builder => $query->verified())
->multiple()
->preload()
->searchable()
@ -59,11 +61,12 @@ public static function configure(Schema $schema): Schema
->required()
->selectablePlaceholder(false)
->helperText('Pilih media yang akan diajak kerja sama.')
->autocomplete(false)
->suffixAction(
Action::make('select_all')
->label('Select All')
->icon(Heroicon::OutlinedCheckCircle)
->action(function ($set, $livewire) {
->action(function (\Filament\Schemas\Components\Utilities\Set $set): void {
$allMediaIds = PartnerMedia::verified()->pluck('id')->toArray();
$set('partner_media_ids', $allMediaIds);
})
@ -74,7 +77,8 @@ public static function configure(Schema $schema): Schema
->placeholder('...')
->required()
->rows(5)
->maxLength(65535),
->maxLength(65535)
->autocomplete(false),
])
->columnSpan(2),
@ -85,7 +89,7 @@ public static function configure(Schema $schema): Schema
->acceptedFileTypes(['image/*'])
->maxSize(1024 * 3)
->collection('cooperations')
->customProperties(fn () => [
->customProperties(fn (): array => [
'feature' => 'cooperations',
'doc_type' => 'banner',
'date' => now()->toDateString(),
@ -97,7 +101,7 @@ public static function configure(Schema $schema): Schema
->disk(config('filesystems.default'))
->acceptedFileTypes(['application/pdf'])
->maxSize(1024 * 10)
->directory(fn () => 'cooperations/proposal-template/'.now()->toDateString())
->directory(fn (): string => 'cooperations/proposal-template/'.now()->toDateString())
->required(),
]),
])

View File

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

View File

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

View File

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

View File

@ -85,7 +85,6 @@ public static function form(Schema $schema): Schema
->label('Alamat Surel')
->placeholder('johndoe@example.com')
->autocomplete(false)
->autofocus()
->required()
->maxLength(254)
->unique('journalists', 'email', ignoreRecord: true)
@ -102,8 +101,8 @@ public static function form(Schema $schema): Schema
Group::make()
->schema(
collect($documents)
->map(
fn ($doc) => Section::make($doc['title'])
->map(function (array $doc): Section {
return Section::make($doc['title'])
->schema([
TextInput::make($doc['text_name'])
->hiddenLabel()
@ -116,11 +115,11 @@ public static function form(Schema $schema): Schema
->hiddenLabel()
->disk(config('filesystems.default'))
->acceptedFileTypes($doc['accept'])
->directory(fn () => 'journalists/'.$doc['folder'].now()->toDateString())
->directory(fn (): string => 'journalists/'.$doc['folder'].now()->toDateString())
->maxSize($doc['max_size'])
->required(),
])
)
]);
})
->toArray()
),
])
@ -187,18 +186,18 @@ public static function table(Table $table): Table
->emptyStateDescription('Setelah Anda membubat data pertama, maka akan muncul disini.')
->defaultSort('created_at', 'desc')
->deferFilters(false)
->modifyQueryUsing(function (Builder $query) {
->modifyQueryUsing(function (Builder $query): void {
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) {
$query->when(auth()->user()->hasRole('Perusahaan'), function (Builder $q): Builder {
return $q->whereHas('partnerMedia.company', function (Builder $q): void {
$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
->emptyStateHeading('Akses Dibatasi')
->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')
->label('Alasan Penolakan')
->visible(fn ($record) => $record->company?->rejection_reason),
->visible(fn (User $record): ?string => $record->company?->rejection_reason),
]),
Grid::make(3)
@ -104,7 +104,7 @@ public static function infolist(Schema $schema): Schema
TextEntry::make('company.director_nik_docs')
->hiddenLabel()
->html()
->getStateUsing(function ($record) {
->getStateUsing(function (User $record): string {
$media = $record->company
?->getMedia('companies')
->where('custom_properties.doc_type', 'director-nik')
@ -197,7 +197,7 @@ public static function infolist(Schema $schema): Schema
TextEntry::make('company.partnerMedia.link')
->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')
->label('Jenis')
@ -281,7 +281,7 @@ public static function table(Table $table): Table
->label('Perusahaan')
->searchable()
->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')
->label('Media')
@ -323,7 +323,7 @@ public static function table(Table $table): Table
->defaultSort('created_at', 'desc')
->deferFilters(false)
->reorderable('sort_order')
->modifyQueryUsing(function (Builder $query) {
->modifyQueryUsing(function (Builder $query): void {
$query->role('Perusahaan')
->whereHas('company');
});
@ -344,7 +344,7 @@ private static function fileEntry(
): PdfViewerEntry {
return PdfViewerEntry::make($name)
->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);
if (! $owner) {
@ -356,7 +356,7 @@ private static function fileEntry(
->slug('-');
return $owner->getMedia($collection)
->where('custom_properties.doc_type', $docType)
->where('custom_properties.doc_type', (string) $docType)
->sortByDesc('created_at')
->first()
?->getUrl();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -80,13 +80,16 @@ public static function form(Schema $schema): Schema
Select::make('roles')
->label('Peran')
->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()
->preload()
->searchable(),
->searchable()
->autocomplete(false),
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);
}
@ -114,8 +117,8 @@ public static function table(Table $table): Table
ToggleColumn::make('is_active')
->label('Status')
->sortable()
->getStateUsing(fn (User $record) => $record->is_active === IsActive::ACTIVE)
->updateStateUsing(function (User $record, bool $state) {
->getStateUsing(fn (User $record): bool => $record->is_active === IsActive::ACTIVE)
->updateStateUsing(function (User $record, bool $state): void {
$record->is_active = $state ? IsActive::ACTIVE : IsActive::INACTIVE;
$record->save();
@ -125,14 +128,14 @@ public static function table(Table $table): Table
->delete();
}
})
->disabled(fn (User $record) => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
->disabled(fn (User $record): bool => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
TextColumn::make('roles.name')
->label('Peran')
->searchable()
->sortable()
->badge()
->getStateUsing(fn (User $record) => $record->roles->pluck('name', 'id')->toArray()),
->getStateUsing(fn (User $record): array => $record->roles->pluck('name', 'id')->toArray()),
...TimestampColumns::make(),
])
@ -143,16 +146,16 @@ public static function table(Table $table): Table
->recordActions([
EditAction::make()
->modalWidth(Width::Large)
->hidden(fn (User $record) => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
->hidden(fn (User $record): bool => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
DeleteAction::make()
->hidden(fn (User $record) => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
->hidden(fn (User $record): bool => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
ForceDeleteAction::make()
->hidden(fn (User $record) => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
->hidden(fn (User $record): bool => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
RestoreAction::make()
->hidden(fn (User $record) => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
->hidden(fn (User $record): bool => $record->hasRole(RoleEnum::PERUSAHAAN->value)),
])
->toolbarActions([
BulkActionGroup::make([

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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