feat(notification): enhance user notifications for cooperation and verification processes
- Added detailed notifications for users and admins upon acceptance, rejection, and submission of proposals, verifications, and reports. - Improved user experience with personalized messages and actionable links in notifications. - Refactored notification logic across various actions to ensure consistent messaging and clarity. - Introduced new notification titles and bodies to better reflect the status of actions taken.
This commit is contained in:
parent
a05e46fd12
commit
ab318a030b
@ -5,7 +5,9 @@
|
|||||||
use App\Enums\DecisionAdmin;
|
use App\Enums\DecisionAdmin;
|
||||||
use App\Enums\VerificationStatus;
|
use App\Enums\VerificationStatus;
|
||||||
use App\Filament\Resources\Manage\Partners\Pages\ViewPartner;
|
use App\Filament\Resources\Manage\Partners\Pages\ViewPartner;
|
||||||
|
use App\Models\User;
|
||||||
use App\Models\VerificationRequest;
|
use App\Models\VerificationRequest;
|
||||||
|
use App\Notifications\BroadcastNotification;
|
||||||
use App\Services\VerificationService;
|
use App\Services\VerificationService;
|
||||||
use BackedEnum;
|
use BackedEnum;
|
||||||
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
|
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
|
||||||
@ -254,10 +256,40 @@ protected function processReview(int $requestId, DecisionAdmin $decision, ?strin
|
|||||||
};
|
};
|
||||||
|
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Berhasil')
|
->title('Berhasil Diproses! ✨')
|
||||||
->body("Verifikasi lengkap telah {$actionLabel}. Status telah diterapkan pada Perusahaan, Media, dan semua Jurnalis.")
|
->body("Mantap! Verifikasi telah {$actionLabel} dan notifikasi sudah dikirim ke user. Kerja bagus, Admin! 💪")
|
||||||
->color($color)
|
->color($color)
|
||||||
->send();
|
->send();
|
||||||
|
|
||||||
|
// Notify User
|
||||||
|
$partnerUser = $verificationRequest->company?->user;
|
||||||
|
if ($partnerUser) {
|
||||||
|
$statusTitle = match ($decision) {
|
||||||
|
DecisionAdmin::APPROVED => 'Horee! Verifikasi Disetujui 🎉',
|
||||||
|
DecisionAdmin::NEED_REVISION => 'Yah, Ada Yang Perlu Direvisi nih 📝',
|
||||||
|
DecisionAdmin::REJECTED => 'Maaf, Verifikasi Ditolak 😔',
|
||||||
|
};
|
||||||
|
|
||||||
|
$body = match ($decision) {
|
||||||
|
DecisionAdmin::APPROVED => 'Yeay! Pengajuan verifikasi perusahaan Anda telah disetujui. Sekarang Anda sudah resmi terverifikasi! 🎊',
|
||||||
|
DecisionAdmin::NEED_REVISION => 'Ayo sedikit lagi! Admin meminta beberapa perbaikan pada pengajuan Anda agar bisa segera disetujui. 💪',
|
||||||
|
DecisionAdmin::REJECTED => 'Yah, maaf banget... pengajuan verifikasi perusahaan Anda belum bisa kami terima saat ini. 💔',
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($note) {
|
||||||
|
$body .= "\n\nCatatan Admin: {$note}";
|
||||||
|
}
|
||||||
|
|
||||||
|
$partnerUser->notify(new BroadcastNotification([
|
||||||
|
'title' => $statusTitle,
|
||||||
|
'body' => $body,
|
||||||
|
'action' => [
|
||||||
|
Action::make('view')
|
||||||
|
->label('Lihat')
|
||||||
|
->url(Verification::getUrl()),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Error')
|
->title('Error')
|
||||||
|
|||||||
@ -3,8 +3,11 @@
|
|||||||
namespace App\Filament\Pages;
|
namespace App\Filament\Pages;
|
||||||
|
|
||||||
use App\Enums\VerificationStatus;
|
use App\Enums\VerificationStatus;
|
||||||
|
use App\Filament\Resources\Manage\Partners\PartnerResource;
|
||||||
use App\Models\Company;
|
use App\Models\Company;
|
||||||
|
use App\Models\User;
|
||||||
use App\Models\VerificationRequest;
|
use App\Models\VerificationRequest;
|
||||||
|
use App\Notifications\BroadcastNotification;
|
||||||
use App\Services\VerificationService;
|
use App\Services\VerificationService;
|
||||||
use BackedEnum;
|
use BackedEnum;
|
||||||
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
|
use BezhanSalleh\FilamentShield\Traits\HasPageShield;
|
||||||
@ -16,6 +19,7 @@
|
|||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Pages\Page;
|
use Filament\Pages\Page;
|
||||||
use Filament\Support\Icons\Heroicon;
|
use Filament\Support\Icons\Heroicon;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
use UnitEnum;
|
use UnitEnum;
|
||||||
|
|
||||||
class Verification extends Page implements HasActions, HasForms
|
class Verification extends Page implements HasActions, HasForms
|
||||||
@ -49,7 +53,8 @@ public function boot(): void
|
|||||||
|
|
||||||
public function mount(): void
|
public function mount(): void
|
||||||
{
|
{
|
||||||
$this->company = auth()->user()->company;
|
$user = Auth::user();
|
||||||
|
$this->company = $user->company;
|
||||||
|
|
||||||
// Load unified verification request
|
// Load unified verification request
|
||||||
if ($this->company) {
|
if ($this->company) {
|
||||||
@ -103,19 +108,7 @@ public function submitVerificationAction(): Action
|
|||||||
->modalSubmitActionLabel('Ya, Ajukan')
|
->modalSubmitActionLabel('Ya, Ajukan')
|
||||||
->visible(fn (): bool => $progress['canSubmit'])
|
->visible(fn (): bool => $progress['canSubmit'])
|
||||||
->disabled(fn (): bool => ! $progress['isDataComplete'])
|
->disabled(fn (): bool => ! $progress['isDataComplete'])
|
||||||
->action(function (): void {
|
->action(function () use ($progress): void {
|
||||||
$this->submitVerification();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle unified verification submission
|
|
||||||
*/
|
|
||||||
protected function submitVerification(): void
|
|
||||||
{
|
|
||||||
$progress = $this->getVerificationProgress();
|
|
||||||
|
|
||||||
// Validate data completeness
|
|
||||||
if (! $progress['isDataComplete']) {
|
if (! $progress['isDataComplete']) {
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Data Belum Lengkap')
|
->title('Data Belum Lengkap')
|
||||||
@ -126,16 +119,37 @@ protected function submitVerification(): void
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$isRevision = $this->verificationRequest && $this->verificationRequest->status === VerificationStatus::NEED_REVISION;
|
||||||
|
|
||||||
$this->verificationRequest = $this->verificationService->submitVerification(
|
$this->verificationRequest = $this->verificationService->submitVerification(
|
||||||
$this->company,
|
$this->company,
|
||||||
$this->verificationRequest
|
$this->verificationRequest
|
||||||
);
|
);
|
||||||
|
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Berhasil!')
|
->title('Berhasil Diajukan! 🚀')
|
||||||
->body('Verifikasi lengkap (Perusahaan, Media, dan Jurnalis) berhasil diajukan untuk diverifikasi.')
|
->body('Yeay! Pengajuan verifikasi Anda sudah terkirim ke Admin. Mohon ditunggu ya, semoga hasilnya memuaskan! ✨')
|
||||||
->success()
|
->success()
|
||||||
->send();
|
->send();
|
||||||
|
|
||||||
|
User::superAdmin()
|
||||||
|
->get()
|
||||||
|
->each(function ($admin) use ($isRevision): void {
|
||||||
|
$user = Auth::user();
|
||||||
|
|
||||||
|
$admin->notify(new BroadcastNotification([
|
||||||
|
'title' => $isRevision ? 'Pembaruan Data Verifikasi ✨' : 'Ada Pengajuan Verifikasi Baru! 🚀',
|
||||||
|
'body' => $isRevision
|
||||||
|
? "Cihuy! {$user->name} baru saja memperbarui data verifikasi untuk perusahaan {$user->company->name}. Yuk, cek perubahannya!"
|
||||||
|
: "Halo Admin! {$user->name} baru saja mengajukan verifikasi data untuk perusahaan {$user->company->name}. Segera diproses ya! 😊",
|
||||||
|
'action' => [
|
||||||
|
Action::make('view')
|
||||||
|
->label('Lihat')
|
||||||
|
->url(PartnerResource::getUrl('view', ['record' => $user])),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getViewData(): array
|
public function getViewData(): array
|
||||||
|
|||||||
@ -3,9 +3,14 @@
|
|||||||
namespace App\Filament\Resources\Manage\Cooperations\Actions\Cooperation;
|
namespace App\Filament\Resources\Manage\Cooperations\Actions\Cooperation;
|
||||||
|
|
||||||
use App\Enums\ApprovalStatus;
|
use App\Enums\ApprovalStatus;
|
||||||
|
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||||
|
use App\Models\Cooperation;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Notifications\BroadcastNotification;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Support\Icons\Heroicon;
|
use Filament\Support\Icons\Heroicon;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
|
|
||||||
class AcceptAction extends Action
|
class AcceptAction extends Action
|
||||||
{
|
{
|
||||||
@ -16,10 +21,10 @@ protected function setUp(): void
|
|||||||
$this->label('Terima')
|
$this->label('Terima')
|
||||||
->icon(Heroicon::OutlinedCheck)
|
->icon(Heroicon::OutlinedCheck)
|
||||||
->color('success')
|
->color('success')
|
||||||
->action(function (\App\Models\Cooperation $record): void {
|
->action(function (Cooperation $record): void {
|
||||||
$cooperationMedia = $record->cooperationMedia()
|
$cooperationMedia = $record->cooperationMedia()
|
||||||
->whereHas('partnerMedia', function (\Illuminate\Database\Eloquent\Builder $query): void {
|
->whereHas('partnerMedia', function (Builder $query): void {
|
||||||
$query->whereHas('company', function (\Illuminate\Database\Eloquent\Builder $subQuery): void {
|
$query->whereHas('company', function (Builder $subQuery): void {
|
||||||
$subQuery->where('user_id', auth()->id());
|
$subQuery->where('user_id', auth()->id());
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@ -27,20 +32,39 @@ protected function setUp(): void
|
|||||||
|
|
||||||
if ($cooperationMedia) {
|
if ($cooperationMedia) {
|
||||||
$cooperationMedia->update(['status' => ApprovalStatus::ACCEPTED]);
|
$cooperationMedia->update(['status' => ApprovalStatus::ACCEPTED]);
|
||||||
|
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Kerja sama diterima')
|
->title('Berhasil Diterima! ✅✨')
|
||||||
|
->body('Mantap! Anda telah menerima penawaran kerja sama ini. Silakan lanjut ke tahap pengajuan proposal ya! 💪')
|
||||||
->success()
|
->success()
|
||||||
->send();
|
->send();
|
||||||
|
|
||||||
|
// Notify Admins
|
||||||
|
User::superAdmin()
|
||||||
|
->get()
|
||||||
|
->each(function ($admin) use ($record, $cooperationMedia): void {
|
||||||
|
$admin->notify(new BroadcastNotification([
|
||||||
|
'title' => 'Kabar Baik! Tawaran Diterima ✨🤝',
|
||||||
|
'body' => "Media {$cooperationMedia->partnerMedia->name} baru saja menerima penawaran kerja sama \"{$record->title}\". Siap-siap cek proposal mereka ya! 😊",
|
||||||
|
'action' => [
|
||||||
|
Action::make('view')
|
||||||
|
->label('Lihat')
|
||||||
|
->url(CooperationResource::getUrl('view', ['record' => $record->id])),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->visible(function (\App\Models\Cooperation $record): bool {
|
->visible(function (Cooperation $record): bool {
|
||||||
if (! auth()->user()->hasRole('Perusahaan')) {
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if (! $user || ! $user->hasRole('Perusahaan')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cooperationMedia = $record->cooperationMedia()
|
$cooperationMedia = $record->cooperationMedia()
|
||||||
->whereHas('partnerMedia', function (\Illuminate\Database\Eloquent\Builder $query): void {
|
->whereHas('partnerMedia', function (Builder $query): void {
|
||||||
$query->whereHas('company', function (\Illuminate\Database\Eloquent\Builder $subQuery): void {
|
$query->whereHas('company', function (Builder $subQuery): void {
|
||||||
$subQuery->where('user_id', auth()->id());
|
$subQuery->where('user_id', auth()->id());
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|||||||
@ -4,7 +4,9 @@
|
|||||||
|
|
||||||
use App\Enums\ApprovalStatus;
|
use App\Enums\ApprovalStatus;
|
||||||
use App\Enums\CooperationStatus;
|
use App\Enums\CooperationStatus;
|
||||||
|
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||||
use App\Models\Cooperation;
|
use App\Models\Cooperation;
|
||||||
|
use App\Notifications\BroadcastNotification;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Forms\Components\DatePicker;
|
use Filament\Forms\Components\DatePicker;
|
||||||
use Filament\Forms\Components\Textarea;
|
use Filament\Forms\Components\Textarea;
|
||||||
@ -50,6 +52,7 @@ protected function setUp(): void
|
|||||||
->minValue(1)
|
->minValue(1)
|
||||||
->required()
|
->required()
|
||||||
->autocomplete(false),
|
->autocomplete(false),
|
||||||
|
|
||||||
Textarea::make('task_description')
|
Textarea::make('task_description')
|
||||||
->label('Deskripsi Tugas')
|
->label('Deskripsi Tugas')
|
||||||
->required()
|
->required()
|
||||||
@ -75,17 +78,34 @@ protected function setUp(): void
|
|||||||
'partner_media_id' => $partnerMedia->id,
|
'partner_media_id' => $partnerMedia->id,
|
||||||
'status' => ApprovalStatus::PENDING,
|
'status' => ApprovalStatus::PENDING,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Notify Partner
|
||||||
|
$partnerUser = $partnerMedia->company?->user;
|
||||||
|
if ($partnerUser) {
|
||||||
|
$partnerUser->notify(new BroadcastNotification([
|
||||||
|
'title' => 'Tugas Baru Telah Menanti! 📝✨',
|
||||||
|
'body' => "Halo! Admin sudah menetapkan tugas untuk kerja sama \"{$record->title}\". Yuk, cek detail tugasnya dan mulai buat laporannya! Semangat! 💪😊",
|
||||||
|
'action' => [
|
||||||
|
Action::make('view')
|
||||||
|
->label('Lihat')
|
||||||
|
->url(CooperationResource::getUrl('view', ['record' => $record->id, 'relation' => 2])),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Penugasan berhasil dibuat')
|
->title('Penugasan Berhasil Dibuat! 🚀✨')
|
||||||
|
->body('Mantap! Penugasan telah dibuat dan semua media terkait sudah diberi tahu. Mari kita pantau progresnya! 💪')
|
||||||
->success()
|
->success()
|
||||||
->send();
|
->send();
|
||||||
})
|
})
|
||||||
->modalHeading('Buat Penugasan')
|
->modalHeading('Buat Penugasan')
|
||||||
->modalSubmitActionLabel('Simpan')
|
->modalSubmitActionLabel('Simpan')
|
||||||
->visible(function (Cooperation $record): bool {
|
->visible(function (Cooperation $record): bool {
|
||||||
return ! auth()->user()->hasRole('Perusahaan')
|
$user = auth()->user();
|
||||||
|
|
||||||
|
return $user && ! $user->hasRole('Perusahaan')
|
||||||
&& ! $record->taskAssignments()->exists()
|
&& ! $record->taskAssignments()->exists()
|
||||||
&& $record->status === CooperationStatus::ASSIGNMENT;
|
&& $record->status === CooperationStatus::ASSIGNMENT;
|
||||||
})
|
})
|
||||||
|
|||||||
@ -3,6 +3,9 @@
|
|||||||
namespace App\Filament\Resources\Manage\Cooperations\Actions\Cooperation;
|
namespace App\Filament\Resources\Manage\Cooperations\Actions\Cooperation;
|
||||||
|
|
||||||
use App\Enums\ApprovalStatus;
|
use App\Enums\ApprovalStatus;
|
||||||
|
use App\Models\Cooperation;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Notifications\BroadcastNotification;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Support\Icons\Heroicon;
|
use Filament\Support\Icons\Heroicon;
|
||||||
@ -16,7 +19,7 @@ protected function setUp(): void
|
|||||||
$this->label('Tolak')
|
$this->label('Tolak')
|
||||||
->icon(Heroicon::XMark)
|
->icon(Heroicon::XMark)
|
||||||
->color('danger')
|
->color('danger')
|
||||||
->action(function (\App\Models\Cooperation $record): void {
|
->action(function (Cooperation $record): void {
|
||||||
$cooperationMedia = $record->cooperationMedia()
|
$cooperationMedia = $record->cooperationMedia()
|
||||||
->whereHas('partnerMedia', function ($query) {
|
->whereHas('partnerMedia', function ($query) {
|
||||||
$query->whereHas('company', function ($subQuery) {
|
$query->whereHas('company', function ($subQuery) {
|
||||||
@ -27,14 +30,28 @@ protected function setUp(): void
|
|||||||
|
|
||||||
if ($cooperationMedia) {
|
if ($cooperationMedia) {
|
||||||
$cooperationMedia->update(['status' => ApprovalStatus::REJECTED]);
|
$cooperationMedia->update(['status' => ApprovalStatus::REJECTED]);
|
||||||
|
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Kerja sama ditolak')
|
->title('Berhasil Ditolak 🙏')
|
||||||
->success()
|
->body('Terima kasih atas konfirmasinya. Pesan penolakan telah diteruskan ke Admin. 😊')
|
||||||
|
->info()
|
||||||
->send();
|
->send();
|
||||||
|
|
||||||
|
// Notify Admins
|
||||||
|
User::superAdmin()
|
||||||
|
->get()
|
||||||
|
->each(function ($admin) use ($record, $cooperationMedia): void {
|
||||||
|
$admin->notify(new BroadcastNotification([
|
||||||
|
'title' => 'Yah, Tawaran Ditolak 😔🤝',
|
||||||
|
'body' => "Media {$cooperationMedia->partnerMedia->name} baru saja menolak penawaran kerja sama \"{$record->title}\". Mungkin di lain waktu ya! 🙏",
|
||||||
|
]));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->visible(function (\App\Models\Cooperation $record): bool {
|
->visible(function (Cooperation $record): bool {
|
||||||
if (! auth()->user()->hasRole('Perusahaan')) {
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if (! $user->hasRole('Perusahaan')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,10 @@
|
|||||||
namespace App\Filament\Resources\Manage\Cooperations\Actions\Cooperation;
|
namespace App\Filament\Resources\Manage\Cooperations\Actions\Cooperation;
|
||||||
|
|
||||||
use App\Enums\ApprovalStatus;
|
use App\Enums\ApprovalStatus;
|
||||||
|
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||||
|
use App\Models\Cooperation;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Notifications\BroadcastNotification;
|
||||||
use Asmit\FilamentUpload\Forms\Components\AdvancedFileUpload;
|
use Asmit\FilamentUpload\Forms\Components\AdvancedFileUpload;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Forms\Components\Textarea;
|
use Filament\Forms\Components\Textarea;
|
||||||
@ -10,6 +14,7 @@
|
|||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Support\Enums\Width;
|
use Filament\Support\Enums\Width;
|
||||||
use Filament\Support\Icons\Heroicon;
|
use Filament\Support\Icons\Heroicon;
|
||||||
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
class SendProposalAction extends Action
|
class SendProposalAction extends Action
|
||||||
@ -45,16 +50,22 @@ protected function setUp(): void
|
|||||||
->directory(fn (): string => 'cooperations/proposal-attachment/'.now()->toDateString())
|
->directory(fn (): string => 'cooperations/proposal-attachment/'.now()->toDateString())
|
||||||
->required(),
|
->required(),
|
||||||
])
|
])
|
||||||
->action(function (\App\Models\Cooperation $record, array $data): void {
|
->action(function (Cooperation $record, array $data): void {
|
||||||
$cooperationMedia = $record->cooperationMedia()
|
$cooperationMedia = $record->cooperationMedia()
|
||||||
->whereHas('partnerMedia', function (\Illuminate\Database\Eloquent\Builder $query): void {
|
->whereHas('partnerMedia', function (Builder $query): void {
|
||||||
$query->whereHas('company', function (\Illuminate\Database\Eloquent\Builder $subQuery): void {
|
$query->whereHas('company', function (Builder $subQuery): void {
|
||||||
$subQuery->where('user_id', auth()->id());
|
$subQuery->where('user_id', auth()->id());
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
->first();
|
->first();
|
||||||
|
|
||||||
if ($cooperationMedia) {
|
if ($cooperationMedia) {
|
||||||
|
$existingProposal = $record->proposals()
|
||||||
|
->where('partner_media_id', $cooperationMedia->partner_media_id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
$isRevision = (bool) $existingProposal;
|
||||||
|
|
||||||
$proposal = $record->proposals()->create([
|
$proposal = $record->proposals()->create([
|
||||||
'partner_media_id' => $cooperationMedia->partner_media_id,
|
'partner_media_id' => $cooperationMedia->partner_media_id,
|
||||||
'description' => $data['description'],
|
'description' => $data['description'],
|
||||||
@ -79,21 +90,42 @@ protected function setUp(): void
|
|||||||
}
|
}
|
||||||
|
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Proposal kerja sama berhasil dikirim')
|
->title('Berhasil Diajukan! 🚀')
|
||||||
|
->body('Yeay! Proposal kerja sama Anda sudah terkirim ke Admin. Mohon ditunggu ya, semoga hasilnya memuaskan! ✨')
|
||||||
->success()
|
->success()
|
||||||
->send();
|
->send();
|
||||||
|
|
||||||
|
// Notify Admin
|
||||||
|
User::superAdmin()
|
||||||
|
->get()
|
||||||
|
->each(function ($admin) use ($isRevision, $record, $cooperationMedia): void {
|
||||||
|
$user = auth()->user();
|
||||||
|
$admin->notify(new BroadcastNotification([
|
||||||
|
'title' => $isRevision ? 'Pembaruan Proposal Kerja Sama ✨' : 'Ada Proposal Kerja Sama Baru! 🚀',
|
||||||
|
'body' => $isRevision
|
||||||
|
? "Cihuy! {$user->name} baru saja memperbarui proposal kerja sama untuk media {$cooperationMedia->partnerMedia->name} pada kampanye {$record->title}. Yuk, cek perubahannya!"
|
||||||
|
: "Halo Admin! {$user->name} baru saja mengajukan proposal kerja sama baru untuk media {$cooperationMedia->partnerMedia->name} pada kampanye {$record->title}. Segera diproses ya! 😊",
|
||||||
|
'action' => [
|
||||||
|
Action::make('view')
|
||||||
|
->label('Lihat')
|
||||||
|
->url(CooperationResource::getUrl('view', ['record' => $record->id, 'relation' => 1])),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->modalHeading('Proposal Kerja Sama')
|
->modalHeading('Proposal Kerja Sama')
|
||||||
->modalSubmitActionLabel('Kirim Proposal')
|
->modalSubmitActionLabel('Kirim Proposal')
|
||||||
->visible(function (\App\Models\Cooperation $record): bool {
|
->visible(function (Cooperation $record): bool {
|
||||||
if (! auth()->user()->hasRole('Perusahaan')) {
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if (! $user->hasRole('Perusahaan')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$cooperationMedia = $record->cooperationMedia()
|
$cooperationMedia = $record->cooperationMedia()
|
||||||
->whereHas('partnerMedia', function (\Illuminate\Database\Eloquent\Builder $query): void {
|
->whereHas('partnerMedia', function (Builder $query): void {
|
||||||
$query->whereHas('company', function (\Illuminate\Database\Eloquent\Builder $subQuery): void {
|
$query->whereHas('company', function (Builder $subQuery): void {
|
||||||
$subQuery->where('user_id', auth()->id());
|
$subQuery->where('user_id', auth()->id());
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@ -104,7 +136,7 @@ protected function setUp(): void
|
|||||||
&& $record->initial_submission_date->toDateString() === now()->toDateString()
|
&& $record->initial_submission_date->toDateString() === now()->toDateString()
|
||||||
&& ! $record->proposals()
|
&& ! $record->proposals()
|
||||||
->where('partner_media_id', $cooperationMedia->partner_media_id)
|
->where('partner_media_id', $cooperationMedia->partner_media_id)
|
||||||
->where(fn (\Illuminate\Database\Eloquent\Builder $q): \Illuminate\Database\Eloquent\Builder => $q->accepted()->orWhere(fn (\Illuminate\Database\Eloquent\Builder $q): \Illuminate\Database\Eloquent\Builder => $q->pending()))
|
->where(fn (Builder $q): Builder => $q->accepted()->orWhere(fn (Builder $q): Builder => $q->pending()))
|
||||||
->exists();
|
->exists();
|
||||||
})
|
})
|
||||||
->modalWidth(Width::Large);
|
->modalWidth(Width::Large);
|
||||||
|
|||||||
@ -3,7 +3,10 @@
|
|||||||
namespace App\Filament\Resources\Manage\Cooperations\Actions\Proposal;
|
namespace App\Filament\Resources\Manage\Cooperations\Actions\Proposal;
|
||||||
|
|
||||||
use App\Enums\ApprovalStatus;
|
use App\Enums\ApprovalStatus;
|
||||||
|
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||||
use App\Models\CooperationProposal;
|
use App\Models\CooperationProposal;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Notifications\BroadcastNotification;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Support\Icons\Heroicon;
|
use Filament\Support\Icons\Heroicon;
|
||||||
@ -24,10 +27,24 @@ protected function setUp(): void
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Proposal Diterima')
|
->title('Berhasil Diproses! ✨')
|
||||||
->body("Proposal dari {$record->partnerMedia->name} telah diterima.")
|
->body("Mantap! Proposal dari {$record->partnerMedia->name} telah diterima. Notifikasi sudah dikirim! 💪")
|
||||||
->success()
|
->success()
|
||||||
->send();
|
->send();
|
||||||
|
|
||||||
|
// Notify User (Partner)
|
||||||
|
$partnerUser = $record->partnerMedia?->company?->user;
|
||||||
|
if ($partnerUser) {
|
||||||
|
$partnerUser->notify(new BroadcastNotification([
|
||||||
|
'title' => 'Horee! Proposal Disetujui 🎉',
|
||||||
|
'body' => 'Yeay! Proposal kerja sama Anda telah disetujui oleh Admin. Mari kita lanjut ke tahap berikutnya! 🎊',
|
||||||
|
'action' => [
|
||||||
|
Action::make('view')
|
||||||
|
->label('Lihat')
|
||||||
|
->url(CooperationResource::getUrl('view', ['record' => $record->cooperation_id])),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
}
|
||||||
})
|
})
|
||||||
->visible(fn (CooperationProposal $record): bool => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING);
|
->visible(fn (CooperationProposal $record): bool => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,10 @@
|
|||||||
namespace App\Filament\Resources\Manage\Cooperations\Actions\Proposal;
|
namespace App\Filament\Resources\Manage\Cooperations\Actions\Proposal;
|
||||||
|
|
||||||
use App\Enums\ApprovalStatus;
|
use App\Enums\ApprovalStatus;
|
||||||
|
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||||
use App\Models\CooperationProposal;
|
use App\Models\CooperationProposal;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Notifications\BroadcastNotification;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Forms\Components\Textarea;
|
use Filament\Forms\Components\Textarea;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
@ -34,10 +37,24 @@ protected function setUp(): void
|
|||||||
$record->rejectionReasons()->create(['reason' => $data['reason']]);
|
$record->rejectionReasons()->create(['reason' => $data['reason']]);
|
||||||
|
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Proposal Ditolak')
|
->title('Berhasil Diproses! ✨')
|
||||||
->body("Proposal dari {$record->partnerMedia->name} telah ditolak.")
|
->body("Proposal dari {$record->partnerMedia->name} telah ditolak. Notifikasi sudah dikirim! 🙏")
|
||||||
->warning()
|
->warning()
|
||||||
->send();
|
->send();
|
||||||
|
|
||||||
|
// Notify User (Partner)
|
||||||
|
$partnerUser = $record->partnerMedia?->company?->user;
|
||||||
|
if ($partnerUser) {
|
||||||
|
$partnerUser->notify(new BroadcastNotification([
|
||||||
|
'title' => 'Maaf, Proposal Belum Diterima 😔',
|
||||||
|
'body' => "Yah, maaf banget... proposal kerja sama Anda belum bisa kami terima saat ini. 💔\n\nAlasan: {$data['reason']}",
|
||||||
|
'action' => [
|
||||||
|
Action::make('view')
|
||||||
|
->label('Lihat')
|
||||||
|
->url(CooperationResource::getUrl('view', ['record' => $record->cooperation_id])),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
}
|
||||||
})
|
})
|
||||||
->visible(fn (CooperationProposal $record): bool => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING)
|
->visible(fn (CooperationProposal $record): bool => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING)
|
||||||
->modalWidth(Width::Large);
|
->modalWidth(Width::Large);
|
||||||
|
|||||||
@ -3,7 +3,9 @@
|
|||||||
namespace App\Filament\Resources\Manage\Cooperations\Actions\Report;
|
namespace App\Filament\Resources\Manage\Cooperations\Actions\Report;
|
||||||
|
|
||||||
use App\Enums\ApprovalStatus;
|
use App\Enums\ApprovalStatus;
|
||||||
|
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||||
use App\Models\Report;
|
use App\Models\Report;
|
||||||
|
use App\Notifications\BroadcastNotification;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Support\Icons\Heroicon;
|
use Filament\Support\Icons\Heroicon;
|
||||||
@ -23,10 +25,30 @@ protected function setUp(): void
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Laporan Diterima')
|
->title('Berhasil Diproses! ✨')
|
||||||
->body("Laporan '{$record->title}' telah diterima.")
|
->body("Laporan '{$record->title}' telah diterima. Notifikasi sudah dikirim ke media! 💪")
|
||||||
->success()
|
->success()
|
||||||
->send();
|
->send();
|
||||||
|
|
||||||
|
// Notify all partners in this cooperation (since reports might be per media even if shared in DB)
|
||||||
|
$partners = $record->taskAssignment?->cooperation?->partnerMedia()
|
||||||
|
->wherePivot('status', ApprovalStatus::ACCEPTED)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
foreach ($partners as $media) {
|
||||||
|
$partnerUser = $media->company?->user;
|
||||||
|
if ($partnerUser) {
|
||||||
|
$partnerUser->notify(new BroadcastNotification([
|
||||||
|
'title' => 'Mantap! Laporan Diterima 🎊✨',
|
||||||
|
'body' => "Hore! Laporan \"{$record->title}\" pada kerja sama \"{$record->taskAssignment->cooperation->title}\" telah disetujui oleh Admin. Satu langkah lebih dekat! 🚀",
|
||||||
|
'action' => [
|
||||||
|
Action::make('view')
|
||||||
|
->label('Lihat')
|
||||||
|
->url(CooperationResource::getUrl('view', ['record' => $record->taskAssignment->cooperation_id, 'relation' => 3])),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
->visible(fn (Report $record): bool => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING);
|
->visible(fn (Report $record): bool => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,9 @@
|
|||||||
namespace App\Filament\Resources\Manage\Cooperations\Actions\Report;
|
namespace App\Filament\Resources\Manage\Cooperations\Actions\Report;
|
||||||
|
|
||||||
use App\Enums\ApprovalStatus;
|
use App\Enums\ApprovalStatus;
|
||||||
|
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||||
use App\Models\Report;
|
use App\Models\Report;
|
||||||
|
use App\Notifications\BroadcastNotification;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Forms\Components\Textarea;
|
use Filament\Forms\Components\Textarea;
|
||||||
use Filament\Notifications\Notification;
|
use Filament\Notifications\Notification;
|
||||||
@ -22,7 +24,7 @@ protected function setUp(): void
|
|||||||
->schema([
|
->schema([
|
||||||
Textarea::make('reason')
|
Textarea::make('reason')
|
||||||
->label('Alasan Penolakan')
|
->label('Alasan Penolakan')
|
||||||
->placeholder('...')
|
->placeholder('Jelaskan apa yang perlu diperbaiki...')
|
||||||
->required(),
|
->required(),
|
||||||
])
|
])
|
||||||
->action(function (Report $record, array $data): void {
|
->action(function (Report $record, array $data): void {
|
||||||
@ -33,10 +35,30 @@ protected function setUp(): void
|
|||||||
$record->rejectionReasons()->create(['reason' => $data['reason']]);
|
$record->rejectionReasons()->create(['reason' => $data['reason']]);
|
||||||
|
|
||||||
Notification::make()
|
Notification::make()
|
||||||
->title('Laporan Ditolak')
|
->title('Berhasil Diproses! ✨')
|
||||||
->body("Laporan '{$record->title}' telah ditolak.")
|
->body("Laporan '{$record->title}' telah ditolak. Media terkait akan segera mendapatkan notifikasi perbaikan. 🙏")
|
||||||
->warning()
|
->warning()
|
||||||
->send();
|
->send();
|
||||||
|
|
||||||
|
// Notify all partners in this cooperation (since we can't tell which specific one)
|
||||||
|
$partners = $record->taskAssignment?->cooperation?->partnerMedia()
|
||||||
|
->wherePivot('status', ApprovalStatus::ACCEPTED)
|
||||||
|
->get();
|
||||||
|
|
||||||
|
foreach ($partners as $media) {
|
||||||
|
$partnerUser = $media->company?->user;
|
||||||
|
if ($partnerUser) {
|
||||||
|
$partnerUser->notify(new BroadcastNotification([
|
||||||
|
'title' => 'Yah, Laporan Perlu Diperbaiki nih 📝',
|
||||||
|
'body' => "Halo! Laporan \"{$record->title}\" pada kerja sama \"{$record->taskAssignment->cooperation->title}\" ditolak oleh Admin. 💪\n\nCatatan Admin: {$data['reason']}",
|
||||||
|
'action' => [
|
||||||
|
Action::make('view')
|
||||||
|
->label('Lihat')
|
||||||
|
->url(CooperationResource::getUrl('view', ['record' => $record->taskAssignment->cooperation_id])),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
->visible(fn (Report $record): bool => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING)
|
->visible(fn (Report $record): bool => ! auth()->user()->hasRole('Perusahaan') && $record->status === ApprovalStatus::PENDING)
|
||||||
->modalWidth(Width::Large);
|
->modalWidth(Width::Large);
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
namespace App\Filament\Resources\Manage\Cooperations\Pages;
|
namespace App\Filament\Resources\Manage\Cooperations\Pages;
|
||||||
|
|
||||||
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||||
|
use App\Notifications\BroadcastNotification;
|
||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Resources\Pages\CreateRecord;
|
use Filament\Resources\Pages\CreateRecord;
|
||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
@ -55,5 +56,22 @@ protected function afterCreate(): void
|
|||||||
'doc_type' => 'proposal-template',
|
'doc_type' => 'proposal-template',
|
||||||
])
|
])
|
||||||
->toMediaCollection('cooperations');
|
->toMediaCollection('cooperations');
|
||||||
|
|
||||||
|
// Notify selected partners
|
||||||
|
$record->load('partnerMedia.company.user');
|
||||||
|
$record->partnerMedia->each(function ($media) use ($record) {
|
||||||
|
$partnerUser = $media->company?->user;
|
||||||
|
if ($partnerUser) {
|
||||||
|
$partnerUser->notify(new BroadcastNotification([
|
||||||
|
'title' => 'Ada Penawaran Kerja Sama Baru! 🤝✨',
|
||||||
|
'body' => "Halo! Admin baru saja menawarkan kerja sama \"{$record->title}\" untuk media {$media->name}. Yuk, cek detailnya dan berikan tanggapanmu! 😊",
|
||||||
|
'action' => [
|
||||||
|
Action::make('view')
|
||||||
|
->label('Lihat')
|
||||||
|
->url(CooperationResource::getUrl('view', ['record' => $record->id])),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,10 +7,8 @@
|
|||||||
use Filament\Actions\Action;
|
use Filament\Actions\Action;
|
||||||
use Filament\Infolists\Components\RepeatableEntry;
|
use Filament\Infolists\Components\RepeatableEntry;
|
||||||
use Filament\Infolists\Components\TextEntry;
|
use Filament\Infolists\Components\TextEntry;
|
||||||
use Filament\Notifications\Notification;
|
|
||||||
use Filament\Resources\Pages\ViewRecord;
|
use Filament\Resources\Pages\ViewRecord;
|
||||||
use Filament\Support\Enums\FontWeight;
|
use Filament\Support\Enums\FontWeight;
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
|
|
||||||
class ViewCooperation extends ViewRecord
|
class ViewCooperation extends ViewRecord
|
||||||
{
|
{
|
||||||
@ -240,68 +238,13 @@ protected function getCompletionDate($record)
|
|||||||
|
|
||||||
protected function getHeaderActions(): array
|
protected function getHeaderActions(): array
|
||||||
{
|
{
|
||||||
$isPerusahaan = Auth::user()->hasRole('Perusahaan');
|
return [
|
||||||
$record = $this->getRecord();
|
Action::make('back')
|
||||||
|
|
||||||
$actions = [];
|
|
||||||
|
|
||||||
if (! $isPerusahaan) {
|
|
||||||
$actions[] = Action::make('markCompleted')
|
|
||||||
->label('Tandai Selesai')
|
|
||||||
->icon('heroicon-o-check-circle')
|
|
||||||
->color('success')
|
|
||||||
->action(function (): void {
|
|
||||||
// Logic to mark cooperation as completed
|
|
||||||
Notification::make()
|
|
||||||
->title('Kerja Sama Ditandai Selesai')
|
|
||||||
->success()
|
|
||||||
->send();
|
|
||||||
})
|
|
||||||
->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 (\Illuminate\Database\Eloquent\Builder $query): void {
|
|
||||||
$query->whereHas('company', function (\Illuminate\Database\Eloquent\Builder $subQuery): void {
|
|
||||||
$subQuery->where('user_id', Auth::id());
|
|
||||||
});
|
|
||||||
})
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($cooperationMedia && $cooperationMedia->status === ApprovalStatus::PENDING) {
|
|
||||||
$actions[] = Action::make('accept')
|
|
||||||
->label('Terima Kerja Sama')
|
|
||||||
->icon('heroicon-o-check-circle')
|
|
||||||
->color('success')
|
|
||||||
->action(function () use ($cooperationMedia): void {
|
|
||||||
$cooperationMedia->update(['status' => ApprovalStatus::ACCEPTED]);
|
|
||||||
Notification::make()
|
|
||||||
->title('Kerja Sama Diterima')
|
|
||||||
->success()
|
|
||||||
->send();
|
|
||||||
});
|
|
||||||
|
|
||||||
$actions[] = Action::make('reject')
|
|
||||||
->label('Tolak Kerja Sama')
|
|
||||||
->icon('heroicon-o-x-circle')
|
|
||||||
->color('danger')
|
|
||||||
->action(function () use ($cooperationMedia): void {
|
|
||||||
$cooperationMedia->update(['status' => ApprovalStatus::REJECTED]);
|
|
||||||
Notification::make()
|
|
||||||
->title('Kerja Sama Ditolak')
|
|
||||||
->success()
|
|
||||||
->send();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$actions[] = Action::make('back')
|
|
||||||
->label('Kembali')
|
->label('Kembali')
|
||||||
->url(fn (): string => static::getResource()::getUrl('index'))
|
->url(fn (): string => static::getResource()::getUrl('index'))
|
||||||
->outlined()
|
->outlined()
|
||||||
->color('secondary');
|
->color('secondary'),
|
||||||
|
];
|
||||||
return $actions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function canMarkAsCompleted(): bool
|
protected function canMarkAsCompleted(): bool
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
use App\Enums\ApprovalStatus;
|
use App\Enums\ApprovalStatus;
|
||||||
use App\Filament\Resources\Manage\Cooperations\Actions\Proposal\AcceptAction;
|
use App\Filament\Resources\Manage\Cooperations\Actions\Proposal\AcceptAction;
|
||||||
use App\Filament\Resources\Manage\Cooperations\Actions\Proposal\RejectAction;
|
use App\Filament\Resources\Manage\Cooperations\Actions\Proposal\RejectAction;
|
||||||
|
use App\Models\CooperationProposal;
|
||||||
use Filament\Actions\BulkActionGroup;
|
use Filament\Actions\BulkActionGroup;
|
||||||
use Filament\Actions\DeleteBulkAction;
|
use Filament\Actions\DeleteBulkAction;
|
||||||
use Filament\Actions\ViewAction;
|
use Filament\Actions\ViewAction;
|
||||||
@ -34,7 +35,7 @@ public function table(Table $table): Table
|
|||||||
|
|
||||||
TextColumn::make('e_catalog')
|
TextColumn::make('e_catalog')
|
||||||
->label('E-Catalog')
|
->label('E-Catalog')
|
||||||
->url(fn (\App\Models\CooperationProposal $record): ?string => $record->e_catalog)
|
->url(fn (CooperationProposal $record): ?string => $record->e_catalog)
|
||||||
->openUrlInNewTab()
|
->openUrlInNewTab()
|
||||||
->color('primary'),
|
->color('primary'),
|
||||||
|
|
||||||
@ -100,10 +101,10 @@ public function infolist(Schema $infolist): Schema
|
|||||||
|
|
||||||
TextEntry::make('e_catalog')
|
TextEntry::make('e_catalog')
|
||||||
->label('E-Catalog')
|
->label('E-Catalog')
|
||||||
->url(fn (\App\Models\CooperationProposal $record): ?string => $record->e_catalog)
|
->url(fn (CooperationProposal $record): ?string => $record->e_catalog)
|
||||||
->openUrlInNewTab()
|
->openUrlInNewTab()
|
||||||
->color('primary')
|
->color('primary')
|
||||||
->visible(fn (\App\Models\CooperationProposal $record): ?string => $record->e_catalog),
|
->visible(fn (CooperationProposal $record): ?string => $record->e_catalog),
|
||||||
|
|
||||||
TextEntry::make('description')
|
TextEntry::make('description')
|
||||||
->label('Deskripsi')
|
->label('Deskripsi')
|
||||||
@ -111,13 +112,13 @@ public function infolist(Schema $infolist): Schema
|
|||||||
|
|
||||||
PdfViewerEntry::make('proposal_attachment')
|
PdfViewerEntry::make('proposal_attachment')
|
||||||
->label('Lampiran Proposal')
|
->label('Lampiran Proposal')
|
||||||
->getStateUsing(fn (\App\Models\CooperationProposal $record): ?string => optional($record->getMedia('cooperations')->where('custom_properties.doc_type', 'proposal-attachment')->sortByDesc('created_at')->first())->getPathRelativeToRoot())
|
->getStateUsing(fn (CooperationProposal $record): ?string => optional($record->getMedia('cooperations')->where('custom_properties.doc_type', 'proposal-attachment')->sortByDesc('created_at')->first())->getPathRelativeToRoot())
|
||||||
->disk(config('filesystems.default')),
|
->disk(config('filesystems.default')),
|
||||||
|
|
||||||
TextEntry::make('rejectionReasons.reason')
|
TextEntry::make('rejectionReasons.reason')
|
||||||
->label('Alasan Penolakan')
|
->label('Alasan Penolakan')
|
||||||
->listWithLineBreaks()
|
->listWithLineBreaks()
|
||||||
->visible(fn (\App\Models\CooperationProposal $record): bool => $record->status === ApprovalStatus::REJECTED && $record->rejectionReasons->isNotEmpty())
|
->visible(fn (CooperationProposal $record): bool => $record->status === ApprovalStatus::REJECTED && $record->rejectionReasons->isNotEmpty())
|
||||||
->columnSpanFull(),
|
->columnSpanFull(),
|
||||||
])
|
])
|
||||||
->columns(1);
|
->columns(1);
|
||||||
|
|||||||
@ -2,18 +2,26 @@
|
|||||||
|
|
||||||
namespace App\Filament\Resources\Manage\Cooperations\RelationManagers;
|
namespace App\Filament\Resources\Manage\Cooperations\RelationManagers;
|
||||||
|
|
||||||
|
use App\Enums\ApprovalStatus;
|
||||||
use App\Filament\Resources\Manage\Cooperations\Actions\Report\AcceptAction;
|
use App\Filament\Resources\Manage\Cooperations\Actions\Report\AcceptAction;
|
||||||
use App\Filament\Resources\Manage\Cooperations\Actions\Report\RejectAction;
|
use App\Filament\Resources\Manage\Cooperations\Actions\Report\RejectAction;
|
||||||
|
use App\Filament\Resources\Manage\Cooperations\CooperationResource;
|
||||||
|
use App\Models\Report;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Notifications\BroadcastNotification;
|
||||||
|
use Filament\Actions\Action;
|
||||||
use Filament\Actions\CreateAction;
|
use Filament\Actions\CreateAction;
|
||||||
use Filament\Forms\Components\DatePicker;
|
use Filament\Forms\Components\DatePicker;
|
||||||
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
|
use Filament\Forms\Components\SpatieMediaLibraryFileUpload;
|
||||||
use Filament\Forms\Components\Textarea;
|
use Filament\Forms\Components\Textarea;
|
||||||
use Filament\Forms\Components\TextInput;
|
use Filament\Forms\Components\TextInput;
|
||||||
|
use Filament\Notifications\Notification;
|
||||||
use Filament\Resources\RelationManagers\RelationManager;
|
use Filament\Resources\RelationManagers\RelationManager;
|
||||||
use Filament\Schemas\Schema;
|
use Filament\Schemas\Schema;
|
||||||
use Filament\Support\Enums\Width;
|
use Filament\Support\Enums\Width;
|
||||||
use Filament\Tables\Columns\TextColumn;
|
use Filament\Tables\Columns\TextColumn;
|
||||||
use Filament\Tables\Table;
|
use Filament\Tables\Table;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
class ReportRelationManager extends RelationManager
|
class ReportRelationManager extends RelationManager
|
||||||
{
|
{
|
||||||
@ -26,6 +34,11 @@ public function isReadOnly(): bool
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function getBadge(Model $ownerRecord, string $pageClass): ?string
|
||||||
|
{
|
||||||
|
return $ownerRecord->reports()->count();
|
||||||
|
}
|
||||||
|
|
||||||
public function form(Schema $schema): Schema
|
public function form(Schema $schema): Schema
|
||||||
{
|
{
|
||||||
return $schema
|
return $schema
|
||||||
@ -86,7 +99,7 @@ public function table(Table $table): Table
|
|||||||
TextColumn::make('link')
|
TextColumn::make('link')
|
||||||
->label('Link')
|
->label('Link')
|
||||||
->limit(30)
|
->limit(30)
|
||||||
->url(fn (\App\Models\Report $record): string => $record->link)
|
->url(fn (Report $record): string => $record->link)
|
||||||
->openUrlInNewTab(),
|
->openUrlInNewTab(),
|
||||||
|
|
||||||
TextColumn::make('status')
|
TextColumn::make('status')
|
||||||
@ -113,14 +126,45 @@ public function table(Table $table): Table
|
|||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
})
|
})
|
||||||
|
->after(function (Report $record): void {
|
||||||
|
Notification::make()
|
||||||
|
->title('Laporan Berhasil Terkirim! 🚀✨')
|
||||||
|
->body('Hore! Laporan Anda sudah masuk ke sistem. Admin akan segera memeriksanya. Terima kasih atas kerja kerasnya! 💪')
|
||||||
|
->success()
|
||||||
|
->send();
|
||||||
|
|
||||||
|
// Notify Admins
|
||||||
|
User::superAdmin()
|
||||||
|
->get()
|
||||||
|
->each(function ($admin) use ($record): void {
|
||||||
|
$user = auth()->user();
|
||||||
|
$admin->notify(new BroadcastNotification([
|
||||||
|
'title' => 'Ada Laporan Baru! 📝✨',
|
||||||
|
'body' => "Halo Admin! {$user->name} baru saja mengirimkan laporan \"{$record->title}\" untuk kerja sama \"{$this->getOwnerRecord()->title}\". Yuk, dicek! 😊",
|
||||||
|
'action' => [
|
||||||
|
Action::make('view')
|
||||||
|
->label('Lihat')
|
||||||
|
->url(CooperationResource::getUrl('view', ['record' => $this->getOwnerRecord()->id, 'relation' => 3])),
|
||||||
|
],
|
||||||
|
]));
|
||||||
|
});
|
||||||
|
})
|
||||||
->visible(function (): bool {
|
->visible(function (): bool {
|
||||||
|
$user = auth()->user();
|
||||||
|
|
||||||
|
if (! $user || ! $user->hasRole('Perusahaan')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$taskAssignment = $this->getOwnerRecord()->taskAssignments()->first();
|
$taskAssignment = $this->getOwnerRecord()->taskAssignments()->first();
|
||||||
|
|
||||||
if (! $taskAssignment) {
|
if (! $taskAssignment) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $taskAssignment->reports()->count() < $taskAssignment->report_amount;
|
return $taskAssignment->reports()
|
||||||
|
->where('status', '!=', ApprovalStatus::REJECTED)
|
||||||
|
->count() < $taskAssignment->report_amount;
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
->toolbarActions([]);
|
->toolbarActions([]);
|
||||||
|
|||||||
@ -3,7 +3,6 @@
|
|||||||
namespace App\Filament\Resources\Manage\Cooperations\RelationManagers;
|
namespace App\Filament\Resources\Manage\Cooperations\RelationManagers;
|
||||||
|
|
||||||
use App\Enums\ApprovalStatus;
|
use App\Enums\ApprovalStatus;
|
||||||
use App\Models\TaskAssignment;
|
|
||||||
use Filament\Actions\BulkActionGroup;
|
use Filament\Actions\BulkActionGroup;
|
||||||
use Filament\Actions\CreateAction;
|
use Filament\Actions\CreateAction;
|
||||||
use Filament\Actions\DeleteAction;
|
use Filament\Actions\DeleteAction;
|
||||||
@ -97,12 +96,6 @@ public function table(Table $table): Table
|
|||||||
|
|
||||||
TextColumn::make('report_amount')
|
TextColumn::make('report_amount')
|
||||||
->label('Jumlah Laporan'),
|
->label('Jumlah Laporan'),
|
||||||
|
|
||||||
TextColumn::make('report_count')
|
|
||||||
->label('Laporan Diterima')
|
|
||||||
->getStateUsing(function (TaskAssignment $record): string {
|
|
||||||
return $record->reports()->count().' / '.($record->report_amount * $record->partnerMedia()->count());
|
|
||||||
}),
|
|
||||||
])
|
])
|
||||||
->filters([
|
->filters([
|
||||||
//
|
//
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Enums\IsActive;
|
use App\Enums\IsActive;
|
||||||
|
use App\Enums\RoleEnum;
|
||||||
use Filament\Models\Contracts\FilamentUser;
|
use Filament\Models\Contracts\FilamentUser;
|
||||||
use Filament\Panel;
|
use Filament\Panel;
|
||||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
@ -42,7 +43,7 @@ public function canAccessPanel(Panel $panel): bool
|
|||||||
protected function withoutDeveloper(Builder $query): void
|
protected function withoutDeveloper(Builder $query): void
|
||||||
{
|
{
|
||||||
$query->whereDoesntHave('roles', function ($q) {
|
$query->whereDoesntHave('roles', function ($q) {
|
||||||
$q->where('name', 'Developer');
|
$q->where('name', RoleEnum::DEVELOPER);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +53,14 @@ protected function active(Builder $query): void
|
|||||||
$query->where('is_active', IsActive::ACTIVE);
|
$query->where('is_active', IsActive::ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Scope]
|
||||||
|
protected function superAdmin(Builder $query): void
|
||||||
|
{
|
||||||
|
$query->whereHas('roles', function ($q) {
|
||||||
|
$q->whereIn('name', [RoleEnum::DEVELOPER, RoleEnum::ADMINISTRATOR]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public function company(): HasOne
|
public function company(): HasOne
|
||||||
{
|
{
|
||||||
return $this->hasOne(Company::class);
|
return $this->hasOne(Company::class);
|
||||||
|
|||||||
@ -23,9 +23,14 @@ public function via($notifiable): array
|
|||||||
|
|
||||||
public function toDatabase($notifiable): array
|
public function toDatabase($notifiable): array
|
||||||
{
|
{
|
||||||
return FilamentNotification::make()
|
$notification = FilamentNotification::make()
|
||||||
->title($this->payload['title'])
|
->title($this->payload['title'])
|
||||||
->body($this->payload['body'])
|
->body($this->payload['body']);
|
||||||
->getDatabaseMessage();
|
|
||||||
|
if (! empty($this->payload['action'])) {
|
||||||
|
$notification->actions($this->payload['action']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $notification->getDatabaseMessage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user