{{-- ================================================================================================= FILE : resources/views/anggota/index.blade.php MODUL : Data Anggota (List + Filter) - Mobile First + Desktop Lengkap TAHUN : 2026 TUJUAN FILE: - Menampilkan data anggota dengan tampilan nyaman di Android. - Tetap menyediakan tampilan tabel lengkap untuk desktop/PC. - Menyediakan filter utama + filter lanjutan. - Pagination tetap membawa query string filter. - User login hanya boleh melihat/mengelola role di bawahnya. - NIK hanya ditampilkan untuk user login dengan role Joudie atau Superadmin. PERUBAHAN VERSI INI: - Tombol "Tambah Anggota" dipindah ke bawah filter. - Blok filter dipercantik untuk Android dan desktop. - Role di mobile diletakkan di atas foto. - Ukuran elemen mobile diperkecil agar lebih hemat tempat. - Keterangan foto ada/belum ada tetap disembunyikan. - NIK di list mobile disembunyikan, diganti No. Kartu. - NIK di desktop dan modal hapus hanya tampil untuk role Joudie / Superadmin. - Aksi mobile tetap 1 tombol kecil (dropdown menu): Detail, Foto, Kartu, Edit, Hapus. - Tombol hapus TIDAK lagi memakai data-bs-toggle modal langsung. - Modal hapus dibuka manual via JavaScript agar tidak mengunci klik mouse. CATATAN: - Controller index() tetap WAJIB membatasi query data berdasarkan hierarki role. - Tombol hapus menyesuaikan controller destroy(Request $request, $id) yang mewajibkan input password login. ================================================================================================= --}} @extends('layouts.dashboard') @section('title', 'Data Anggota') @section('pagetitle', 'Data Anggota') @section('content')
{{-- ============================================================================================= BLOK 1: PERSIAPAN DATA BLADE ============================================================================================== --}} @php $user = $user ?? auth()->user(); $roleRaw = (string)($user->role ?? ''); $roleKey = strtolower(trim($roleRaw)); $roleKey = str_replace([' ', '-'], '_', $roleKey); $roleAliasMap = [ 'joudie' => 'joudie', 'superadmin' => 'superadmin', 'super_admin' => 'superadmin', 'dpp' => 'dpp', 'dpd_pengurus' => 'dpdpengurus', 'dpdpengurus' => 'dpdpengurus', 'dpd_operator' => 'dpdoperator', 'dpdoperator' => 'dpdoperator', 'opr_dpd' => 'dpdoperator', 'operator_dpd' => 'dpdoperator', 'dpc_pengurus' => 'dpcpengurus', 'dpcpengurus' => 'dpcpengurus', 'dpc_operator' => 'dpcoperator', 'dpcoperator' => 'dpcoperator', 'opr_dpc' => 'dpcoperator', 'operator_dpc' => 'dpcoperator', 'ranting_pengurus' => 'rantingpengurus', 'rantingpengurus' => 'rantingpengurus', 'ranting_operator' => 'rantingoperator', 'rantingoperator' => 'rantingoperator', 'opr_ranting' => 'rantingoperator', 'operator_ranting' => 'rantingoperator', 'opr_rtg' => 'rantingoperator', 'anggota' => 'anggota', ]; $roleNorm = $roleAliasMap[$roleKey] ?? strtolower(str_replace('_', '', $roleKey)); $userId = $user->anggotaid ?? ($user->anggota_id ?? ($user->id ?? null)); $provinsis = $provinsis ?? collect(); $kotas = $kotas ?? collect(); $kecamatans = $kecamatans ?? collect(); $desas = $desas ?? collect(); $pendidikans = $pendidikans ?? collect(); $statusPekerjaans = $statusPekerjaans ?? collect(); $jabatans = $jabatans ?? collect(); $rolesOperator = [ 'joudie','superadmin', 'dpp','dpdpengurus','dpdoperator', 'dpcpengurus','dpcoperator', 'rantingpengurus','rantingoperator', ]; $canCreate = in_array($roleNorm, $rolesOperator, true); $canDelete = in_array($roleNorm, $rolesOperator, true); $canEditAll = in_array($roleNorm, $rolesOperator, true); $canSeeFilterPanel = in_array($roleNorm, $rolesOperator, true); $canViewNik = in_array($roleNorm, ['joudie', 'superadmin'], true); $req = request(); $reqStatusKartu = $req->get('statuskartu') ?? $req->get('status_kartu'); $advancedKeys = [ 'pendidikanid','idstatus','statusorganisasi','jabatanid', 'statusrumah','kondisirumah','statustanahpekarangan', 'akseslistrik','aksesairbersih','sanitasi', 'bpjskesehatan','bpjsketenagakerjaan','asuransinelayan', 'keanggotaankoperasi','kartukusuka', 'statuskartu','status_kartu', 'cara_pesan_kartu', 'no_kartu_anggota', ]; $hasAdvancedFilter = $req->hasAny($advancedKeys); $roleLabelMap = [ 'joudie' => 'Joudie', 'superadmin' => 'Superadmin', 'dpp' => 'DPP', 'dpdpengurus' => 'DPD Pengurus', 'dpdoperator' => 'DPD Operator', 'dpcpengurus' => 'DPC Pengurus', 'dpcoperator' => 'DPC Operator', 'rantingpengurus' => 'Ranting Pengurus', 'rantingoperator' => 'Ranting Operator', 'anggota' => 'Anggota', 'oprranting' => 'Ranting Operator', ]; $roleRank = [ 'joudie' => 1, 'superadmin' => 2, 'dpp' => 3, 'dpdpengurus' => 4, 'dpdoperator' => 5, 'dpcpengurus' => 6, 'dpcoperator' => 7, 'rantingpengurus' => 8, 'rantingoperator' => 9, 'anggota' => 10, ]; $loginRank = $roleRank[$roleNorm] ?? 99; $canEditByRoleHierarchy = function (?string $targetRoleRaw) use ($roleRank, $loginRank, $roleAliasMap) { $tKey = strtolower(trim((string)($targetRoleRaw ?? 'anggota'))); $tKey = str_replace([' ', '-'], '_', $tKey); $tNorm = $roleAliasMap[$tKey] ?? strtolower(str_replace('_', '', $tKey)); $targetRank = $roleRank[$tNorm] ?? 99; return $targetRank > $loginRank; }; $canSeeByRoleHierarchy = function (?string $targetRoleRaw) use ($roleRank, $loginRank, $roleAliasMap) { $tKey = strtolower(trim((string)($targetRoleRaw ?? 'anggota'))); $tKey = str_replace([' ', '-'], '_', $tKey); $tNorm = $roleAliasMap[$tKey] ?? strtolower(str_replace('_', '', $tKey)); $targetRank = $roleRank[$tNorm] ?? 99; return $targetRank > $loginRank; }; $caraPesanOptions = [ '' => 'Semua', 'manual' => 'Manual', 'online' => 'Online', 'system' => 'System', ]; @endphp {{-- ============================================================================================= BLOK 2: CSS KHUSUS HALAMAN ============================================================================================== --}} {{-- ============================================================================================= BLOK 3: HEADER HALAMAN ============================================================================================== --}}

