feat: display media who send proposal

This commit is contained in:
myuqinurrohman 2025-03-08 15:55:43 +07:00
parent d0c9a29970
commit ea5fe73361
17 changed files with 299 additions and 33 deletions

View File

@ -148,3 +148,9 @@ function get_cooperation_notif() {
}
}
}
if (! function_exists('slugify')) {
function slugify($param) {
return Str::slug($param);
}
}

View File

@ -3,7 +3,9 @@
namespace App\Http\Controllers\Dashboard;
use App\Http\Controllers\Controller;
use App\Http\Requests\JournalistCooperationProposalRequest;
use App\Models\Cooperation;
use App\Models\CooperationProposal;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
@ -66,12 +68,36 @@ public function accept(Request $request, $id){
}
public function proposal($id){
$cooperation = Cooperation::with(['media'])->findOrFail(decrypt_id($id));
$mediaCooperationPivot = $cooperation->media()
->where('media.id', Auth::user()->company->media->id)
->first()->pivot;
return view('dashboard.cooperation-requests.proposal', [
'title' => 'Ajukan Kerjasama',
'user' => Auth::user()
'user' => Auth::user(),
'cooperation' => $cooperation,
'mediaCooperationPivot' => $mediaCooperationPivot
]);
}
public function proposalAction(JournalistCooperationProposalRequest $request, $id){
$validatedData = $request->validated();
$validatedData['cooperation_id'] = decrypt_id($id);
$validatedData['media_id'] = Auth::user()->company->media->id;
$validatedData['attachment'] = store_file($validatedData['attachment'], '/uploads/cooperation-proposals', 'public')['randomFileName'];
$createdCooperationProposal = CooperationProposal::create($validatedData);
$createdCooperationProposal->journalists()->attach($validatedData['journalist_ids']);
if ($createdCooperationProposal->journalists()->count() > 0) {
return redirect()->back()->with('success-status', 'Berhasil melakukan pengajuan kerjasama.');
} else {
return redirect()->back()->with('failed-status', 'Gagal melakukan pengajuan kerjasama');
}
}
public function reject($id){
$cooperation = Cooperation::with(['media'])->findOrFail(decrypt_id($id));

View File

@ -8,6 +8,7 @@
use App\Models\Company;
use App\Models\ContentRecap;
use App\Models\Cooperation;
use App\Models\CooperationProposal;
use App\Models\GovernmentAgency;
use App\Models\IssueManagement;
use App\Models\Journalist;
@ -783,14 +784,17 @@ public function cooperationMedia(Request $request, $id){
->addColumn('classification', function ($data) {
return ucfirst($data->classification);
})
->addColumn('status', function ($data) {
->addColumn('status', function ($data) use ($cooperation) {
switch($data->pivot->status){
case 0:
return '<span class="badge bg-warning" style="display:inline-block;font-size:0.8rem;">Menunggu</span>';
case 1:
$status = '<span class="badge bg-success" style="display:inline-block;font-size:0.8rem;">Menerima</span> <br>';
if(true){
$isCooperationProposalExists = CooperationProposal::where('cooperation_id', '=', $cooperation->id)
->where('media_id', '=', $data->id)->exists();
if(!$isCooperationProposalExists){
$status .= '<span class="badge bg-warning" style="display:inline-block;font-size:0.8rem;">Belum Pengajuan</span>';
}else{
$status .= '<span class="badge bg-primary" style="display:inline-block;font-size:0.8rem;">Sudah Pengajuan</span>';
@ -852,12 +856,19 @@ public function cooperationRequest(Request $request){
$mediaId = $user->company->media->id;
$media = Media::with('cooperations')->findOrFail($mediaId);
// $currentDate = Carbon::now()->format('Y-m-d');
$data = $media->cooperations()
->where('start_date', '<=', Carbon::now()->locale('id')->toDateString())
->where('end_date', '>=', Carbon::now()->locale('id')->toDateString())
->get();
->where(function ($query) {
$query->where('media_cooperations.status', '!=', 0)
->orWhere(function ($q) {
$q->where('media_cooperations.status', 0)
->where('cooperations.end_date', '>=', now()->toDateString());
});
})
->where('cooperations.start_date', '<=', now()->toDateString())
->get();
return DataTables::of($data)
->addIndexColumn()
@ -873,14 +884,17 @@ public function cooperationRequest(Request $request){
->addColumn('posted_at', function ($data) {
return idn_date($data->created_at, 'l, d F Y');
})
->addColumn('status', function ($data){
->addColumn('status', function ($data) use ($media){
$isCooperationProposalExists = CooperationProposal::where('cooperation_id', '=', $data->id)
->where('media_id', '=', $media->id)->exists();
switch($data->pivot->status){
case '0':
return '<span class="badge bg-warning" style="display:inline-block;font-size:0.8rem;">Menunggu</span>';
case 1:
$status = '<span class="badge bg-success" style="display:inline-block;font-size:0.8rem;">Menerima</span> <br>';
if(true){
if(!$isCooperationProposalExists){
$status .= '<span class="badge bg-warning" style="display:inline-block;font-size:0.8rem;">Belum Mengajukan</span>';
}else{
$status .= '<span class="badge bg-primary" style="display:inline-block;font-size:0.8rem;">Sudah Mengajukan</span>';
@ -894,7 +908,11 @@ public function cooperationRequest(Request $request){
}
})
->addColumn('action', function ($data) {
->addColumn('action', function ($data) use ($media) {
$isCooperationProposalExists = CooperationProposal::where('cooperation_id', '=', $data->id)
->where('media_id', '=', $media->id)->exists();
$showUrl = route('dashboard.cooperations.requests.show', ['id' => encrypt_id($data->id)]);
// $editUrl = route('dashboard.cooperations.edit', ['id' => encrypt_id($data->id)]);
@ -913,7 +931,10 @@ public function cooperationRequest(Request $request){
<ul class="link-list-opt">
<li><a href="'.$showUrl.'"><em class="icon ni ni-eye"></em><span>Detail</span></a></li>';
if (is_role(['3']) && $data->pivot->status === '1') {
$isCooperationProposalExists = CooperationProposal::where('cooperation_id', '=', $data->id)
->where('media_id', '=', Auth::user()->company->media->id)->exists();
if (is_role(['3']) && $data->pivot->status === '1' && !$isCooperationProposalExists) {
$dropdown .= '<li><a href="'.$cooperationProposalUrl.'"><em class="icon ni ni-upload"></em><span>Ajukan Kerjasama</span></a></li>';
}

View File

@ -29,7 +29,7 @@ public function rules(): array
'media_ids' => ['required', 'array'],
'media_ids.*' => ['required', 'exists:media,id'],
'banner' => ['nullable', 'image', 'mimes:png,jpg,jpeg', 'max:2048'],
'offer_file_template' => ['nullable', 'file','mimes:pdf' , 'max:2048'],
'offer_file_template' => ['required', 'file','mimes:pdf' , 'max:2048'],
'description' => ['required'],
];
}
@ -52,6 +52,7 @@ public function messages(): array
'banner.mimes' => 'Format banner harus PNG, JPG, atau JPEG.',
'banner.max' => 'Ukuran banner maksimal 2MB.',
'offer_file_template.required' => 'File wajib diisi.',
'offer_file_template.file' => 'File template harus berupa file yang valid.',
'offer_file_template.mimes' => 'Format file template harus PDF.',
'offer_file_template.max' => 'Ukuran file template maksimal 2MB.',

View File

@ -0,0 +1,50 @@
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class JournalistCooperationProposalRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return Auth::check() && is_role(['3']);
}
/**
* Get the validation rules that apply to the request.
*
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'journalist_ids' => ['required', 'array'],
'journalist_ids.*' => ['required', 'exists:journalists,id'],
'attachment' => ['required', 'file', 'mimes:pdf', 'max:2048'],
'description' => ['nullable']
];
}
public function messages(): array
{
return [
'journalist_ids.required' => 'Pilih setidaknya satu jurnalis.',
'journalist_ids.array' => 'Jurnalis yang dipilih tidak valid.',
'journalist_ids.*.required' => 'Setiap jurnalis yang dipilih harus valid.',
'journalist_ids.*.exists' => 'Jurnalis yang dipilih tidak ditemukan di database.',
'attachment.required' => 'File pengajuan wajib diunggah.',
'attachment.file' => 'File yang diunggah tidak valid.',
'attachment.mimes' => 'File harus berformat PDF.',
'attachment.max' => 'Ukuran file maksimal 2 MB.',
'description.nullable' => 'Deskripsi boleh kosong.',
];
}
}

View File

@ -18,4 +18,19 @@ class CooperationProposal extends Model
'cooperation_id',
'media_id',
];
public function media(){
return $this->belongsTo(Media::class, 'media_id', 'id');
}
public function cooperation(){
return $this->belongsTo(Cooperation::class, 'cooperation_id', 'id');
}
public function journalists()
{
return $this->belongsToMany(Journalist::class, 'journalists_cooperation_proposals', 'cooperation_proposal_id', 'journalist_id')
->using(JournalistCooperationProposal::class)
->withTimestamps();
}
}

View File

@ -27,4 +27,11 @@ class Journalist extends Model
public function media(){
return $this->belongsTo(Media::class, 'media_id', 'id');
}
public function cooperationProposals()
{
return $this->belongsToMany(CooperationProposal::class, 'journalists_cooperation_proposals', 'journalist_id', 'cooperation_proposal_id')
->using(JournalistCooperationProposal::class)
->withTimestamps();
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;
class JournalistCooperationProposal extends Pivot
{
protected $table = 'journalists_cooperation_proposals';
protected $fillable = [
'journalist_id',
'cooperation_proposal_id',
];
public function journalist(){
return $this->belongsTo(Journalist::class, 'journalists_id', 'id');
}
public function cooperationProposal(){
return $this->belongsTo(CooperationProposal::class, 'cooperation_proposal_id', 'id');
}
}

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('journalists_cooperation_proposals', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('cooperation_proposal_id');
$table->unsignedBigInteger('journalist_id');
$table->foreign('cooperation_proposal_id', 'journalists_cooperation_propososals_coop_id_foreign')
->references('id')->on('cooperation_proposals')
->onDelete('cascade');
$table->foreign('journalist_id', 'journalists_cooperation_propososals_journalist_id_foreign')
->references('id')->on('journalists')
->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('journalists_cooperation_proposals');
}
};

View File

@ -125,7 +125,18 @@ .dropdown-menu-datatable-custom {
z-index: 1050 !important;
}
.nk-wizard #previous{
background-color: transparent !important;
border: grey !important;
.nk-wizard .actions {
margin-top: 0.8rem !important;
}
.nk-wizard .actions a[href="#previous"] {
float: right !important;
background-color: transparent !important;
border: 1px solid grey !important;
color: grey !important;
margin-left: -0.8rem !important; /* Hapus margin negatif */
}

View File

@ -483,7 +483,7 @@
return $self_id.valid();
},
onFinished: function onFinished(event, currentIndex) {
$self_id.submit();
document.getElementById("proposal-wizard").submit();
}
}).validate({
errorElement: "span",

View File

@ -11,13 +11,13 @@
<div class="nk-block-head-content">
<h3 class="nk-block-title page-title">{{$title}}</h3>
</div><!-- .nk-block-head-content -->
{{-- @if (is_role(['1']))
@if (is_role(['3']))
<div class="nk-block-head-content">
<div class="toggle-wrap nk-block-tools-toggle">
<a href="#" class="btn btn-icon btn-trigger toggle-expand me-n1" data-target="pageMenu"><em class="icon ni ni-more-v"></em></a>
<div class="toggle-expand-content" data-content="pageMenu">
<ul class="nk-block-tools g-3">
<li>
{{-- <li>
<div class="drodown">
<a href="#" class="dropdown-toggle btn btn-white btn-dim btn-outline-light" data-bs-toggle="dropdown"><em class="d-none d-sm-inline icon ni ni-calender-date"></em><span><span class="d-none d-md-inline">Last</span> 30 Days</span><em class="dd-indc icon ni ni-chevron-right"></em></a>
<div class="dropdown-menu dropdown-menu-end">
@ -28,13 +28,13 @@
</ul>
</div>
</div>
</li>
<li class="nk-block-tools-opt"><a href="{{route('dashboard.cooperations.create')}}" class="btn btn-primary"><em class="icon ni ni-plus"></em><span>Tambah</span></a></li>
</li> --}}
<li class="nk-block-tools-opt"><a href="{{route('dashboard.cooperations.create')}}" class="btn btn-primary"><em class="icon ni ni-file-docs"></em><span>Ajuan Saya</span></a></li>
</ul>
</div>
</div>
</div><!-- .nk-block-head-content -->
@endif --}}
@endif
</div><!-- .nk-block-between -->
</div><!-- .nk-block-head -->
<div class="nk-block nk-block-lg">

View File

@ -0,0 +1,66 @@
@include('partials.dashboard.head')
@include('partials.dashboard.sidebar', ['page' => 'cooperation_requests'])
@include('partials.dashboard.header')
<!-- content @s -->
<div class="nk-content ">
<div class="container-fluid">
<div class="nk-content-inner">
<div class="nk-content-body">
<div class="nk-block-head nk-block-head-sm">
<div class="nk-block-between">
<div class="nk-block-head-content">
<h3 class="nk-block-title page-title">{{$title}}</h3>
</div><!-- .nk-block-head-content -->
@if (is_role(['3']))
<div class="nk-block-head-content">
<div class="toggle-wrap nk-block-tools-toggle">
<a href="#" class="btn btn-icon btn-trigger toggle-expand me-n1" data-target="pageMenu"><em class="icon ni ni-more-v"></em></a>
<div class="toggle-expand-content" data-content="pageMenu">
<ul class="nk-block-tools g-3">
{{-- <li>
<div class="drodown">
<a href="#" class="dropdown-toggle btn btn-white btn-dim btn-outline-light" data-bs-toggle="dropdown"><em class="d-none d-sm-inline icon ni ni-calender-date"></em><span><span class="d-none d-md-inline">Last</span> 30 Days</span><em class="dd-indc icon ni ni-chevron-right"></em></a>
<div class="dropdown-menu dropdown-menu-end">
<ul class="link-list-opt no-bdr">
<li><a href="#"><span>Last 30 Days</span></a></li>
<li><a href="#"><span>Last 6 Months</span></a></li>
<li><a href="#"><span>Last 1 Years</span></a></li>
</ul>
</div>
</div>
</li> --}}
<li class="nk-block-tools-opt"><a href="{{route('dashboard.cooperations.create')}}" class="btn btn-primary"><em class="icon ni ni-file-docs"></em><span>Ajuan Saya</span></a></li>
</ul>
</div>
</div>
</div><!-- .nk-block-head-content -->
@endif
</div><!-- .nk-block-between -->
</div><!-- .nk-block-head -->
<div class="nk-block nk-block-lg">
<div class="card card-bordered card-preview">
<div class="card-inner">
<div class="table-responsive">
<table class="table table-striped table-bordered nowrap" id="cooperationRequestsTable" border="1">
<thead>
<tr>
<th style="width: 10% !important;">No</th>
<th>Nama Kegiatan</th>
<th>Tanggal Mulai</th>
<th>Tanggal Selesai</th>
<th>Dibuat Pada</th>
<th>Status</th>
<th style="width: 10% !important;"></th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- content @e -->
@include('partials.dashboard.footer' ,['datatable' => 'cooperation_request'])

View File

@ -14,7 +14,8 @@
</li>
</ul><!-- .nav-tabs -->
<div class="card-inner">
<form action="#" class="nk-wizard nk-wizard-simple is-alter" id="wizard-01">
<form action="{{route('dashboard.cooperations.requests.proposal.action', ['id' => encrypt_id($cooperation->id)])}}" class="nk-wizard nk-wizard-simple is-alter" id="proposal-wizard" method="post" enctype="multipart/form-data">
@csrf
<div class="nk-wizard-head">
<h5>Data Perusahaan</h5>
</div>
@ -258,7 +259,7 @@
@foreach ($user->company->media->journalists as $journalist)
<li>
<div class="custom-control custom-control-sm custom-checkbox custom-control-pro">
<input type="checkbox" class="custom-control-input" id="journalists-{{$journalist->id}}" name="journalists[]" value="{{$journalist->id}}" required>
<input type="checkbox" class="custom-control-input" id="journalists-{{$journalist->id}}" name="journalist_ids[]" value="{{$journalist->id}}" required>
<label class="custom-control-label" for="journalists-{{$journalist->id}}">
<span class="user-card">
<span class="user-avatar sm bg-info">
@ -285,18 +286,18 @@
<div class="row gy-2">
<div class="col-md-6">
<div class="form-group">
<label class="form-label" for="fw-telegram-username">Lampiran Pengajuan</label>
<label class="form-label" for="attachment">Lampiran Pengajuan<span class="required-input">*</span></label>
<div class="form-control-wrap">
<input type="file" data-msg="Wajib Di isi" class="form-control required" id="fw-telegram-username" name="fw-telegram-username" required>
<input type="file" data-msg="Wajib Di isi" class="form-control required" id="attachment" name="attachment" required accept="application/pdf">
</div>
</div>
</div><!-- .col -->
<div class="col-md-6">
<div class="form-group">
<label class="form-label" for="fw-telegram-username">Template Lampiran Pengajuan</label>
<label class="form-label" for="offer_file_download">Template Lampiran Pengajuan</label>
<div class="form-control-wrap">
<a href="#" class="btn btn-info" style="width: 100%;">
<em class="icon ni ni-download" style="margin-top: -0.2rem"></em> Unduh template lampiran pengajuan
<a href="{{asset('storage/uploads/cooperations/'. $cooperation->offer_file_template)}}" class="btn btn-info" style="width: 100%;" download="template-pengajuan-{{slugify($cooperation->name. '.pdf')}}">
<em class="icon ni ni-download" style="margin-top: -0.2rem"></em> Unduh template pengajuan
</a>
</div>
</div>
@ -305,7 +306,7 @@
<div class="form-group">
<label class="form-label" for="fw-token-address">Deskripsi</label>
<div class="form-control-wrap">
<textarea class="tinymce-basic form-control" name="content">{!!old('content')!!}</textarea>
<textarea class="tinymce-basic form-control" name="description">{!!old('description')!!}</textarea>
</div>
</div>
</div>

View File

@ -28,7 +28,7 @@
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="start_date">Tanggal Mulai Informasi<span class="required-input">*</span></label>
<label class="form-label" for="start_date">Tanggal Mulai Pengajuan<span class="required-input">*</span></label>
<div class="form-control-wrap">
<input type="date" class="form-control @error('start_date') border-danger @enderror" id="start_date" name="start_date" placeholder="Masukan tanggal mulai" value="{{old('start_date')}}">
</div>
@ -39,7 +39,7 @@
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="end_date">Tanggal Akhir Informasi<span class="required-input">*</span></label>
<label class="form-label" for="end_date">Tanggal Akhir Pengajuan<span class="required-input">*</span></label>
<div class="form-control-wrap">
<input type="date" class="form-control @error('end_date') border-danger @enderror" id="end_date" name="end_date" placeholder="Masukan tanggal selesai" value="{{old('end_date')}}">
</div>
@ -80,7 +80,7 @@
</div>
<div class="col-lg-6">
<div class="form-group">
<label class="form-label" for="offer_file_template">Template PDF</label>
<label class="form-label" for="offer_file_template">Template Pengajuan<span class="required-input">*</span></label>
<div class="form-control-wrap">
<input type="file" class="form-control @error('offer_file_template') border-danger @enderror" id="offer_file_template" name="offer_file_template" placeholder="Masukan template penawaran" value="{{old('offer_file_template')}}" accept="application/pdf">
</div>

View File

@ -383,7 +383,7 @@
],
language: datatableLanguage,
autoWidth: false,
order: [[6, 'desc']],
order: [[7, 'desc']],
pagingType: "simple",
lengthMenu: [[10, 25, 50, 100, -1], ['Tampilkan 10 data', 'Tampilkan 25 data', 'Tampilkan 50 data', 'Tampilkan 100 data', 'Tampilkan semua']],
scrollX: true,

View File

@ -250,6 +250,7 @@
Route::post('/', 'store')->name('store');
Route::post('/{id}/accept', 'accept')->name('accept');
Route::get('/{id}/proposal', 'proposal')->name('proposal');
Route::post('/{id}/proposal', 'proposalAction')->name('proposal.action');
Route::get('/{id}/reject', 'reject')->name('reject');
Route::post('/{id}/reject', 'rejectAction')->name('reject.action');
Route::get('/{id}/edit', 'edit')->name('edit');