Files
ProjectKP/KP-ASOY FIX (2)/KP-ASOY/resources/views/admin/dashboard.blade.php
T
2026-06-28 15:14:51 +07:00

913 lines
34 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('admin.layouts.app')
@section('content')
<style>
/* ══════════════════════════════════════════════
DISNAKER KALBAR ADMIN DASHBOARD
Professional Government Dashboard UI
══════════════════════════════════════════════ */
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap');
*, *::before, *::after { box-sizing: border-box; }
.d-wrap {
padding: 2rem 2.5rem 3rem;
max-width: 1440px;
margin: 0 auto;
font-family: 'Plus Jakarta Sans', sans-serif;
}
/* ── Page Header ─────────────────────────────── */
.page-header {
display: flex;
justify-content: space-between;
align-items: flex-end;
margin-bottom: 1.75rem;
}
.page-header-left h2 {
font-size: 22px;
font-weight: 700;
color: #0D215C;
letter-spacing: -0.3px;
line-height: 1;
}
.page-header-left .subtitle {
font-size: 12.5px;
color: #94a3b8;
font-weight: 500;
margin-top: 5px;
display: flex;
align-items: center;
gap: 6px;
}
.status-dot {
width: 7px; height: 7px;
border-radius: 50%;
background: #22c55e;
display: inline-block;
box-shadow: 0 0 0 3px rgba(34,197,94,0.2);
animation: pulse-dot 2s infinite;
}
@keyframes pulse-dot {
0%,100% { box-shadow: 0 0 0 3px rgba(34,197,94,0.2); }
50% { box-shadow: 0 0 0 6px rgba(34,197,94,0.08); }
}
.page-header-right {
display: flex;
align-items: center;
gap: 10px;
}
.hdr-chip {
font-size: 11px;
font-weight: 600;
padding: 7px 18px;
border-radius: 50px;
letter-spacing: 0.4px;
display: flex;
align-items: center;
gap: 6px;
}
.hdr-chip.navy { background: #0D215C; color: #fff; box-shadow: 0 4px 14px rgba(13,33,92,0.22); }
.hdr-chip.light { background: #fff; color: #64748b; border: 1px solid #e2e8f0; }
.hdr-chip svg { flex-shrink: 0; }
/* ── Stat Cards ──────────────────────────────── */
.stats-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 18px;
margin-bottom: 1.75rem;
}
.s-card {
background: #fff;
border-radius: 20px;
padding: 1.5rem 1.6rem 1.4rem;
border: 1px solid #edf1f7;
position: relative;
overflow: hidden;
cursor: default;
transition: transform 0.22s cubic-bezier(.4,0,.2,1),
box-shadow 0.22s cubic-bezier(.4,0,.2,1);
}
.s-card:hover {
transform: translateY(-5px);
box-shadow: 0 16px 40px rgba(13,33,92,0.12);
}
.s-card::after {
content: '';
position: absolute;
bottom: 0; left: 0; right: 0;
height: 4px;
border-radius: 0 0 20px 20px;
opacity: 0.9;
}
.s-card.c-blue::after { background: linear-gradient(90deg,#3b82f6,#6366f1); }
.s-card.c-green::after { background: linear-gradient(90deg,#22c55e,#10b981); }
.s-card.c-yellow::after { background: linear-gradient(90deg,#f59e0b,#f97316); }
.s-card.c-red::after { background: linear-gradient(90deg,#64748b,#475569); }
.s-card::before {
content: '';
position: absolute;
top: -20px; right: -20px;
width: 100px; height: 100px;
border-radius: 50%;
opacity: 0.04;
}
.s-card.c-blue::before { background: #3b82f6; }
.s-card.c-green::before { background: #22c55e; }
.s-card.c-yellow::before { background: #f59e0b; }
.s-card.c-red::before { background: #64748b; }
.s-icon {
width: 44px; height: 44px;
border-radius: 12px;
display: flex; align-items: center; justify-content: center;
margin-bottom: 16px;
}
.s-icon.c-blue { background: #eff6ff; color: #3b82f6; }
.s-icon.c-green { background: #f0fdf4; color: #16a34a; }
.s-icon.c-yellow { background: #fffbeb; color: #d97706; }
.s-icon.c-red { background: #f8fafc; color: #475569; }
.s-icon svg { width: 20px; height: 20px; }
.s-num {
font-size: 36px;
font-weight: 700;
color: #0f172a;
letter-spacing: -2px;
line-height: 1;
}
.s-label {
font-size: 12px;
font-weight: 500;
color: #94a3b8;
margin-top: 5px;
letter-spacing: 0.3px;
}
.s-trend {
font-size: 11.5px;
font-weight: 500;
margin-top: 12px;
display: flex;
align-items: center;
gap: 4px;
color: #94a3b8;
}
.s-trend.up { color: #16a34a; }
.s-trend.down { color: #94a3b8; }
.s-trend.flat { color: #94a3b8; }
.s-trend svg { width: 13px; height: 13px; }
/* ── Main Content Grid ───────────────────────── */
.content-grid {
display: grid;
grid-template-columns: 1fr 360px;
gap: 20px;
align-items: start;
}
/* ── Generic Card ────────────────────────────── */
.g-card {
background: #fff;
border-radius: 20px;
padding: 1.5rem 1.6rem;
border: 1px solid #edf1f7;
box-shadow: 0 2px 12px rgba(13,33,92,0.04);
}
.g-card-title {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1.2rem;
}
.g-card-title h3 {
font-size: 14px;
font-weight: 700;
color: #0D215C;
letter-spacing: -0.1px;
}
.g-card-title a {
font-size: 12px;
font-weight: 500;
color: #3b82f6;
text-decoration: none;
display: flex;
align-items: center;
gap: 4px;
transition: gap 0.18s;
}
.g-card-title a:hover { gap: 8px; }
/* ── Divider ─────────────────────────────────── */
.act-divider {
height: 1px;
background: #f1f5f9;
margin: 0 0 12px 0;
}
/* ── Filter Tabs ─────────────────────────────── */
.ftabs {
display: flex;
gap: 6px;
margin-bottom: 1rem;
flex-wrap: wrap;
}
.ftab {
padding: 5px 15px;
border-radius: 50px;
font-size: 11px;
font-weight: 600;
cursor: pointer;
border: 1.5px solid transparent;
transition: all 0.15s;
user-select: none;
letter-spacing: 0.3px;
}
.ftab.on { background: #0D215C; color: #fff; border-color: #0D215C; }
.ftab.off { background: #f8fafc; color: #94a3b8; border-color: #e2e8f0; }
.ftab.off:hover { background: #eff6ff; color: #3b82f6; border-color: #bfdbfe; }
/* ── Activity Rows ───────────────────────────── */
.act-item {
display: flex;
align-items: center;
gap: 13px;
padding: 10px 10px;
border-radius: 12px;
cursor: pointer;
transition: background 0.15s, box-shadow 0.15s, transform 0.15s;
}
.act-item:hover {
background: #f8fafc;
box-shadow: 0 4px 16px rgba(13,33,92,0.06);
transform: translateX(2px);
}
.act-item:active { transform: scale(0.99); }
.act-ava {
width: 38px; height: 38px;
border-radius: 10px;
display: flex; align-items: center; justify-content: center;
font-size: 12px;
font-weight: 700;
color: #fff;
flex-shrink: 0;
}
.av-1 { background: linear-gradient(135deg,#3b82f6,#6366f1); }
.av-2 { background: linear-gradient(135deg,#14b8a6,#06b6d4); }
.av-3 { background: linear-gradient(135deg,#a855f7,#ec4899); }
.av-4 { background: linear-gradient(135deg,#f97316,#f59e0b); }
.av-5 { background: linear-gradient(135deg,#22c55e,#10b981); }
.act-body { flex: 1; min-width: 0; }
.act-name {
font-size: 13px;
font-weight: 600;
color: #1e293b;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.act-meta {
font-size: 11px;
color: #94a3b8;
font-weight: 400;
margin-top: 2px;
}
.pill {
font-size: 10px;
font-weight: 600;
padding: 4px 12px;
border-radius: 50px;
letter-spacing: 0.3px;
white-space: nowrap;
flex-shrink: 0;
}
.pill-ok { background: #dcfce7; color: #15803d; }
.pill-run { background: #dbeafe; color: #1d4ed8; }
.pill-del { background: #fee2e2; color: #b91c1c; }
.pill-pnd { background: #fef9c3; color: #92400e; }
.empty-box {
padding: 3.5rem 1rem;
text-align: center;
color: #cbd5e1;
}
.empty-box .ei {
width: 48px; height: 48px;
margin: 0 auto 12px;
display: flex; align-items: center; justify-content: center;
background: #f1f5f9;
border-radius: 14px;
color: #94a3b8;
}
.empty-box .ei svg { width: 22px; height: 22px; }
.empty-box p { font-size: 13px; font-weight: 500; color: #94a3b8; }
/* ── Modal ────────────────────────────────────── */
.modal-overlay {
display: none;
position: fixed;
inset: 0;
background: rgba(13,33,92,0.28);
backdrop-filter: blur(4px);
z-index: 999;
align-items: center;
justify-content: center;
animation: fadeIn 0.2s ease;
}
.modal-overlay.show { display: flex; }
@keyframes fadeIn { from { opacity:0; } to { opacity:1; } }
.modal-box {
background: #fff;
border-radius: 22px;
padding: 2rem;
width: 460px;
max-width: 95vw;
box-shadow: 0 30px 80px rgba(13,33,92,0.18);
animation: slideUp 0.25s cubic-bezier(.4,0,.2,1);
}
@keyframes slideUp {
from { opacity:0; transform:translateY(20px); }
to { opacity:1; transform:translateY(0); }
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 1.2rem;
}
.modal-header h4 {
font-size: 15px;
font-weight: 700;
color: #0D215C;
line-height: 1.4;
max-width: 85%;
}
.modal-close {
width: 30px; height: 30px;
border-radius: 50%;
background: #f1f5f9;
border: none;
cursor: pointer;
display: flex; align-items: center; justify-content: center;
color: #64748b;
transition: all 0.15s;
}
.modal-close:hover { background: #fee2e2; color: #ef4444; }
.modal-close svg { width: 14px; height: 14px; }
.modal-field {
display: flex;
gap: 10px;
padding: 10px 0;
border-bottom: 1px solid #f1f5f9;
font-size: 13px;
}
.modal-field:last-child { border-bottom: none; }
.modal-field .mf-label {
width: 120px;
flex-shrink: 0;
color: #94a3b8;
font-weight: 500;
font-size: 11.5px;
letter-spacing: 0.3px;
padding-top: 1px;
}
.modal-field .mf-value {
color: #1e293b;
font-weight: 500;
font-size: 13px;
}
/* ── Sidebar ─────────────────────────────────── */
.sidebar-col { display: flex; flex-direction: column; gap: 18px; }
/* Bar Chart */
.chart-bars {
display: flex;
align-items: flex-end;
gap: 8px;
height: 88px;
margin: 4px 0 8px;
}
.bar-wrap {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
height: 100%;
gap: 6px;
cursor: pointer;
}
.bar-body {
width: 100%;
border-radius: 6px 6px 0 0;
background: #e0e7ff;
margin-top: auto;
transition: all 0.3s cubic-bezier(.4,0,.2,1);
position: relative;
}
.bar-wrap:hover .bar-body {
filter: brightness(0.9);
transform: scaleY(1.04);
transform-origin: bottom;
}
.bar-body::after {
content: attr(data-val);
position: absolute;
top: -28px;
left: 50%;
transform: translateX(-50%);
background: #0D215C;
color: #fff;
font-size: 10px;
font-weight: 600;
padding: 3px 8px;
border-radius: 6px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.15s;
}
.bar-wrap:hover .bar-body::after { opacity: 1; }
.bar-body.today { background: linear-gradient(180deg,#3b82f6 0%,#0D215C 100%); }
.bar-body.active { background: #93c5fd; }
.bar-lbl {
font-size: 10px;
font-weight: 500;
color: #94a3b8;
text-align: center;
}
.bar-lbl.today-lbl { color: #3b82f6; font-weight: 600; }
.chart-footer {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 10px;
border-top: 1px solid #f1f5f9;
font-size: 12px;
color: #64748b;
font-weight: 400;
}
.chart-footer span { color: #94a3b8; }
.chart-footer strong { color: #0D215C; font-weight: 700; }
/* Progress */
.prog-item { margin-bottom: 14px; }
.prog-item:last-child { margin-bottom: 0; }
.prog-head { display: flex; justify-content: space-between; margin-bottom: 7px; }
.prog-head span { font-size: 12.5px; font-weight: 500; color: #334155; }
.prog-head strong { font-size: 12.5px; font-weight: 700; color: #0D215C; }
.prog-track { height: 8px; background: #f1f5f9; border-radius: 50px; overflow: hidden; }
.prog-fill { height: 100%; border-radius: 50px; transition: width 1.2s cubic-bezier(.4,0,.2,1); }
/* Top Users */
.usr-row {
display: flex;
align-items: center;
gap: 11px;
padding: 8px 10px;
border-radius: 12px;
transition: background 0.15s, box-shadow 0.15s;
cursor: default;
}
.usr-row:hover {
background: #f8fafc;
box-shadow: 0 2px 10px rgba(13,33,92,0.05);
}
.usr-rank {
width: 24px; height: 24px;
border-radius: 7px;
font-size: 11px;
font-weight: 700;
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
}
.rank-1 { background: #fef9c3; color: #b45309; }
.rank-2 { background: #f1f5f9; color: #64748b; }
.rank-3 { background: #fff7ed; color: #c2410c; }
.rank-n { background: #f8fafc; color: #94a3b8; }
.usr-ava {
width: 32px; height: 32px;
border-radius: 9px;
background: linear-gradient(135deg,#0D215C,#2563eb);
color: #fff;
font-size: 10px;
font-weight: 700;
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
}
.usr-name { flex: 1; font-size: 12.5px; font-weight: 500; color: #334155; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.usr-count {
font-size: 11px;
font-weight: 600;
color: #3b82f6;
background: #eff6ff;
padding: 3px 11px;
border-radius: 50px;
flex-shrink: 0;
}
/* ── Animations ──────────────────────────────── */
@keyframes fadeUp {
from { opacity:0; transform:translateY(16px); }
to { opacity:1; transform:translateY(0); }
}
.s-card { animation: fadeUp 0.4s ease both; }
.s-card:nth-child(1) { animation-delay:.06s; }
.s-card:nth-child(2) { animation-delay:.12s; }
.s-card:nth-child(3) { animation-delay:.18s; }
.s-card:nth-child(4) { animation-delay:.24s; }
.content-grid { animation: fadeUp 0.4s .28s ease both; }
/* ── Responsive ──────────────────────────────── */
@media (max-width:1100px) { .content-grid { grid-template-columns:1fr; } }
@media (max-width:768px) {
.stats-grid { grid-template-columns:repeat(2,1fr); gap: 12px; }
.d-wrap { padding: 1rem 0.5rem; }
.page-header { flex-direction:column; align-items:flex-start; gap:12px; }
.page-header-right { flex-wrap: wrap; gap: 8px; }
.g-card { padding: 1.2rem; }
.act-item { gap: 10px; padding: 8px; }
.hdr-chip { padding: 6px 12px; }
}
@media (max-width:480px) {
.stats-grid { grid-template-columns:1fr; }
.d-wrap { padding: 0.8rem 0; }
.g-card { padding: 1rem; border-radius: 16px; }
.act-meta { font-size: 10px; }
.s-card { padding: 1.2rem; }
.act-item { flex-direction: column; align-items: flex-start; gap: 8px; }
.act-item .pill { align-self: flex-start; }
}
</style>
{{-- ═══════ MODAL (Detail Kegiatan) ═══════ --}}
<div class="modal-overlay" id="detailModal">
<div class="modal-box">
<div class="modal-header">
<h4 id="mdl-title"></h4>
<button class="modal-close" onclick="closeModal()">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
<div id="mdl-body"></div>
</div>
</div>
<div class="d-wrap">
{{-- ── PAGE HEADER ── --}}
<div class="page-header">
<div class="page-header-left">
<h2>Dashboard Admin</h2>
<div class="subtitle">
<span class="status-dot"></span>
{{ \Carbon\Carbon::now()->timezone('Asia/Jakarta')->locale('id')->translatedFormat('l, d F Y') }}
&nbsp;·&nbsp; Sistem Online
</div>
</div>
<div class="page-header-right">
<span class="hdr-chip light">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
{{ \Carbon\Carbon::now()->timezone('Asia/Jakarta')->format('H:i') }} WIB
</span>
<span class="hdr-chip navy">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
Disnaker Kalbar
</span>
</div>
</div>
{{-- ── STAT CARDS ── --}}
<div class="stats-grid">
<div class="s-card c-blue">
<div class="s-icon c-blue">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2"/>
<rect x="9" y="3" width="6" height="4" rx="1"/>
<line x1="9" y1="12" x2="15" y2="12"/>
<line x1="9" y1="16" x2="13" y2="16"/>
</svg>
</div>
<div class="s-num">{{ $stats['total'] ?? 0 }}</div>
<div class="s-label">Total Kegiatan</div>
<div class="s-trend up">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="18 15 12 9 6 15"/></svg>
12% bulan ini
</div>
</div>
<div class="s-card c-green">
<div class="s-icon c-green">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/>
<polyline points="22 4 12 14.01 9 11.01"/>
</svg>
</div>
<div class="s-num">{{ $stats['selesai'] ?? 0 }}</div>
<div class="s-label">Kegiatan Selesai</div>
<div class="s-trend up">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="18 15 12 9 6 15"/></svg>
8% dari kemarin
</div>
</div>
<div class="s-card c-yellow">
<div class="s-icon c-yellow">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<line x1="12" y1="2" x2="12" y2="6"/>
<line x1="12" y1="18" x2="12" y2="22"/>
<line x1="4.93" y1="4.93" x2="7.76" y2="7.76"/>
<line x1="16.24" y1="16.24" x2="19.07" y2="19.07"/>
<line x1="2" y1="12" x2="6" y2="12"/>
<line x1="18" y1="12" x2="22" y2="12"/>
<line x1="4.93" y1="19.07" x2="7.76" y2="16.24"/>
<line x1="16.24" y1="7.76" x2="19.07" y2="4.93"/>
</svg>
</div>
<div class="s-num">{{ $stats['proses'] ?? 0 }}</div>
<div class="s-label">Sedang Berjalan</div>
<div class="s-trend flat">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="12" x2="19" y2="12"/></svg>
Sama seperti kemarin
</div>
</div>
<div class="s-card c-red">
<div class="s-icon c-red">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/>
<circle cx="9" cy="7" r="4"/>
<path d="M23 21v-2a4 4 0 0 0-3-3.87"/>
<path d="M16 3.13a4 4 0 0 1 0 7.75"/>
</svg>
</div>
<div class="s-num">{{ $stats['users'] ?? 0 }}</div>
<div class="s-label">Pengguna Aktif</div>
<div class="s-trend down">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>
3% minggu ini
</div>
</div>
</div>
{{-- ── MAIN GRID ── --}}
<div class="content-grid">
{{-- LEFT: Kegiatan Terbaru --}}
<div class="g-card">
<div class="g-card-title">
<h3>5 Kegiatan Terbaru</h3>
<a href="{{ route('admin.kegiatan.index') }}">Lihat Semua &rarr;</a>
</div>
<div class="ftabs">
<div class="ftab on" onclick="filterAct(this,'semua')">Semua</div>
<div class="ftab off" onclick="filterAct(this,'selesai')">Selesai</div>
<div class="ftab off" onclick="filterAct(this,'on_progres')">Berjalan</div>
<div class="ftab off" onclick="filterAct(this,'terlambat')">Terlambat</div>
<div class="ftab off" onclick="filterAct(this,'dibatalkan')">Dibatalkan</div>
</div>
<div class="act-divider"></div>
<div id="act-list">
@php
$avClasses = ['av-1','av-2','av-3','av-4','av-5'];
$pillMap = [
'selesai' => ['pill-ok', 'Selesai'],
'telah_ditinjau' => ['pill-ok', 'Ditinjau'],
'on_progres' => ['pill-run', 'Berjalan'],
'terlambat' => ['pill-del', 'Terlambat'],
'dibatalkan' => ['pill-del', 'Dibatalkan'],
'review' => ['pill-pnd', 'Review'],
'pending' => ['pill-pnd', 'Pending'],
];
@endphp
@forelse($activities ?? [] as $idx => $item)
@php
$st = strtolower($item->status ?? 'pending');
$pc = $pillMap[$st] ?? ['pill-pnd', ucfirst($st)];
$ac = $avClasses[$idx % 5];
$tgl = \Carbon\Carbon::parse($item->tanggal)->locale('id')->translatedFormat('d M Y');
$usr = e($item->user->name ?? 'Sistem');
$nm = e($item->nama_kegiatan);
@endphp
<div class="act-item"
data-status="{{ $st }}"
onclick="openModal(
'{{ addslashes($nm) }}',
'{{ addslashes($usr) }}',
'{{ $tgl }}',
'{{ $st }}',
'{{ addslashes(str_replace(["\r", "\n"], ["", "\\n"], $item->keterangan ?? '-')) }}',
'{{ addslashes(str_replace(["\r", "\n"], ["", "\\n"], $item->status_note ?? '')) }}',
'{{ addslashes($item->lokasi ?? '-') }}',
'{{ $item->lampiran ? rtrim(env('BACKEND_API_URL', 'http://127.0.0.1:8000'), '/api') . '/storage/' . $item->lampiran : '' }}'
)">
<div class="act-ava {{ $ac }}">{{ strtoupper(substr($item->user->name ?? 'U', 0, 2)) }}</div>
<div class="act-body">
<div class="act-name">{{ $nm }}</div>
<div class="act-meta">{{ $usr }} &bull; {{ $tgl }}</div>
</div>
<span class="pill {{ $pc[0] }}">{{ $pc[1] }}</span>
</div>
@empty
<div class="empty-box">
<div class="ei">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"/><polyline points="13 2 13 9 20 9"/></svg>
</div>
<p>Belum ada aktivitas kegiatan yang tercatat.</p>
</div>
@endforelse
</div>
</div>
{{-- RIGHT: Sidebar --}}
<div class="sidebar-col">
{{-- Weekly Chart --}}
<div class="g-card">
<div class="g-card-title" style="margin-bottom:.8rem">
<h3>Aktivitas Minggu Ini</h3>
@php $wTotal = array_sum($weeklyData ?? [0,0,0,0,0,0,0]); @endphp
<span class="pill pill-run">{{ $wTotal }} kegiatan</span>
</div>
@php
$days = ['Sen','Sel','Rab','Kam','Jum','Sab','Min'];
$wData = $weeklyData ?? [0,0,0,0,0,0,0];
$maxBar = max($wData) ?: 1;
$todayDI = (int)\Carbon\Carbon::now()->dayOfWeekIso - 1;
@endphp
<div class="chart-bars">
@foreach($days as $i => $d)
@php $pct = round(($wData[$i] / $maxBar) * 100); $isToday = $i === $todayDI; @endphp
<div class="bar-wrap">
<div class="bar-body {{ $isToday ? 'today' : ($wData[$i] > 0 ? 'active' : '') }}"
style="height:{{ max($pct, 8) }}%"
data-val="{{ $wData[$i] }} kegiatan">
</div>
<span class="bar-lbl {{ $isToday ? 'today-lbl' : '' }}">{{ $d }}</span>
</div>
@endforeach
</div>
<div class="chart-footer">
<span>Total minggu ini</span>
<strong>{{ $wTotal }} kegiatan</strong>
</div>
</div>
{{-- Division Progress --}}
<div class="g-card">
<div class="g-card-title" style="margin-bottom:.8rem">
<h3>Progres Divisi</h3>
</div>
{{-- FIX: Gunakan $divisionProgress dari controller, fallback jika tidak ada --}}
@php
$divs = $divisionProgress ?? [
['name' => 'Operasional', 'pct' => 78, 'clr' => 'linear-gradient(90deg,#3b82f6,#6366f1)'],
['name' => 'Keuangan', 'pct' => 64, 'clr' => 'linear-gradient(90deg,#22c55e,#10b981)'],
['name' => 'SDM', 'pct' => 91, 'clr' => 'linear-gradient(90deg,#f97316,#f59e0b)'],
['name' => 'IT', 'pct' => 55, 'clr' => 'linear-gradient(90deg,#a855f7,#ec4899)'],
];
@endphp
@foreach($divs as $dv)
<div class="prog-item">
<div class="prog-head">
<span>{{ $dv['name'] }}</span>
<strong>{{ $dv['pct'] ?? 0 }}%</strong>
</div>
<div class="prog-track">
<div class="prog-fill" style="width:{{ $dv['pct'] ?? 0 }}%;background:{{ $dv['clr'] ?? '#3b82f6' }}"></div>
</div>
</div>
@endforeach
</div>
{{-- Top Kontributor --}}
@if(!empty($topUsers) && count($topUsers))
<div class="g-card">
<div class="g-card-title" style="margin-bottom:.8rem">
<h3>Top Kontributor</h3>
</div>
@foreach($topUsers as $ri => $u)
@php
$rankCls = match($ri) { 0 => 'rank-1', 1 => 'rank-2', 2 => 'rank-3', default => 'rank-n' };
$medal = match($ri) {
0 => '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="#b45309" stroke="none"><circle cx="12" cy="8" r="6"/><path d="M15.477 12.89L17 22l-5-3-5 3 1.523-9.11"/></svg>',
1 => '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="#64748b" stroke="none"><circle cx="12" cy="8" r="6"/><path d="M15.477 12.89L17 22l-5-3-5 3 1.523-9.11"/></svg>',
2 => '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="#c2410c" stroke="none"><circle cx="12" cy="8" r="6"/><path d="M15.477 12.89L17 22l-5-3-5 3 1.523-9.11"/></svg>',
default => $ri + 1
};
@endphp
<div class="usr-row">
<div class="usr-rank {{ $rankCls }}">{!! $medal !!}</div>
<div class="usr-ava">{{ strtoupper(substr($u->name, 0, 2)) }}</div>
<span class="usr-name">{{ $u->name }}</span>
{{-- FIX: Ganti kegiatan_count activities_count (sesuai withCount('activities')) --}}
<span class="usr-count">{{ $u->activities_count ?? 0 }} Lap.</span>
</div>
@endforeach
</div>
@endif
</div>{{-- /sidebar --}}
</div>{{-- /content-grid --}}
</div>{{-- /d-wrap --}}
<script>
/* ── Filter Tabs ─────────────────── */
function filterAct(el, status) {
document.querySelectorAll('.ftab').forEach(t => {
t.classList.remove('on');
t.classList.add('off');
});
el.classList.add('on');
el.classList.remove('off');
document.querySelectorAll('#act-list .act-item').forEach(row => {
row.style.display = (status === 'semua' || row.dataset.status === status) ? 'flex' : 'none';
});
}
/* ── Modal ───────────────────────── */
const pillLabels = {
selesai: '<span class="pill pill-ok">Selesai</span>',
on_progres: '<span class="pill pill-run">Berjalan</span>',
terlambat: '<span class="pill pill-del">Terlambat</span>',
dibatalkan: '<span class="pill pill-del">Dibatalkan</span>',
review: '<span class="pill pill-pnd">Review</span>',
pending: '<span class="pill pill-pnd">Pending</span>'
};
function openModal(nama, user, tgl, status, ket, statusNote, lokasi, lampiranUrl) {
document.getElementById('mdl-title').textContent = nama;
let lampiranHtml = '';
if (lampiranUrl) {
lampiranHtml = `
<div class="modal-field" style="margin-top: 15px; grid-column: span 2;">
<span class="mf-label">Lampiran Foto/Dokumen</span>
<div style="margin-top: 8px;">
<img src="${lampiranUrl}" alt="Lampiran" style="max-width: 100%; max-height: 400px; border-radius: 6px; box-shadow: 0 1px 3px rgba(0,0,0,0.1);">
</div>
</div>`;
}
document.getElementById('mdl-body').innerHTML = `
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 12px;">
<div class="modal-field">
<span class="mf-label">Pegawai Ditugaskan</span>
<span class="mf-value">${user}</span>
</div>
<div class="modal-field">
<span class="mf-label">Tanggal</span>
<span class="mf-value">${tgl}</span>
</div>
<div class="modal-field">
<span class="mf-label">Lokasi Tugas</span>
<span class="mf-value">${lokasi}</span>
</div>
<div class="modal-field">
<span class="mf-label">Status</span>
<span class="mf-value">${pillLabels[status] || status}</span>
</div>
<div class="modal-field" style="grid-column: span 2;">
<span class="mf-label">Deskripsi Laporan (Keterangan)</span>
<span class="mf-value" style="white-space: pre-wrap; line-height: 1.5;">${ket || '—'}</span>
</div>
${statusNote ? `
<div class="modal-field" style="grid-column: span 2; background: #eff6ff; padding: 12px; border-radius: 8px;">
<span class="mf-label" style="color: #2563eb; margin-bottom: 4px; display: block;">Catatan Status (Node Petugas)</span>
<span class="mf-value" style="white-space: pre-wrap; line-height: 1.5; color: #1e3a8a;">${statusNote}</span>
</div>
` : ''}
${lampiranHtml}
</div>
`;
document.getElementById('detailModal').classList.add('show');
}
function closeModal() {
document.getElementById('detailModal').classList.remove('show');
}
document.getElementById('detailModal').addEventListener('click', function(e) {
if (e.target === this) closeModal();
});
document.addEventListener('keydown', e => {
if (e.key === 'Escape') closeModal();
});
</script>
@endsection