Database

{{-- ============================================================================================= BLOK 4: ALERT / PESAN SISTEM ============================================================================================== --}} @if(session('success')) @endif @if(session('error')) @endif @if($errors->has('password')) @endif {{-- ============================================================================================= BLOK 5: FILTER DATA ============================================================================================== --}} @if($canSeeFilterPanel)
Filter Data Anggota

Cari data anggota lebih cepat berdasarkan nama, wilayah, status kartu, dan filter lanjutan lainnya.

Reset
Filter lanjutan
Reset
@endif {{-- ============================================================================================= BLOK 5B: TOOLBAR AKSI DI BAWAH FILTER ============================================================================================== --}} @if($canCreate)
Kelola data anggota

Tambahkan data anggota baru setelah menentukan filter atau wilayah yang dibutuhkan.

Tambah Anggota
@endif {{-- ============================================================================================= BLOK 6: PEMBUNGKUS DATA LIST / TABLE ============================================================================================== --}}
@forelse($anggotas as $a) @php $aId = $a->anggotaid ?? ($a->anggota_id ?? ($a->id ?? null)); $nama = $a->namalengkap ?? ($a->nama_lengkap ?? '-'); $nik = $a->nik ?? '-'; $hasFoto = !empty($a->foto); $statusKartu = $a->status_kartu ?? ($a->statuskartu ?? null); $statusKartuNorm = strtolower(trim((string)($statusKartu ?? ''))); $noKartu = trim((string)($a->no_kartu_anggota ?? ($a->nokartuanggota ?? ''))); $noKartuReady = ($noKartu !== ''); $badgeStatusKartu = 'secondary'; if ($statusKartuNorm === 'aktif') $badgeStatusKartu = 'success'; elseif ($statusKartuNorm === 'proses') $badgeStatusKartu = 'primary'; elseif ($statusKartuNorm === 'pesan') $badgeStatusKartu = 'warning'; elseif (!empty($statusKartuNorm)) $badgeStatusKartu = 'info'; $isSelf = ($aId !== null && $userId !== null) ? ((string)$aId === (string)$userId) : false; $aRoleRawLoop = (string)($a->role ?? 'anggota'); $canSeeThis = ($roleNorm === 'anggota' && $isSelf) || ($roleNorm !== 'anggota' && $canSeeByRoleHierarchy($aRoleRawLoop)); if (!$canSeeThis) { continue; } $canEditThis = ($roleNorm === 'anggota' && $isSelf) || ($canEditAll && $canEditByRoleHierarchy($aRoleRawLoop)); $canDeleteThis = ($canDelete && $roleNorm !== 'anggota' && $canEditByRoleHierarchy($aRoleRawLoop)); $aRoleKey = strtolower(trim((string)($a->role ?? ''))); $aRoleKey = str_replace([' ', '-'], '_', $aRoleKey); $aRoleNorm = $roleAliasMap[$aRoleKey] ?? strtolower(str_replace('_', '', $aRoleKey)); $aRoleLabel = $roleLabelMap[$aRoleNorm] ?? ($aRoleKey !== '' ? $aRoleKey : '-'); $thumbUrl = null; if (!empty($a->foto)) { try { $filename = basename((string)$a->foto); $thumbUrl = route('pasfoto.thumb', ['filename' => $filename, 's' => 64]); } catch (\Throwable $e) { $thumbUrl = null; } } $requirePhotoForPrint = false; $canPrint = ($statusKartuNorm === 'aktif' && $noKartuReady && ($requirePhotoForPrint ? $hasFoto : true)); $provId = $a->alamatprovinsiid ?? ($a->alamat_provinsi_id ?? null); $kotaId = $a->alamatkotaid ?? ($a->alamat_kota_id ?? null); $kecId = $a->alamatkecamatanid ?? ($a->alamat_kecamatan_id ?? null); $desaId = $a->alamatdesaid ?? ($a->alamat_desa_id ?? null); $wilayah = collect([ $a->provinsi->name ?? $provId, $a->kota->name ?? $kotaId, $a->kecamatan->name ?? $kecId, $a->desa->name ?? $desaId, ])->filter()->implode(', '); @endphp
{{ $aRoleLabel }} @if($thumbUrl) Foto {{ $nama }} @else @endif
@if(!empty($statusKartu)) {{ ucfirst($statusKartu) }} @endif
#{{ ($anggotas->firstItem() ?? 0) + $loop->index }}
{{ $nama }}
No. Kartu: {{ $noKartuReady ? $noKartu : '-' }}
{{ $wilayah ?: '-' }}
@if($statusKartuNorm === 'aktif' && !$canPrint)
Kartu belum siap dicetak
@endif
@empty
Belum ada data anggota.
@endforelse
@php $shownDesktop = 0; @endphp @forelse($anggotas as $a) @php $aId = $a->anggotaid ?? ($a->anggota_id ?? ($a->id ?? null)); $nama = $a->namalengkap ?? ($a->nama_lengkap ?? '-'); $nik = $a->nik ?? '-'; $hasFoto = !empty($a->foto); $statusKartu = $a->status_kartu ?? ($a->statuskartu ?? null); $statusKartuNorm = strtolower(trim((string)($statusKartu ?? ''))); $noKartu = trim((string)($a->no_kartu_anggota ?? ($a->nokartuanggota ?? ''))); $noKartuReady = ($noKartu !== ''); $badgeStatusKartu = 'secondary'; if ($statusKartuNorm === 'aktif') $badgeStatusKartu = 'success'; elseif ($statusKartuNorm === 'proses') $badgeStatusKartu = 'primary'; elseif ($statusKartuNorm === 'pesan') $badgeStatusKartu = 'warning'; elseif (!empty($statusKartuNorm)) $badgeStatusKartu = 'info'; $isSelf = ($aId !== null && $userId !== null) ? ((string)$aId === (string)$userId) : false; $aRoleRawLoop = (string)($a->role ?? 'anggota'); $canSeeThis = ($roleNorm === 'anggota' && $isSelf) || ($roleNorm !== 'anggota' && $canSeeByRoleHierarchy($aRoleRawLoop)); if (!$canSeeThis) { continue; } $shownDesktop++; $canEditThis = ($roleNorm === 'anggota' && $isSelf) || ($canEditAll && $canEditByRoleHierarchy($aRoleRawLoop)); $canDeleteThis = ($canDelete && $roleNorm !== 'anggota' && $canEditByRoleHierarchy($aRoleRawLoop)); $aRoleKey = strtolower(trim((string)($a->role ?? ''))); $aRoleKey = str_replace([' ', '-'], '_', $aRoleKey); $aRoleNorm = $roleAliasMap[$aRoleKey] ?? strtolower(str_replace('_', '', $aRoleKey)); $aRoleLabel = $roleLabelMap[$aRoleNorm] ?? ($aRoleKey !== '' ? $aRoleKey : '-'); $thumbUrl = null; if (!empty($a->foto)) { try { $filename = basename((string)$a->foto); $thumbUrl = route('pasfoto.thumb', ['filename' => $filename, 's' => 64]); } catch (\Throwable $e) { $thumbUrl = null; } } $requirePhotoForPrint = false; $canPrint = ($statusKartuNorm === 'aktif' && $noKartuReady && ($requirePhotoForPrint ? $hasFoto : true)); $provId = $a->alamatprovinsiid ?? ($a->alamat_provinsi_id ?? null); $kotaId = $a->alamatkotaid ?? ($a->alamat_kota_id ?? null); $kecId = $a->alamatkecamatanid ?? ($a->alamat_kecamatan_id ?? null); $desaId = $a->alamatdesaid ?? ($a->alamat_desa_id ?? null); @endphp @empty @endforelse @if(($anggotas->count() ?? 0) > 0 && $shownDesktop === 0) @endif
No Status Kartu Identitas Aksi
{{ $shownDesktop }} @if($canPrint) KARTU @elseif($statusKartuNorm === 'aktif') Kartu belum siap @endif
{{ $statusKartu ?: '-' }}
@if($thumbUrl) Foto {{ $nama }} @else @endif
{{ $nama }}
{{ $a->provinsi->name ?? $provId }}, {{ $a->kota->name ?? $kotaId }}, {{ $a->kecamatan->name ?? $kecId }}, {{ $a->desa->name ?? $desaId }}
@if($canViewNik) NIK: {{ $nik }} @if($noKartuReady) | Kartu: {{ $noKartu }} @endif @else @if($noKartuReady) Kartu: {{ $noKartu }} @else No. Kartu: - @endif @endif
{{ $aRoleLabel }}
Detail @if($canEditThis) Edit @else @endif @if($canDeleteThis) @elseif($canDelete && $roleNorm !== 'anggota') @endif
Belum ada data anggota.
Tidak ada data anggota yang boleh Anda lihat.
Menampilkan {{ $anggotas->firstItem() ?? 0 }} sampai {{ $anggotas->lastItem() ?? 0 }} dari {{ $anggotas->total() }} data anggota.
{{ $anggotas->appends(request()->query())->links() }}
{{-- ============================================================================================= BLOK 7: PANEL HAPUS CUSTOM TANPA MODAL BOOTSTRAP ============================================================================================= --}}
@endsection @push('scripts') @endpush