This commit is contained in:
JokoPrasetio 2025-08-14 15:51:02 +07:00
parent 8323d33c3b
commit f87add2ae4
27 changed files with 156 additions and 62 deletions

View File

@ -28,7 +28,7 @@ class CustomerController extends Controller
public function dataOrder(){
$search = request('search');
$jenis_menu = request('jenis_menu');
$perPage = request()->get('per_page', 12);
$perPage = request()->get('per_page', 50);
$tanggal_awal = (int) request('tanggal_awal');
$tanggal_akhir = (int) request('tanggal_akhir');
@ -57,8 +57,7 @@ class CustomerController extends Controller
// Step 2: Query menu
$menuQuery = DB::connection('dbOrderGizi')
->table('public.master_menu as mn')
->where('mn.statusenabled', true);
->where(['mn.statusenabled' => true, 'mn.status' => true]);
if (!empty($jenis_menu)) {
$menuQuery->where('mn.jenis_menu', 'ILIKE', '%' . $jenis_menu . '%');
}
@ -96,7 +95,6 @@ class CustomerController extends Controller
)->get();
$menuIds = $menuItems->pluck('master_menu_id')->toArray();
if (empty($menuIds)) {
return self::emptyMenuResponse($perPage);
}
@ -123,26 +121,22 @@ class CustomerController extends Controller
->get()
->groupBy('master_menu_id');
function buildGroupLabel($tglList, $isSomeday){
if($isSomeday) return 'Menu Sameday';
function buildGroupLabel($tglList, $isSomeday){
if($isSomeday) return 'Menu Sameday';
if(empty($tglList)) return '-';
$days = collect($tglList)->map(fn($t) => substr($t, -2))
->unique()
->sort()
->values();
$groups = [];
foreach ($days as $d) {
$lastDigit = substr($d, -1);
$groups[$lastDigit][] = $d;
if(empty($tglList)) return '-';
$days = collect($tglList)
->map(fn($t) => substr($t, -2))
->unique()
->sort()
->values();
// Jika semua tanggal memiliki digit terakhir yang sama, gabungkan
$tanggal = implode(',', $days->toArray());
return 'Menu Normal Tersedia Tanggal ' . $tanggal;
}
// buat label
$labels = [];
foreach ($groups as $list) {
$labels[] = 'Menu Normal Tersedia Tanggal ' . implode(',', $list);
}
return implode(' & ', $labels);
}
// Step 4: Transform response
$enriched = $menuItems->map(function ($menu) use ($klasifikasi, $dmph, $kkal) {

View File

@ -58,7 +58,7 @@ class MenuController extends Controller
'status' => true,
'apakah_someday' => $data['kategori_menu'] === "Menu Normal" ? false : true,
'apakah_menu_siang' => (isset($data['apakah_menu_siang']) && $data['apakah_menu_siang'] === "iya") ? true : false,
'apakah_menu_sore' => (isset($data['apakah_menu_sore']) && $data['apakah_menu_sore'] === "iya") ? true : false,
'apakah_menu_sore' => (isset($data['apakah_menu_sore']) && $data['apakah_menu_sore'] === "iya") ? true : false
];
if($data['foto']){
@ -115,7 +115,6 @@ class MenuController extends Controller
]);
} catch (\Throwable $th) {
DB::connection('dbOrderGizi')->rollBack();
return response()->json([
'status' => false,
'message' => 'Menu gagal ditambahkan!',
@ -169,7 +168,7 @@ class MenuController extends Controller
'status' => true,
'apakah_someday' => request('kategori_menu') === "Menu Normal" ? false : true,
'apakah_menu_siang' => (request('apakah_menu_siang') && request('apakah_menu_siang') === "iya") ? true : false,
'apakah_menu_sore' => (request('apakah_menu_sore') && request('apakah_menu_sore') === "iya") ? true : false,
'apakah_menu_sore' => (request('apakah_menu_sore') && request('apakah_menu_sore') === "iya") ? true : false
];
if(request()->hasFile('foto')){
$imageName = Str::random(15) . '.' . request('foto')->getClientOriginalExtension();
@ -235,8 +234,8 @@ class MenuController extends Controller
*/
public function destroy(string $id)
{
$data = Menu::where(['statusenabled' => true, 'master_menu_id' => $id])->first();
$payload = [
$data = Menu::where(['statusenabled' => true, 'master_menu_id' => $id])->first();
$payload = [
'statusenabled' => false,
'pegawai_id_entry' => auth()->user()->id,
'pegawai_nama_entry' => auth()->user()->full_name,
@ -342,4 +341,18 @@ class MenuController extends Controller
'message' => 'berhasil mendapatkan data'
]);
}
public function switchMenu(string $id, $status){
$data = Menu::where('master_menu_id', $id)->first();
$statusResult = $status === "true" ? true : false;
$data->update([
'status' => $statusResult
]);
return response()->json([
'status' => true,
'message' => 'berhasil memperbarui data'
], 200);
}
}

View File

@ -268,6 +268,7 @@ class PesananController extends Controller
$q->where('status_order', 'Lunas');
});
$tanggal = request('tanggal');
$status = request('status');
if(!empty($tanggal)){
$flattened = is_array($tanggal[0]) ? Arr::flatten($tanggal) : $tanggal;
$data->whereIn('tgl_antar', $flattened);
@ -275,6 +276,9 @@ class PesananController extends Controller
$now = Carbon::now()->format('Y-m-d');
$data->where('tgl_antar', $now);
}
// if($status !== "all"){
// $data->where('status_order', $status);
// }
$data = $data->get();
return response()->json([

View File

@ -28,7 +28,7 @@ class Menu extends Model
'status',
'apakah_someday',
'apakah_menu_siang',
'apakah_menu_sore'
'apakah_menu_sore',
];
public function klasifikasiMenuKalori(){

View File

@ -130,3 +130,11 @@
.tagify__dropdown {
z-index: 99999 !important;
}
.row-disabled {
opacity: 0.5;
}
/* Kunci interaksi di semua kolom kecuali Action */
.row-disabled td:not(:first-child) {
pointer-events: none;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

View File

@ -387,8 +387,12 @@ function editMasterMenu(e) {
$("#harga_karyawan_edit").val(dataOld.harga_karyawan);
$("#jenis_makanan_edit").val(dataOld.jenis_menu);
$("#deskripsi_edit").val(dataOld.deskripsi);
let kategoriValue = 'Menu Normal';
if (dataOld?.apakah_someday) {
kategoriValue = 'Sameday';
}
$(`input[name="kategori_menu"][value="${dataOld.apakah_someday ? 'Sameday' : 'Menu Normal'}"]`).prop('checked', true);
$(`input[name="kategori_menu"][value="${kategoriValue}"]`).prop('checked', true);
$(`input[name="apakah_menu_siang"][value="${dataOld.apakah_menu_siang ? 'iya' : ''}"]`).prop('checked', true);
$(`input[name="apakah_menu_sore"][value="${dataOld.apakah_menu_sore ? 'iya' : ''}"]`).prop('checked', true);
@ -601,9 +605,10 @@ function detailMasterMenu(e){
const sore = el.data('apakah_menu_sore');
const kalori = JSON.parse(decodeURIComponent(el.data('kalori')))
const kaloriMenu = kalori.map(kal => `
const kaloriMenu = kalori.length > 0 && kalori.every(item => item.kalori_id !== null) ? kalori.map(kal => `
<span class="badge bg-secondary me-1 mb-1">${kal.nilai_kalori} (kkal)</span>
`).join('');
`).join('') :'-';
const tags = JSON.parse(decodeURIComponent(el.data('klasifikasi_menu')));
const klasifikasiMenu = tags.map(tag => `
@ -615,7 +620,7 @@ function detailMasterMenu(e){
<div class="mb-1 small text-muted">
<i class="fa fa-calendar-check me-1"></i>
${someday ? 'Tersedia setiap hari (Senin - Minggu)' :
tgl.length ? `Tersedia pada tanggal: ${tgl.map(d => d.tgl_harian).join(', ')}` :
tgl.length ? `Tersedia pada tanggal: ${tgl.map(d => d.tgl_harian).join(', ')}` :
'Tidak ada info tanggal tersedia'}
</div>
<div class="mb-1 small text-muted">
@ -645,10 +650,11 @@ function detailMasterMenu(e){
${klasifikasiMenu || '<span class="text-muted">Tidak ada klasifikasi</span>'}
</div>
`);
$('#kalori_menu').html(`
<div class="mb-2">
<p class="mb-1 fw-semibold">Kalori:</p>
${kaloriMenu || '<span class="text-muted">-</span>'}
${kaloriMenu}
</div>
`);

View File

@ -9,11 +9,10 @@
searchOnEnterKey: false,
searchHighlight: true,
pagination: true,
serverSide:true,
serverSide: true,
pageSize: 10,
pageList: [10, 20, 30, 40, 50, 100, 200],
cookie: true,
cookieIdTable: "datatableMasterMenu",
icons: {
refresh: "fas fa-sync-alt", // atau ganti ke icon lain
columns: "fas fa-th-large"
@ -24,6 +23,10 @@
title: "Action",
field: 'master_menu_id',
formatter: function(value, row) {
let statusLabel = '';
if (!row.status) {
statusLabel = `<div class="text-danger small mb-1"><strong>Tidak Aktif</strong></div>`;
}
let buttons = ''
buttons += `
@ -72,7 +75,13 @@
<i class="fa-solid fa-circle-info"></i>
</button>
`
buttons +=`
<div class="form-check form-switch" data-master_menu_id="${row.master_menu_id}">
<input class="form-check-input" type="checkbox" role="switch" id="switchActiveMenu" ${row?.status ? 'checked' : ''}>
</div>
`
return `
${statusLabel}
<div class="d-flex space-x">
${buttons}
</div>
@ -114,14 +123,13 @@
title: "Waktu Makan",
field: "master_menu_id",
formatter: function (value, row) {
if (row?.apakah_menu_siang && row?.apakah_menu_sore) {
if (row?.apakah_menu_siang && row?.apakah_menu_sore) {
return `Makan Siang & Sore`;
} else if (row?.apakah_menu_siang) {
return `Makan Siang`;
} else if (row?.apakah_menu_sore) {
return `Makan Sore`;
} else {
} else {
return `-`;
}
},
@ -139,4 +147,55 @@
},
],
rowStyle: function(row, index) {
if (!row.status) {
return {
classes: 'row-disabled'
};
}
return {};
}
});
// Tambahkan event listener pada elemen induk (misalnya, body)
document.body.addEventListener('click', function(event) {
if (event.target.type === 'checkbox' && event.target.id === 'switchActiveMenu') {
const isChecked = event.target.checked;
const masterMenuId = event.target.closest('.form-check').getAttribute('data-master_menu_id');
toggleActiveMenu(masterMenuId, isChecked);
}
});
// Fungsi untuk menangani aktivasi atau deaktivasi menu
function toggleActiveMenu(masterMenuId, isChecked) {
fetch(`/dashboard/menu/switch/${masterMenuId}/${isChecked}`, {
headers: {
'X-CSRF-TOKEN': document.querySelector('input[name="_token"]').value,
},
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
Swal.fire({
icon: 'success',
title: 'Berhasil',
text: 'Status Menu diperbarui',
timer: 1500,
showConfirmButton: false,
backdrop: true,
});
datatableMasterMenu.bootstrapTable('refresh');
})
.catch(err => {
console.error('Error:', err);
Swal.fire({
icon: 'error',
title: 'Gagal',
text: err.message || 'Terjadi kesalahan pada server.',
});
});
}

View File

@ -4,7 +4,7 @@ $(document).ready(function(){
filterState ={
jenis_menu: jenisMenuAwal,
search:'',
per_page: 12,
per_page: 50,
}
fetchMenu(filterState)

View File

@ -59,7 +59,7 @@
let params = new URLSearchParams({
page: filter.page || 1,
per_page: filter.per_page || 12,
per_page: filter.per_page || 50,
search: filter.search || '',
jenis_menu: filter.jenis_menu || '',
tanggal_awal: filter.tanggal_awal || '',
@ -119,8 +119,8 @@
scheduleInfo = `<div style="font-size:.80rem">Dipesan maksimal <strong>H-1</strong> sebelum pukul <strong>13.00 WIB</strong></div>`;
}
html += `
<div class="col-12 mb-2 col-12 col-xs-12 col-sm-12 col-md-12 col-lg-12 mb-2 mb-2">
<div class="text-white text-center rounded-pill py-1 px-2" style="font-size:.95rem; background-color: #2d996cff;">
<div class="col-12 mb-2 col-12 col-xs-12 col-sm-12 col-md-12 col-lg-12">
<div class="text-white text-center rounded-5 py-1 px-2" style="font-size:.95rem; background-color: #2d996cff;">
<strong>${label}</strong>
<div class="mt-1 text-center" style="font-size:.80rem;">
${scheduleInfo}
@ -250,16 +250,17 @@
html += `<div class="col-md-12 d-flex justify-content-between align-items-center mt-3">`;
if(res.data.total > 12){
if(res.data.total > 50){
html +=`<div>
<label for="perPageSelect" class="me-2">Tampilkan:</label>
<select id="perPageSelect" class="form-select form-select-sm d-inline-block w-auto" onchange="changePerPage(this)">
<option value="12" ${filter.per_page == 12 ? 'selected' : ''}>12</option>
<option value="24" ${filter.per_page == 24 ? 'selected' : ''}>24</option>
<option value="50" ${filter.per_page == 50 ? 'selected' : ''}>50</option>
<option value="65" ${filter.per_page == 65 ? 'selected' : ''}>65</option>
<option value="70" ${filter.per_page == 70 ? 'selected' : ''}>70</option>
</select>
</div>`
}
// Pagination buttons
if (res.data.last_page > 1) {
html += `

View File

@ -122,6 +122,7 @@ document.getElementById('formActionApproveBillingOrder').addEventListener('submi
});
getReminderKonfirmasiPesanan()
getReminderVerifikasiMakanan()
getReminderVerifikasiMakananOffCanvas()
datatablePending.bootstrapTable('refresh');
modalActionApproveBillingnOrder.removeEventListener('hidden.bs.modal', handler); // ✅ pakai DOM
};

View File

@ -63,7 +63,11 @@ function initPekerjaanDt(selectDate = []) {
datatableOfPekerjaan.bootstrapTable('destroy').bootstrapTable({
url: "/dashboard/datatable/pekerjaan",
method: 'get',
queryParams: params => ({ ...params, tanggal: selectDate }),
queryParams: params => ({
...params,
tanggal: selectDate,
// status: $('#filterStatus').val()
}),
showColumns: true,
showColumnsToggleAll: true,
showRefresh: true,
@ -80,6 +84,9 @@ function initPekerjaanDt(selectDate = []) {
icons: { refresh: "fas fa-sync-alt", columns: "fas fa-th-large" },
columns: getTableColumns(),
});
$('#filterStatus').on('change', function () {
datatableOfPekerjaan.bootstrapTable('refresh');
});
// Checkbox Handling
$(document).off('click', '#selectAll').on('click', '#selectAll', function () {

View File

@ -101,12 +101,6 @@
Menu Normal
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="data[0][kategori_menu]" id="" value="Menu MCU" required>
<label class="form-check-label" for="">
Menu MCU
</label>
</div>
</div>
<div class="col-md-6">
<label for="exampleInputEmail1" class="form-label">Waktu Menu Tersedia</label>

View File

@ -96,12 +96,6 @@
Menu Normal
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="data[0][kategori_menu]" id="" value="Menu MCU" required>
<label class="form-check-label" for="">
Menu MCU
</label>
</div>
</div>
<div class="col-md-6">
<label for="exampleInputEmail1" class="form-label">Waktu Menu Tersedia</label>

View File

@ -65,8 +65,7 @@
<li class="menu-item {{ Request::is('dashboard/pending') ? 'active' : '' }}">
<a href="/dashboard/pending" class="menu-link">
<i class="menu-icon tf-icons bx bx-collection"></i>
<div data-i18n="Basic">Konfirmasi Pesanan
<span class="badge badge-canter rounded-circle bg-danger ms-2 mb-1" id="konfirmasi_pesanan"></span>
<div data-i18n="Basic">Konfirmasi Pesanan<span class="badge badge-canter rounded-circle bg-danger ms-1 mb-1 fs-6" id="konfirmasi_pesanan"></span>
</div>
</a>
</li>

View File

@ -33,9 +33,22 @@
</div>
</div>
<!-- Table -->
<div class="table-responsive">
<table class="table table-hover" id="datatableVerifikasiMakananOffcanvas"></table>
{{-- <div id="toolbarPekerjaan" class="d-flex align-items-center gap-2 d-none">
<label for="filterStatus" class="mb-0 fw-semibold">Status:</label>
<select class="form-select form-select-sm " id="filterStatus" style="width: 200px; margin-bottom:-50px;">
<option value="all">Pilih Status</option>
<option value="Semua">Semua</option>
<option value="Pending">Pending</option>
<option value="Selesai">Selesai</option>
</select>
</div> --}}
<table id="datatableVerifikasiMakananOffcanvas"></table>
</div>
</div>
</div>

View File

@ -17,7 +17,7 @@ use Illuminate\Support\Facades\Route;
// Route::get('/blank', function () {
// return view('layouts.blank');
// });
Route::get('/login', [AuthController::class, 'index'])->name('login');
Route::get('/login', [AuthController::class, 'index'])->name('login')->middleware('guest');
Route::post('/login', [AuthController::class, 'authanticate']);
@ -40,6 +40,7 @@ Route::group(['middleware' => ['auth']], function(){
Route::get('/option/kalori', [KaloriController::class, 'option']);
Route::resource('/menu', MenuController::class);
Route::get('/menu/switch/{id}/{status}', [MenuController::class, 'switchMenu']);
Route::get('/menu/{id}/detail', [MenuController::class, 'getDataDetail']);
Route::get('/datatable/menu', [MenuController::class, 'datatable']);