2026-05-07 19:26:20 +07:00

223 lines
6.4 KiB
PHP

@extends('partials.main')
@section('content')
<div class="card card-flush">
<div class="card-header pt-7">
<div class="card-title">
<h2 class="mb-0 fw-bold">Master PitStop</h2>
</div>
<div class="card-toolbar">
<div class="d-flex align-items-center gap-2">
<div class="d-flex align-items-center position-relative">
<span class="svg-icon svg-icon-1 position-absolute ms-4">
<i class="fa-solid fa-magnifying-glass"></i>
</span>
<input type="text" id="searchMaster" class="form-control form-control-solid w-300px ps-12" placeholder="Cari pitstop..." autocomplete="off" />
</div>
<button type="button" class="btn btn-sm btn-primary" id="btnAdd">
<i class="fa-solid fa-plus me-2"></i>Tambah
</button>
</div>
</div>
</div>
<div class="card-body pt-3">
<div class="table-responsive">
<table id="tblMaster" class="table align-middle table-row-dashed fs-6 gy-3 w-100">
<thead>
<tr class="text-muted fw-semibold fs-7 text-uppercase gs-0">
<th style="width: 70px">ID</th>
<th>Nama</th>
<th style="width: 130px">Status</th>
<th class="text-end" style="width: 220px">Aksi</th>
</tr>
</thead>
<tbody class="fw-semibold text-gray-800"></tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="modalMaster" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<form id="formMaster">
<div class="modal-header">
<h5 class="modal-title" id="modalTitle">Tambah Master PitStop</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input type="hidden" id="master_id" />
<div class="mb-4">
<label for="nama" class="form-label">Nama</label>
<input type="text" id="nama" class="form-control" placeholder="Nama pitstop..." required />
<div class="form-text">Contoh: Upload Berkas, Verifikasi, dsb.</div>
</div>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="statusenabled" checked />
<label class="form-check-label" for="statusenabled">Aktif</label>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light" data-bs-dismiss="modal">Batal</button>
<button type="submit" class="btn btn-primary" id="btnSave">
<span class="indicator-label">Simpan</span>
</button>
</div>
</form>
</div>
</div>
</div>
@endsection
@section('custom_js')
<script>
$(document).ready(function () {
const csrf = $('meta[name="csrf-token"]').attr('content');
const escapeHtml = (str) => String(str ?? '').replace(/[&<>"']/g, (m) => ({
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#39;',
}[m]));
const table = $('#tblMaster').DataTable({
processing: true,
serverSide: true,
searchDelay: 350,
dom: 'rtip',
pageLength: 10,
lengthMenu: [10, 20, 50, 100],
order: [[0, 'asc']],
ajax: { url: '/master-pitstop/data', type: 'GET' },
columns: [
{ data: 'id' },
{ data: 'nama', render: (d) => `<span class="fw-bold">${escapeHtml(d)}</span>` },
{
data: 'statusenabled',
render: (v) => (v ? '<span class="badge badge-light-success">Aktif</span>' : '<span class="badge badge-light-danger">Nonaktif</span>'),
},
{
data: null,
className: 'text-end',
orderable: false,
searchable: false,
render: function (data, type, row) {
const toggleLabel = row.statusenabled ? 'Nonaktifkan' : 'Aktifkan';
const toggleClass = row.statusenabled ? 'btn-light-danger' : 'btn-light-success';
return `
<button type="button" class="btn btn-sm btn-light editRow"
data-id="${row.id}"
data-nama="${escapeHtml(row.nama)}"
data-status="${row.statusenabled ? 1 : 0}"
>
Edit
</button>
<button type="button" class="btn btn-sm ${toggleClass} toggleRow" data-id="${row.id}">
${toggleLabel}
</button>`;
},
},
],
});
let timer = null;
$('#searchMaster').on('keyup', function () {
const val = String($(this).val() ?? '');
clearTimeout(timer);
timer = setTimeout(function () {
table.search(val).draw();
}, 250);
});
const modalEl = document.getElementById('modalMaster');
const modal = new bootstrap.Modal(modalEl);
const resetForm = () => {
$('#master_id').val('');
$('#nama').val('');
$('#statusenabled').prop('checked', true);
$('#modalTitle').text('Tambah Master PitStop');
};
$('#btnAdd').on('click', function () {
resetForm();
modal.show();
});
$(document).on('click', '.editRow', function () {
resetForm();
$('#master_id').val($(this).data('id'));
$('#nama').val($(this).data('nama'));
$('#statusenabled').prop('checked', Number($(this).data('status')) === 1);
$('#modalTitle').text('Edit Master PitStop');
modal.show();
});
$('#formMaster').on('submit', function (e) {
e.preventDefault();
const id = String($('#master_id').val() ?? '').trim();
const payload = {
nama: $('#nama').val(),
statusenabled: $('#statusenabled').is(':checked') ? 1 : 0,
};
const url = id ? `/master-pitstop/${id}` : '/master-pitstop';
const method = id ? 'PUT' : 'POST';
$.ajax({
url,
method,
headers: { 'X-CSRF-TOKEN': csrf },
data: payload,
})
.done(function () {
modal.hide();
table.ajax.reload(null, false);
})
.fail(function (xhr) {
const msg =
xhr?.responseJSON?.message ||
(xhr?.status === 422 ? 'Validasi gagal.' : 'Gagal menyimpan data.');
Swal.fire({
toast: true,
position: 'top-end',
icon: 'error',
title: msg,
showConfirmButton: false,
timer: 2600,
timerProgressBar: true,
});
});
});
$(document).on('click', '.toggleRow', function () {
const id = $(this).data('id');
$.ajax({
url: `/master-pitstop/${id}/toggle`,
method: 'PATCH',
headers: { 'X-CSRF-TOKEN': csrf },
})
.done(function () {
table.ajax.reload(null, false);
})
.fail(function () {
Swal.fire({
toast: true,
position: 'top-end',
icon: 'error',
title: 'Gagal mengubah status.',
showConfirmButton: false,
timer: 2600,
timerProgressBar: true,
});
});
});
});
</script>
@endsection