324 lines
13 KiB
PHP
324 lines
13 KiB
PHP
@extends('dashboard.base')
|
|
|
|
@section('title', 'Ranking Abensi Karyawan')
|
|
|
|
@section('content')
|
|
<div class="content-wrapper">
|
|
<div class="row">
|
|
<div class="col-md-12 grid-margin">
|
|
<div class="row">
|
|
<div class="col-12 col-xl-8 mb-4 mb-xl-0">
|
|
<h3 class="font-weight-bold">Ranking Karyawan Berdasarkan Absensi</h3>
|
|
<h6 class="font-weight-normal mb-0" id="monthYearDisplay">
|
|
Bulan: {{ $months[$currentMonth] }} {{ $currentYear }}
|
|
<span class="text"> | Urutan: {{ $sort == 'desc' ? 'Terbanyak' : 'Tersedikit' }}</span>
|
|
</h6>
|
|
</div>
|
|
<div class="col-12 col-xl-4 text-right">
|
|
<div class="dropdown d-inline mr-2">
|
|
<button class="btn btn-sm btn-outline-primary dropdown-toggle" type="button" id="monthDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
Pilih Bulan
|
|
</button>
|
|
<div class="dropdown-menu" aria-labelledby="monthDropdown">
|
|
@foreach($months as $key => $month)
|
|
<a class="dropdown-item month-select" href="#" data-month="{{ $key }}">{{ $month }}</a>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
<div class="dropdown d-inline">
|
|
<button class="btn btn-sm btn-outline-primary dropdown-toggle" type="button" id="sortDropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
{{ $sort == 'desc' ? 'Terbanyak Izin' : 'Tersedikit Izin' }}
|
|
</button>
|
|
<div class="dropdown-menu" aria-labelledby="sortDropdown">
|
|
<a class="dropdown-item sort-select" href="#" data-sort="desc">Terbanyak Izin</a>
|
|
<a class="dropdown-item sort-select" href="#" data-sort="asc">Tersedikit Izin</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ... (bagian tabel tetap sama) ... -->
|
|
|
|
|
|
<div class="row">
|
|
<div class="col-md-12 grid-margin stretch-card">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover">
|
|
<thead>
|
|
<tr>
|
|
<th>Rank</th>
|
|
<th>Nama Karyawan</th>
|
|
<th>Total Absen (in+out)</th>
|
|
<th>Detail</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="rankingTableBody">
|
|
@forelse($ranking as $index => $user)
|
|
<tr>
|
|
<td>{{ $ranking->firstItem() + $index }}</td>
|
|
<td>{{ $user->name }}</td>
|
|
<td>{{ $user->total_absen }}</td>
|
|
<td>
|
|
<a href="#" class="btn btn-sm btn-info view-detail"
|
|
data-user-id="{{ $user->id }}"
|
|
data-user-name="{{ $user->name }}">
|
|
<i class="ti-eye"></i> Lihat
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="4" class="text-center">Tidak ada data absensi bulan ini</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
<div class="mt-3">
|
|
{{ $ranking->appends([
|
|
'month' => $currentMonth,
|
|
'year' => $currentYear,
|
|
'sort' => $sort
|
|
])->links() }}
|
|
</div>
|
|
|
|
<h6 class="font-weight-normal mb-0" id="monthYearDisplay" style="display:none;">
|
|
Bulan: {{ $months[$currentMonth] }} {{ $currentYear }}
|
|
<span class="text"> | Urutan: {{ $sort == 'desc' ? 'Terbanyak' : 'Tersedikit' }}</span>
|
|
</h6>
|
|
|
|
</table>
|
|
</div>
|
|
<div class="mt-3">
|
|
{{ $ranking->appends([
|
|
'month' => $currentMonth,
|
|
'year' => $currentYear,
|
|
'sort' => $sort
|
|
])->links() }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
@endsection
|
|
|
|
<div class="modal fade" id="detailModal" tabindex="-1" role="dialog" aria-labelledby="detailModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-lg" role="document">
|
|
<div class="modal-content">
|
|
<div class="modal-header bg-info text-white">
|
|
<h5 class="modal-title" id="detailModalLabel">
|
|
Detail Absensi: <span id="userName"></span>
|
|
</h5>
|
|
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
|
|
<span aria-hidden="true">×</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<table class="table table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Nama</th>
|
|
<th>Tanggal</th>
|
|
<th>Jam</th>
|
|
<th>Type</th>
|
|
<th>Foto</th>
|
|
<th>Latitude</th>
|
|
<th>Longitude</th>
|
|
<th>Lokasi</th>
|
|
<th>Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="absenDetailBody">
|
|
<tr><td colspan="9" class="text-center">Memuat data...</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Tutup</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
@push('script')
|
|
<script>
|
|
$(document).ready(function() {
|
|
let currentMonth = {{ $currentMonth }};
|
|
let currentYear = {{ $currentYear }};
|
|
let currentSort = '{{ $sort }}';
|
|
|
|
// Fungsi untuk memuat data ranking
|
|
function loadRankingData() {
|
|
$.ajax({
|
|
url: '/toprank/absensi',
|
|
type: 'GET',
|
|
data: {
|
|
month: currentMonth,
|
|
year: currentYear,
|
|
sort: currentSort
|
|
},
|
|
success: function(response) {
|
|
$('#rankingTableBody').html($(response).find('#rankingTableBody').html());
|
|
$('#monthYearDisplay').html($(response).find('#monthYearDisplay').html());
|
|
},
|
|
error: function(xhr) {
|
|
console.error('Error loading ranking data:', xhr);
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
// Handle pemilihan bulan
|
|
$(document).on('click', '.month-select', function(e) {
|
|
e.preventDefault();
|
|
currentMonth = $(this).data('month');
|
|
loadRankingData();
|
|
});
|
|
|
|
// Handle pemilihan sorting
|
|
$(document).on('click', '.sort-select', function(e) {
|
|
e.preventDefault();
|
|
currentSort = $(this).data('sort');
|
|
loadRankingData();
|
|
});
|
|
|
|
|
|
// Fungsi untuk render permissions
|
|
function renderPermissions(permissions, targetId) {
|
|
let html = '<div class="list-group">';
|
|
|
|
if (permissions && permissions.length > 0) {
|
|
permissions.forEach(function(permission) {
|
|
let statusBadge = '';
|
|
let statusClass = '';
|
|
|
|
if (permission.status === 'accepted') {
|
|
statusBadge = 'Disetujui';
|
|
statusClass = 'success';
|
|
} else if (permission.status === 'pending') {
|
|
statusBadge = 'Pending';
|
|
statusClass = 'warning';
|
|
} else {
|
|
statusBadge = 'Ditolak';
|
|
statusClass = 'danger';
|
|
}
|
|
|
|
let proofPhoto = permission.proof_photo ?
|
|
`<a href="/storage/permissions/${permission.proof_photo}" target="_blank" class="btn btn-sm btn-link mt-1">
|
|
<i class="ti-image"></i> Lihat Bukti
|
|
</a>` : '';
|
|
|
|
let approvedInfo = permission.approved_at ?
|
|
`<small class="text-muted d-block mt-1">
|
|
Disetujui pada: ${new Date(permission.approved_at).toLocaleDateString('id-ID')}
|
|
</small>` : '';
|
|
|
|
html += `
|
|
<div class="list-group-item">
|
|
<div class="d-flex justify-content-between align-items-start">
|
|
<div>
|
|
<h6 class="mb-1 font-weight-bold">${permission.category}</h6>
|
|
<p class="mb-1">${permission.start_date} s/d ${permission.end_date}</p>
|
|
<p class="mb-1 small">Alasan: ${permission.reason}</p>
|
|
</div>
|
|
<span class="badge badge-${statusClass}">${statusBadge}</span>
|
|
</div>
|
|
${proofPhoto}
|
|
<small class="text-muted d-block mt-1">
|
|
Diajukan pada: ${new Date(permission.created_at).toLocaleDateString('id-ID')}
|
|
</small>
|
|
${approvedInfo}
|
|
</div>
|
|
`;
|
|
});
|
|
} else {
|
|
html += `
|
|
<div class="list-group-item text-center py-4">
|
|
<i class="ti-info-alt" style="font-size: 2rem;"></i>
|
|
<p class="mt-2 mb-0">Tidak ada data izin</p>
|
|
</div>
|
|
`;
|
|
}
|
|
|
|
html += '</div>';
|
|
$('#' + targetId).html(html);
|
|
}
|
|
|
|
// Handle modal detail
|
|
$(document).on('click', '.view-detail', function(e) {
|
|
e.preventDefault();
|
|
const userId = $(this).data('user-id');
|
|
const userName = $(this).data('user-name');
|
|
|
|
const modal = $('#detailModal');
|
|
modal.find('#userName').text(userName);
|
|
modal.modal('show');
|
|
|
|
$('#absenDetailBody').html('<tr><td colspan="9" class="text-center">Memuat data...</td></tr>');
|
|
|
|
$.ajax({
|
|
url: '/toprank/absensi/user/' + userId + '/attendances',
|
|
type: 'GET',
|
|
data: {
|
|
month: {{ $currentMonth }},
|
|
year: {{ $currentYear }}
|
|
},
|
|
headers: {
|
|
'Accept': 'application/json',
|
|
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
let html = '';
|
|
if (response.data.length > 0) {
|
|
response.data.forEach(function(absen) {
|
|
const tanggal = new Date(absen.created_at).toLocaleDateString('id-ID');
|
|
const jam = new Date(absen.created_at).toLocaleTimeString('id-ID');
|
|
const foto = absen.photo ?
|
|
`<a href="/storage/attendances/${absen.photo}" target="_blank">Lihat Foto</a>` : '-';
|
|
|
|
|
|
html += `
|
|
<tr>
|
|
<td>${absen.user.name}</td>
|
|
<td>${tanggal}</td>
|
|
<td>${jam}</td>
|
|
<td>${absen.type.toUpperCase()}</td>
|
|
<td>${foto}</td>
|
|
<td>${absen.lat}</td>
|
|
<td>${absen.long}</td>
|
|
<td>${absen.location ? absen.location.name : '-'}</td>
|
|
<td>${absen.status.replaceAll('_', ' ').toUpperCase()}</td>
|
|
</tr>
|
|
`;
|
|
});
|
|
} else {
|
|
html = '<tr><td colspan="9" class="text-center">Tidak ada data absensi</td></tr>';
|
|
}
|
|
$('#absenDetailBody').html(html);
|
|
} else {
|
|
$('#absenDetailBody').html(`<tr><td colspan="9" class="text-center text-danger">${response.message}</td></tr>`);
|
|
}
|
|
},
|
|
error: function(xhr) {
|
|
let message = 'Terjadi kesalahan saat memuat data';
|
|
if (xhr.responseJSON && xhr.responseJSON.message) {
|
|
message = xhr.responseJSON.message;
|
|
}
|
|
$('#absenDetailBody').html(`<tr><td colspan="9" class="text-center text-danger">${message}</td></tr>`);
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
});
|
|
</script>
|
|
@endpush |