diff --git a/app/Http/Controllers/DashboardController.php b/app/Http/Controllers/DashboardController.php index fc20fbd..fa47e2d 100644 --- a/app/Http/Controllers/DashboardController.php +++ b/app/Http/Controllers/DashboardController.php @@ -103,11 +103,7 @@ class DashboardController extends Controller $applyFileFilters = function ($q) use ($keyword, $katArray, $subArray, $entryPegawaiId) { $q->where(function($subQuery) use ($entryPegawaiId){ - $subQuery->where('status_action', '!=', 'rejected') - ->orWhere(function ($pending) use ($entryPegawaiId) { - $pending->whereNull('status_action') - ->where('pegawai_id_entry', $entryPegawaiId); - }); + $subQuery->where('status_action', '!=', 'rejected')->whereNotNull('status_action'); }) ->when($subArray, fn($sq) => $sq->whereIn('id_sub_unit_kerja', $subArray)) ->when($katArray, fn($sq) => $sq->whereIn('master_kategori_directory_id', $katArray)) @@ -243,7 +239,24 @@ class DashboardController extends Controller $file->storeAs($path, $imageName, 'file_directory'); $payload['file'] =$path .'/' .$imageName; } - FileDirectory::create($payload); + $fd = FileDirectory::create($payload); + + $payloadLog = [ + 'file_directory_id' => $fd->file_directory_id, + 'pegawai_id_entry' => $fd->pegawai_id_entry, + 'pegawai_nama_entry' => $fd->pegawai_nama_entry, + 'entry_at' => Carbon::now(), + 'action_type' => 'Upload Dokumen', + 'statusenabled' => true, + 'mod_change' => $fd->entry_at, + 'id_unit_kerja' => $fd->id_unit_kerja, + 'id_sub_unit_kerja' => $fd->id_sub_unit_kerja, + 'file' => $fd->file, + 'tanggal_terbit' => $fd->tanggal_terbit ?? null, + 'no_dokumen' => $fd->no_dokumen ?? null, + 'permission_file' => $fd->permission_file ?? null, + ]; + LogActivity::create($payloadLog); } } } @@ -465,11 +478,7 @@ class DashboardController extends Controller $query = FileDirectory::where('statusenabled', true) ->where(function($subQuery) use ($entryPegawaiId){ - $subQuery->where('status_action', '!=', 'rejected') - ->orWhere(function ($pending) use ($entryPegawaiId) { - $pending->whereNull('status_action') - ->where('pegawai_id_entry', $entryPegawaiId); - }); + $subQuery->where('status_action', '!=', 'rejected')->whereNotNull('status_action'); })->when($keyword, function ($q) use ($keyword) { $q->where(function ($sub) use ($keyword) { $sub->where('file', 'ILIKE', "%{$keyword}%") @@ -533,7 +542,10 @@ class DashboardController extends Controller if(!$uploadedFile){ throw new \RuntimeException('File wajib diunggah pada baris ke-' . ($index+1)); } - + $unitPegawaiIds = auth()->user()->masterPersetujuan->details->pluck('unit_pegawai_id')->unique()->toArray(); + $status = in_array($id_unit_kerja, $unitPegawaiIds) + ? 'approved' + : null; $payload = [ 'id_unit_kerja' => $id_unit_kerja, 'id_sub_unit_kerja' => $id_sub_unit_kerja, @@ -543,6 +555,9 @@ class DashboardController extends Controller 'tanggal_terbit' => $data['date_active'] ?? null, 'no_dokumen' => $data['no_dokumen'] ?? null, 'permission_file' => ($data['is_permission'] ?? null) == "1", + 'status_action' => $status, + 'action_by' => $status === "approved" ? auth()->user()->objectpegawaifk : null, + 'action_at' => $status === "approved" ? now() : null ]; $imageName = $uploadedFile->getClientOriginalName(); @@ -556,7 +571,7 @@ class DashboardController extends Controller 'file_directory_id' => $fd->file_directory_id, 'pegawai_id_entry' => $fd->pegawai_id_entry, 'pegawai_nama_entry' => $fd->pegawai_nama_entry, - 'entry_at' => $fd->entry_at, + 'entry_at' => now(), 'action_type' => 'Upload Dokumen', 'statusenabled' => true, 'mod_change' => $fd->entry_at, @@ -882,7 +897,7 @@ class DashboardController extends Controller } $data->update([ 'status_action' => 'approved', - 'action_at' => Carbon::now(), + 'action_at' => now(), 'action_by' => auth()->user()->dataUser->id, ]); $payloadLog = [ @@ -924,7 +939,7 @@ class DashboardController extends Controller } $data->update([ 'status_action' => 'rejected', - 'action_at' => Carbon::now(), + 'action_at' => now(), 'action_by' => auth()->user()->dataUser->id, ]); $payloadLog = [ @@ -973,4 +988,62 @@ class DashboardController extends Controller ]); } } + + public function pengajuanFile(){ + return view('pengajuanFile.index', ['title' => 'Data Pending']); + } + + public function dataPengajuanFile(){ + $perPage = (int) request('per_page', 10); + $keyword = request('keyword'); + $start = request('start_date'); + $end = request('end_date'); + $query = FileDirectory::where('statusenabled', true)->where('pegawai_id_entry', auth()->user()->objectpegawaifk) + ->where(function($q){ + $q->where('status_action', '!=', 'approved') + ->orWhereNull('status_action'); + })->orderBy('entry_at','desc'); + if($keyword){ + $query->where(function($q) use ($keyword){ + $q->where('file', 'ILIKE', "%{$keyword}%") + ->orWhere('no_dokumen', 'ILIKE', "%{$keyword}%"); + }); + } + if($start){ + $query->whereDate('entry_at','>=',$start); + } + if($end){ + $query->whereDate('entry_at','<=',$end); + } + + $paginated = $query->paginate($perPage); + $data = $paginated->getCollection()->map(function($item){ + $dataSlice = array_values(array_filter(explode('/', $item->file))); + return [ + 'file_directory_id' => $item->file_directory_id, + 'pegawai_nama_entry' => $item->pegawai_nama_entry, + 'part' => $dataSlice[0] . '/' . $dataSlice[1], + 'folder' => $dataSlice[2], + 'fileName' =>$dataSlice[3], + 'file' => $item->file, + 'no_dokumen' => $item->no_dokumen, + 'entry_at' => $item->entry_at, + 'tanggal_terbit' => $item->tanggal_terbit, + 'permission_file' => $item->permission_file, + 'status_action' => $item->status_action + ]; + }); + return response()->json([ + 'status' => true, + 'data' => $data, + 'pagination' => [ + 'current_page' => $paginated->currentPage(), + 'next_page' => $paginated->hasMorePages() ? $paginated->currentPage() + 1 : null, + 'has_more' => $paginated->hasMorePages(), + 'last_page' => $paginated->lastPage(), + 'per_page' => $paginated->perPage(), + 'total' => $paginated->total(), + ] + ]); + } } diff --git a/config/app.php b/config/app.php index 423eed5..213c66e 100644 --- a/config/app.php +++ b/config/app.php @@ -65,7 +65,7 @@ return [ | */ - 'timezone' => 'UTC', + 'timezone' => env('APP_TIMEZONE'), /* |-------------------------------------------------------------------------- diff --git a/public/js/pengajuanFile/index.js b/public/js/pengajuanFile/index.js new file mode 100644 index 0000000..275a18d --- /dev/null +++ b/public/js/pengajuanFile/index.js @@ -0,0 +1,230 @@ +document.addEventListener('DOMContentLoaded', () => { + const tableState = { data: [], page: 1, pageSize: 10, search: '', lastPage: 1, total: 0, startDate: '', endDate: '' }; + const tbody = document.getElementById('tablePengajuanFile'); + const paginationEl = document.getElementById('paginationControls'); + const summaryEl = document.getElementById('tableSummary'); + const pageSizeSelect = document.getElementById('tablePageSize'); + const startDateInput = document.getElementById('startDate'); + const endDateInput = document.getElementById('endDate'); + + if (pageSizeSelect) { + const initialSize = parseInt(pageSizeSelect.value); + if (!isNaN(initialSize)) tableState.pageSize = initialSize; + pageSizeSelect.addEventListener('change', (e) => { + const val = parseInt(e.target.value); + if (!isNaN(val) && val > 0) { + tableState.pageSize = val; + tableState.page = 1; + fetchData(); + } + }); + } + + window.applyDateFilter = function(){ + tableState.startDate = startDateInput.value || ''; + tableState.endDate = endDateInput.value || ''; + tableState.page = 1; + fetchData(); + } + + function formatTanggal(dateString) { + if (!dateString) return '-'; + const d = new Date(dateString); + return d.toLocaleDateString('id-ID', { + day: '2-digit', + month: 'short', + year: 'numeric', + hour: '2-digit', + minute: '2-digit' + }); + } + + function buildRow(item){ + let tanggal = item.entry_at ? formatTanggal(item.entry_at) : '-'; + const aksi = ` +
+ + +
+ `; + return ` + + ${item.no_dokumen || '-'} + + + + ${item.fileName} + ${item.folder || '-'} + ${item.part || '-'} + ${tanggal} + + `; + } + + function renderPagination(totalPages){ + if (!paginationEl) return; + if (totalPages <= 1) { + paginationEl.innerHTML = ''; + return; + } + const maxButtons = 5; + let start = Math.max(1, tableState.page - Math.floor(maxButtons/2)); + let end = Math.min(totalPages, start + maxButtons - 1); + start = Math.max(1, end - maxButtons + 1); + + let buttons = ''; + buttons += ``; + for (let i = start; i <= end; i++) { + buttons += ``; + } + buttons += ``; + + paginationEl.innerHTML = ` +
+
${buttons}
+ Halaman ${tableState.page} dari ${totalPages} +
+ `; + } + + if (paginationEl) { + paginationEl.addEventListener('click', (e) => { + const page = e.target.getAttribute('data-page'); + if (!page) return; + if (page === 'prev' && tableState.page > 1) tableState.page--; + else if (page === 'next') { + if (tableState.page < tableState.lastPage) tableState.page++; + } else { + tableState.page = parseInt(page); + } + fetchData(); + }); + } + + function renderTable(){ + const pageData = tableState.data || []; + if (pageData.length === 0) { + tbody.innerHTML = ` + + + Tidak ada data + + + `; + } else { + tbody.innerHTML = pageData.map(buildRow).join(''); + } + + const from = tableState.total === 0 ? 0 : ((tableState.page - 1) * tableState.pageSize) + 1; + const to = Math.min(((tableState.page - 1) * tableState.pageSize) + pageData.length, tableState.total); + if (summaryEl) { + summaryEl.textContent = tableState.total ? `Menampilkan ${from} - ${to} dari ${tableState.total} data` : 'Tidak ada data'; + } + + renderPagination(tableState.lastPage || 1); + } + + let searchDebounce; + window.debouncedTableSearch = function(value){ + clearTimeout(searchDebounce); + searchDebounce = setTimeout(() => { + tableState.search = value.trim(); + tableState.page = 1; + fetchData(); + }, 250); + } + + window.refreshLog = function(){ + tableState.search = ''; + tableState.startDate = ''; + tableState.endDate = ''; + document.getElementById('tableSearch').value = ''; + startDateInput.value = ''; + endDateInput.value = ''; + tableState.page = 1; + fetchData(); + } + + function fetchData(){ + if (summaryEl) summaryEl.textContent = 'Memuat data...'; + const params = new URLSearchParams({ + page: tableState.page, + per_page: tableState.pageSize, + keyword: tableState.search || '', + start_date: tableState.startDate || '', + end_date: tableState.endDate || '' + }); + fetch(`/datatable/pengajuan-file?${params.toString()}`) + .then(res => res.json()) + .then(data => { + tableState.data = data?.data || []; + tableState.lastPage = data?.pagination?.last_page || 1; + tableState.total = data?.pagination?.total || 0; + renderTable(); + }) + .catch(err => { + console.error(err); + if (summaryEl) summaryEl.textContent = 'Gagal memuat data'; + }); + } + + fetchData(); + + +}); +document.addEventListener('click', function(e){ + if(e.target.matches('.file-link')){ + e.preventDefault(); + let fileUrl = e.target.getAttribute('data-file'); + let noDokumen = e.target.getAttribute('data-no_dokumen') + let tanggalTerbit = e.target.getAttribute('data-tanggal_terbit') + let permissionFile = e.target.getAttribute('data-permission_file') + let fileName = e.target.getAttribute('data-fileName') + currentFile = fileUrl; + idDirectory = e.target.getAttribute('data-id'); + + + const titleEl = document.getElementById('confirm_preview_file'); + if (titleEl) titleEl.textContent = fileName; + + // set footer info + const noEl = document.getElementById('confirm-upload-dokumen'); + if (noEl) noEl.textContent = noDokumen; + + const tglEl = document.getElementById('confirm-time-dokumen'); + + if (tglEl) tglEl.textContent = tanggalTerbit; + + const permEl = document.getElementById('confirm-permission'); + if (permEl) { + const publicDoc = isPublic(permissionFile); + permEl.textContent = publicDoc ? 'Bisa dilihat unit lain' : 'Hanya unit ini'; + permEl.className = 'badge ' + (publicDoc ? 'bg-success' : 'bg-secondary'); + } + let previewBox = document.getElementById('file-preview'); + previewBox.innerHTML = ``; + $("#previewModal").modal('show') + } + + + if(e.target.matches('#btn-view-full')){ + window.open(`/file-preview/${idDirectory}`, '_blank'); + } + }) +function isPublic(permissionVal){ + if(permissionVal === null || permissionVal === undefined) return false; + const val = String(permissionVal).toLowerCase(); + return val === '1' || val === 'true' || val === 'iya' || val === 'yes'; + } diff --git a/resources/views/dashboard/modal/create.blade.php b/resources/views/dashboard/modal/create.blade.php index 502df94..80f0cf6 100644 --- a/resources/views/dashboard/modal/create.blade.php +++ b/resources/views/dashboard/modal/create.blade.php @@ -44,7 +44,7 @@
- +
diff --git a/resources/views/dashboardV2/modal/create.blade.php b/resources/views/dashboardV2/modal/create.blade.php index 9f6051e..a59cf5f 100644 --- a/resources/views/dashboardV2/modal/create.blade.php +++ b/resources/views/dashboardV2/modal/create.blade.php @@ -44,7 +44,7 @@
- +
diff --git a/resources/views/layout/partials/sidenav.blade.php b/resources/views/layout/partials/sidenav.blade.php index 4e850fe..a6f5b53 100644 --- a/resources/views/layout/partials/sidenav.blade.php +++ b/resources/views/layout/partials/sidenav.blade.php @@ -62,6 +62,17 @@ 0 + @else + @endif {{-- RECAP --}} diff --git a/resources/views/pengajuanFile/index.blade.php b/resources/views/pengajuanFile/index.blade.php new file mode 100644 index 0000000..e0370cd --- /dev/null +++ b/resources/views/pengajuanFile/index.blade.php @@ -0,0 +1,68 @@ +@extends('layout.main') +@section('body_main') +
+
+
+
+

Data Pending

+
+
+
+
+ + + + +
+
+ + +
+
+ + +
+
+ +
+ +
+
+
+ + + + + + + + + + + + + + +
No DokumenStatusFileFolderUnit/Sub UnitTanggal
+
+
+
+ +
+
+
+ @include('pendingFile.modal.view') + +@endsection diff --git a/routes/web.php b/routes/web.php index 5d4b526..d4d46f6 100644 --- a/routes/web.php +++ b/routes/web.php @@ -48,6 +48,8 @@ Route::middleware(['auth'])->group(function(){ Route::get('/data/recap', [DashboardController::class, 'recapData']); + Route::get('/pengajuan-file', [DashboardController::class, 'pengajuanFile']); + Route::get('/datatable/pengajuan-file', [DashboardController::class, 'dataPengajuanFile']); Route::middleware(['master.persetujuan'])->group(function () { Route::get('/pending-file', [DashboardController::class, 'pendingFile']);