314 lines
17 KiB
PHP
314 lines
17 KiB
PHP
<x-app-layout>
|
|
@push('styles')
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="{{ asset('css/tugas.css') }}" rel="stylesheet">
|
|
<style>
|
|
/* Tambahan khusus monitoring agar tetap presisi */
|
|
.pug-progress-cell { width: 140px; }
|
|
.pug-prog-track { height: 8px; background: var(--pug-bg); border-radius: 10px; overflow: hidden; margin-bottom: 4px; border: 1px solid var(--pug-border); }
|
|
.pug-prog-fill { height: 100%; background: linear-gradient(90deg, var(--pug-green), var(--pug-green-m)); border-radius: 10px; transition: width 0.8s ease; }
|
|
.pug-prog-val { font-size: 10px; font-weight: 800; color: var(--pug-green); }
|
|
</style>
|
|
@endpush
|
|
|
|
<div class="pug-wrap">
|
|
<div class="pug-inner">
|
|
<!-- Header -->
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div class="d-flex align-items-center gap-3">
|
|
<div class="pug-icon-wrap">
|
|
<i class="fas fa-desktop"></i>
|
|
</div>
|
|
<div>
|
|
<h1 class="pug-page-title">Monitoring Progres Kerja</h1>
|
|
<p class="pug-page-sub">Pantau real-time perkembangan tugas teknisi di lapangan.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Statistics -->
|
|
<div class="pug-stats">
|
|
<div class="pug-stat pug-stat-total" onclick="setStatus('')" style="cursor: pointer;" title="Klik untuk melihat semua">
|
|
<div class="pug-stat-icon"><i class="fas fa-list-ul"></i></div>
|
|
<div class="pug-stat-label">TOTAL TUGAS</div>
|
|
<div class="pug-stat-val">{{ $statistics['total'] ?? 0 }}</div>
|
|
</div>
|
|
<div class="pug-stat pug-stat-proses" onclick="setStatus('dalam_proses')" style="cursor: pointer;" title="Klik untuk filter: Dalam Proses">
|
|
<div class="pug-stat-icon"><i class="fas fa-spinner"></i></div>
|
|
<div class="pug-stat-label">DALAM PROGRES</div>
|
|
<div class="pug-stat-val">{{ $statistics['dalam_progres'] ?? 0 }}</div>
|
|
</div>
|
|
<div class="pug-stat pug-stat-selesai" onclick="setStatus('selesai')" style="cursor: pointer;" title="Klik untuk filter: Selesai">
|
|
<div class="pug-stat-icon"><i class="fas fa-check-double"></i></div>
|
|
<div class="pug-stat-label">SELESAI</div>
|
|
<div class="pug-stat-val">{{ $statistics['selesai'] ?? 0 }}</div>
|
|
</div>
|
|
<div class="pug-stat pug-stat-belum" onclick="setStatus('belum_mulai')" style="cursor: pointer;" title="Klik untuk filter: Belum Mulai">
|
|
<div class="pug-stat-icon"><i class="fas fa-clock"></i></div>
|
|
<div class="pug-stat-label">BELUM MULAI</div>
|
|
<div class="pug-stat-val">{{ $statistics['belum_mulai'] ?? 0 }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="pug-main-content">
|
|
<!-- Toolbar Filter -->
|
|
<div class="pug-toolbar">
|
|
<form method="GET" action="{{ route('pekerjaan.monitoring') }}" class="pug-toolbar-form">
|
|
<input type="hidden" name="status" id="statusFilter" value="{{ request('status') }}">
|
|
<div class="pug-toolbar-item" style="flex: 1;">
|
|
<label class="pug-field-label">Teknisi</label>
|
|
<select name="teknisi_id" class="pug-input" onchange="this.form.submit()">
|
|
<option value="">Semua Teknisi</option>
|
|
@foreach($teknisiList as $t)
|
|
<option value="{{ $t->id_teknisi }}" {{ request('teknisi_id') == $t->id_teknisi ? 'selected' : '' }}>{{ $t->nama }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
<div class="pug-toolbar-item" style="flex: 1.5; min-width: 280px;">
|
|
<label class="pug-field-label">Rentang Tanggal</label>
|
|
<div class="d-flex align-items-center gap-2">
|
|
<input type="date" name="start_date" class="pug-input" value="{{ request('start_date') }}" onchange="this.form.submit()" style="padding: 10px 8px;">
|
|
<span class="text-muted small">s/d</span>
|
|
<input type="date" name="end_date" class="pug-input" value="{{ request('end_date') }}" onchange="this.form.submit()" style="padding: 10px 8px;">
|
|
</div>
|
|
</div>
|
|
<div class="pug-toolbar-item item-btn" style="flex: 0 0 auto;">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<a href="{{ route('pekerjaan.monitoring') }}" class="pug-reset-btn" style="height: 44px; display: flex; align-items: center;">
|
|
<i class="fas fa-redo"></i> Reset Filter
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Table Panel -->
|
|
<div class="pug-panel">
|
|
<div class="pug-panel-head">
|
|
<div class="pug-panel-head-left">
|
|
<i class="fas fa-table"></i> DAFTAR PROGRES KERJA
|
|
</div>
|
|
<div class="pug-panel-head-right">
|
|
Menampilkan {{ count($progresKerja) }} data terbaru
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="pug-table">
|
|
<thead>
|
|
<tr>
|
|
<th>#</th>
|
|
<th>Teknisi / Tim</th>
|
|
<th>Foto</th>
|
|
<th>Pekerjaan & Lokasi</th>
|
|
<th>Status</th>
|
|
<th>Aksi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse($progresKerja as $index => $progres)
|
|
<tr>
|
|
<td>
|
|
<span class="pug-rownum">{{ str_pad($progresKerja->firstItem() + $index, 2, '0', STR_PAD_LEFT) }}</span>
|
|
</td>
|
|
<td>
|
|
<div style="display:flex; flex-wrap:wrap; gap:6px; max-width:280px;">
|
|
@foreach($progres->timTeknisi as $member)
|
|
<span class="pug-tech-badge">
|
|
<i class="fas fa-user" style="font-size:10px;"></i> {{ $member->teknisi->nama }}
|
|
</span>
|
|
@endforeach
|
|
</div>
|
|
</td>
|
|
<td>
|
|
@php
|
|
$fotoTampil = $progres->foto_sesudah ?? $progres->foto_sebelum ?? $progres->foto_surat;
|
|
@endphp
|
|
@if($fotoTampil)
|
|
<img src="{{ 'https://ta.myhost.id/E31230906/laravel/public/storage/'.$fotoTampil }}" class="pug-thumb"
|
|
onclick="previewFoto('{{ 'https://ta.myhost.id/E31230906/laravel/public/storage/'.$fotoTampil }}')">
|
|
@else
|
|
<div class="pug-thumb d-flex align-items-center justify-content-center bg-light">
|
|
<i class="fas fa-image text-muted opacity-50"></i>
|
|
</div>
|
|
@endif
|
|
</td>
|
|
<td>
|
|
<div class="pug-av-name">{{ $progres->label_jenis_pekerjaan }}</div>
|
|
<div class="pug-note"><i class="fas fa-map-marker-alt text-danger"></i> {{ Str::limit($progres->alamat_lokasi, 40) }}</div>
|
|
</td>
|
|
<td>
|
|
@switch($progres->status_pekerjaan)
|
|
@case('belum_mulai') <span class="pug-badge pug-badge-muted">Belum Mulai</span> @break
|
|
@case('dalam_proses') <span class="pug-badge pug-badge-violet">Progres</span> @break
|
|
@case('selesai') <span class="pug-badge pug-badge-green">Selesai</span> @break
|
|
@endswitch
|
|
<div class="text-muted mt-1" style="font-size:9px;">{{ \Carbon\Carbon::parse($progres->updated_at)->format('d/m H:i') }}</div>
|
|
</td>
|
|
<td>
|
|
<div class="pug-actions">
|
|
<button class="pug-action-btn pug-action-view" onclick="showDetail({{ $progres->id_penugasan }})">
|
|
<i class="fas fa-eye"></i>
|
|
</button>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="6">
|
|
<div class="pug-empty">
|
|
<div class="pug-empty-icon"><i class="fas fa-folder-open"></i></div>
|
|
<div class="pug-empty-title">Data Tidak Ditemukan</div>
|
|
<div class="pug-empty-sub">Gunakan filter untuk mencari data progres lainnya.</div>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
@if($progresKerja->hasPages())
|
|
<div class="pug-pag">
|
|
{{ $progresKerja->links() }}
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Detail Progres -->
|
|
<div class="pug-overlay" id="detailModal">
|
|
<div class="pug-modal pug-modal-lg">
|
|
<div class="pug-modal-header">
|
|
<div class="pug-modal-title">
|
|
<i class="fas fa-info-circle"></i> DETAIL PROGRES KERJA
|
|
</div>
|
|
<button class="pug-close-btn" onclick="closeModal('detailModal')">
|
|
<i class="fas fa-times"></i>
|
|
</button>
|
|
</div>
|
|
<div class="pug-modal-body" id="detailContent">
|
|
<!-- Loading state -->
|
|
<div class="text-center py-5">
|
|
<div class="spinner-border text-success" role="status"></div>
|
|
<p class="mt-2 text-muted">Mengambil data...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal Foto Preview -->
|
|
<div id="previewOverlay" class="pug-preview-overlay" onclick="closePreview()">
|
|
<button class="pug-preview-x" onclick="closePreview()"><i class="fas fa-times"></i></button>
|
|
<img id="previewImg" src="">
|
|
</div>
|
|
|
|
@push('scripts')
|
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
|
<script>
|
|
function previewFoto(url) {
|
|
document.getElementById('previewImg').src = url;
|
|
document.getElementById('previewOverlay').classList.add('show');
|
|
}
|
|
function closePreview() {
|
|
document.getElementById('previewOverlay').classList.remove('show');
|
|
}
|
|
|
|
function closeModal(id) {
|
|
document.getElementById(id).classList.remove('show');
|
|
}
|
|
|
|
function showDetail(id) {
|
|
const modal = document.getElementById('detailModal');
|
|
const content = document.getElementById('detailContent');
|
|
|
|
modal.classList.add('show');
|
|
content.innerHTML = `<div class="text-center py-5"><div class="spinner-border text-success"></div><p class="mt-2 text-muted">Mengambil data...</p></div>`;
|
|
|
|
fetch(`{{ url('pekerjaan/penugasan') }}/${id}`)
|
|
.then(res => res.json())
|
|
.then(res => {
|
|
if(res.success) {
|
|
const d = res.data;
|
|
let teamHtml = '';
|
|
if(d.tim_teknisi && d.tim_teknisi.length > 0) {
|
|
d.tim_teknisi.forEach(t => {
|
|
teamHtml += `
|
|
<div class="pug-tech-badge" style="background:var(--bg); border:1px solid var(--line);">
|
|
<i class="fas fa-user"></i> ${t.teknisi.nama}
|
|
</div>
|
|
`;
|
|
});
|
|
}
|
|
|
|
content.innerHTML = `
|
|
<div class="row">
|
|
<div class="col-md-7">
|
|
<div class="pug-detail-section">
|
|
<div class="pug-detail-section-title"><i class="fas fa-briefcase"></i> INFORMASI PEKERJAAN</div>
|
|
<div class="pug-detail-grid">
|
|
<div class="pug-form-field">
|
|
<div class="pug-detail-item-label">Jenis Pekerjaan</div>
|
|
<div class="pug-detail-item-val">${d.label_jenis_pekerjaan || '-'}</div>
|
|
</div>
|
|
<div class="pug-form-field">
|
|
<div class="pug-detail-item-label">Status</div>
|
|
<span class="pug-badge ${d.status_pekerjaan == 'selesai' ? 'pug-badge-green' : 'pug-badge-violet'}">
|
|
${d.status_pekerjaan.replace('_', ' ').toUpperCase()}
|
|
</span>
|
|
</div>
|
|
<div class="pug-form-full">
|
|
<div class="pug-detail-item-label">Lokasi / Alamat</div>
|
|
<div class="pug-detail-item-val">${d.alamat_lokasi || '-'}</div>
|
|
</div>
|
|
<div class="pug-form-field">
|
|
<div class="pug-detail-item-label">Pelanggan</div>
|
|
<div class="pug-detail-item-val">${d.nama_pelanggan || '-'}</div>
|
|
</div>
|
|
<div class="pug-form-field">
|
|
<div class="pug-detail-item-label">No. Sambungan</div>
|
|
<div class="pug-detail-item-val">${d.no_sambungan || '-'}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="pug-detail-section">
|
|
<div class="pug-detail-section-title"><i class="fas fa-users"></i> TIM LAPANGAN</div>
|
|
<div class="d-flex flex-wrap gap-2">
|
|
${teamHtml || '<span class="text-muted small">Tidak ada data tim</span>'}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-5">
|
|
<div class="pug-photo-container mb-3">
|
|
<div class="pug-photo-label"><i class="fas fa-camera"></i> FOTO SESUDAH</div>
|
|
${d.foto_sesudah_url ? `<img src="${d.foto_sesudah_url}" class="pug-photo-item" onclick="previewFoto('${d.foto_sesudah_url}')">` : `<div class="pug-photo-empty">Belum ada foto</div>`}
|
|
</div>
|
|
<div class="pug-photo-container">
|
|
<div class="pug-photo-label"><i class="fas fa-file-invoice"></i> FOTO SURAT</div>
|
|
${d.foto_surat_url ? `<img src="${d.foto_surat_url}" class="pug-photo-item" onclick="previewFoto('${d.foto_surat_url}')">` : `<div class="pug-photo-empty">Belum ada foto</div>`}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="pug-detail-section mt-3">
|
|
<div class="pug-detail-section-title"><i class="fas fa-comment-alt"></i> CATATAN PEKERJAAN</div>
|
|
<div class="pug-detail-item-val" style="font-weight:400; font-style:italic;">
|
|
${d.detail_pekerjaan || 'Tidak ada catatan teknisi.'}
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
})
|
|
.catch(err => {
|
|
content.innerHTML = `<div class="alert alert-danger">Gagal mengambil data.</div>`;
|
|
});
|
|
}
|
|
function setStatus(val) {
|
|
document.getElementById('statusFilter').value = val;
|
|
document.querySelector('.pug-toolbar-form').submit();
|
|
}
|
|
</script>
|
|
@endpush
|
|
</x-app-layout> |