223 lines
6.4 KiB
PHP
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) => ({
|
|
'&': '&',
|
|
'<': '<',
|
|
'>': '>',
|
|
'"': '"',
|
|
"'": ''',
|
|
}[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
|
|
|