⚝
One Hat Cyber Team
⚝
Your IP:
192.168.31.6
Server IP:
192.168.1.11
Server:
Linux pams 6.1.0-29-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.123-1 (2025-01-02) x86_64
PHP Version:
8.2.28
Buat File
|
Buat Folder
Upload File
Eksekusi
Dir :
~
/
var
/
www
/
apik
/
modules
/
Absen
/
Views
/
Edit File: struktur-bc.php
<div class="d-flex justify-content-between align-items-sm-center flex-column flex-sm-row mb-3"> <div class="me-4 mb-3 mb-sm-0"> <h1 class="mb-0" id="judul-rekap"><?=$title?></h1> </div> </div> <div class="row"> <div class="col-12 mb-4"> <div class="card border-start-lg border-start-primary h-100 card card-header-actions"> <div class="card-header"> <div id="export"></div> <div class="card-tools"> </div> </div> <div class="card-body"> <!-- Form Filter (Tanpa Submit Page Reload) --> <div class="row align-items-end g-3 mb-4"> <div class="col-md-3 col-sm-6"> <label for="bulan" class="form-label fw-bold">Pilih Bulan</label> <select id="bulan" class="form-select"> <option value="1">Januari</option> <option value="2">Februari</option> <option value="3">Maret</option> <option value="4">April</option> <option value="5">Mei</option> <option value="6">Juni</option> <option value="7">Juli</option> <option value="8">Agustus</option> <option value="9">September</option> <option value="10">Oktober</option> <option value="11">November</option> <option value="12">Desember</option> </select> </div> <div class="col-md-3 col-sm-6"> <label for="tahun" class="form-label fw-bold">Pilih Tahun</label> <select id="tahun" class="form-select"> <!-- Tahun akan diisi via JS / Manual --> <option value="2025">2025</option> <option value="2026" selected>2026</option> <option value="2027">2027</option> </select> </div> <div class="col-md-3 col-sm-6"> <button type="button" id="btn-filter" class="btn btn-primary w-100"> <i class="fas fa-filter me-1"></i> Tampilkan </button> </div> </div> <!-- Custom CSS untuk kerapihan tabel --> <style> /* Freeze kolom 1 (No) dan kolom 2 (Nama) */ #myTable td:nth-child(1), #myTable th:nth-child(1) { position: sticky; left: 0; z-index: 5; background-color: #fff; } #myTable td:nth-child(2), #myTable th:nth-child(2) { position: sticky; left: 40px; /* Jarak disesuaikan dengan lebar kolom No */ z-index: 5; background-color: #fff; } </style> <!-- Container Tabel Matriks --> <div class="table-responsive"> <table id="myTable" class="table table-bordered table-striped" style="width:100%"> <thead id="table-head"> <!-- Header akan di-render dinamis oleh jQuery --> </thead> <tbody id="isi"> <!-- Body akan di-render dinamis oleh jQuery / AJAX --> </tbody> </table> </div> </div> </div> </div> </div> <script type="text/javascript"> // ========================================== // 1. HELPER FUNCTIONS (Di LUAR ready) // ========================================== function renderBody(dataPegawai, totalHari, bulan, tahun) { var htmlBody = ''; if (dataPegawai && dataPegawai.length > 0) { $.each(dataPegawai, function(index, pegawai) { var totalHadir = 0; var totalAbsenWeekend = 0; htmlBody += `<tr>`; htmlBody += `<td class="text-center align-middle">${index + 1}</td>`; htmlBody += `<td class="text-start align-middle fw-bold">${pegawai.nama}</td>`; for (var d = 1; d <= totalHari; d++) { var dateObj = new Date(tahun, bulan - 1, d); var dayOfWeek = dateObj.getDay(); var isWeekendOrJumat = (dayOfWeek === 5 || dayOfWeek === 6 || dayOfWeek === 0); var cellContent = '-'; var bgClass = ''; var textClass = ''; var isHadir = pegawai.absen && pegawai.absen[d]; // Hitung total hadir (semua hari) if (isHadir) { totalHadir++; } if (isWeekendOrJumat) { // Logic Jumat, Sabtu, Minggu if (isHadir) { bgClass = 'bg-success'; textClass = 'text-white fw-bold'; cellContent = pegawai.absen[d].waktu.substring(0, 5); } else { bgClass = 'bg-danger'; textClass = 'text-white'; cellContent = '-'; // Hitung tidak hadir KHUSUS Jumat, Sabtu, Minggu totalAbsenWeekend++; } } else { // Logic Senin - Kamis if (isHadir) { cellContent = pegawai.absen[d].waktu.substring(0, 5); textClass = 'fw-semibold text-dark'; } else { cellContent = '-'; textClass = 'text-muted small'; } } htmlBody += `<td class="text-center align-middle ${bgClass} ${textClass}">${cellContent}</td>`; } // Tambahkan 2 Kolom Total di Paling Kanan htmlBody += `<td class="text-center align-middle fw-bold text-success fs-6">${totalHadir}</td>`; htmlBody += `<td class="text-center align-middle fw-bold text-danger fs-6">${totalAbsenWeekend}</td>`; htmlBody += `</tr>`; }); } else { // Colspan ditambah 4 (No + Nama + 2 Kolom Total) htmlBody = `<tr><td colspan="${totalHari + 4}" class="text-center py-4">Tidak ada data.</td></tr>`; } $('#isi').html(htmlBody); } function renderHeader(totalHari, labelBulanTahun, bulan, tahun) { var htmlHead = ` <tr> <th rowspan="2" class="align-middle text-center">No</th> <th rowspan="2" class="align-middle text-center">Nama</th> <th colspan="${totalHari}" class="text-center">${labelBulanTahun}</th> <th rowspan="2" class="align-middle text-center bg-success text-white">Jml Hadir</th> <th rowspan="2" class="align-middle text-center bg-danger text-white">Jml Tdk Hadir</th> </tr> <tr> `; for (var d = 1; d <= totalHari; d++) { var dateObj = new Date(tahun, bulan - 1, d); var dayOfWeek = dateObj.getDay(); var isWeekendOrJumat = (dayOfWeek === 5 || dayOfWeek === 6 || dayOfWeek === 0); var bgHeader = isWeekendOrJumat ? 'bg-warning text-dark' : ''; htmlHead += `<th class="text-center ${bgHeader}">${d}</th>`; } htmlHead += `</tr>`; if ($.fn.DataTable.isDataTable('#myTable')) { $('#myTable').DataTable().clear().destroy(); } $('#table-head').html(htmlHead); } function initDataTables(judul) { var table = $('#myTable').DataTable({ dom: 'Bfrtip', scrollX: true, // Mengaktifkan scroll horizontal DataTables scrollCollapse: true, autoWidth: false, // Mematikan auto-width agar lebar kolom terbagi presisi paging: false, destroy: true, columnDefs: [ { targets: '_all', className: 'dt-head-center' } // Merapikan alignment header ], buttons: [ { extend: 'excelHtml5', title: judul, className: 'btn btn-success btn-sm', text: '<i class="fas fa-file-excel me-1"></i> Excel' }, { extend: 'pdfHtml5', title: judul, orientation: 'landscape', pageSize: 'A4', className: 'btn btn-danger btn-sm', text: '<i class="fas fa-file-pdf me-1"></i> PDF' }, { extend: 'print', className: 'btn btn-primary btn-sm', text: '<i class="fas fa-print me-1"></i> Print' } ] }); // Menyelaraskan ulang ukuran kolom setelah DataTables di-render table.columns.adjust(); $('#export').empty(); table.buttons().container().appendTo('#export'); } // ========================================== // 2. MAIN LOGIC & EVENT LISTENERS (Di DALAM ready) // ========================================== $(document).ready(function() { // Jalankan pertama kali saat halaman loaded loadAbsensi(); // Event Klik Filter $('#btn-filter').on('click', function() { loadAbsensi(); }); function loadAbsensi() { var bulan = $('#bulan').val(); var tahun = $('#tahun').val(); var namaBulan = $('#bulan option:selected').text(); var totalHari = new Date(tahun, bulan, 0).getDate(); var judul = 'Rekap Absensi Pejabat Struktural - ' + namaBulan + ' ' + tahun; $('#judul-rekap').text(judul); // Panggil fungsi renderHeader yang ada di luar renderHeader(totalHari, namaBulan + ' ' + tahun); $.ajax({ url: '<?= base_url("absen/syncAbsenStruktur") ?>/' + bulan + '/' + tahun , type: 'GET', dataType: 'json', beforeSend: function() { $('#isi').html('<tr><td colspan="' + (totalHari + 4) + '" class="text-center py-5"><div class="spinner-border text-primary" role="status"></div><br><span class="mt-2 d-inline-block">Memuat data absensi...</span></td></tr>'); }, success: function(response) { if (response.status === 200) { // Tambahkan parameter bulan dan tahun di sini renderBody(response.data, totalHari, bulan, tahun); initDataTables(judul); } else { $('#isi').html('<tr><td colspan="' + (totalHari + 2) + '" class="text-center text-danger py-4">Gagal memuat data.</td></tr>'); } }, error: function() { $('#isi').html('<tr><td colspan="' + (totalHari + 2) + '" class="text-center text-danger py-4">Terjadi kesalahan koneksi server.</td></tr>'); } }); } }); </script>
Simpan