MIF_E31231594/resources/views/pembina/dashboard.blade.php

554 lines
24 KiB
PHP

@extends('layouts.pembina')
@section('title', 'Dashboard')
@section('content')
@php
$total =
($stats['kegiatan_pending'] ?? 0) +
($stats['kegiatan_disetujui_pembina'] ?? 0) +
($stats['kegiatan_disetujui_admin'] ?? 0) +
($stats['kegiatan_ditolak'] ?? 0);
@endphp
<div class="row g-2 g-md-3 mb-3 mb-md-4">
<div class="col-6 col-md-4 col-lg-2">
<a href="{{ route('pembina.organisasi') }}" class="text-decoration-none">
<div class="card stat-card border-0 shadow-sm h-100 stat-card-link">
<div class="card-body p-2 p-md-3">
<div class="d-flex align-items-start gap-2 mb-1">
<div class="stat-icon bg-primary-light">
<i class="fas fa-building text-primary"></i>
</div>
<div class="flex-grow-1 min-w-0">
<p class="text-muted small mb-0 text-truncate fw-bold">Total Organisasi</p>
<h3 class="mb-0">{{ $stats['total_organisasi'] ?? 0 }}</h3>
</div>
</div>
<small class="text-muted d-block text-center">Semua Organisasi</small>
</div>
</div>
</a>
</div>
<div class="col-6 col-md-4 col-lg-2">
<a href="{{ route('pembina.kegiatan') }}" class="text-decoration-none">
<div class="card stat-card border-0 shadow-sm h-100 stat-card-link">
<div class="card-body p-2 p-md-3">
<div class="d-flex align-items-start gap-2 mb-1">
<div class="stat-icon bg-success-light">
<i class="fas fa-calendar-alt text-success"></i>
</div>
<div class="flex-grow-1 min-w-0">
<p class="text-muted small mb-0 text-truncate fw-bold">Total Kegiatan</p>
<h3 class="mb-0">{{ $stats['total_kegiatan'] ?? 0 }}</h3>
</div>
</div>
<small class="text-muted d-block text-center">Semua Kegiatan</small>
</div>
</div>
</a>
</div>
<div class="col-6 col-md-4 col-lg-2">
<a href="{{ route('pembina.validasi') }}" class="text-decoration-none">
<div class="card stat-card border-0 shadow-sm h-100 stat-card-link">
<div class="card-body p-2 p-md-3">
<div class="d-flex align-items-start gap-2 mb-1">
<div class="stat-icon bg-warning-light">
<i class="fas fa-hourglass-half text-warning"></i>
</div>
<div class="flex-grow-1 min-w-0">
<p class="text-muted small mb-0 text-truncate fw-bold">Pending</p>
<h3 class="mb-0">{{ $stats['kegiatan_pending'] ?? 0 }}</h3>
</div>
</div>
<small class="text-warning d-block text-center">Perlu Validasi</small>
</div>
</div>
</a>
</div>
<div class="col-6 col-md-4 col-lg-2">
<a href="{{ route('pembina.kegiatan') }}?status=disetujui" class="text-decoration-none">
<div class="card stat-card border-0 shadow-sm h-100 stat-card-link">
<div class="card-body p-2 p-md-3">
<div class="d-flex align-items-start gap-2 mb-1">
<div class="stat-icon bg-success-light">
<i class="fas fa-check-circle text-success"></i>
</div>
<div class="flex-grow-1 min-w-0">
<p class="text-muted small mb-0 text-truncate fw-bold">Disetujui</p>
<h3 class="mb-0">{{ $stats['kegiatan_disetujui_pembina'] ?? 0 }}</h3>
</div>
</div>
<small class="text-muted d-block text-center">Telah Disetujui</small>
</div>
</div>
</a>
</div>
<div class="col-6 col-md-4 col-lg-2">
<a href="{{ route('pembina.kegiatan') }}?status=ditolak" class="text-decoration-none">
<div class="card stat-card border-0 shadow-sm h-100 stat-card-link">
<div class="card-body p-2 p-md-3">
<div class="d-flex align-items-start gap-2 mb-1">
<div class="stat-icon bg-danger-light">
<i class="fas fa-times-circle text-danger"></i>
</div>
<div class="flex-grow-1 min-w-0">
<p class="text-muted small mb-0 text-truncate fw-bold">Ditolak</p>
<h3 class="mb-0">{{ $stats['kegiatan_ditolak'] ?? 0 }}</h3>
</div>
</div>
<small class="text-danger d-block text-center">Ditolak</small>
</div>
</div>
</a>
</div>
<div class="col-6 col-md-4 col-lg-2">
<a href="{{ route('pembina.dokumentasi') }}" class="text-decoration-none">
<div class="card stat-card border-0 shadow-sm h-100 stat-card-link">
<div class="card-body p-2 p-md-3">
<div class="d-flex align-items-start gap-2 mb-1">
<div class="stat-icon bg-purple-light">
<i class="fas fa-file-alt text-purple"></i>
</div>
<div class="flex-grow-1 min-w-0">
<p class="text-muted small mb-0 text-truncate fw-bold">Dokumentasi</p>
<h3 class="mb-0">{{ $stats['total_dokumentasi'] ?? 0 }}</h3>
</div>
</div>
<small class="text-muted d-block text-center">Semua Dokumentasi</small>
</div>
</div>
</a>
</div>
</div>
<div class="row g-2 g-md-3 mb-3 mb-md-4">
<div class="col-12 col-lg-5">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-0 p-3 d-flex justify-content-between align-items-center">
<h6 class="mb-0">Ringkasan Kegiatan</h6>
<select class="form-select form-select-sm w-auto">
<option>Semua Waktu</option>
</select>
</div>
<div class="card-body">
<div class="d-flex flex-column flex-sm-row align-items-center gap-3 gap-sm-4">
<div class="doughnut-container">
<canvas id="statusChart"></canvas>
</div>
<div class="w-100">
<div class="d-flex align-items-center gap-2 mb-2">
<span class="legend-dot" style="background:#ffc107;"></span>
<div>
<div class="fw-semibold small">Pending</div>
<small class="text-muted">
{{ $stats['kegiatan_pending'] ?? 0 }} Kegiatan
({{ $total > 0 ? number_format((($stats['kegiatan_pending'] ?? 0) / $total) * 100, 1) : 0 }}%)
</small>
</div>
</div>
<div class="d-flex align-items-center gap-2 mb-2">
<span class="legend-dot" style="background:#198754;"></span>
<div>
<div class="fw-semibold small">Disetujui</div>
<small class="text-muted">
{{ ($stats['kegiatan_disetujui_pembina'] ?? 0) + ($stats['kegiatan_disetujui_admin'] ?? 0) }}
Kegiatan
({{ $total > 0 ? number_format(((($stats['kegiatan_disetujui_pembina'] ?? 0) + ($stats['kegiatan_disetujui_admin'] ?? 0)) / $total) * 100, 1) : 0 }}%)
</small>
</div>
</div>
<div class="d-flex align-items-center gap-2 mb-3">
<span class="legend-dot" style="background:#dc3545;"></span>
<div>
<div class="fw-semibold small">Ditolak</div>
<small class="text-muted">
{{ $stats['kegiatan_ditolak'] ?? 0 }} Kegiatan
({{ $total > 0 ? number_format((($stats['kegiatan_ditolak'] ?? 0) / $total) * 100, 1) : 0 }}%)
</small>
</div>
</div>
<small class="text-muted">Total: <strong>{{ $total }}</strong> kegiatan</small>
</div>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-7">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-0 p-3 d-flex justify-content-between align-items-center">
<h6 class="mb-0">
Kegiatan Pending
<span class="text-warning d-none d-sm-inline">(Perlu Validasi)</span>
</h6>
<a href="{{ route('pembina.validasi') }}" class="text-primary small">Lihat Semua Validasi</a>
</div>
<div class="card-body p-0">
@php
$pendingIcons = ['fa-users', 'fa-paint-brush', 'fa-hands-helping', 'fa-microphone', 'fa-tint'];
$pendingColors = ['primary', 'purple', 'danger', 'success', 'danger'];
@endphp
@forelse ($kegiatanPending ?? [] as $item)
@php $pi = $loop->index % 5; @endphp
<div class="d-flex align-items-center gap-2 px-3 py-2 border-bottom">
<!-- Icon -->
<div class="stat-icon bg-{{ $pendingColors[$pi] }}-light flex-shrink-0"
style="width:36px;height:36px;font-size:15px;">
<i class="fas {{ $pendingIcons[$pi] }} text-{{ $pendingColors[$pi] }}"></i>
</div>
<!-- Info -->
<div class="flex-grow-1 min-w-0">
<div class="fw-semibold small text-truncate">
{{ $item->nama_kegiatan }}
</div>
<div class="text-muted" style="font-size:11px;">
{{ $item->organisasi?->nama_organisasi ?? '-' }}
</div>
</div>
<!-- Tanggal & Status (2 Kolom Horizontal) -->
<div class="d-flex align-items-center flex-shrink-0 me-2" style="gap:12px; min-width:200px;">
<!-- Kolom Tanggal -->
<div class="text-muted text-end" style="font-size:11px; min-width:110px;">
<i class="fas fa-calendar-alt me-1"></i>
{{ $item->tanggal_mulai ? $item->tanggal_mulai->translatedFormat('d M Y') : '-' }}
</div>
<!-- Kolom Status -->
<div class="text-end" style="min-width:80px;">
<span class="badge bg-warning text-dark">Pending</span>
</div>
</div>
<!-- Button -->
<a href="{{ route('pembina.validasi') }}" class="btn btn-primary btn-sm flex-shrink-0">
Validasi
</a>
</div>
@empty
<div class="text-center text-muted py-4">
Tidak ada kegiatan pending.
</div>
@endforelse
<div class="text-center py-2 border-top">
<a href="{{ route('pembina.validasi') }}" class="text-primary small fw-semibold">
Lihat Semua Pengajuan <i class="fas fa-arrow-right ms-1"></i>
</a>
</div>
</div>
</div>
</div>
</div>
<!-- ===== ROW 3: Kegiatan Terbaru + Jadwal Mendatang ===== -->
<div class="row g-2 g-md-3">
<!-- Kegiatan Terbaru -->
<div class="col-12 col-lg-6">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-0 p-3 d-flex justify-content-between align-items-center">
<h6 class="mb-0">Kegiatan Terbaru</h6>
<a href="{{ route('pembina.kegiatan') }}" class="text-primary small">Lihat Semua Kegiatan</a>
</div>
<div class="card-body p-0">
@php
$recentIcons = ['fa-laptop', 'fa-camera', 'fa-pen', 'fa-chalkboard-teacher', 'fa-palette'];
$recentColors = ['primary', 'purple', 'success', 'warning', 'danger'];
@endphp
@forelse ($kegiatanTerbaru as $item)
@php
$ri = $loop->index % 5;
$badgeClass = match ($item->status) {
'disetujui admin', 'disetujui pembina' => 'bg-success',
'ditolak admin', 'ditolak pembina' => 'bg-danger',
default => 'bg-warning text-dark',
};
$statusLabel = match ($item->status) {
'disetujui admin', 'disetujui pembina' => 'Disetujui',
'ditolak admin', 'ditolak pembina' => 'Ditolak',
default => 'Pending',
};
@endphp
<div class="d-flex align-items-center gap-2 px-3 py-2 border-bottom">
<!-- Icon -->
<div class="stat-icon bg-{{ $recentColors[$ri] }}-light flex-shrink-0"
style="width:34px;height:34px;font-size:14px;">
<i class="fas {{ $recentIcons[$ri] }} text-{{ $recentColors[$ri] }}"></i>
</div>
<!-- Info -->
<div class="flex-grow-1 min-w-0">
<div class="fw-semibold small text-truncate">
{{ $item->nama_kegiatan }}
</div>
<div class="text-muted" style="font-size:11px;">
{{ $item->organisasi?->nama_organisasi ?? '-' }}
</div>
</div>
<!-- Status & Tanggal (2 Kolom Horizontal) -->
<div class="d-flex align-items-center flex-shrink-0" style="gap:12px; min-width:200px;">
<!-- Kolom Status -->
<div class="text-end" style="min-width:90px;">
<span class="badge {{ $badgeClass }}">{{ $statusLabel }}</span>
</div>
<!-- Kolom Tanggal -->
<div class="text-muted text-end" style="font-size:11px; min-width:110px;">
<i class="fas fa-calendar-alt me-1"></i>
{{ $item->tanggal_mulai ? $item->tanggal_mulai->translatedFormat('d M Y') : '-' }}
</div>
</div>
</div>
@empty
<div class="text-center text-muted py-4">
Belum ada data kegiatan.
</div>
@endforelse
<div class="text-center py-2 border-top">
<a href="{{ route('pembina.kegiatan') }}" class="text-primary small fw-semibold">
Lihat Semua Kegiatan <i class="fas fa-arrow-right ms-1"></i>
</a>
</div>
</div>
</div>
</div>
<!-- Jadwal Kegiatan Mendatang -->
<div class="col-12 col-lg-6">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-white border-0 p-3 d-flex justify-content-between align-items-center">
<h6 class="mb-0">Jadwal Kegiatan Mendatang</h6>
<a href="{{ route('pembina.jadwal') }}" class="text-primary small">Lihat Semua Jadwal</a>
</div>
<div class="card-body p-0">
@forelse ($jadwalMendatang ?? [] as $item)
<div class="d-flex gap-2 gap-md-3 px-3 py-2 border-bottom align-items-start">
<!-- Tanggal (Kiri) -->
<div class="text-center flex-shrink-0" style="min-width:36px;">
<div class="fw-bold" style="font-size:20px;line-height:1;color:#222;">
{{ $item->tanggal_mulai ? $item->tanggal_mulai->format('d') : '-' }}
</div>
<div class="text-uppercase text-muted" style="font-size:10px;">
{{ $item->tanggal_mulai ? $item->tanggal_mulai->translatedFormat('M') : '' }}
</div>
</div>
<!-- Content -->
<div class="flex-grow-1 min-w-0 d-flex justify-content-between align-items-start">
<!-- Kiri: Nama & Lokasi -->
<div class="min-w-0">
<div class="fw-semibold small text-truncate">
{{ $item->nama_kegiatan }}
</div>
<div class="text-muted" style="font-size:11px;">
{{ $item->lokasi ?? '-' }}
</div>
</div>
<!-- Kanan: Jam -->
<div class="text-end flex-shrink-0" style="font-size:11px; min-width:70px;">
<i class="fas fa-clock me-1"></i>
{{ $item->tanggal_mulai ? $item->tanggal_mulai->format('H.i') : '-' }} WIB
</div>
</div>
</div>
@empty
<div class="text-center text-muted py-4">
Tidak ada jadwal mendatang.
</div>
@endforelse
<div class="text-center py-2 border-top">
<a href="{{ route('pembina.jadwal') }}" class="text-primary small fw-semibold">
Lihat Semua Jadwal <i class="fas fa-arrow-right ms-1"></i>
</a>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')
<script>
const statusCtx = document.getElementById('statusChart').getContext('2d');
new Chart(statusCtx, {
type: 'doughnut',
data: {
labels: ['Pending', 'Disetujui', 'Ditolak'],
datasets: [{
data: [
{{ $stats['kegiatan_pending'] ?? 0 }},
{{ ($stats['kegiatan_disetujui_pembina'] ?? 0) + ($stats['kegiatan_disetujui_admin'] ?? 0) }},
{{ $stats['kegiatan_ditolak'] ?? 0 }}
],
backgroundColor: ['#ffc107', '#198754', '#dc3545'],
borderColor: '#fff',
borderWidth: 3,
hoverOffset: 6
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
cutout: '65%',
plugins: {
legend: {
display: false
},
tooltip: {
callbacks: {
label: (ctx) => ` ${ctx.label}: ${ctx.raw} kegiatan`
}
}
}
}
});
</script>
@endsection
<style>
.stat-card {
border-radius: 10px;
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.stat-card-link {
cursor: pointer;
text-decoration: none;
display: block;
color: inherit;
}
.stat-card-link:hover .stat-card,
.stat-card-link:hover {
color: inherit;
text-decoration: none;
}
.stat-card:hover {
transform: translateY(-3px);
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.1) !important;
}
.stat-icon {
width: 40px;
height: 40px;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
flex-shrink: 0;
}
.legend-dot {
width: 11px;
height: 11px;
border-radius: 50%;
display: inline-block;
flex-shrink: 0;
}
.doughnut-container {
position: relative;
width: 160px;
height: 160px;
flex-shrink: 0;
}
/* Mobile tweaks */
@media (max-width: 575.98px) {
.doughnut-container {
width: 130px;
height: 130px;
}
.stat-icon {
width: 34px;
height: 34px;
font-size: 15px;
}
h3 {
font-size: 1.3rem;
}
}
.bg-primary-light {
background-color: rgba(13, 110, 253, 0.1);
}
.bg-success-light {
background-color: rgba(25, 135, 84, 0.1);
}
.bg-warning-light {
background-color: rgba(255, 193, 7, 0.1);
}
.bg-danger-light {
background-color: rgba(220, 53, 69, 0.1);
}
.bg-purple-light {
background-color: rgba(124, 58, 237, 0.12);
}
.text-purple {
color: #7c3aed !important;
}
h3 {
font-weight: 700;
color: #222;
}
.card {
border-radius: 10px;
}
.card-header {
border-bottom: 1px solid #f0f0f0 !important;
}
.min-w-0 {
min-width: 0;
}
</style>