Files
backend_parkir/resources/views/setup/lokasi/lokasi.blade.php
T

239 lines
14 KiB
PHP

@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