diff --git a/app/Filament/Pages/Verification.php b/app/Filament/Pages/Verification.php index 1c21fb6..3ef53c7 100644 --- a/app/Filament/Pages/Verification.php +++ b/app/Filament/Pages/Verification.php @@ -85,7 +85,7 @@ public function submitVerificationAction(): Action { $progress = $this->getVerificationProgress(); - return Action::make('submitVerification') + return Action::make('submit_verification') ->label(fn () => $this->verificationRequest && $this->verificationRequest->status === VerificationStatus::NEED_REVISION ? 'Kirim Ulang' : 'Ajukan Verifikasi') diff --git a/app/Filament/Resources/Manage/Cooperations/Actions/Cooperation/AcceptAction.php b/app/Filament/Resources/Manage/Cooperations/Actions/Cooperation/AcceptAction.php new file mode 100644 index 0000000..4df858b --- /dev/null +++ b/app/Filament/Resources/Manage/Cooperations/Actions/Cooperation/AcceptAction.php @@ -0,0 +1,52 @@ +label('Terima') + ->icon(Heroicon::OutlinedCheck) + ->color('success') + ->action(function ($record) { + $cooperationMedia = $record->cooperationMedia() + ->whereHas('partnerMedia', function ($query) { + $query->whereHas('company', function ($subQuery) { + $subQuery->where('user_id', auth()->id()); + }); + }) + ->first(); + + if ($cooperationMedia) { + $cooperationMedia->update(['status' => ApprovalStatus::ACCEPTED]); + Notification::make() + ->title('Kerja sama diterima') + ->success() + ->send(); + } + }) + ->visible(function ($record) { + if (! auth()->user()->hasRole('Perusahaan')) { + return false; + } + + $cooperationMedia = $record->cooperationMedia() + ->whereHas('partnerMedia', function ($query) { + $query->whereHas('company', function ($subQuery) { + $subQuery->where('user_id', auth()->id()); + }); + }) + ->first(); + + return $cooperationMedia && $cooperationMedia->status === ApprovalStatus::PENDING; + }); + } +} diff --git a/app/Filament/Resources/Manage/Cooperations/Actions/Cooperation/CreateTaskAssignmentAction.php b/app/Filament/Resources/Manage/Cooperations/Actions/Cooperation/CreateTaskAssignmentAction.php new file mode 100644 index 0000000..c56636f --- /dev/null +++ b/app/Filament/Resources/Manage/Cooperations/Actions/Cooperation/CreateTaskAssignmentAction.php @@ -0,0 +1,87 @@ +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(), + + 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'), + + 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) { + $taskAssignment = $record->taskAssignments()->create([ + 'start_date' => $data['start_date'], + 'end_date' => $data['end_date'], + 'task_description' => $data['task_description'], + 'report_amount' => $data['report_amount'], + ]); + + $partnerMedias = $record->partnerMedia() + ->wherePivot('status', ApprovalStatus::ACCEPTED) + ->get(); + + foreach ($partnerMedias as $partnerMedia) { + $taskAssignment->mediaTaskAssignments()->create([ + 'partner_media_id' => $partnerMedia->id, + 'status' => ApprovalStatus::PENDING, + ]); + } + + Notification::make() + ->title('Penugasan berhasil dibuat') + ->success() + ->send(); + }) + ->modalHeading('Buat Penugasan') + ->modalSubmitActionLabel('Simpan') + ->visible( + fn (Cooperation $record): bool => ! auth()->user()->hasRole('Perusahaan') + && ! $record->taskAssignments()->exists() + && $record->status === CooperationStatus::ASSIGNMENT + ) + ->modalWidth(Width::Large); + } +} diff --git a/app/Filament/Resources/Manage/Cooperations/Actions/Cooperation/RejectAction.php b/app/Filament/Resources/Manage/Cooperations/Actions/Cooperation/RejectAction.php new file mode 100644 index 0000000..b85aae6 --- /dev/null +++ b/app/Filament/Resources/Manage/Cooperations/Actions/Cooperation/RejectAction.php @@ -0,0 +1,52 @@ +label('Tolak') + ->icon(Heroicon::XMark) + ->color('danger') + ->action(function ($record) { + $cooperationMedia = $record->cooperationMedia() + ->whereHas('partnerMedia', function ($query) { + $query->whereHas('company', function ($subQuery) { + $subQuery->where('user_id', auth()->id()); + }); + }) + ->first(); + + if ($cooperationMedia) { + $cooperationMedia->update(['status' => ApprovalStatus::REJECTED]); + Notification::make() + ->title('Kerja sama ditolak') + ->success() + ->send(); + } + }) + ->visible(function ($record) { + if (! auth()->user()->hasRole('Perusahaan')) { + return false; + } + + $cooperationMedia = $record->cooperationMedia() + ->whereHas('partnerMedia', function ($query) { + $query->whereHas('company', function ($subQuery) { + $subQuery->where('user_id', auth()->id()); + }); + }) + ->first(); + + return $cooperationMedia && $cooperationMedia->status === ApprovalStatus::PENDING; + }); + } +} diff --git a/app/Filament/Resources/Manage/Cooperations/Actions/Cooperation/SendProposalAction.php b/app/Filament/Resources/Manage/Cooperations/Actions/Cooperation/SendProposalAction.php new file mode 100644 index 0000000..687e200 --- /dev/null +++ b/app/Filament/Resources/Manage/Cooperations/Actions/Cooperation/SendProposalAction.php @@ -0,0 +1,111 @@ +label('Ajukan Proposal') + ->icon(Heroicon::DocumentText) + ->color('info') + ->schema([ + TextInput::make('e_catalog') + ->label('E-Catalog') + ->placeholder('https://katalog.inaproc.id/purwakarta-kita-media-karya') + ->autocomplete(false) + ->autofocus() + ->nullable() + ->url(), + + Textarea::make('description') + ->label('Deskripsi') + ->autocomplete(false) + ->required() + ->rows(4) + ->placeholder('...'), + + AdvancedFileUpload::make('proposal_attachment') + ->label('Lampiran') + ->disk(config('filesystems.default')) + ->acceptedFileTypes(['application/pdf']) + ->maxSize(1024 * 10) + ->directory(fn () => 'cooperations/proposal-attachment/'.now()->toDateString()) + ->required(), + ]) + ->action(function ($record, array $data) { + $cooperationMedia = $record->cooperationMedia() + ->whereHas('partnerMedia', function ($query) { + $query->whereHas('company', function ($subQuery) { + $subQuery->where('user_id', auth()->id()); + }); + }) + ->first(); + + if ($cooperationMedia) { + $proposal = $record->proposals()->create([ + 'partner_media_id' => $cooperationMedia->partner_media_id, + 'description' => $data['description'], + 'e_catalog' => $data['e_catalog'], + 'status' => ApprovalStatus::PENDING->value, + ]); + + if (! empty($data['proposal_attachment'])) { + $filePath = collect($data['proposal_attachment'])->first(); + $fullPath = Storage::disk(config('filesystems.default'))->path($filePath); + + if (file_exists($fullPath)) { + $proposal->addMediaFromDisk($filePath, config('filesystems.default')) + ->preservingOriginal() + ->withCustomProperties([ + 'feature' => 'cooperations', + 'date' => now()->toDateString(), + 'doc_type' => 'proposal-attachment', + ]) + ->toMediaCollection('cooperations'); + } + } + + Notification::make() + ->title('Proposal kerja sama berhasil dikirim') + ->success() + ->send(); + } + }) + ->modalHeading('Proposal Kerja Sama') + ->modalSubmitActionLabel('Kirim Proposal') + ->visible(function ($record) { + if (! auth()->user()->hasRole('Perusahaan')) { + return false; + } + + $cooperationMedia = $record->cooperationMedia() + ->whereHas('partnerMedia', function ($query) { + $query->whereHas('company', function ($subQuery) { + $subQuery->where('user_id', auth()->id()); + }); + }) + ->first(); + + return $cooperationMedia + && $cooperationMedia->status === ApprovalStatus::ACCEPTED + && ! $record->proposals() + ->where('partner_media_id', $cooperationMedia->partner_media_id) + ->where(fn ($q) => $q->accepted()->orWhere(fn ($q) => $q->pending())) + ->exists(); + }) + ->modalWidth(Width::Large); + } +} diff --git a/app/Filament/Resources/Manage/Cooperations/Actions/Proposal/AcceptAction.php b/app/Filament/Resources/Manage/Cooperations/Actions/Proposal/AcceptAction.php new file mode 100644 index 0000000..b162cf2 --- /dev/null +++ b/app/Filament/Resources/Manage/Cooperations/Actions/Proposal/AcceptAction.php @@ -0,0 +1,34 @@ +label('Terima') + ->icon(Heroicon::OutlinedCheck) + ->color('success') + ->action(function (CooperationProposal $record) { + $record->update([ + 'status' => ApprovalStatus::ACCEPTED, + 'responded_at' => now(), + ]); + + Notification::make() + ->title('Proposal Diterima') + ->body("Proposal dari {$record->partnerMedia->name} telah diterima.") + ->success() + ->send(); + }) + ->visible(fn (CooperationProposal $record) => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING); + } +} diff --git a/app/Filament/Resources/Manage/Cooperations/Actions/Proposal/RejectAction.php b/app/Filament/Resources/Manage/Cooperations/Actions/Proposal/RejectAction.php new file mode 100644 index 0000000..ec8f53a --- /dev/null +++ b/app/Filament/Resources/Manage/Cooperations/Actions/Proposal/RejectAction.php @@ -0,0 +1,45 @@ +label('Tolak') + ->icon(Heroicon::XMark) + ->color('danger') + ->schema([ + Textarea::make('reason') + ->label('Alasan Penolakan') + ->placeholder('...') + ->required(), + ]) + ->action(function (CooperationProposal $record, array $data) { + $record->update([ + 'status' => ApprovalStatus::REJECTED, + 'responded_at' => now(), + ]); + + $record->rejectionReasons()->create(['reason' => $data['reason']]); + + Notification::make() + ->title('Proposal Ditolak') + ->body("Proposal dari {$record->partnerMedia->name} telah ditolak.") + ->warning() + ->send(); + }) + ->visible(fn (CooperationProposal $record) => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING) + ->modalWidth(Width::Large); + } +} diff --git a/app/Filament/Resources/Manage/Cooperations/Actions/Report/AcceptAction.php b/app/Filament/Resources/Manage/Cooperations/Actions/Report/AcceptAction.php new file mode 100644 index 0000000..de18bdc --- /dev/null +++ b/app/Filament/Resources/Manage/Cooperations/Actions/Report/AcceptAction.php @@ -0,0 +1,33 @@ +label('Terima') + ->icon(Heroicon::OutlinedCheck) + ->color('success') + ->action(function (Report $record) { + $record->update([ + 'status' => ApprovalStatus::ACCEPTED, + ]); + + Notification::make() + ->title('Laporan Diterima') + ->body("Laporan '{$record->title}' telah diterima.") + ->success() + ->send(); + }) + ->visible(fn (Report $record) => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING); + } +} diff --git a/app/Filament/Resources/Manage/Cooperations/Actions/Report/RejectAction.php b/app/Filament/Resources/Manage/Cooperations/Actions/Report/RejectAction.php new file mode 100644 index 0000000..7e52a2d --- /dev/null +++ b/app/Filament/Resources/Manage/Cooperations/Actions/Report/RejectAction.php @@ -0,0 +1,44 @@ +label('Tolak') + ->icon(Heroicon::XMark) + ->color('danger') + ->schema([ + Textarea::make('reason') + ->label('Alasan Penolakan') + ->placeholder('...') + ->required(), + ]) + ->action(function (Report $record, array $data) { + $record->update([ + 'status' => ApprovalStatus::REJECTED, + ]); + + $record->rejectionReasons()->create(['reason' => $data['reason']]); + + Notification::make() + ->title('Laporan Ditolak') + ->body("Laporan '{$record->title}' telah ditolak.") + ->warning() + ->send(); + }) + ->visible(fn (Report $record) => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING) + ->modalWidth(Width::Large); + } +} diff --git a/app/Filament/Resources/Manage/Cooperations/RelationManagers/CooperationProposalRelationManager.php b/app/Filament/Resources/Manage/Cooperations/RelationManagers/CooperationProposalRelationManager.php index c875f94..0100270 100644 --- a/app/Filament/Resources/Manage/Cooperations/RelationManagers/CooperationProposalRelationManager.php +++ b/app/Filament/Resources/Manage/Cooperations/RelationManagers/CooperationProposalRelationManager.php @@ -3,19 +3,15 @@ namespace App\Filament\Resources\Manage\Cooperations\RelationManagers; use App\Enums\ApprovalStatus; -use App\Models\CooperationProposal; -use Filament\Actions\Action; +use App\Filament\Resources\Manage\Cooperations\Actions\Proposal\AcceptAction; +use App\Filament\Resources\Manage\Cooperations\Actions\Proposal\RejectAction; use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteBulkAction; use Filament\Actions\ViewAction; -use Filament\Forms\Components\Textarea; use Filament\Infolists\Components\TextEntry; -use Filament\Notifications\Notification; use Filament\Resources\RelationManagers\RelationManager; use Filament\Schemas\Components\Grid; use Filament\Schemas\Schema; -use Filament\Support\Enums\Width; -use Filament\Support\Icons\Heroicon; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Model; @@ -73,51 +69,8 @@ public function table(Table $table): Table ->headerActions([]) ->recordActions([ ViewAction::make(), - - Action::make('accept') - ->label('Terima') - ->icon(Heroicon::OutlinedCheck) - ->color('success') - ->action(function (CooperationProposal $record) { - $record->update([ - 'status' => ApprovalStatus::ACCEPTED, - 'responded_at' => now(), - ]); - - Notification::make() - ->title('Proposal Diterima') - ->body("Proposal dari {$record->partnerMedia->name} telah diterima.") - ->success() - ->send(); - }) - ->visible(fn (CooperationProposal $record) => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING), - - Action::make('reject') - ->label('Tolak') - ->icon(Heroicon::XMark) - ->color('danger') - ->schema([ - Textarea::make('reason') - ->label('Alasan Penolakan') - ->placeholder('...') - ->required(), - ]) - ->action(function (CooperationProposal $record, array $data) { - $record->update([ - 'status' => ApprovalStatus::REJECTED, - 'responded_at' => now(), - ]); - - $record->rejectionReasons()->create(['reason' => $data['reason']]); - - Notification::make() - ->title('Proposal Ditolak') - ->body("Proposal dari {$record->partnerMedia->name} telah ditolak.") - ->warning() - ->send(); - }) - ->visible(fn (CooperationProposal $record) => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING) - ->modalWidth(Width::Large), + AcceptAction::make('accept'), + RejectAction::make('reject'), ]) ->toolbarActions([ BulkActionGroup::make([ diff --git a/app/Filament/Resources/Manage/Cooperations/RelationManagers/ReportRelationManager.php b/app/Filament/Resources/Manage/Cooperations/RelationManagers/ReportRelationManager.php index de52ce5..e8d93e2 100644 --- a/app/Filament/Resources/Manage/Cooperations/RelationManagers/ReportRelationManager.php +++ b/app/Filament/Resources/Manage/Cooperations/RelationManagers/ReportRelationManager.php @@ -2,19 +2,16 @@ namespace App\Filament\Resources\Manage\Cooperations\RelationManagers; -use App\Enums\ApprovalStatus; -use App\Models\Report; -use Filament\Actions\Action; +use App\Filament\Resources\Manage\Cooperations\Actions\Report\AcceptAction; +use App\Filament\Resources\Manage\Cooperations\Actions\Report\RejectAction; use Filament\Actions\CreateAction; use Filament\Forms\Components\DatePicker; use Filament\Forms\Components\SpatieMediaLibraryFileUpload; use Filament\Forms\Components\Textarea; use Filament\Forms\Components\TextInput; -use Filament\Notifications\Notification; use Filament\Resources\RelationManagers\RelationManager; use Filament\Schemas\Schema; use Filament\Support\Enums\Width; -use Filament\Support\Icons\Heroicon; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Table; @@ -98,48 +95,8 @@ public function table(Table $table): Table ]) ->filters([]) ->recordActions([ - Action::make('accept') - ->label('Terima') - ->icon(Heroicon::OutlinedCheck) - ->color('success') - ->action(function (Report $record) { - $record->update([ - 'status' => ApprovalStatus::ACCEPTED, - ]); - - Notification::make() - ->title('Laporan Diterima') - ->body("Laporan '{$record->title}' telah diterima.") - ->success() - ->send(); - }) - ->visible(fn (Report $record) => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING), - - Action::make('reject') - ->label('Tolak') - ->icon(Heroicon::XMark) - ->color('danger') - ->schema([ - Textarea::make('reason') - ->label('Alasan Penolakan') - ->placeholder('...') - ->required(), - ]) - ->action(function (Report $record, array $data) { - $record->update([ - 'status' => ApprovalStatus::REJECTED, - ]); - - $record->rejectionReasons()->create(['reason' => $data['reason']]); - - Notification::make() - ->title('Laporan Ditolak') - ->body("Laporan '{$record->title}' telah ditolak.") - ->warning() - ->send(); - }) - ->visible(fn (Report $record) => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING) - ->modalWidth(Width::Large), + AcceptAction::make('accept'), + RejectAction::make('reject'), ]) ->headerActions([ CreateAction::make() diff --git a/app/Filament/Resources/Manage/Cooperations/Schemas/CooperationForm.php b/app/Filament/Resources/Manage/Cooperations/Schemas/CooperationForm.php index 30a0dfc..01aa246 100644 --- a/app/Filament/Resources/Manage/Cooperations/Schemas/CooperationForm.php +++ b/app/Filament/Resources/Manage/Cooperations/Schemas/CooperationForm.php @@ -60,7 +60,7 @@ public static function configure(Schema $schema): Schema ->selectablePlaceholder(false) ->helperText('Pilih media yang akan diajak kerja sama.') ->suffixAction( - Action::make('selectAll') + Action::make('select_all') ->label('Select All') ->icon(Heroicon::OutlinedCheckCircle) ->action(function ($set, $livewire) { diff --git a/app/Filament/Resources/Manage/Cooperations/Tables/CooperationsTable.php b/app/Filament/Resources/Manage/Cooperations/Tables/CooperationsTable.php index 2add9ee..a0c99da 100644 --- a/app/Filament/Resources/Manage/Cooperations/Tables/CooperationsTable.php +++ b/app/Filament/Resources/Manage/Cooperations/Tables/CooperationsTable.php @@ -2,28 +2,22 @@ namespace App\Filament\Resources\Manage\Cooperations\Tables; -use App\Enums\ApprovalStatus; -use App\Enums\CooperationStatus; use App\Filament\Actions\DefaultBulkActions; use App\Filament\Columns\TimestampColumns; +use App\Filament\Resources\Manage\Cooperations\Actions\Cooperation\AcceptAction; +use App\Filament\Resources\Manage\Cooperations\Actions\Cooperation\CreateTaskAssignmentAction; +use App\Filament\Resources\Manage\Cooperations\Actions\Cooperation\RejectAction; +use App\Filament\Resources\Manage\Cooperations\Actions\Cooperation\SendProposalAction; use App\Models\Cooperation; -use Asmit\FilamentUpload\Forms\Components\AdvancedFileUpload; use Carbon\CarbonInterface; -use Filament\Actions\Action; use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteAction; use Filament\Actions\EditAction; use Filament\Actions\ViewAction; -use Filament\Forms\Components\DatePicker; -use Filament\Forms\Components\Textarea; -use Filament\Forms\Components\TextInput; -use Filament\Notifications\Notification; -use Filament\Support\Enums\Width; use Filament\Support\Icons\Heroicon; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Filters\TrashedFilter; use Filament\Tables\Table; -use Illuminate\Support\Facades\Storage; class CooperationsTable { @@ -154,236 +148,13 @@ public static function configure(Table $table): Table ->recordActions([ ViewAction::make(), - Action::make('accept') - ->label('Terima') - ->icon(Heroicon::OutlinedCheck) - ->color('success') - ->action(function ($record) { - $cooperationMedia = $record->cooperationMedia() - ->whereHas('partnerMedia', function ($query) { - $query->whereHas('company', function ($subQuery) { - $subQuery->where('user_id', auth()->id()); - }); - }) - ->first(); + AcceptAction::make('accept'), - if ($cooperationMedia) { - $cooperationMedia->update(['status' => ApprovalStatus::ACCEPTED]); - Notification::make() - ->title('Kerja sama diterima') - ->success() - ->send(); - } - }) - ->visible(function ($record) { - if (! auth()->user()->hasRole('Perusahaan')) { - return false; - } + RejectAction::make('reject'), - $cooperationMedia = $record->cooperationMedia() - ->whereHas('partnerMedia', function ($query) { - $query->whereHas('company', function ($subQuery) { - $subQuery->where('user_id', auth()->id()); - }); - }) - ->first(); + SendProposalAction::make('send_proposal'), - return $cooperationMedia && $cooperationMedia->status === ApprovalStatus::PENDING; - }), - - Action::make('reject') - ->label('Tolak') - ->icon(Heroicon::XMark) - ->color('danger') - ->action(function ($record) { - $cooperationMedia = $record->cooperationMedia() - ->whereHas('partnerMedia', function ($query) { - $query->whereHas('company', function ($subQuery) { - $subQuery->where('user_id', auth()->id()); - }); - }) - ->first(); - - if ($cooperationMedia) { - $cooperationMedia->update(['status' => ApprovalStatus::REJECTED]); - Notification::make() - ->title('Kerja sama ditolak') - ->success() - ->send(); - } - }) - ->visible(function ($record) { - if (! auth()->user()->hasRole('Perusahaan')) { - return false; - } - - $cooperationMedia = $record->cooperationMedia() - ->whereHas('partnerMedia', function ($query) { - $query->whereHas('company', function ($subQuery) { - $subQuery->where('user_id', auth()->id()); - }); - }) - ->first(); - - return $cooperationMedia && $cooperationMedia->status === ApprovalStatus::PENDING; - }), - - Action::make('send_proposal') - ->label('Ajukan Proposal') - ->icon(Heroicon::DocumentText) - ->color('info') - ->schema([ - TextInput::make('e_catalog') - ->label('E-Catalog') - ->placeholder('https://katalog.inaproc.id/purwakarta-kita-media-karya') - ->autocomplete(false) - ->autofocus() - ->nullable() - ->url(), - - Textarea::make('description') - ->label('Deskripsi') - ->autocomplete(false) - ->required() - ->rows(4) - ->placeholder('...'), - - AdvancedFileUpload::make('proposal_attachment') - ->label('Lampiran') - ->disk(config('filesystems.default')) - ->acceptedFileTypes(['application/pdf']) - ->maxSize(1024 * 10) - ->directory(fn () => 'cooperations/proposal-attachment/'.now()->toDateString()) - ->required(), - ]) - ->action(function ($record, array $data) { - $cooperationMedia = $record->cooperationMedia() - ->whereHas('partnerMedia', function ($query) { - $query->whereHas('company', function ($subQuery) { - $subQuery->where('user_id', auth()->id()); - }); - }) - ->first(); - - if ($cooperationMedia) { - $proposal = $record->proposals()->create([ - 'partner_media_id' => $cooperationMedia->partner_media_id, - 'description' => $data['description'], - 'e_catalog' => $data['e_catalog'], - 'status' => ApprovalStatus::PENDING->value, - ]); - - if (! empty($data['proposal_attachment'])) { - $filePath = collect($data['proposal_attachment'])->first(); - $fullPath = Storage::disk(config('filesystems.default'))->path($filePath); - - if (file_exists($fullPath)) { - $proposal->addMediaFromDisk($filePath, config('filesystems.default')) - ->preservingOriginal() - ->withCustomProperties([ - 'feature' => 'cooperations', - 'date' => now()->toDateString(), - 'doc_type' => 'proposal-attachment', - ]) - ->toMediaCollection('cooperations'); - } - } - - Notification::make() - ->title('Proposal kerja sama berhasil dikirim') - ->success() - ->send(); - } - }) - ->modalHeading('Proposal Kerja Sama') - ->modalSubmitActionLabel('Kirim Proposal') - ->visible(function ($record) { - if (! auth()->user()->hasRole('Perusahaan')) { - return false; - } - - $cooperationMedia = $record->cooperationMedia() - ->whereHas('partnerMedia', function ($query) { - $query->whereHas('company', function ($subQuery) { - $subQuery->where('user_id', auth()->id()); - }); - }) - ->first(); - - return $cooperationMedia - && $cooperationMedia->status === ApprovalStatus::ACCEPTED - && ! $record->proposals() - ->where('partner_media_id', $cooperationMedia->partner_media_id) - ->where(fn ($q) => $q->accepted()->orWhere(fn ($q) => $q->pending())) - ->exists(); - }) - ->modalWidth(Width::Large), - - Action::make('create_task_assignment') - ->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(), - - 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'), - - 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) { - $taskAssignment = $record->taskAssignments()->create([ - 'start_date' => $data['start_date'], - 'end_date' => $data['end_date'], - 'task_description' => $data['task_description'], - 'report_amount' => $data['report_amount'], - ]); - - $partnerMedias = $record->partnerMedia() - ->wherePivot('status', ApprovalStatus::ACCEPTED) - ->get(); - - foreach ($partnerMedias as $partnerMedia) { - $taskAssignment->mediaTaskAssignments()->create([ - 'partner_media_id' => $partnerMedia->id, - 'status' => ApprovalStatus::PENDING, - ]); - } - - Notification::make() - ->title('Penugasan berhasil dibuat') - ->success() - ->send(); - }) - ->modalHeading('Buat Penugasan') - ->modalSubmitActionLabel('Simpan') - ->visible( - fn (Cooperation $record): bool => ! auth()->user()->hasRole('Perusahaan') - && ! $record->taskAssignments()->exists() - && $record->status === CooperationStatus::ASSIGNMENT - ) - ->modalWidth(Width::Large), + CreateTaskAssignmentAction::make('create_task_assignment'), EditAction::make() ->visible(fn () => ! auth()->user()->hasRole('Perusahaan')), diff --git a/app/Filament/Resources/Manage/Journalists/Actions/DeleteJournalistAction.php b/app/Filament/Resources/Manage/Journalists/Actions/DeleteJournalistAction.php new file mode 100644 index 0000000..c656da6 --- /dev/null +++ b/app/Filament/Resources/Manage/Journalists/Actions/DeleteJournalistAction.php @@ -0,0 +1,37 @@ +visible(function () { + $user = auth()->user(); + + if (! $user->hasRole('Perusahaan')) { + return true; + } + + if (! $user->company?->partnerMedia) { + return false; + } + + $verificationRequest = $user->company + ->verificationRequest() + ->latest() + ->first(); + + if ($verificationRequest && $verificationRequest->status !== VerificationStatus::NEED_REVISION) { + return false; + } + + return true; + }); + } +} diff --git a/app/Filament/Resources/Manage/Journalists/Actions/EditJournalistAction.php b/app/Filament/Resources/Manage/Journalists/Actions/EditJournalistAction.php new file mode 100644 index 0000000..ee9256d --- /dev/null +++ b/app/Filament/Resources/Manage/Journalists/Actions/EditJournalistAction.php @@ -0,0 +1,113 @@ +modalWidth(Width::Large) + ->fillForm(function (Journalist $journalist) { + $data = [ + 'name' => $journalist->name, + 'email' => $journalist->email, + 'phone_number' => $journalist->phone_number, + 'press_card' => $journalist->press_card, + 'ukw_certificate' => $journalist->ukw_certificate, + ]; + + $documents = [ + 'press_card', + 'ukw_certificate', + ]; + + $mediaItems = $journalist->getMedia('journalists'); + + foreach ($documents as $docType) { + $media = $mediaItems + ->where('custom_properties.doc_type', str($docType)->replace('_docs', '')->slug('-')) + ->sortByDesc('created_at') + ->first(); + + if ($media) { + $data["{$docType}_docs"] = [$media->getPathRelativeToRoot()]; + } + } + + return $data; + }) + ->using(function (Model $record, array $data): Model { + $record->update([ + 'name' => $data['name'], + 'email' => $data['email'], + 'phone_number' => $data['phone_number'], + 'press_card' => $data['press_card'], + 'ukw_certificate' => $data['ukw_certificate'], + ]); + + $documents = [ + 'press_card_docs', + 'ukw_certificate_docs', + ]; + + foreach ($documents as $field) { + if (empty($data[$field])) { + continue; + } + + foreach ((array) $data[$field] as $filePath) { + $fullPath = Storage::disk(config('filesystems.default'))->path($filePath); + + if (! file_exists($fullPath)) { + continue; + } + + $record + ->addMediaFromDisk($filePath, config('filesystems.default')) + ->preservingOriginal() + ->withCustomProperties([ + 'feature' => 'journalists', + 'date' => now()->toDateString(), + 'doc_type' => str($field) + ->replace('_docs', '') + ->slug('-'), + ]) + ->toMediaCollection('journalists'); + } + } + + return $record; + }) + ->visible(function () { + $user = auth()->user(); + + if (! $user->hasRole('Perusahaan')) { + return true; + } + + if (! $user->company?->partnerMedia) { + return false; + } + + $verificationRequest = $user->company + ->verificationRequest() + ->latest() + ->first(); + + if ($verificationRequest && $verificationRequest->status !== VerificationStatus::NEED_REVISION) { + return false; + } + + return true; + }); + } +} diff --git a/app/Filament/Resources/Manage/Journalists/JournalistResource.php b/app/Filament/Resources/Manage/Journalists/JournalistResource.php index 6f11617..b999fbc 100644 --- a/app/Filament/Resources/Manage/Journalists/JournalistResource.php +++ b/app/Filament/Resources/Manage/Journalists/JournalistResource.php @@ -2,18 +2,17 @@ namespace App\Filament\Resources\Manage\Journalists; -use App\Enums\VerificationStatus; use App\Filament\Columns\TimestampColumns; use App\Filament\Pages\Media; +use App\Filament\Resources\Manage\Journalists\Actions\DeleteJournalistAction; +use App\Filament\Resources\Manage\Journalists\Actions\EditJournalistAction; use App\Filament\Resources\Manage\Journalists\Pages\ManageJournalists; use App\Models\Journalist; use Asmit\FilamentUpload\Forms\Components\AdvancedFileUpload; use BackedEnum; use Filament\Actions\Action; use Filament\Actions\BulkActionGroup; -use Filament\Actions\DeleteAction; use Filament\Actions\DeleteBulkAction; -use Filament\Actions\EditAction; use Filament\Actions\ForceDeleteAction; use Filament\Actions\ForceDeleteBulkAction; use Filament\Actions\RestoreAction; @@ -23,15 +22,12 @@ use Filament\Schemas\Components\Group; use Filament\Schemas\Components\Section; use Filament\Schemas\Schema; -use Filament\Support\Enums\Width; use Filament\Support\Icons\Heroicon; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Filters\TrashedFilter; use Filament\Tables\Table; use Illuminate\Database\Eloquent\Builder; -use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\SoftDeletingScope; -use Illuminate\Support\Facades\Storage; use UnitEnum; class JournalistResource extends Resource @@ -170,125 +166,9 @@ public static function table(Table $table): Table ->native(false), ]) ->recordActions([ - EditAction::make() - ->modalWidth(Width::Large) - ->fillForm(function (Journalist $journalist) { - $data = [ - 'name' => $journalist->name, - 'email' => $journalist->email, - 'phone_number' => $journalist->phone_number, - 'press_card' => $journalist->press_card, - 'ukw_certificate' => $journalist->ukw_certificate, - ]; + EditJournalistAction::make('edit'), - $documents = [ - 'press_card', - 'ukw_certificate', - ]; - - $mediaItems = $journalist->getMedia('journalists'); - - foreach ($documents as $docType) { - $media = $mediaItems - ->where('custom_properties.doc_type', str($docType)->replace('_docs', '')->slug('-')) - ->sortByDesc('created_at') - ->first(); - - if ($media) { - $data["{$docType}_docs"] = [$media->getPathRelativeToRoot()]; - } - } - - return $data; - }) - ->using(function (Model $record, array $data): Model { - $record->update([ - 'name' => $data['name'], - 'email' => $data['email'], - 'phone_number' => $data['phone_number'], - 'press_card' => $data['press_card'], - 'ukw_certificate' => $data['ukw_certificate'], - ]); - - $documents = [ - 'press_card_docs', - 'ukw_certificate_docs', - ]; - - foreach ($documents as $field) { - if (empty($data[$field])) { - continue; - } - - foreach ((array) $data[$field] as $filePath) { - $fullPath = Storage::disk(config('filesystems.default'))->path($filePath); - - if (! file_exists($fullPath)) { - continue; - } - - $record - ->addMediaFromDisk($filePath, config('filesystems.default')) - ->preservingOriginal() - ->withCustomProperties([ - 'feature' => 'journalists', - 'date' => now()->toDateString(), - 'doc_type' => str($field) - ->replace('_docs', '') - ->slug('-'), - ]) - ->toMediaCollection('journalists'); - } - } - - return $record; - }) - ->visible(function () { - $user = auth()->user(); - - if (! $user->hasRole('Perusahaan')) { - return true; - } - - if (! $user->company?->partnerMedia) { - return false; - } - - $verificationRequest = $user->company - ->verificationRequest() - ->latest() - ->first(); - - if ($verificationRequest && $verificationRequest->status !== VerificationStatus::NEED_REVISION) { - return false; - } - - return true; - }), - - DeleteAction::make() - ->visible(function () { - $user = auth()->user(); - - if (! $user->hasRole('Perusahaan')) { - return true; - } - - if (! $user->company?->partnerMedia) { - return false; - } - - $verificationRequest = $user->company - ->verificationRequest() - ->latest() - ->first(); - - if ($verificationRequest && $verificationRequest->status !== VerificationStatus::NEED_REVISION) { - return false; - } - - return true; - }), + DeleteJournalistAction::make('delete'), ForceDeleteAction::make(), @@ -324,7 +204,7 @@ public static function table(Table $table): Table ->emptyStateDescription('Mohon lengkapi data Media Anda terlebih dahulu.') ->emptyStateIcon(Heroicon::LockClosed) ->emptyStateActions([ - Action::make('completeMedia') + Action::make('complete_media') ->label('Lengkapi Data Media') ->url(Media::getUrl()) ->button(), diff --git a/app/Filament/Resources/Monitoring/MediaMonitorings/Actions/CrawlNewsAction.php b/app/Filament/Resources/Monitoring/MediaMonitorings/Actions/CrawlNewsAction.php new file mode 100644 index 0000000..b020fa5 --- /dev/null +++ b/app/Filament/Resources/Monitoring/MediaMonitorings/Actions/CrawlNewsAction.php @@ -0,0 +1,65 @@ +label('Crawl Berita') + ->icon(Heroicon::MagnifyingGlass) + ->color('info') + ->schema([ + TextInput::make('keyword') + ->label('Kata Kunci') + ->placeholder('Pendidikan, UMKM, Pariwisata') + ->autofocus() + ->autocomplete('off') + ->required() + ->helperText('Jika kata kunci nya lebih dari 1, pisahkan dengan koma.'), + + Select::make('theme_id') + ->label('Tema') + ->required() + ->options(Theme::active()->pluck('name', 'id')) + ->searchable() + ->multiple(), + + TextInput::make('limit') + ->label('Jumlah Berita') + ->placeholder(10) + ->numeric() + ->required() + ->default(10), + ]) + ->action(function (array $data, NewsCrawlerService $service) { + $count = $service->crawlFromGoogleNews($data['keyword'], $data['limit'], $data['theme_id'] ?? []); + + if ($count > 0) { + Notification::make() + ->title('Crawl Selesai') + ->body("Berhasil mengambil {$count} berita baru tentang '{$data['keyword']}' di Purwakarta.") + ->success() + ->send(); + } else { + Notification::make() + ->title('Tidak Ada Berita Baru') + ->body("Tidak ditemukan berita baru untuk '{$data['keyword']}' yang belum ada di database.") + ->info() + ->send(); + } + }) + ->modalWidth(Width::Large); + } +} diff --git a/app/Filament/Resources/Monitoring/MediaMonitorings/Tables/MediaMonitoringsTable.php b/app/Filament/Resources/Monitoring/MediaMonitorings/Tables/MediaMonitoringsTable.php index 5d75c34..c85bc2b 100644 --- a/app/Filament/Resources/Monitoring/MediaMonitorings/Tables/MediaMonitoringsTable.php +++ b/app/Filament/Resources/Monitoring/MediaMonitorings/Tables/MediaMonitoringsTable.php @@ -4,18 +4,12 @@ use App\Filament\Actions\DefaultBulkActions; use App\Filament\Columns\TimestampColumns; -use App\Models\Theme; -use App\Services\NewsCrawlerService; -use Filament\Actions\Action; +use App\Filament\Resources\Monitoring\MediaMonitorings\Actions\CrawlNewsAction; use Filament\Actions\BulkActionGroup; use Filament\Actions\DeleteAction; use Filament\Actions\EditAction; use Filament\Actions\ForceDeleteAction; use Filament\Actions\RestoreAction; -use Filament\Forms\Components\Select; -use Filament\Forms\Components\TextInput; -use Filament\Notifications\Notification; -use Filament\Support\Enums\Width; use Filament\Support\Icons\Heroicon; use Filament\Tables\Columns\TextColumn; use Filament\Tables\Filters\TrashedFilter; @@ -103,51 +97,7 @@ public static function configure(Table $table): Table RestoreAction::make(), ]) ->headerActions([ - Action::make('crawlNews') - ->label('Crawl Berita') - ->icon(Heroicon::MagnifyingGlass) - ->color('info') - ->schema([ - TextInput::make('keyword') - ->label('Kata Kunci') - ->placeholder('Pendidikan, UMKM, Pariwisata') - ->autofocus() - ->autocomplete('off') - ->required() - ->helperText('Jika kata kunci nya lebih dari 1, pisahkan dengan koma.'), - - Select::make('theme_id') - ->label('Tema') - ->required() - ->options(Theme::active()->pluck('name', 'id')) - ->searchable() - ->multiple(), - - TextInput::make('limit') - ->label('Jumlah Berita') - ->placeholder(10) - ->numeric() - ->required() - ->default(10), - ]) - ->action(function (array $data, NewsCrawlerService $service) { - $count = $service->crawlFromGoogleNews($data['keyword'], $data['limit'], $data['theme_id'] ?? []); - - if ($count > 0) { - Notification::make() - ->title('Crawl Selesai') - ->body("Berhasil mengambil {$count} berita baru tentang '{$data['keyword']}' di Purwakarta.") - ->success() - ->send(); - } else { - Notification::make() - ->title('Tidak Ada Berita Baru') - ->body("Tidak ditemukan berita baru untuk '{$data['keyword']}' yang belum ada di database.") - ->info() - ->send(); - } - }) - ->modalWidth(Width::Large), + CrawlNewsAction::make('crawl_news'), ]) ->toolbarActions([ BulkActionGroup::make([