CRUD area & gate, statistik pengunjung per pintu, laporan okupansi area
This commit is contained in:
@@ -24,6 +24,14 @@
|
||||
.text-label {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
#example tbody tr:not(.edit-row) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#example tbody tr.table-active td {
|
||||
background-color: #e7f1ff;
|
||||
}
|
||||
/*
|
||||
.table-selectable tbody tr {
|
||||
cursor: pointer;
|
||||
@@ -66,6 +74,7 @@
|
||||
<th style="text-align: center;">Mode Pintu</th>
|
||||
<th style="text-align: center;">Grace Periode</th>
|
||||
<th style="text-align: center;">Manless?</th>
|
||||
<th style="text-align: center;" width="15%">Area Parkir</th>
|
||||
<th style="text-align: center;">Pengaturan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -82,10 +91,17 @@
|
||||
? '<span class="d-inline-block rounded-circle bg-success" style="width:12px;height:12px;"></span>'
|
||||
: '<span class="d-inline-block rounded-circle bg-danger" style="width:12px;height:12px;"></span>';
|
||||
@endphp
|
||||
<tr>
|
||||
<tr data-gate-id="{{ $pintu->id }}"
|
||||
data-gate-nama="{{ $pintu->nama }}"
|
||||
data-gate-jenis="{{ $pintu->jenis }}"
|
||||
data-gate-grace="{{ $pintu->grace_period }}"
|
||||
data-gate-manless="{{ $pintu->manless }}"
|
||||
data-gate-area="{{ $pintu->area }}"
|
||||
data-gate-tanggal="{{ $pintu->tanggal }}">
|
||||
<td class="text-center">{{ $loop->iteration }}</td>
|
||||
{{-- <td class="text-center" width="7%">{{ $pintu->id }}</td> --}}
|
||||
<td>{{ $pintu->nama }} <strong> - ({{ $pintu->id }})</strong></td>
|
||||
|
||||
<td width="10%">{{
|
||||
match($pintu->jenis) {
|
||||
0 => 'Masuk',
|
||||
@@ -104,7 +120,18 @@
|
||||
style="width:12px;height:12px;">
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-center" width="12%">
|
||||
<td class="text-center">
|
||||
@if ($pintu->areaParkir)
|
||||
<span class="badge bg-primary">{{ $pintu->areaParkir->nama_lokasi }}</span>
|
||||
<small class="text-muted d-block">{{ $pintu->areaParkir->id_lokasi }}</small>
|
||||
@elseif ($pintu->area)
|
||||
<span class="badge bg-warning text-dark">{{ $pintu->area }}</span>
|
||||
<small class="text-muted d-block">Area tidak ditemukan</small>
|
||||
@else
|
||||
<span class="badge bg-secondary">Belum diset</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="text-center text-nowrap" width="18%">
|
||||
<a class="btn btn-warning btn-sm parameter-button" id="parameter" data-bs-toggle="modal" data-bs-target=".bd-ubah-modal-lg">Pos</a>
|
||||
<button class="btn btn-primary btn-sm hardware-button" data-id="{{ $pintu->id }}" data-nama="{{ $pintu->nama }}">Hardware</button>
|
||||
</td>
|
||||
@@ -115,10 +142,10 @@
|
||||
</div>
|
||||
<div class="d-flex justify-content-center align-items-center mt-2">
|
||||
<div>
|
||||
<button class="btn btn-primary btn-sm add-button" data-bs-toggle="modal" data-bs-target=".bd-example-modal-lg">Tambah</button>
|
||||
<button class="btn btn-warning btn-sm edit-button" id="btnEdit" data-bs-toggle="modal" data-bs-target=".bd-ubah-modal-lg">Ubah</button>
|
||||
<button class="btn btn-danger btn-sm" id="btnDelete">Hapus</button>
|
||||
<button class="btn btn-danger btn-sm" id="btnDelete">Detail</button>
|
||||
<button class="btn btn-primary btn-sm add-button" id="btnAddGate" type="button">Tambah</button>
|
||||
<button class="btn btn-warning btn-sm" id="btnEdit" type="button" disabled>Ubah</button>
|
||||
<button class="btn btn-danger btn-sm" id="btnDeleteGate" type="button" disabled>Hapus</button>
|
||||
<button class="btn btn-info btn-sm" id="btnDetailGate" type="button" disabled>Detail</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- ADD MEMMBER MODAL -->
|
||||
@@ -134,6 +161,78 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="gate-form-modal" tabindex="-1">
|
||||
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<form id="form-gate">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="gate-form-title">Tambah Pintu/Pos</h5>
|
||||
<button class="btn-close" data-bs-dismiss="modal" type="button"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<input type="hidden" id="gate-mode">
|
||||
<div class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label" for="gate-id">ID Pintu/Pos</label>
|
||||
<input class="form-control text-uppercase" id="gate-id" name="id" maxlength="10" required>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label class="form-label" for="gate-nama">Nama Pintu/Pos</label>
|
||||
<input class="form-control" id="gate-nama" name="nama" maxlength="100" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label" for="gate-jenis">Mode Pintu</label>
|
||||
<select class="form-select" id="gate-jenis" name="jenis" required>
|
||||
<option value="0">Masuk</option>
|
||||
<option value="1">Keluar</option>
|
||||
<option value="2">Transit</option>
|
||||
<option value="3">Emergency</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label" for="gate-grace">Grace Periode</label>
|
||||
<select class="form-select" id="gate-grace" name="grace_period">
|
||||
<option value="1">Aktif</option>
|
||||
<option value="0">Nonaktif</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label" for="gate-manless">Manless</label>
|
||||
<select class="form-select" id="gate-manless" name="manless">
|
||||
<option value="1">Ya</option>
|
||||
<option value="0">Tidak</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="gate-area">Area Parkir</label>
|
||||
<select class="form-select" id="gate-area" name="area">
|
||||
<option value="">-- Tanpa Area --</option>
|
||||
@foreach ($Area as $area)
|
||||
<option value="{{ $area->id_lokasi }}">{{ $area->nama_lokasi }} ({{ $area->id_lokasi }})</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-light border" data-bs-dismiss="modal" type="button">Batal</button>
|
||||
<button class="btn btn-primary" id="btn-save-gate" type="submit">Simpan</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="gate-detail-modal" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Detail Pintu/Pos</h5>
|
||||
<button class="btn-close" data-bs-dismiss="modal" type="button"></button>
|
||||
</div>
|
||||
<div class="modal-body" id="gate-detail-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('javascript')
|
||||
@@ -154,6 +253,130 @@
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
||||
const routes = {
|
||||
store: "{{ route('gate.store', [], false) }}",
|
||||
show: "{{ route('gate.show', ':id', false) }}",
|
||||
update: "{{ route('gate.update', ':id', false) }}",
|
||||
destroy: "{{ route('gate.destroy', ':id', false) }}"
|
||||
};
|
||||
const csrfToken = "{{ csrf_token() }}";
|
||||
let selectedGate = null;
|
||||
|
||||
function openGateForm(mode, gate) {
|
||||
const isEdit = mode === 'edit';
|
||||
$('#form-gate')[0].reset();
|
||||
$('#gate-mode').val(mode);
|
||||
$('#gate-form-title').text(isEdit ? 'Ubah Pintu/Pos' : 'Tambah Pintu/Pos');
|
||||
$('#gate-id').val(gate?.gateId || '').prop('readonly', isEdit);
|
||||
$('#gate-nama').val(gate?.gateNama || '');
|
||||
$('#gate-jenis').val(gate?.gateJenis ?? 0);
|
||||
$('#gate-grace').val(gate?.gateGrace ?? 1);
|
||||
$('#gate-manless').val(gate?.gateManless ?? 0);
|
||||
$('#gate-area').val(gate?.gateArea || '');
|
||||
new bootstrap.Modal(document.getElementById('gate-form-modal')).show();
|
||||
}
|
||||
|
||||
$('#example tbody').on('click', 'tr:not(.edit-row)', function () {
|
||||
$('#example tbody tr').removeClass('table-active');
|
||||
$(this).addClass('table-active');
|
||||
selectedGate = $(this).data();
|
||||
$('#btnEdit, #btnDeleteGate, #btnDetailGate').prop('disabled', false);
|
||||
});
|
||||
|
||||
$('#btnAddGate').on('click', function () {
|
||||
openGateForm('create');
|
||||
});
|
||||
|
||||
$('#btnEdit').on('click', function () {
|
||||
if (!selectedGate) return;
|
||||
openGateForm('edit', selectedGate);
|
||||
});
|
||||
|
||||
$('#form-gate').on('submit', function (event) {
|
||||
event.preventDefault();
|
||||
const isEdit = $('#gate-mode').val() === 'edit';
|
||||
const id = $('#gate-id').val();
|
||||
const btn = $('#btn-save-gate');
|
||||
const btnHtml = btn.html();
|
||||
btn.prop('disabled', true).html('<span class="spinner-border spinner-border-sm me-1"></span>Menyimpan...');
|
||||
$.ajax({
|
||||
url: isEdit ? routes.update.replace(':id', encodeURIComponent(id)) : routes.store,
|
||||
type: isEdit ? 'PUT' : 'POST',
|
||||
data: $('#form-gate').serialize(),
|
||||
headers: { 'X-CSRF-TOKEN': csrfToken },
|
||||
success: function (r) {
|
||||
bootstrap.Modal.getInstance(document.getElementById('gate-form-modal'))?.hide();
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil',
|
||||
text: r.message || 'Data pintu/pos disimpan.',
|
||||
timer: 1300,
|
||||
showConfirmButton: false
|
||||
}).then(() => window.location.reload());
|
||||
},
|
||||
error: function (xhr) {
|
||||
btn.prop('disabled', false).html(btnHtml);
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Gagal menyimpan',
|
||||
text: xhr.responseJSON?.message || Object.values(xhr.responseJSON?.errors || {}).flat().join('\n') || 'Gagal menyimpan pintu/pos.'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#btnDeleteGate').on('click', function () {
|
||||
if (!selectedGate) return;
|
||||
Swal.fire({
|
||||
title: 'Hapus pintu/pos?',
|
||||
text: `${selectedGate.gateId} - ${selectedGate.gateNama}`,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Ya, hapus',
|
||||
cancelButtonText: 'Batal',
|
||||
confirmButtonColor: '#dc3545',
|
||||
showLoaderOnConfirm: true,
|
||||
preConfirm: () => $.ajax({
|
||||
url: routes.destroy.replace(':id', encodeURIComponent(selectedGate.gateId)),
|
||||
type: 'DELETE',
|
||||
headers: { 'X-CSRF-TOKEN': csrfToken }
|
||||
}).catch(xhr => {
|
||||
Swal.showValidationMessage(xhr.responseJSON?.message || 'Pintu/pos tidak dapat dihapus.');
|
||||
})
|
||||
}).then(result => {
|
||||
if (result.isConfirmed && result.value) {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil',
|
||||
text: 'Pintu/pos dihapus.',
|
||||
timer: 1300,
|
||||
showConfirmButton: false
|
||||
}).then(() => window.location.reload());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#btnDetailGate').on('click', function () {
|
||||
if (!selectedGate) return;
|
||||
const btn = $(this);
|
||||
const btnHtml = btn.html();
|
||||
btn.prop('disabled', true).html('<span class="spinner-border spinner-border-sm me-1"></span>Memuat...');
|
||||
$('#gate-detail-body').html('<div class="text-center py-3"><span class="spinner-border spinner-border-sm me-2"></span>Memuat detail...</div>');
|
||||
new bootstrap.Modal(document.getElementById('gate-detail-modal')).show();
|
||||
$.get(routes.show.replace(':id', encodeURIComponent(selectedGate.gateId)), function (r) {
|
||||
const d = r.data;
|
||||
const jenis = { 0: 'Masuk', 1: 'Keluar', 2: 'Transit', 3: 'Emergency' };
|
||||
const area = d.area_parkir
|
||||
? `${esc(d.area_parkir.nama_lokasi)} (${esc(d.area_parkir.id_lokasi)})`
|
||||
: (d.area ? esc(d.area) + ' (tidak ditemukan)' : 'Tanpa Area');
|
||||
$('#gate-detail-body').html(`<dl class="row mb-0"><dt class="col-5">ID Pintu/Pos</dt><dd class="col-7">${esc(d.id)}</dd><dt class="col-5">Nama</dt><dd class="col-7">${esc(d.nama)}</dd><dt class="col-5">Mode Pintu</dt><dd class="col-7">${jenis[d.jenis] ?? '-'}</dd><dt class="col-5">Grace Periode</dt><dd class="col-7">${Number(d.grace_period) === 1 ? 'Aktif' : 'Nonaktif'}</dd><dt class="col-5">Manless</dt><dd class="col-7">${Number(d.manless) === 1 ? 'Ya' : 'Tidak'}</dd><dt class="col-5">Area Parkir</dt><dd class="col-7">${area}</dd><dt class="col-5">Dibuat</dt><dd class="col-7">${esc(d.tanggal || '-')}</dd></dl>`);
|
||||
}).fail(function (xhr) {
|
||||
$('#gate-detail-body').html('<div class="text-danger text-center">' + (xhr.responseJSON?.message || 'Gagal memuat detail.') + '</div>');
|
||||
}).always(function () {
|
||||
btn.prop('disabled', false).html(btnHtml);
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.hardware-button', function () {
|
||||
let btn = $(this);
|
||||
let btnHtml = btn.html();
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
@extends('layouts.master')
|
||||
|
||||
@section('styles')
|
||||
<style>
|
||||
.card-body label {
|
||||
font-size: 13px;
|
||||
color: #6c757d;
|
||||
}
|
||||
|
||||
.card-body .form-control,
|
||||
.card-body .form-select {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.table-selectable tbody tr:not(.lokasi-form-row) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.table-selectable tbody tr:not(.lokasi-form-row):hover {
|
||||
background-color: #f2f6ff;
|
||||
}
|
||||
</style>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="container-fluid page-body-wrapper">
|
||||
<div class="main-panel">
|
||||
<div class="content-wrapper">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-10 grid-margin stretch-card">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-body">
|
||||
<h4 class="card-title">Master Area Parkir</h4>
|
||||
<div class="table-responsive mb-2">
|
||||
<table class="table table-bordered table-selectable" id="lokasi-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="p-3" width="5%">No.</th>
|
||||
<th style="text-align: center;" width="12%">ID Lokasi</th>
|
||||
<th style="text-align: center;">Nama Area</th>
|
||||
<th style="text-align: center;" width="12%">Kapasitas</th>
|
||||
<th style="text-align: center;" width="12%">Sisa</th>
|
||||
<th style="text-align: center;" width="10%">Prioritas</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($lokasi as $item)
|
||||
<tr>
|
||||
<td class="text-center">{{ $loop->iteration }}</td>
|
||||
<td class="text-center"
|
||||
data-lokasi-id="{{ $item->id_lokasi }}"
|
||||
data-lokasi-nama="{{ $item->nama_lokasi }}"
|
||||
data-lokasi-max="{{ $item->max_space }}"
|
||||
data-lokasi-sisa="{{ $item->sisa }}"
|
||||
data-lokasi-prioritas="{{ $item->prioritas }}">
|
||||
{{ $item->id_lokasi }}
|
||||
</td>
|
||||
<td>{{ $item->nama_lokasi }}</td>
|
||||
<td class="text-end">{{ number_format((int) $item->max_space, 0, ',', '.') }}</td>
|
||||
<td class="text-end">
|
||||
<span class="badge {{ (int) $item->sisa > 0 ? 'bg-success' : 'bg-danger' }}">
|
||||
{{ number_format((int) $item->sisa, 0, ',', '.') }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="text-center">{{ $item->prioritas ?? '-' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr class="empty-lokasi-row">
|
||||
<td colspan="6" class="text-center text-muted">Belum ada area parkir.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between align-items-center mt-3">
|
||||
<button class="btn btn-primary btn-sm" id="btnAddLokasi" type="button"><i class="fa fa-plus me-1"></i>Tambah</button>
|
||||
<div class="d-flex gap-2">
|
||||
<button class="btn btn-info btn-sm" id="btnDetailLokasi" type="button" disabled><i class="fa fa-circle-info me-1"></i>Detail</button>
|
||||
<button class="btn btn-warning btn-sm" id="btnEditLokasi" type="button" disabled><i class="fa fa-pen me-1"></i>Ubah</button>
|
||||
<button class="btn btn-danger btn-sm" id="btnDeleteLokasi" type="button" disabled><i class="fa fa-trash me-1"></i>Hapus</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal fade" id="lokasi-detail-modal" tabindex="-1">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Detail Area Parkir</h5>
|
||||
<button class="btn-close" data-bs-dismiss="modal" type="button"></button>
|
||||
</div>
|
||||
<div class="modal-body" id="lokasi-detail-body"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('javascript')
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
|
||||
<script src="{{ asset('vendor/sweetalert2/dist/sweetalert2.min.js') }}"></script>
|
||||
<script>
|
||||
$(function () {
|
||||
let selected = null;
|
||||
const csrf = $('meta[name="csrf-token"]').attr('content');
|
||||
const routes = {
|
||||
store: '{{ route('lokasi.store', [], false) }}',
|
||||
show: '{{ route('lokasi.show', ':id', false) }}',
|
||||
update: '{{ route('lokasi.update', ':id', false) }}',
|
||||
destroy: '{{ route('lokasi.destroy', ':id', false) }}'
|
||||
};
|
||||
|
||||
function setSelected(row) {
|
||||
$('#lokasi-table tbody tr').removeClass('table-active');
|
||||
selected = row ? $(row).find('[data-lokasi-id]').data() : null;
|
||||
if (row) $(row).addClass('table-active');
|
||||
$('#btnDetailLokasi, #btnEditLokasi, #btnDeleteLokasi').prop('disabled', !selected);
|
||||
}
|
||||
|
||||
function formRow(mode, lokasi) {
|
||||
const isEdit = mode === 'edit';
|
||||
return `<tr class="lokasi-form-row"><td colspan="6"><form class="lokasi-inline-form" data-mode="${mode}" data-id="${lokasi?.lokasiId || ''}"><div class="row g-2 align-items-end"><div class="col-md-2"><label class="form-label mb-1">ID Lokasi</label><input class="form-control text-uppercase" name="id_lokasi" maxlength="10" value="${lokasi?.lokasiId || ''}" ${isEdit ? 'readonly' : ''} required></div><div class="col-md-3"><label class="form-label mb-1">Nama Area</label><input class="form-control" name="nama_lokasi" maxlength="100" value="${lokasi?.lokasiNama || ''}" required></div><div class="col-md-2"><label class="form-label mb-1">Kapasitas</label><input class="form-control" type="number" name="max_space" min="0" max="32767" value="${lokasi?.lokasiMax ?? 0}" required></div><div class="col-md-2"><label class="form-label mb-1">Sisa</label><input class="form-control" type="number" name="sisa" min="0" max="32767" value="${lokasi?.lokasiSisa ?? 0}" required></div><div class="col-md-1"><label class="form-label mb-1">Prioritas</label><input class="form-control" type="number" name="prioritas" value="${lokasi?.lokasiPrioritas ?? ''}"></div><div class="col-md-2 d-flex gap-2"><button class="btn btn-success" type="submit">Simpan</button><button class="btn btn-light border cancel-lokasi-form" type="button">Batal</button></div></div></form></td></tr>`;
|
||||
}
|
||||
|
||||
$('#lokasi-table tbody').on('click', 'tr:not(.lokasi-form-row):not(.empty-lokasi-row)', function () {
|
||||
setSelected(this);
|
||||
});
|
||||
|
||||
$('#btnAddLokasi').on('click', function () {
|
||||
$('.lokasi-form-row').remove();
|
||||
$('#lokasi-table tbody').prepend(formRow('create'));
|
||||
setSelected(null);
|
||||
});
|
||||
|
||||
$('#btnEditLokasi').on('click', function () {
|
||||
if (!selected) return;
|
||||
$('.lokasi-form-row').remove();
|
||||
$('#lokasi-table tbody tr').filter(function () {
|
||||
return $(this).find('[data-lokasi-id]').data('lokasiId') === selected.lokasiId;
|
||||
}).after(formRow('edit', selected));
|
||||
});
|
||||
|
||||
$(document).on('click', '.cancel-lokasi-form', function () {
|
||||
$(this).closest('tr').remove();
|
||||
});
|
||||
|
||||
$(document).on('input', '.lokasi-inline-form [name="max_space"]', function () {
|
||||
const form = $(this).closest('form');
|
||||
if (form.data('mode') === 'create') form.find('[name="sisa"]').val($(this).val());
|
||||
});
|
||||
|
||||
$(document).on('submit', '.lokasi-inline-form', function (event) {
|
||||
event.preventDefault();
|
||||
const form = $(this);
|
||||
const id = form.data('id');
|
||||
const isEdit = form.data('mode') === 'edit';
|
||||
const btn = form.find('[type="submit"]');
|
||||
const btnHtml = btn.html();
|
||||
btn.prop('disabled', true).html('<span class="spinner-border spinner-border-sm me-1"></span>Menyimpan...');
|
||||
$.ajax({
|
||||
url: isEdit ? routes.update.replace(':id', encodeURIComponent(id)) : routes.store,
|
||||
type: isEdit ? 'PUT' : 'POST',
|
||||
data: form.serialize(),
|
||||
headers: { 'X-CSRF-TOKEN': csrf },
|
||||
success: function (r) {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil',
|
||||
text: r.message || 'Data area parkir disimpan.',
|
||||
timer: 1300,
|
||||
showConfirmButton: false
|
||||
}).then(() => window.location.reload());
|
||||
},
|
||||
error: function (xhr) {
|
||||
btn.prop('disabled', false).html(btnHtml);
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: 'Gagal menyimpan',
|
||||
text: xhr.responseJSON?.message || Object.values(xhr.responseJSON?.errors || {}).flat().join('\n') || 'Gagal menyimpan area parkir.'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#btnDeleteLokasi').on('click', function () {
|
||||
if (!selected) return;
|
||||
Swal.fire({
|
||||
title: 'Hapus area parkir?',
|
||||
text: `${selected.lokasiId} - ${selected.lokasiNama}`,
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Ya, hapus',
|
||||
cancelButtonText: 'Batal',
|
||||
confirmButtonColor: '#dc3545',
|
||||
showLoaderOnConfirm: true,
|
||||
preConfirm: () => $.ajax({
|
||||
url: routes.destroy.replace(':id', encodeURIComponent(selected.lokasiId)),
|
||||
type: 'DELETE',
|
||||
headers: { 'X-CSRF-TOKEN': csrf }
|
||||
}).catch(xhr => {
|
||||
Swal.showValidationMessage(xhr.responseJSON?.message || 'Area parkir tidak dapat dihapus.');
|
||||
})
|
||||
}).then(result => {
|
||||
if (result.isConfirmed && result.value) {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: 'Berhasil',
|
||||
text: 'Area parkir dihapus.',
|
||||
timer: 1300,
|
||||
showConfirmButton: false
|
||||
}).then(() => window.location.reload());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$('#btnDetailLokasi').on('click', function () {
|
||||
if (!selected) return;
|
||||
const btn = $(this);
|
||||
const btnHtml = btn.html();
|
||||
btn.prop('disabled', true).html('<span class="spinner-border spinner-border-sm me-1"></span>Memuat...');
|
||||
$('#lokasi-detail-body').html('<div class="text-center py-3"><span class="spinner-border spinner-border-sm me-2"></span>Memuat detail...</div>');
|
||||
new bootstrap.Modal(document.getElementById('lokasi-detail-modal')).show();
|
||||
$.get(routes.show.replace(':id', encodeURIComponent(selected.lokasiId)), function (r) {
|
||||
const d = r.data;
|
||||
$('#lokasi-detail-body').html(`<dl class="row mb-0"><dt class="col-5">ID Lokasi</dt><dd class="col-7">${d.id_lokasi}</dd><dt class="col-5">Nama Area</dt><dd class="col-7">${d.nama_lokasi}</dd><dt class="col-5">Kapasitas</dt><dd class="col-7">${Number(d.max_space || 0).toLocaleString('id-ID')}</dd><dt class="col-5">Sisa</dt><dd class="col-7">${Number(d.sisa || 0).toLocaleString('id-ID')}</dd><dt class="col-5">Prioritas</dt><dd class="col-7">${d.prioritas ?? '-'}</dd></dl>`);
|
||||
}).fail(function (xhr) {
|
||||
$('#lokasi-detail-body').html('<div class="text-danger text-center">' + (xhr.responseJSON?.message || 'Gagal memuat detail.') + '</div>');
|
||||
}).always(function () {
|
||||
btn.prop('disabled', false).html(btnHtml);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endsection
|
||||
Reference in New Issue
Block a user