MIF_E31230892/sim-pkpps/resources/views/santri/kegiatan/show.blade.php

245 lines
12 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@extends('layouts.app')
@section('title', 'Detail Kegiatan: ' . $kegiatan->nama_kegiatan)
@section('content')
<style>
.kd-header {
background: linear-gradient(135deg, #0d3b2e 0%, #1a7a5e 60%, #2bbd8e 100%);
border-radius: 14px;
padding: 26px 28px;
color: white;
margin-bottom: 20px;
position: relative;
overflow: hidden;
}
.kd-header::before { content:''; position:absolute; top:-50px; right:-50px; width:180px; height:180px; border-radius:50%; background:rgba(255,255,255,0.05); }
.kd-header-top { display:flex; justify-content:space-between; align-items:flex-start; flex-wrap:wrap; gap:12px; margin-bottom:14px; }
.kd-title { font-size:1.3rem; font-weight:800; margin:0 0 6px; }
.kd-tags { display:flex; gap:8px; flex-wrap:wrap; }
.kd-tag { background:rgba(255,255,255,0.15); border:1px solid rgba(255,255,255,0.2); padding:4px 12px; border-radius:20px; font-size:0.79rem; font-weight:600; display:inline-flex; align-items:center; gap:5px; }
.kd-btn-back {
background: rgba(255,255,255,0.18);
border: 1px solid rgba(255,255,255,0.28);
color: white;
padding: 8px 16px;
border-radius: 9px;
font-size: 0.82rem;
font-weight: 600;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 7px;
transition: background 0.2s;
white-space: nowrap;
}
.kd-btn-back:hover { background:rgba(255,255,255,0.28); color:white; }
.kd-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-bottom:20px; }
.kd-stat { background:white; border-radius:12px; padding:15px; box-shadow:0 4px 20px rgba(0,0,0,0.07); text-align:center; border-top:3px solid transparent; }
.kd-stat.green { border-top-color:#2bbd8e; }
.kd-stat.blue { border-top-color:#3b82f6; }
.kd-stat.orange { border-top-color:#f97316; }
.kd-stat.red { border-top-color:#e53e3e; }
.kd-stat-icon { width:34px; height:34px; border-radius:8px; display:flex; align-items:center; justify-content:center; font-size:0.88rem; margin:0 auto 7px; }
.green .kd-stat-icon { background:#d1fae5; color:#059669; }
.blue .kd-stat-icon { background:#dbeafe; color:#2563eb; }
.orange .kd-stat-icon { background:#ffedd5; color:#ea580c; }
.red .kd-stat-icon { background:#fee2e2; color:#dc2626; }
.kd-stat-value { font-size:1.9rem; font-weight:800; color:#1a2332; line-height:1; }
.kd-stat-label { font-size:0.77rem; color:#6b7280; margin-top:4px; font-weight:500; }
.kd-two-col { display:grid; grid-template-columns:1fr 1fr; gap:16px; margin-bottom:20px; }
.kd-chart-box { background:white; border-radius:12px; padding:18px; box-shadow:0 4px 20px rgba(0,0,0,0.07); }
.kd-chart-title { font-size:0.86rem; font-weight:700; color:#1a2332; margin-bottom:14px; display:flex; align-items:center; gap:6px; }
.kd-pct-card { background:linear-gradient(135deg,#e8f7f2,#d4f1e3); padding:14px; border-radius:10px; text-align:center; margin-top:12px; }
.kd-pct-label { font-size:0.79rem; color:#6b7280; margin-bottom:2px; }
.kd-pct-val { font-size:2.1rem; font-weight:800; line-height:1; }
.kd-pct-sub { font-size:0.76rem; color:#6b7280; }
.kd-table-box { background:white; border-radius:12px; box-shadow:0 4px 20px rgba(0,0,0,0.07); overflow:hidden; }
.kd-table-head { padding:13px 16px; border-bottom:1px solid #e2e8f0; font-size:0.86rem; font-weight:700; color:#1a2332; display:flex; align-items:center; gap:6px; }
.kd-table { width:100%; border-collapse:collapse; }
.kd-table thead tr { background:#f8fafb; }
.kd-table th { padding:10px 13px; text-align:left; font-size:0.77rem; font-weight:700; color:#6b7280; text-transform:uppercase; letter-spacing:0.4px; border-bottom:1px solid #e2e8f0; }
.kd-table td { padding:10px 13px; font-size:0.84rem; border-bottom:1px solid #f8fafc; color:#1a2332; }
.kd-table tbody tr:last-child td { border-bottom:none; }
.kd-table tbody tr:hover { background:#f8fafc; }
.kd-pill { padding:3px 11px; border-radius:20px; font-size:0.77rem; font-weight:700; }
.kd-pill.hadir { background:#d1fae5; color:#065f46; }
.kd-pill.izin { background:#dbeafe; color:#1e40af; }
.kd-pill.sakit { background:#ede9fe; color:#5b21b6; }
.kd-pill.alpa { background:#fee2e2; color:#991b1b; }
@media (max-width: 680px) {
.kd-stats { grid-template-columns:repeat(2,1fr); }
.kd-two-col { grid-template-columns:1fr; }
}
</style>
{{-- HEADER --}}
<div class="kd-header">
<div class="kd-header-top">
<div>
<h2 class="kd-title"><i class="fas fa-clipboard-check"></i> {{ $kegiatan->nama_kegiatan }}</h2>
<div class="kd-tags">
<span class="kd-tag"><i class="fas fa-tag"></i> {{ $kegiatan->kategori->nama_kategori }}</span>
<span class="kd-tag"><i class="fas fa-calendar-day"></i> {{ $kegiatan->hari }}</span>
<span class="kd-tag"><i class="fas fa-clock"></i> {{ date('H:i', strtotime($kegiatan->waktu_mulai)) }}{{ date('H:i', strtotime($kegiatan->waktu_selesai)) }}</span>
</div>
</div>
{{-- FIX: Tombol kembali pakai $fromTab agar kembali ke tab yang benar --}}
<a href="{{ route('santri.kegiatan.index') }}?tab={{ $fromTab ?? 'riwayat' }}" class="kd-btn-back">
<i class="fas fa-arrow-left"></i> Kembali
</a>
</div>
@if($kegiatan->materi)
<div style="background:rgba(255,255,255,0.12);padding:9px 13px;border-radius:8px;font-size:0.83rem;border:1px solid rgba(255,255,255,0.15);">
<i class="fas fa-book"></i> <strong>Materi:</strong> {{ $kegiatan->materi }}
</div>
@endif
</div>
{{-- STATS --}}
<div class="kd-stats">
<div class="kd-stat green">
<div class="kd-stat-icon"><i class="fas fa-check-circle"></i></div>
<div class="kd-stat-value">{{ $stats['Hadir'] ?? 0 }}</div>
<div class="kd-stat-label">Hadir</div>
</div>
<div class="kd-stat blue">
<div class="kd-stat-icon"><i class="fas fa-info-circle"></i></div>
<div class="kd-stat-value">{{ $stats['Izin'] ?? 0 }}</div>
<div class="kd-stat-label">Izin</div>
</div>
<div class="kd-stat orange">
<div class="kd-stat-icon"><i class="fas fa-heartbeat"></i></div>
<div class="kd-stat-value">{{ $stats['Sakit'] ?? 0 }}</div>
<div class="kd-stat-label">Sakit</div>
</div>
<div class="kd-stat red">
<div class="kd-stat-icon"><i class="fas fa-times-circle"></i></div>
<div class="kd-stat-value">{{ $stats['Alpa'] ?? 0 }}</div>
<div class="kd-stat-label">Alpa</div>
</div>
</div>
{{-- CHART + PERSENTASE --}}
<div class="kd-two-col">
<div class="kd-chart-box">
<div class="kd-chart-title"><i class="fas fa-chart-line" style="color:#2bbd8e;"></i> Tren Kehadiran (6 Bulan)</div>
<canvas id="chartTren" style="max-height:220px;"></canvas>
</div>
<div class="kd-chart-box">
<div class="kd-chart-title"><i class="fas fa-chart-pie" style="color:#f5a623;"></i> Distribusi Kehadiran</div>
<canvas id="chartDonut" style="max-height:170px;"></canvas>
<div class="kd-pct-card">
<div class="kd-pct-label">Persentase Kehadiran</div>
<div class="kd-pct-val" style="color:{{ $persentaseHadir >= 85 ? '#059669' : ($persentaseHadir >= 70 ? '#d97706' : '#dc2626') }};">
{{ $persentaseHadir }}%
</div>
<div class="kd-pct-sub">dari {{ $totalAbsensi }} total absensi</div>
</div>
</div>
</div>
{{-- RIWAYAT TABLE --}}
<div class="kd-table-box">
<div class="kd-table-head">
<i class="fas fa-history" style="color:#2bbd8e;"></i> Riwayat Lengkap
<span style="margin-left:auto;background:#e8f7f2;color:#1a7a5e;padding:2px 8px;border-radius:8px;font-size:0.74rem;">{{ $riwayats->total() }} data</span>
</div>
@if($riwayats->count() > 0)
<table class="kd-table">
<thead>
<tr>
<th>No</th>
<th>Tanggal</th>
<th>Hari</th>
<th>Waktu Absen</th>
<th>Status</th>
<th>Metode</th>
</tr>
</thead>
<tbody>
@foreach($riwayats as $idx => $absensi)
<tr>
<td style="color:#9ca3af;font-size:0.77rem;">{{ $riwayats->firstItem() + $idx }}</td>
<td style="font-weight:600;">{{ \Carbon\Carbon::parse($absensi->tanggal)->format('d M Y') }}</td>
<td style="color:#6b7280;font-size:0.82rem;">{{ \Carbon\Carbon::parse($absensi->tanggal)->locale('id')->dayName }}</td>
<td style="color:#6b7280;font-size:0.82rem;">
{{ $absensi->waktu_absen ? \Carbon\Carbon::parse($absensi->waktu_absen)->format('H:i') : '-' }}
</td>
<td>
<span class="kd-pill {{ strtolower($absensi->status) }}">{{ $absensi->status }}</span>
</td>
<td style="font-size:0.79rem;color:#6b7280;">
<i class="fas fa-{{ ($absensi->metode_absen ?? '') === 'RFID' ? 'id-card' : 'hand-pointer' }}"></i>
{{ $absensi->metode_absen ?? '-' }}
</td>
</tr>
@endforeach
</tbody>
</table>
<div style="padding:12px 16px;border-top:1px solid #f0f0f0;">{{ $riwayats->links() }}</div>
@else
<div style="text-align:center;padding:32px;color:#6b7280;font-size:0.85rem;">
<i class="fas fa-inbox" style="font-size:2.5rem;opacity:0.2;display:block;margin-bottom:10px;"></i>
Belum ada riwayat absensi untuk kegiatan ini.
</div>
@endif
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
new Chart(document.getElementById('chartTren'), {
type: 'line',
data: {
labels: @json(collect($trendBulanan)->pluck('bulan')),
datasets: [{
label: 'Hadir',
data: @json(collect($trendBulanan)->pluck('hadir')),
borderColor: '#2bbd8e', backgroundColor: 'rgba(43,189,142,0.12)',
borderWidth: 3, pointRadius: 5, pointBackgroundColor: '#2bbd8e',
tension: 0.4, fill: true
}]
},
options: {
responsive: true, maintainAspectRatio: true,
plugins: { legend: { display: false } },
scales: {
y: { beginAtZero: true, ticks: { stepSize: 1 }, grid: { color: 'rgba(0,0,0,0.04)' } },
x: { grid: { display: false } }
}
}
});
new Chart(document.getElementById('chartDonut'), {
type: 'doughnut',
data: {
labels: ['Hadir','Izin','Sakit','Alpa'],
datasets: [{
data: [{{ $stats['Hadir'] ?? 0 }}, {{ $stats['Izin'] ?? 0 }}, {{ $stats['Sakit'] ?? 0 }}, {{ $stats['Alpa'] ?? 0 }}],
backgroundColor: ['#2bbd8e','#3b82f6','#f59e0b','#e53e3e'],
borderWidth: 3, borderColor: '#fff'
}]
},
options: {
responsive: true, maintainAspectRatio: true, cutout: '60%',
plugins: {
legend: { position: 'bottom', labels: { padding: 12, font: { size: 11 } } },
tooltip: { callbacks: { label: function(ctx) {
var total = {{ $totalAbsensi }};
var pct = total > 0 ? ((ctx.parsed / total) * 100).toFixed(1) : 0;
return ctx.label + ': ' + ctx.parsed + ' (' + pct + '%)';
}}}
}
}
});
});
</script>
@endsection