796 lines
46 KiB
PHP
796 lines
46 KiB
PHP
@extends('layout.app')
|
|
|
|
@section('content')
|
|
<div class="page-header">
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item">Home</li>
|
|
<li class="breadcrumb-item active">Data Warga</li>
|
|
</ol>
|
|
</div>
|
|
|
|
{{-- NOTIFIKASI --}}
|
|
@if (session('error'))
|
|
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
|
<i class="icon-warning"></i> {{ session('error') }}
|
|
<button type="button" class="close" data-dismiss="alert"><span>×</span></button>
|
|
</div>
|
|
@endif
|
|
|
|
<div class="row gutters">
|
|
<div class="col-12">
|
|
|
|
{{-- VISUAL SEARCH & FILTER PANEL --}}
|
|
<div class="card shadow-sm border-0 mb-4">
|
|
<div class="card-header bg-white">
|
|
<div class="card-title text-primary"><i class="icon-search"></i> Panel Pencarian & Filter</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<form action="{{ route('warga.index') }}" method="GET" id="filterForm">
|
|
<input type="hidden" name="per_page" value="{{ request('per_page', 10) }}">
|
|
{{-- Simpan status saat ini agar filter tidak hilang saat nge-search --}}
|
|
<input type="hidden" name="status" value="{{ request('status') }}">
|
|
|
|
<div class="row gutters">
|
|
<div class="col-xl-4 col-lg-4 col-md-12 col-sm-12 col-12">
|
|
<div class="form-group">
|
|
<label class="font-weight-bold small">Cari Nama atau NIK</label>
|
|
<div class="input-group">
|
|
<div class="input-group-prepend">
|
|
<span class="input-group-text"><i class="icon-user"></i></span>
|
|
</div>
|
|
<input type="text" name="search" id="filterSearch" class="form-control"
|
|
placeholder="Nama / NIK..." value="{{ request('search') }}">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-1 col-lg-2 col-md-3 col-sm-6 col-6">
|
|
<div class="form-group">
|
|
<label class="font-weight-bold small">RT</label>
|
|
<input type="text" name="rt" id="filterRT" class="form-control"
|
|
placeholder="001" value="{{ request('rt') }}" maxlength="3">
|
|
</div>
|
|
</div>
|
|
<div class="col-xl-1 col-lg-2 col-md-3 col-sm-6 col-6">
|
|
<div class="form-group">
|
|
<label class="font-weight-bold small">RW</label>
|
|
<input type="text" name="rw" id="filterRW" class="form-control"
|
|
placeholder="001" value="{{ request('rw') }}" maxlength="3">
|
|
</div>
|
|
</div>
|
|
@foreach ($kriterias->take(2) as $k)
|
|
<div class="col-xl-2 col-lg-2 col-md-3 col-sm-12 col-12">
|
|
<div class="form-group">
|
|
<label class="font-weight-bold small">{{ $k->nama }}</label>
|
|
<select name="f_kriteria_{{ $k->id }}" class="form-control">
|
|
<option value="">Semua</option>
|
|
@foreach ($k->subKriterias as $sub)
|
|
<option value="{{ $sub->nama_sub }}"
|
|
{{ request('f_kriteria_' . $k->id) == $sub->nama_sub ? 'selected' : '' }}>
|
|
{{ $sub->nama_sub }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
<div class="col-xl-2 col-lg-2 col-md-3 col-sm-12 col-12 d-flex align-items-end">
|
|
<div class="form-group w-100">
|
|
<button type="submit" class="btn btn-primary btn-block">Cari</button>
|
|
<a href="{{ route('warga.index', ['status' => request('status')]) }}"
|
|
class="btn btn-outline-secondary btn-block btn-sm mt-1">Reset</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-body">
|
|
{{-- HEADER --}}
|
|
<div class="mb-3 d-flex justify-content-between align-items-center flex-wrap">
|
|
<div>
|
|
<h5 class="mb-0 text-dark font-weight-bold">Data Calon Penerima Bantuan</h5>
|
|
<p class="text-muted small mb-0">Total: <strong>{{ $wargas->total() }}</strong> KK Ditemukan
|
|
</p>
|
|
</div>
|
|
<div class="d-flex gap-2 mt-2 mt-md-0">
|
|
{{-- TOMBOL AKSI MASSAL (Hidden by default) --}}
|
|
@if (auth()->user()->role == 'admin')
|
|
<button type="button" id="btnBulkUpdate"
|
|
class="btn btn-warning btn-sm mr-2 d-none shadow-sm" data-toggle="modal"
|
|
data-target="#modalBulkUpdate">
|
|
<i class="icon-edit"></i> Edit Massal (<span id="selectedCount"
|
|
class="font-weight-bold">0</span>)
|
|
</button>
|
|
|
|
{{-- TAMBAHAN TOMBOL HAPUS MASSAL --}}
|
|
<button type="button" id="btnBulkDelete"
|
|
class="btn btn-danger btn-sm mr-2 d-none shadow-sm">
|
|
<i class="icon-trash-2"></i> Hapus Massal (<span id="deleteCount"
|
|
class="font-weight-bold">0</span>)
|
|
</button>
|
|
@endif
|
|
|
|
<button type="button" class="btn btn-outline-success btn-sm mr-2" data-toggle="modal"
|
|
data-target="#exportModal">
|
|
<i class="icon-file-text"></i> Export Excel
|
|
</button>
|
|
|
|
{{-- Hanya Admin yang bisa Import dan Tambah --}}
|
|
@if (auth()->user()->role == 'admin')
|
|
<button type="button" class="btn btn-outline-primary btn-sm mr-2" data-toggle="modal"
|
|
data-target="#importModal">
|
|
<i class="icon-upload"></i> Import
|
|
</button>
|
|
<a href="{{ route('warga.create') }}" class="btn btn-success btn-sm">
|
|
<i class="icon-plus"></i> Tambah
|
|
</a>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
{{-- FILTER CEPAT BERDASARKAN STATUS (QUICK PILLS) --}}
|
|
<div class="d-flex flex-wrap gap-2 mb-4 pb-3 border-bottom">
|
|
<a href="{{ request()->fullUrlWithQuery(['status' => null, 'page' => 1]) }}"
|
|
class="btn btn-sm mr-2 {{ !request('status') ? 'btn-primary shadow-sm' : 'btn-outline-primary' }} rounded-pill px-3">
|
|
Semua Data
|
|
</a>
|
|
<a href="{{ request()->fullUrlWithQuery(['status' => 'pending', 'page' => 1]) }}"
|
|
class="btn btn-sm mr-2 {{ request('status') == 'pending' ? 'btn-warning text-dark shadow-sm' : 'btn-outline-warning text-dark' }} rounded-pill px-3">
|
|
<i class="icon-clock"></i> Pending (Antrean)
|
|
</a>
|
|
<a href="{{ request()->fullUrlWithQuery(['status' => 'setuju', 'page' => 1]) }}"
|
|
class="btn btn-sm mr-2 {{ request('status') == 'setuju' ? 'btn-success shadow-sm' : 'btn-outline-success' }} rounded-pill px-3">
|
|
<i class="icon-check-circle"></i> Disetujui
|
|
</a>
|
|
<a href="{{ request()->fullUrlWithQuery(['status' => 'tolak', 'page' => 1]) }}"
|
|
class="btn btn-sm {{ request('status') == 'tolak' ? 'btn-danger shadow-sm' : 'btn-outline-danger' }} rounded-pill px-3">
|
|
<i class="icon-x-circle"></i> Ditolak
|
|
</a>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-between mb-3">
|
|
<form action="{{ route('warga.index') }}" method="GET" class="d-flex align-items-center">
|
|
{{-- Pertahankan semua parameter pencarian --}}
|
|
<input type="hidden" name="search" value="{{ request('search') }}">
|
|
<input type="hidden" name="rt" value="{{ request('rt') }}">
|
|
<input type="hidden" name="rw" value="{{ request('rw') }}">
|
|
<input type="hidden" name="status" value="{{ request('status') }}">
|
|
@foreach ($kriterias->take(2) as $k)
|
|
@if (request('f_kriteria_' . $k->id))
|
|
<input type="hidden" name="f_kriteria_{{ $k->id }}"
|
|
value="{{ request('f_kriteria_' . $k->id) }}">
|
|
@endif
|
|
@endforeach
|
|
|
|
<select name="per_page" class="form-control form-control-sm" onchange="this.form.submit()">
|
|
@foreach ([10, 25, 50, 100, 500] as $size)
|
|
<option value="{{ $size }}"
|
|
{{ request('per_page') == $size ? 'selected' : '' }}>{{ $size }}</option>
|
|
@endforeach
|
|
</select>
|
|
<span class="ml-2 small">halaman</span>
|
|
</form>
|
|
|
|
{{-- Link Template hanya untuk Admin --}}
|
|
@if (auth()->user()->role == 'admin')
|
|
<a href="{{ route('warga.download_template') }}"
|
|
class="btn btn-link text-info btn-sm font-weight-bold"><i class="icon-download"></i>
|
|
Unduh Template Excel</a>
|
|
@endif
|
|
</div>
|
|
|
|
<style>
|
|
.table-wide {
|
|
white-space: nowrap;
|
|
font-size: 0.82rem;
|
|
}
|
|
|
|
.table-wide th {
|
|
background: #f8f9fa;
|
|
text-transform: uppercase;
|
|
font-size: 10px;
|
|
vertical-align: middle !important;
|
|
}
|
|
|
|
.sticky-col {
|
|
position: sticky;
|
|
left: 0;
|
|
background: white !important;
|
|
z-index: 10;
|
|
border-right: 2px solid #dee2e6 !important;
|
|
}
|
|
|
|
.badge-status {
|
|
min-width: 80px;
|
|
}
|
|
|
|
.nik-code {
|
|
font-family: monospace;
|
|
color: #e83e8c;
|
|
}
|
|
|
|
.doc-preview-img {
|
|
width: 100%;
|
|
height: 150px;
|
|
object-fit: cover;
|
|
border-radius: 8px;
|
|
margin-bottom: 10px;
|
|
border: 1px solid #ddd;
|
|
}
|
|
|
|
.doc-card {
|
|
border: none;
|
|
background: #fff;
|
|
border-radius: 12px;
|
|
transition: transform 0.2s;
|
|
}
|
|
|
|
.doc-card:hover {
|
|
transform: translateY(-5px);
|
|
}
|
|
|
|
.modal-body-scroll {
|
|
max-height: 70vh;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
/* Styling Checkbox Massal */
|
|
.checkbox-massal {
|
|
width: 16px;
|
|
height: 16px;
|
|
cursor: pointer;
|
|
}
|
|
</style>
|
|
|
|
<div class="table-responsive border rounded">
|
|
<table class="table table-hover table-bordered table-wide mb-0">
|
|
<thead>
|
|
<tr class="text-center">
|
|
{{-- Kolom Checkbox Tambahan --}}
|
|
@if (auth()->user()->role == 'admin')
|
|
<th width="40" class="sticky-col text-center bg-light">
|
|
Pilih semua <br> <br>
|
|
<input type="checkbox" id="selectAllWarga" class="checkbox-massal"
|
|
title="Pilih Semua">
|
|
</th>
|
|
@endif
|
|
|
|
<th width="50" class="sticky-col">No</th>
|
|
<th class="sticky-col">Nama Lengkap</th>
|
|
<th>NIK</th>
|
|
<th>RT/RW</th>
|
|
@foreach ($kriterias as $k)
|
|
<th class="text-center">
|
|
<span class="d-block">{{ $k->nama }}</span>
|
|
<small class="text-muted font-weight-normal"
|
|
style="text-transform: capitalize; display: block; margin-top: 2px;">
|
|
{{ $k->kode }}
|
|
</small>
|
|
</th>
|
|
@endforeach
|
|
<th>Status</th>
|
|
<th>Catatan</th>
|
|
<th>Dokumen</th>
|
|
<th>Status Warga</th>
|
|
{{-- Kolom Aksi Hanya untuk Admin --}}
|
|
@if (auth()->user()->role == 'admin')
|
|
<th>Aksi</th>
|
|
@endif
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse ($wargas as $index => $w)
|
|
<tr class="{{ $w->status_verifikasi == 'tolak' ? 'bg-light' : '' }}">
|
|
{{-- Checkbox Tiap Warga --}}
|
|
@if (auth()->user()->role == 'admin')
|
|
<td class="text-center sticky-col">
|
|
<input type="checkbox" class="warga-checkbox checkbox-massal"
|
|
value="{{ $w->id }}">
|
|
</td>
|
|
@endif
|
|
|
|
<td class="text-center sticky-col">{{ $wargas->firstItem() + $index }}</td>
|
|
|
|
<td class="font-weight-bold sticky-col">
|
|
{{ $w->nama }}
|
|
@if ($w->status_verifikasi == 'tolak')
|
|
<i class="icon-alert-circle text-danger ml-1"
|
|
title="Data ditolak, cek catatan"></i>
|
|
@endif
|
|
</td>
|
|
|
|
<td class="nik-code">{{ $w->nik }}</td>
|
|
<td class="text-center">{{ $w->rt }}/{{ $w->rw }}</td>
|
|
|
|
@foreach ($kriterias as $k)
|
|
@php $detail = $w->details->firstWhere('kriteria_id', $k->id); @endphp
|
|
<td class="text-center">{{ $detail->nilai_asli ?? '-' }}</td>
|
|
@endforeach
|
|
|
|
<td class="text-center">
|
|
@php $badges = ['pending' => 'badge-warning text-dark', 'setuju' => 'badge-success text-white', 'tolak' => 'badge-danger text-white']; @endphp
|
|
<span
|
|
class="badge {{ $badges[$w->status_verifikasi] ?? 'badge-secondary' }} p-2 badge-status"
|
|
title="{{ $w->catatan ?? '' }}">
|
|
{{ strtoupper($w->status_verifikasi) }}
|
|
</span>
|
|
</td>
|
|
|
|
<td style="white-space: normal; min-width: 200px;">
|
|
@if ($w->catatan)
|
|
<small
|
|
class="{{ $w->status_verifikasi == 'tolak' ? 'text-danger font-weight-bold' : 'text-muted' }}">
|
|
{{ $w->catatan }}
|
|
</small>
|
|
@else
|
|
<span class="text-muted small">-</span>
|
|
@endif
|
|
</td>
|
|
|
|
<td class="text-center">
|
|
@if ($w->dokumen_pendukung && is_array($w->dokumen_pendukung) && count($w->dokumen_pendukung) > 0)
|
|
<button type="button" class="btn btn-outline-info btn-xs"
|
|
data-toggle="modal" data-target="#viewDoc{{ $w->id }}">
|
|
<i class="icon-eye"></i> {{ count($w->dokumen_pendukung) }} File
|
|
</button>
|
|
|
|
{{-- MODAL LIHAT DOKUMEN --}}
|
|
<div class="modal fade" id="viewDoc{{ $w->id }}" tabindex="-1"
|
|
role="dialog">
|
|
<div class="modal-dialog modal-lg" role="document">
|
|
<div class="modal-content border-0 shadow-lg">
|
|
<div class="modal-header bg-dark text-white">
|
|
<h5 class="modal-title text-white">Dokumen:
|
|
{{ $w->nama }}</h5>
|
|
<button type="button" class="close text-white"
|
|
data-dismiss="modal"><span>×</span></button>
|
|
</div>
|
|
<div class="modal-body bg-light px-4 modal-body-scroll text-left"
|
|
style="white-space: normal;">
|
|
|
|
@if ($w->status_verifikasi == 'tolak')
|
|
<div
|
|
class="alert alert-danger py-2 px-3 mb-3 border-0">
|
|
<strong><i class="icon-x-circle mr-1"></i> Alasan
|
|
Ditolak:</strong>
|
|
{{ $w->catatan ?: 'Tidak ada catatan spesifik.' }}
|
|
</div>
|
|
@endif
|
|
|
|
<div class="row">
|
|
@foreach ($w->dokumen_pendukung as $file)
|
|
<div class="col-lg-4 col-md-6 col-sm-12 mb-4">
|
|
<div class="card doc-card shadow-sm h-100">
|
|
<div
|
|
class="card-body p-3 text-center d-flex flex-column">
|
|
@if (Str::endsWith($file, '.pdf'))
|
|
<div
|
|
class="py-4 bg-white rounded mb-2 border">
|
|
<i
|
|
class="icon-file-text h1 text-danger"></i>
|
|
<p
|
|
class="small text-muted mt-2 text-truncate px-2">
|
|
{{ basename($file) }}</p>
|
|
</div>
|
|
@else
|
|
<img src="{{ asset('storage/' . $file) }}"
|
|
class="doc-preview-img shadow-sm">
|
|
@endif
|
|
<div class="mt-auto">
|
|
<div class="btn-group w-100">
|
|
<a href="{{ asset('storage/' . $file) }}"
|
|
target="_blank"
|
|
class="btn btn-primary btn-xs mr-1"><i
|
|
class="icon-zoom-in"></i>
|
|
Lihat</a>
|
|
<a href="{{ asset('storage/' . $file) }}"
|
|
download
|
|
class="btn btn-success btn-xs"><i
|
|
class="icon-download"></i>
|
|
Unduh</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer bg-light border-0">
|
|
@if ($w->status_verifikasi == 'tolak')
|
|
<a href="{{ route('warga.edit', $w->id) }}"
|
|
class="btn btn-danger btn-sm px-4 mr-auto"><i
|
|
class="icon-edit"></i> Edit Data Sekarang</a>
|
|
@endif
|
|
<button type="button"
|
|
class="btn btn-secondary btn-sm px-4"
|
|
data-dismiss="modal">Tutup</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@else
|
|
<span class="text-muted small">-</span>
|
|
@endif
|
|
</td>
|
|
<td class="text-center">
|
|
@php
|
|
$badgesRiil = [
|
|
'aktif' => 'badge-success',
|
|
'meninggal' => 'badge-dark',
|
|
'pindah' => 'badge-warning text-dark',
|
|
'mampu' => 'badge-info',
|
|
];
|
|
@endphp
|
|
<span
|
|
class="badge {{ $badgesRiil[$w->status_bansos_riil] ?? 'badge-secondary' }} p-2"
|
|
style="min-width: 80px;">
|
|
{{ strtoupper($w->status_bansos_riil) }}
|
|
</span>
|
|
</td>
|
|
|
|
@if (auth()->user()->role == 'admin')
|
|
<td class="text-center">
|
|
<div class="d-flex justify-content-center">
|
|
<a href="{{ route('warga.edit', $w->id) }}"
|
|
class="btn btn-primary btn-xs mr-1"><i class="icon-edit1"></i></a>
|
|
<form action="{{ route('warga.destroy', $w->id) }}" method="POST"
|
|
class="delete-form">
|
|
@csrf @method('DELETE')
|
|
<button type="button"
|
|
class="btn btn-danger btn-xs btn-delete-confirm"><i
|
|
class="icon-trash-2"></i></button>
|
|
</form>
|
|
</div>
|
|
</td>
|
|
@endif
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="{{ (auth()->user()->role == 'admin' ? 11 : 9) + $kriterias->count() }}"
|
|
class="text-center py-5 text-muted">
|
|
<i class="icon-folder-minus h1 d-block mb-3"></i>
|
|
Tidak ada data warga yang sesuai dengan filter.
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="mt-4 d-flex justify-content-center">
|
|
{{ $wargas->appends(request()->all())->links('pagination::bootstrap-4') }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- FORM HIDDEN UNTUK HAPUS MASSAL --}}
|
|
@if (auth()->user()->role == 'admin')
|
|
<form action="{{ route('warga.bulk-delete') }}" method="POST" id="formBulkDelete" class="d-none">
|
|
@csrf
|
|
@method('DELETE')
|
|
<input type="hidden" name="ids" id="ids_to_delete">
|
|
</form>
|
|
@endif
|
|
|
|
{{-- MODAL BULK UPDATE (Hanya Admin) --}}
|
|
@if (auth()->user()->role == 'admin')
|
|
<div class="modal fade" id="modalBulkUpdate" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog" role="document">
|
|
<form action="{{ route('warga.bulk-update') }}" method="POST">
|
|
@csrf
|
|
<div class="modal-content border-0 shadow-lg">
|
|
<div class="modal-header bg-warning text-dark">
|
|
<h5 class="modal-title font-weight-bold"><i class="icon-edit"></i> Update Kriteria Massal</h5>
|
|
<button type="button" class="close" data-dismiss="modal"><span>×</span></button>
|
|
</div>
|
|
<div class="modal-body px-4">
|
|
<input type="hidden" name="ids" id="ids_to_update">
|
|
|
|
<div class="alert alert-info border-0 shadow-sm mb-3">
|
|
<i class="icon-info"></i> Anda akan memperbarui <strong id="modalSelectedCount">0</strong>
|
|
data warga sekaligus.
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="font-weight-bold small">Pilih Kriteria yang Akan Diubah</label>
|
|
<select name="kriteria_id" id="bulk_kriteria_id" class="form-control" required>
|
|
<option value="">-- Pilih Kriteria --</option>
|
|
@foreach ($kriterias as $k)
|
|
<option value="{{ $k->id }}">{{ $k->nama }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label class="font-weight-bold small">Pilih Kondisi / Sub-Kriteria Baru</label>
|
|
<select name="sub_kriteria_id" id="bulk_sub_kriteria_id" class="form-control" required
|
|
disabled>
|
|
<option value="">-- Pilih Kriteria Terlebih Dahulu --</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer bg-light">
|
|
<button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">Batal</button>
|
|
<button type="submit" class="btn btn-warning btn-sm px-4 font-weight-bold">Simpan Perubahan
|
|
Massal</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
{{-- MODAL EXPORT CONFIRMATION (Admin & Verifikator Bisa) --}}
|
|
<div class="modal fade" id="exportModal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content border-0 shadow-lg">
|
|
<div class="modal-header bg-success text-white">
|
|
<h5 class="modal-title text-white"><i class="icon-file-text"></i> Konfirmasi Export Excel</h5>
|
|
<button type="button" class="close text-white" data-dismiss="modal"><span>×</span></button>
|
|
</div>
|
|
<div class="modal-body text-center py-4">
|
|
<p class="mb-1">Anda akan mengekspor data dengan filter saat ini:</p>
|
|
<div class="p-3 bg-light rounded mb-3">
|
|
<h6 class="font-weight-bold text-dark mb-0" id="exportFilterInfo">Semua Data</h6>
|
|
<small class="text-muted">Total: <strong>{{ $wargas->total() }}</strong> baris data
|
|
ditemukan</small>
|
|
</div>
|
|
<p class="small text-muted">Pastikan filter sudah sesuai sebelum melanjutkan.</p>
|
|
</div>
|
|
<div class="modal-footer bg-light">
|
|
<button type="button" class="btn btn-secondary btn-sm px-4" data-dismiss="modal">Batal</button>
|
|
<a id="btnConfirmExport" href="{{ route('warga.export', request()->all()) }}"
|
|
class="btn btn-success btn-sm px-4">
|
|
<i class="icon-download"></i> <span id="textExport">Download Sekarang</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{{-- MODAL IMPORT (Hanya Admin) --}}
|
|
@if (auth()->user()->role == 'admin')
|
|
<div class="modal fade" id="importModal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog" role="document">
|
|
<div class="modal-content border-0 shadow-lg">
|
|
<div class="modal-header bg-primary text-white">
|
|
<h5 class="modal-title text-white">Import Data Warga</h5>
|
|
<button type="button" class="close text-white"
|
|
data-dismiss="modal"><span>×</span></button>
|
|
</div>
|
|
<form action="{{ route('warga.import') }}" method="POST" enctype="multipart/form-data"
|
|
id="importForm">
|
|
@csrf
|
|
<div class="modal-body px-4">
|
|
<div class="alert alert-warning border-0 shadow-sm mb-3">
|
|
<div class="d-flex text-left">
|
|
<div class="mr-2"><i class="icon-alert-triangle" style="font-size: 1.2rem;"></i>
|
|
</div>
|
|
<div>
|
|
<strong class="d-block mb-1 text-dark">Perhatian:</strong>
|
|
<ul class="pl-3 mb-0 small text-dark" style="line-height: 1.6;">
|
|
<li>Gunakan file template <strong>.xlsx</strong> yang sudah disediakan.</li>
|
|
<li>Pastikan data setiap kolom sudah sesuai dengan format.</li>
|
|
<li>Maksimal ukuran file adalah 2MB.</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group text-left">
|
|
<label class="font-weight-bold small">Pilih File Excel/CSV</label>
|
|
<input type="file" name="file_excel" class="form-control" required
|
|
accept=".xlsx, .xls, .csv">
|
|
</div>
|
|
<div class="text-left">
|
|
<a href="{{ route('warga.download_template') }}"
|
|
class="small font-weight-bold text-info">
|
|
<i class="icon-download"></i> Belum Punya Template? Silahkan Unduh Template disini
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer bg-light">
|
|
<button type="button" class="btn btn-secondary btn-sm" data-dismiss="modal">Batal</button>
|
|
<button type="submit" class="btn btn-success btn-sm px-4" id="btnImport">Proses
|
|
Import</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
|
|
// --- LOGIKA BULK UPDATE & DELETE (AKSI MASSAL) ---
|
|
const $selectAll = $('#selectAllWarga');
|
|
const $checkboxes = $('.warga-checkbox');
|
|
const $btnBulkUpdate = $('#btnBulkUpdate');
|
|
const $btnBulkDelete = $('#btnBulkDelete'); // Tombol hapus massal
|
|
const $selectedCount = $('#selectedCount');
|
|
const $deleteCount = $('#deleteCount');
|
|
const $modalCount = $('#modalSelectedCount');
|
|
const $idsUpdateInput = $('#ids_to_update');
|
|
const $idsDeleteInput = $('#ids_to_delete');
|
|
|
|
function updateBulkButton() {
|
|
let selected = $('.warga-checkbox:checked').map(function() {
|
|
return $(this).val();
|
|
}).get();
|
|
|
|
let count = selected.length;
|
|
|
|
if (count > 0) {
|
|
$btnBulkUpdate.removeClass('d-none');
|
|
$btnBulkDelete.removeClass('d-none'); // Munculkan tombol hapus
|
|
$selectedCount.text(count);
|
|
$deleteCount.text(count);
|
|
$modalCount.text(count);
|
|
|
|
let joinedIds = selected.join(',');
|
|
$idsUpdateInput.val(joinedIds);
|
|
$idsDeleteInput.val(joinedIds); // Isi hidden input hapus massal
|
|
} else {
|
|
$btnBulkUpdate.addClass('d-none');
|
|
$btnBulkDelete.addClass('d-none'); // Sembunyikan tombol hapus
|
|
$idsUpdateInput.val('');
|
|
$idsDeleteInput.val('');
|
|
}
|
|
}
|
|
|
|
$selectAll.on('change', function() {
|
|
$checkboxes.prop('checked', $(this).prop('checked'));
|
|
updateBulkButton();
|
|
});
|
|
|
|
$checkboxes.on('change', function() {
|
|
if (!$(this).prop('checked')) {
|
|
$selectAll.prop('checked', false);
|
|
}
|
|
updateBulkButton();
|
|
});
|
|
|
|
// Konfirmasi Hapus Massal SweetAlert
|
|
$btnBulkDelete.on('click', function() {
|
|
Swal.fire({
|
|
title: 'Hapus Massal?',
|
|
text: $deleteCount.text() +
|
|
" data warga yang dipilih akan dihapus permanen beserta dokumennya!",
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#d33',
|
|
cancelButtonColor: '#858796',
|
|
confirmButtonText: 'Ya, Hapus Semua!',
|
|
cancelButtonText: 'Batal'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
$('#formBulkDelete').submit();
|
|
}
|
|
});
|
|
});
|
|
|
|
// --- PERBAIKAN AJAX 404 DI HOSTING ---
|
|
$('#bulk_kriteria_id').on('change', function() {
|
|
let k_id = $(this).val();
|
|
let $subSelect = $('#bulk_sub_kriteria_id');
|
|
|
|
if (k_id) {
|
|
$subSelect.prop('disabled', true).html('<option value="">Memuat...</option>');
|
|
$.ajax({
|
|
// MENGGUNAKAN HELPER url() AGAR ALAMATNYA DINAMIS MENGIKUTI HOSTING
|
|
url: '{{ url('subkriteria/get-by-kriteria') }}/' + k_id,
|
|
type: 'GET',
|
|
success: function(data) {
|
|
let options = '<option value="">-- Pilih Kondisi Baru --</option>';
|
|
$.each(data, function(index, item) {
|
|
options +=
|
|
`<option value="${item.id}">${item.nama_sub}</option>`;
|
|
});
|
|
$subSelect.html(options).prop('disabled', false);
|
|
},
|
|
error: function() {
|
|
$subSelect.html('<option value="">Gagal memuat data</option>');
|
|
}
|
|
});
|
|
} else {
|
|
$subSelect.html('<option value="">-- Pilih Kriteria Terlebih Dahulu --</option>').prop(
|
|
'disabled', true);
|
|
}
|
|
});
|
|
// --- END LOGIKA BULK UPDATE ---
|
|
|
|
// Modal Export Info Update
|
|
$('#exportModal').on('show.bs.modal', function() {
|
|
const rt = document.getElementById('filterRT').value;
|
|
const rw = document.getElementById('filterRW').value;
|
|
const search = document.getElementById('filterSearch').value;
|
|
let info = "Semua Data";
|
|
if (rt && rw) {
|
|
info = `Data RT ${rt} / RW ${rw}`;
|
|
} else if (rt) {
|
|
info = `Data RT ${rt}`;
|
|
} else if (rw) {
|
|
info = `Data RW ${rw}`;
|
|
}
|
|
if (search) {
|
|
info += ` | "${search}"`;
|
|
}
|
|
document.getElementById('exportFilterInfo').innerText = info;
|
|
});
|
|
|
|
// Export Process Notification
|
|
const btnExport = document.getElementById('btnConfirmExport');
|
|
const textExport = document.getElementById('textExport');
|
|
if (btnExport) {
|
|
btnExport.addEventListener('click', function() {
|
|
textExport.innerText = "Sedang Memproses...";
|
|
btnExport.classList.add('disabled');
|
|
btnExport.style.pointerEvents = 'none';
|
|
setTimeout(() => {
|
|
$('#exportModal').modal('hide');
|
|
textExport.innerText = "Download Sekarang";
|
|
btnExport.classList.remove('disabled');
|
|
btnExport.style.pointerEvents = 'auto';
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: 'Export Berhasil!',
|
|
text: 'File data warga sedang diunduh.',
|
|
timer: 3000,
|
|
toast: true,
|
|
position: 'top-end',
|
|
showConfirmButton: false
|
|
});
|
|
}, 2000);
|
|
});
|
|
}
|
|
|
|
// Delete Confirmation (Hanya Admin)
|
|
const deleteButtons = document.querySelectorAll('.btn-delete-confirm');
|
|
deleteButtons.forEach(button => {
|
|
button.addEventListener('click', function() {
|
|
const form = this.closest('.delete-form');
|
|
Swal.fire({
|
|
title: 'Hapus data?',
|
|
text: "Data warga dan file dokumen akan ikut terhapus selamanya!",
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#d33',
|
|
confirmButtonText: 'Ya, Hapus!',
|
|
cancelButtonText: 'Batal'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) form.submit();
|
|
});
|
|
});
|
|
});
|
|
|
|
// Import Loading State
|
|
const importForm = document.getElementById('importForm');
|
|
const btnImport = document.getElementById('btnImport');
|
|
if (importForm) {
|
|
importForm.addEventListener('submit', function() {
|
|
btnImport.innerHTML =
|
|
'<span class="spinner-border spinner-border-sm"></span> Mengimport...';
|
|
btnImport.disabled = true;
|
|
});
|
|
}
|
|
|
|
@if (session('success'))
|
|
Swal.fire({
|
|
icon: 'success',
|
|
title: 'Berhasil!',
|
|
text: "{{ session('success') }}",
|
|
timer: 3000,
|
|
toast: true,
|
|
position: 'top-end',
|
|
showConfirmButton: false
|
|
});
|
|
@endif
|
|
});
|
|
</script>
|
|
@endsection
|