@php $appSettings = app(\App\Services\AppSettingsService::class); $midtransSettings = app(\App\Services\MidtransSettingsService::class); @endphp {{ isset($title) ? $title.' - ' : '' }}{{ $appSettings->namaAplikasi() }} @if ($appSettings->hasLogo()) @endif @vite(['resources/css/app.css', 'resources/js/app.js']) @stack('styles') @livewireStyles @if ($midtransSettings->clientKey()) @endif @php $navGroups = []; if (auth()->check() && auth()->user()->hasAnyRole(['superadmin', 'admin', 'bendahara'])) { $navGroups = [ [ 'label' => null, 'items' => [ ['route' => 'admin.dashboard', 'match' => 'admin.dashboard', 'label' => 'Dashboard', 'icon' => 'home'], ], ], [ 'label' => 'Transaksi Keuangan', 'items' => [ ['route' => 'admin.tagihan.index', 'match' => ['admin.tagihan.index', 'admin.tagihan.generate'], 'label' => 'Tagihan', 'icon' => 'document'], ['route' => 'admin.topup.index', 'match' => 'admin.topup.*', 'label' => 'Top Up Wali', 'icon' => 'arrow-up-circle'], ['route' => 'admin.penarikan.index', 'match' => 'admin.penarikan.*', 'label' => 'Penarikan Tunai', 'icon' => 'arrow-down-circle'], ['route' => 'admin.transaksi.index', 'match' => 'admin.transaksi.*', 'label' => 'Riwayat Transaksi', 'icon' => 'receipt'], ], ], [ 'label' => 'Kas & Pengendalian', 'items' => [ ['route' => 'admin.sesi-kas.index', 'match' => 'admin.sesi-kas.*', 'label' => 'Sesi Kas', 'icon' => 'wallet'], ['route' => 'admin.penyesuaian-keuangan.index', 'match' => 'admin.penyesuaian-keuangan.*', 'label' => 'Penyesuaian Keuangan', 'icon' => 'adjustments'], ], ], [ 'label' => 'Master Keuangan', 'items' => [ ['route' => 'admin.tagihan.jenis.index', 'match' => 'admin.tagihan.jenis.*', 'label' => 'Jenis Tagihan', 'icon' => 'tag'], ['route' => 'admin.periode.index', 'match' => 'admin.periode.*', 'label' => 'Periode Tagihan', 'icon' => 'calendar'], ['route' => 'admin.kategori-diskon.index', 'match' => 'admin.kategori-diskon.*', 'label' => 'Kategori Diskon', 'icon' => 'percent'], ['route' => 'admin.kebijakan.penarikan', 'match' => 'admin.kebijakan.*', 'label' => 'Kebijakan Penarikan', 'icon' => 'shield'], ], ], [ 'label' => 'Laporan', 'items' => [ ['route' => 'admin.laporan-keuangan.index', 'match' => 'admin.laporan-keuangan.*', 'label' => 'Laporan Keuangan', 'icon' => 'chart'], ['route' => 'admin.leger-kas-pondok.index', 'match' => 'admin.leger-kas-pondok.*', 'label' => 'Leger Kas Pondok', 'icon' => 'wallet'], ], ], ]; // Santri/keluarga record-keeping, kantin, and settings/system // administration are all admin-only - bendahara's job is financial // management (the Keuangan/Laporan groups above), not kesantrian // record-keeping, kantin operations, or system administration, so // these groups are hidden rather than shown with dead links // bendahara can't actually open (see routes/web.php). if (auth()->user()->hasAnyRole(['superadmin', 'admin'])) { $navGroups[] = [ 'label' => 'Data Master Santri', 'items' => [ ['route' => 'admin.santri.index', 'match' => 'admin.santri.*', 'label' => 'Data Santri', 'icon' => 'users'], ['route' => 'admin.lembaga.index', 'match' => 'admin.lembaga.*', 'label' => 'Lembaga Pendidikan', 'icon' => 'building'], ['route' => 'admin.rayon.index', 'match' => 'admin.rayon.*', 'label' => 'Data Rayon', 'icon' => 'building'], ['route' => 'admin.kamar.index', 'match' => 'admin.kamar.*', 'label' => 'Data Kamar', 'icon' => 'room'], ['route' => 'admin.keluarga.index', 'match' => 'admin.keluarga.*', 'label' => 'Data Keluarga', 'icon' => 'family'], ['route' => 'admin.wali.index', 'match' => 'admin.wali.*', 'label' => 'Data Wali Santri', 'icon' => 'user-group'], ['route' => 'admin.kartu.index', 'match' => 'admin.kartu.*', 'label' => 'Kartu Santri', 'icon' => 'card'], ], ]; $navGroups[] = [ 'label' => 'Kantin', 'items' => [ ['route' => 'admin.kantin.index', 'match' => 'admin.kantin.index', 'label' => 'Kelola Kantin', 'icon' => 'shop'], ['route' => 'admin.kantin.penarikan.index', 'match' => 'admin.kantin.penarikan.*', 'label' => 'Penarikan Kantin', 'icon' => 'arrow-down-circle'], ['route' => 'admin.kantin.rekening.index', 'match' => 'admin.kantin.rekening.*', 'label' => 'Perubahan Rekening', 'icon' => 'credit-card'], ['route' => 'admin.kantin.ledger.index', 'match' => 'admin.kantin.ledger.*', 'label' => 'Riwayat Transaksi', 'icon' => 'receipt'], ['route' => 'admin.kantin.kebijakan.index', 'match' => 'admin.kantin.kebijakan.*', 'label' => 'Kebijakan Belanja', 'icon' => 'shield'], ], ]; $navGroups[] = [ 'label' => 'Sistem & Akses', 'items' => [ ['route' => 'admin.perangkat.index', 'match' => 'admin.perangkat.*', 'label' => 'Perangkat Kiosk', 'icon' => 'device'], ['route' => 'admin.banner.index', 'match' => 'admin.banner.*', 'label' => 'Banner Beranda', 'icon' => 'image'], ], ]; if (auth()->user()->hasRole('superadmin')) { $navGroups[] = [ 'label' => 'Kontrol Sistem', 'items' => [ ['route' => 'admin.pengaturan.aplikasi', 'match' => 'admin.pengaturan.aplikasi', 'label' => 'Pengaturan Aplikasi', 'icon' => 'adjustments'], ['route' => 'admin.users.index', 'match' => 'admin.users.*', 'label' => 'Pengguna & Petugas', 'icon' => 'users'], ['route' => 'admin.pengaturan.midtrans', 'match' => 'admin.pengaturan.midtrans', 'label' => 'Pengaturan Midtrans', 'icon' => 'credit-card'], ['route' => 'admin.pengaturan.2fa', 'match' => 'admin.pengaturan.2fa', 'label' => 'Keamanan 2FA', 'icon' => 'shield'], ['route' => 'admin.audit-keuangan.index', 'match' => 'admin.audit-keuangan.*', 'label' => 'Audit Keuangan', 'icon' => 'document'], ['route' => 'admin.rekonsiliasi.index', 'match' => 'admin.rekonsiliasi.*', 'label' => 'Rekonsiliasi Keuangan', 'icon' => 'receipt'], ['route' => 'admin.periode-keuangan.index', 'match' => 'admin.periode-keuangan.*', 'label' => 'Tutup Buku', 'icon' => 'calendar'], ['route' => 'admin.backup.index', 'match' => 'admin.backup.*', 'label' => 'Backup & Restore', 'icon' => 'archive'], ['route' => 'admin.pengaturan.maintenance', 'match' => 'admin.pengaturan.maintenance', 'label' => 'Maintenance', 'icon' => 'shield'], ], ]; } } } elseif (auth()->check() && auth()->user()->hasAnyRole(['admin_lembaga', 'admin_rayon'])) { $navGroups = [[ 'label' => 'Pengelolaan Unit', 'items' => [ ['route' => 'unit.dashboard', 'match' => 'unit.dashboard', 'label' => 'Dashboard', 'icon' => 'home'], ['route' => 'unit.santri.index', 'match' => 'unit.santri.*', 'label' => 'Data Santri', 'icon' => 'users'], ], ]]; } elseif (auth()->check() && auth()->user()->hasRole('petugas_kios')) { $navGroups = [[ 'label' => 'Operasional Kios', 'items' => [ ['route' => 'petugas-kios.dashboard', 'match' => 'petugas-kios.dashboard', 'label' => 'Beranda Kios', 'icon' => 'home'], ['route' => 'petugas-kios.transaksi', 'match' => 'petugas-kios.transaksi', 'label' => 'Transaksi Tunai', 'icon' => 'wallet'], ['route' => 'petugas-kios.tutup-sesi', 'match' => 'petugas-kios.tutup-sesi', 'label' => 'Tutup Sesi Kas', 'icon' => 'lock'], ['route' => 'petugas-kios.mutasi', 'match' => 'petugas-kios.mutasi', 'label' => 'Riwayat Mutasi', 'icon' => 'receipt'], ], ]]; } elseif (auth()->check() && auth()->user()->hasRole('pengasuh')) { $navGroups = [[ 'label' => null, 'items' => [ ['route' => 'pengasuh.dashboard', 'match' => 'pengasuh.dashboard', 'label' => 'Dashboard', 'icon' => 'home'], ['route' => 'pengasuh.persetujuan-midtrans', 'match' => 'pengasuh.persetujuan-midtrans', 'label' => 'Persetujuan Midtrans', 'icon' => 'credit-card'], ['route' => 'pengasuh.laporan', 'match' => 'pengasuh.laporan', 'label' => 'Laporan Santri', 'icon' => 'document'], ], ]]; } elseif (auth()->check() && auth()->user()->hasRole('wali')) { $navGroups = [[ 'label' => null, 'items' => [ ['route' => 'wali.dashboard', 'match' => 'wali.dashboard', 'label' => 'Dashboard', 'icon' => 'home'], ['route' => 'wali.saldo', 'match' => 'wali.saldo', 'label' => 'Saldo', 'icon' => 'wallet'], ['route' => 'wali.tagihan.index', 'match' => 'wali.tagihan.*', 'label' => 'Tagihan', 'icon' => 'document'], ['route' => 'wali.topup', 'match' => 'wali.topup*', 'label' => 'Top Up', 'icon' => 'arrow-up-circle'], ], ]]; } elseif (auth()->check() && auth()->user()->hasRole('santri')) { $navGroups = [[ 'label' => null, 'items' => [ ['route' => 'santri.dashboard', 'match' => 'santri.dashboard', 'label' => 'Dashboard', 'icon' => 'home'], ['route' => 'santri.saldo', 'match' => 'santri.saldo', 'label' => 'Saldo', 'icon' => 'wallet'], ['route' => 'santri.tagihan.index', 'match' => 'santri.tagihan.*', 'label' => 'Tagihan', 'icon' => 'document'], ['route' => 'santri.penarikan.request', 'match' => 'santri.penarikan.request', 'label' => 'Tarik Tunai', 'icon' => 'arrow-down-circle'], ['route' => 'santri.penarikan.riwayat', 'match' => 'santri.penarikan.riwayat', 'label' => 'Riwayat', 'icon' => 'receipt'], ], ]]; } elseif (auth()->check() && auth()->user()->hasRole('pengelola')) { $navGroups = [[ 'label' => 'Ringkasan', 'items' => [ ['route' => 'pengelola.dashboard', 'match' => 'pengelola.dashboard', 'label' => 'Dashboard', 'icon' => 'home'], ], ], [ 'label' => 'Operasional Kantin', 'items' => [ ['route' => 'pengelola.pos', 'match' => 'pengelola.pos', 'label' => 'Kasir POS', 'icon' => 'shop'], ['route' => 'pengelola.produk', 'match' => 'pengelola.produk', 'label' => 'Produk & Kategori', 'icon' => 'clipboard'], ['route' => 'pengelola.qr', 'match' => 'pengelola.qr', 'label' => 'QR Pembayaran', 'icon' => 'receipt'], ['route' => 'pengelola.transaksi', 'match' => 'pengelola.transaksi', 'label' => 'Riwayat & Export', 'icon' => 'receipt'], ], ], ...((auth()->user()->unitUsahaDikelola?->is_affiliated ?? false) ? [[ 'label' => 'Voucher Eksternal', 'items' => [ ['route' => 'pengelola.voucher', 'params' => ['section' => 'ringkasan'], 'match' => 'pengelola.voucher', 'label' => 'Ringkasan Voucher', 'icon' => 'receipt'], ['route' => 'pengelola.voucher', 'params' => ['section' => 'terbitkan'], 'match' => '__none__', 'label' => 'Terbitkan Voucher', 'icon' => 'plus-circle'], ['route' => 'pengelola.voucher', 'params' => ['section' => 'pencairan'], 'match' => '__none__', 'label' => 'Pencairan Voucher', 'icon' => 'qr-code'], ['route' => 'pengelola.voucher', 'params' => ['section' => 'pengelolaan'], 'match' => '__none__', 'label' => 'Hilang & Riwayat', 'icon' => 'clipboard'], ], ]] : []), [ 'label' => 'Keuangan & Rekening', 'items' => [ ['route' => 'pengelola.penarikan', 'match' => 'pengelola.penarikan', 'label' => 'Penarikan', 'icon' => 'arrow-down-circle'], ['route' => 'pengelola.rekening', 'match' => 'pengelola.rekening', 'label' => 'Rekening', 'icon' => 'credit-card'], ], ]]; } elseif (auth()->check() && auth()->user()->hasRole('dev')) { $navGroups = [[ 'label' => 'Dokumentasi Internal', 'items' => [ ['route' => 'dev.tentang', 'match' => ['dev.dashboard', 'dev.tentang'], 'label' => 'Tentang Aplikasi', 'icon' => 'info'], ['route' => 'dev.instalasi', 'match' => 'dev.instalasi', 'label' => 'Instalasi & Kebutuhan', 'icon' => 'cog'], ['route' => 'dev.deployment', 'match' => 'dev.deployment', 'label' => 'Deployment & Mitigasi', 'icon' => 'shield'], ['route' => 'dev.arsitektur', 'match' => 'dev.arsitektur', 'label' => 'Arsitektur Sistem', 'icon' => 'database'], ['route' => 'dev.flow-sistem', 'match' => 'dev.flow-sistem', 'label' => 'Flow Fitur Sistem', 'icon' => 'document'], ['route' => 'dev.skema-database', 'match' => 'dev.skema-database', 'label' => 'Skema Database', 'icon' => 'database'], ['route' => 'dev.api.wali', 'match' => 'dev.api.wali', 'label' => 'Dokumentasi API Wali', 'icon' => 'document'], ['route' => 'dev.api.kiosk', 'match' => 'dev.api.kiosk', 'label' => 'Dokumentasi API Kiosk', 'icon' => 'document'], ], ]]; } $maintenanceNavigation = auth()->check() && auth()->user()->hasRole('superadmin') && app(\App\Services\MaintenanceModeService::class)->active(); if ($maintenanceNavigation) { $navGroups = [[ 'label' => 'Mode Pemulihan', 'items' => [ ['route' => 'admin.pengaturan.maintenance', 'match' => 'admin.pengaturan.maintenance', 'label' => 'Maintenance', 'icon' => 'shield'], ['route' => 'admin.backup.index', 'match' => 'admin.backup.*', 'label' => 'Backup & Restore', 'icon' => 'archive'], ['route' => 'admin.rekonsiliasi.index', 'match' => 'admin.rekonsiliasi.*', 'label' => 'Rekonsiliasi Keuangan', 'icon' => 'receipt'], ['route' => 'admin.pengaturan.2fa', 'match' => 'admin.pengaturan.2fa', 'label' => 'Keamanan 2FA', 'icon' => 'shield'], ], ]]; } $icons = [ 'home' => 'M3 12 12 4l9 8M5 10v10h5v-6h4v6h5V10', 'users' => 'M17 20a3 3 0 0 0-3-3H10a3 3 0 0 0-3 3M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm7 8a3 3 0 0 0-2.5-2.96M17 4.13a3 3 0 0 1 0 5.74', 'card' => 'M3 6h18a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1Zm-1 5h20M6 15h4', 'user-group' => 'M9 12a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm0 0a5 5 0 0 0-5 5v1h10v-1a5 5 0 0 0-5-5Zm7-3a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5Zm1.5 8v-1a4.5 4.5 0 0 0-3-4.24', 'tag' => 'm12 2 9 9-9 9-9-9V4a2 2 0 0 1 2-2h7Zm-3.5 6.5h.01', 'percent' => 'M6 6 18 18M7 9a2 2 0 1 0 0-4 2 2 0 0 0 0 4Zm10 10a2 2 0 1 0 0-4 2 2 0 0 0 0 4Z', 'document' => 'M7 3h7l5 5v13a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1Zm7 0v5h5M9 13h6M9 17h6', 'receipt' => 'M6 3h12v18l-3-2-3 2-3-2-3 2V3Zm2 5h8m-8 4h8', 'arrow-up-circle' => 'M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Zm0-4V8m0 0-4 4m4-4 4 4', 'arrow-down-circle' => 'M12 3a9 9 0 1 0 0 18 9 9 0 0 0 0-18Zm0 4v9m0 0-4-4m4 4 4-4', 'shield' => 'M12 3l7 3v6c0 4.5-3 7.5-7 9-4-1.5-7-4.5-7-9V6l7-3Z', 'cog' => 'M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm7.4-3a7.4 7.4 0 0 1-.14 1.4l2 1.56-2 3.46-2.36-.95a7.5 7.5 0 0 1-2.4 1.4L14 22h-4l-.5-2.13a7.5 7.5 0 0 1-2.4-1.4l-2.36.95-2-3.46 2-1.56A7.4 7.4 0 0 1 4.6 12a7.4 7.4 0 0 1 .14-1.4l-2-1.56 2-3.46 2.36.95a7.5 7.5 0 0 1 2.4-1.4L10 2h4l.5 2.13a7.5 7.5 0 0 1 2.4 1.4l2.36-.95 2 3.46-2 1.56c.1.46.14.92.14 1.4Z', 'building' => 'M4 21V5a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v16M4 21h16M13 21v-6h4v6M8 7h1m3 0h1M8 11h1m3 0h1M8 15h1m3 0h1', 'room' => 'M4 21V5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v16M4 21h16M8 21v-5h8v5M8 8h3v3H8V8Zm5 0h3v3h-3V8Z', 'credit-card' => 'M3 6h18a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1Zm-1 5h20M6 15h4', 'wallet' => 'M21 7H5a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6a2 2 0 0 0-2-2h-4a2 2 0 1 0 0 4h4M5 7l1-3h9l3 3', 'lock' => 'M7 10V7a5 5 0 0 1 10 0v3m-11 0h12a1 1 0 0 1 1 1v9H5v-9a1 1 0 0 1 1-1Zm6 4v3', 'info' => 'M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Zm0-9v5m0-8h.01', 'calendar' => 'M8 2v3m8-3v3M3.5 9h17M4 5h16a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1Z', 'chart' => 'M4 19V10m6 9V4m6 15v-7M3 19h18', 'database' => 'M12 3c-4.42 0-8 1.57-8 3.5S7.58 10 12 10s8-1.57 8-3.5S16.42 3 12 3ZM4 6.5V12c0 1.93 3.58 3.5 8 3.5s8-1.57 8-3.5V6.5M4 12v5.5C4 19.43 7.58 21 12 21s8-1.57 8-3.5V12', 'adjustments' => 'M4 6h6m4 0h6M4 12h10m4 0h2M4 18h2m4 0h10M8 4v4M16 10v4M10 16v4', 'family' => 'M12 3 4 9v11h5v-6h6v6h5V9l-8-6Z', 'archive' => 'M3 7h18v3H3V7Zm1 3h16v9a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-9Zm6 3h4M6 7l1.5-3h9L18 7', 'device' => 'M4 4h16a1 1 0 0 1 1 1v11a1 1 0 0 1-1 1h-6l1 3H9l1-3H4a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1Zm3 5h.01M7 12h6', 'shop' => 'M3 9l1-5h16l1 5M3 9v10a1 1 0 0 0 1 1h5v-6h6v6h5a1 1 0 0 0 1-1V9M3 9h18', 'image' => 'M4 5h16a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1Zm3.5 6a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM4 16l5-5 4 4 3-3 5 5', 'download' => 'M12 3v12m0 0-4-4m4 4 4-4M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2', ]; $isActive = function ($match, ?array $params = null) { if ($params && request()->routeIs('pengelola.voucher')) { return request()->route('section', 'ringkasan') === ($params['section'] ?? null); } foreach ((array) $match as $pattern) { if (request()->routeIs($pattern)) { return true; } } return false; }; $activeGroupLabel = null; foreach ($navGroups as $group) { foreach ($group['items'] as $item) { if ($isActive($item['match'], $item['params'] ?? null)) { $activeGroupLabel = $group['label']; break 2; } } } @endphp
{{-- Mobile backdrop --}}
@if ($activeGroupLabel)

{{ $activeGroupLabel }}

@endif

{{ $title ?? '' }}

@auth @if (auth()->user()->hasRole('wali'))
@endif @php $topbarNotifications = auth()->user()->systemNotifications()->latest()->limit(6)->get(); $topbarUnreadCount = auth()->user()->systemNotifications()->whereNull('read_at')->count(); @endphp

Notifikasi

{{ $topbarUnreadCount }} belum dibaca

@if($topbarUnreadCount > 0)
@csrf
@endif
@forelse($topbarNotifications as $notification)
@csrf
@empty
Belum ada notifikasi.
@endforelse

{{ auth()->user()->name }}

{{ auth()->user()->roles->first()?->name }}

Masuk sebagai

{{ auth()->user()->email ?? auth()->user()->nis }}

Profil Saya
@csrf
@endauth
@if (auth()->check() && auth()->user()->hasRole('superadmin') && !request()->routeIs('admin.backup.*')) @php($activeSnapshot = app(\App\Services\DataSnapshotService::class)->current()) @if ($activeSnapshot) Database memakai {{ $activeSnapshot['backup_name'] }}. Transaksi baru tersimpan pada snapshot ini dan tidak otomatis digabung saat berpindah ke backup lain. Lihat detail restore. @endif @endif {{ $slot }}
@livewireScripts