on progress
This commit is contained in:
parent
9d8558d235
commit
652bd8cc45
@ -18,7 +18,7 @@ class CustomerController extends Controller
|
|||||||
public function dataOrder(){
|
public function dataOrder(){
|
||||||
$search = request('search');
|
$search = request('search');
|
||||||
$jenis_menu = request('jenis_menu');
|
$jenis_menu = request('jenis_menu');
|
||||||
$perPage = request()->get('perPage', 1);
|
$perPage = request()->get('per_page', 6);
|
||||||
if($jenis_menu === "paket"){
|
if($jenis_menu === "paket"){
|
||||||
return self::dataPaketMenuOrder($search, $perPage);
|
return self::dataPaketMenuOrder($search, $perPage);
|
||||||
}
|
}
|
||||||
@ -102,53 +102,65 @@ class CustomerController extends Controller
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static function dataPaketMenuOrder($search = null){
|
private static function dataPaketMenuOrder($search = null, $perPage){
|
||||||
$query = DB::connection('dbOrderGizi')->table('public.master_paket_menu as mpn')
|
$query = DB::connection('dbOrderGizi')->table('public.master_paket_menu as mpn')->where('mpn.statusenabled', true);
|
||||||
->leftJoin('public.master_paket_menu_detail as mpd', 'mpd.master_paket_menu_id', '=', 'mpn.master_paket_menu_id')
|
|
||||||
->leftJoin('public.master_menu as mn', 'mpd.master_menu_id', '=', 'mn.master_menu_id')
|
|
||||||
->leftJoin('public.klasifikasi_menu_diet as kmd', 'kmd.master_paket_menu_id', '=', 'mpn.master_paket_menu_id')
|
|
||||||
->leftJoin('public.kategori_diet as kd', 'kd.kategori_diet_id', '=', 'kmd.kategori_diet_id')
|
|
||||||
->select('mpn.*', 'mpd.master_paket_menu_detail_id', 'mn.master_menu_id', 'kmd.klasifikasi_menu_diet', 'kd.*')
|
|
||||||
->where('mpn.statusenabled', true);
|
|
||||||
|
|
||||||
if(!empty($search)){
|
if(!empty($search)){
|
||||||
$query->where(function($q) use($search){
|
$query->where('mpn.nama_paket', 'ILIKE', '%' . $search . '%');
|
||||||
$q->where('mpn.nama_paket', 'ILIKE', '%' . $search . '%')
|
|
||||||
->orWhere('kd.nama_kategori_diet', 'ILIKE', '%'. $search . '%');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$paketMenu = $query->get();
|
$paginated = $query->select(
|
||||||
|
'mpn.master_paket_menu_id',
|
||||||
|
'mpn.nama_paket',
|
||||||
|
'mpn.foto',
|
||||||
|
'mpn.harga_public',
|
||||||
|
'mpn.harga_karyawan',
|
||||||
|
'mpn.harga_keluarga_pasien',
|
||||||
|
'mpn.deskripsi',
|
||||||
|
'mpn.status'
|
||||||
|
)->paginate($perPage);
|
||||||
|
|
||||||
|
$paketMenuIds = collect($paginated->items())->pluck('master_paket_menu_id')->toArray();
|
||||||
|
|
||||||
$grouped = $paketMenu->groupBy('master_paket_menu_id')->map(function($items){
|
$klasifikasi = DB::connection('dbOrderGizi')
|
||||||
$first = $items->first();
|
->table('public.klasifikasi_menu_diet as kmd')
|
||||||
$klasifikasiMenu = $items->filter(fn($d) => $d->kategori_diet_id !== null)
|
->join('public.kategori_diet as kd', 'kd.kategori_diet_id', '=', 'kmd.kategori_diet_id')
|
||||||
->unique('kategori_diet_id')
|
->whereIn('kmd.master_paket_menu_id', $paketMenuIds)
|
||||||
->map(function($items) {
|
->select('kmd.master_paket_menu_id', 'kd.kategori_diet_id', 'kd.nama_kategori_diet')
|
||||||
|
->get()
|
||||||
|
->groupBy('master_paket_menu_id');
|
||||||
|
|
||||||
|
$result = collect($paginated->items())->map(function ($paketMenu) use ($klasifikasi) {
|
||||||
return [
|
return [
|
||||||
'kategori_diet_id' => $items->kategori_diet_id,
|
'master_paket_menu_id' => $paketMenu->master_paket_menu_id,
|
||||||
'nama_kategori_diet'=> $items->nama_kategori_diet
|
'nama' => $paketMenu->nama_paket,
|
||||||
];
|
'foto' => $paketMenu->foto,
|
||||||
})->values();
|
|
||||||
return [
|
|
||||||
'master_paket_menu_id' => $first->master_paket_menu_id,
|
|
||||||
'nama' => $first->nama_paket,
|
|
||||||
'foto' => $first->foto,
|
|
||||||
'jenis_menu' => "paket",
|
'jenis_menu' => "paket",
|
||||||
'harga_public' => $first->harga_public,
|
'harga_public' => $paketMenu->harga_public,
|
||||||
'harga_karyawan' => $first->harga_karyawan,
|
'harga_karyawan' => $paketMenu->harga_karyawan,
|
||||||
'harga_keluarga_pasien' => $first->harga_keluarga_pasien,
|
'harga_keluarga_pasien' => $paketMenu->harga_keluarga_pasien,
|
||||||
'status' => $first->status,
|
'status' => $paketMenu->status,
|
||||||
'deskripsi' => $first->deskripsi,
|
'deskripsi' => $paketMenu->deskripsi,
|
||||||
'klasifikasiMenu' => $klasifikasiMenu
|
'klasifikasiMenu' => isset($klasifikasi[$paketMenu->master_paket_menu_id]) ? $klasifikasi[$paketMenu->master_paket_menu_id]->map(function ($item) {
|
||||||
|
return [
|
||||||
|
'kategori_diet_id' => $item->kategori_diet_id,
|
||||||
|
'nama_kategori_diet' => $item->nama_kategori_diet,
|
||||||
];
|
];
|
||||||
})->values();
|
})->values() : [],
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'status' => true,
|
'status' => true,
|
||||||
'message' => 'Berhasil mendapatkan data',
|
'message' => 'Berhasil mendapatkan data',
|
||||||
'data' => $grouped
|
'data' => [
|
||||||
], 200);
|
'data' => $result,
|
||||||
|
'current_page' => $paginated->currentPage(),
|
||||||
|
'last_page' => $paginated->lastPage(),
|
||||||
|
'per_page' => $paginated->perPage(),
|
||||||
|
'total' => $paginated->total(),
|
||||||
|
]
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,6 +65,24 @@ body {
|
|||||||
color: var(--default-color);
|
color: var(--default-color);
|
||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
font-family: var(--default-font);
|
font-family: var(--default-font);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#order_guest_id {
|
||||||
|
flex: 1;
|
||||||
|
min-height: 920px; /* supaya tetap tinggi walau data kosong */
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@ -612,7 +630,6 @@ h6 {
|
|||||||
background-color: var(--background-color);
|
background-color: var(--background-color);
|
||||||
border-top: 1px solid color-mix(in srgb, var(--accent-color), transparent 75%);
|
border-top: 1px solid color-mix(in srgb, var(--accent-color), transparent 75%);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer .footer-top {
|
.footer .footer-top {
|
||||||
@ -1729,3 +1746,13 @@ section,
|
|||||||
.starter-section {
|
.starter-section {
|
||||||
/* Add your styles here */
|
/* Add your styles here */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cart-floating {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1055;
|
||||||
|
border-radius: 12px 12px 0 0;
|
||||||
|
box-shadow: 0 -2px 8px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
|
let filterState = {};
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
const jenisMenuAwal = $("#tabJenisMenu .nav-link.active").data("filter")
|
const jenisMenuAwal = $("#tabJenisMenu .nav-link.active").data("filter")
|
||||||
let filterState ={
|
filterState ={
|
||||||
jenis_menu: jenisMenuAwal,
|
jenis_menu: jenisMenuAwal,
|
||||||
search:''
|
search:'',
|
||||||
|
per_page: 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
fetchMenu(filterState)
|
fetchMenu(filterState)
|
||||||
@ -33,7 +35,8 @@ $(document).ready(function(){
|
|||||||
|
|
||||||
function changePerPage(select) {
|
function changePerPage(select) {
|
||||||
const newPerPage = parseInt(select.value);
|
const newPerPage = parseInt(select.value);
|
||||||
console.log(newPerPage);
|
filterState.per_page = newPerPage
|
||||||
|
fetchMenu(filterState)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1,3 +1,16 @@
|
|||||||
|
$(document).ready(function () {
|
||||||
|
// Auto render setiap buka offcanvas
|
||||||
|
const cartSidebar = document.getElementById('cartSidebar');
|
||||||
|
cartSidebar.addEventListener('shown.bs.offcanvas', renderCartList);
|
||||||
|
cartSidebar.addEventListener('hidden.bs.offcanvas', function () {
|
||||||
|
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
|
||||||
|
if (cart.length > 0) {
|
||||||
|
$('#floatingCartButton').removeClass('d-none');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function fetchMenu(filter = {}) {
|
function fetchMenu(filter = {}) {
|
||||||
const containerGuest = $("#order_guest_id");
|
const containerGuest = $("#order_guest_id");
|
||||||
@ -13,25 +26,32 @@ function fetchMenu(filter = {}) {
|
|||||||
fetch(`/datamenu?${params}`)
|
fetch(`/datamenu?${params}`)
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (!res.status)
|
if (!res.status){
|
||||||
return containerGuest.html('<p class="text-danger">Gagal Memuat Data...</p>');
|
return containerGuest.html('<p class="text-danger">Gagal Memuat Data...</p>');
|
||||||
|
}
|
||||||
|
const session = JSON.parse(sessionStorage.getItem('customerData') || '{}')
|
||||||
|
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
|
||||||
|
if(cart.length > 0){
|
||||||
|
updateCartCount(cart.length)
|
||||||
|
}
|
||||||
|
if(session.nama_customer){
|
||||||
|
$("#welcomeMessage").html(`Selamat Datang, <strong>${session.nama_customer}</strong> !`)
|
||||||
|
}
|
||||||
const menus = res.data.data || [];
|
const menus = res.data.data || [];
|
||||||
|
|
||||||
if (menus.length === 0)
|
if (menus.length === 0){
|
||||||
return containerGuest.html('<p class="text-muted">Pencarian tidak ditemukan.</p>');
|
return containerGuest.html('<p class="text-muted">Pencarian tidak ditemukan.</p>');
|
||||||
|
}
|
||||||
let html = '<div class="container"><div class="row row-cols-1 row-cols-md-2 g-4">';
|
let html = '<div class="container"><div class="row row-cols-1 row-cols-md-2 g-4">';
|
||||||
if (res.data.last_page > 1) {
|
|
||||||
html += `<div class="col-md-12 d-flex justify-content-end mt-4 gap-2">`;
|
|
||||||
for (let i = 1; i <= res.data.last_page; i++) {
|
|
||||||
html += `
|
|
||||||
<button class="btn btn-outline-success btn-sm ${res.data.current_page === i ? 'active' : ''}"
|
|
||||||
onclick='fetchMenu(${JSON.stringify({...filter, page: i})})'>${i}</button>`;
|
|
||||||
}
|
|
||||||
html += `</div>`;
|
|
||||||
}
|
|
||||||
menus.forEach(menu => {
|
menus.forEach(menu => {
|
||||||
|
let hargaResult = 0;
|
||||||
|
if(session.jenis_customer === "Karyawan RSAB Harapan Kita"){
|
||||||
|
hargaResult = menu.harga_karyawan
|
||||||
|
}else if(session.jenis_customer === "Keluarga Pasien / Penunggu Pasien"){
|
||||||
|
hargaResult = menu.harga_keluarga_pasien
|
||||||
|
}else{
|
||||||
|
hargaResult = menu.harga_public
|
||||||
|
}
|
||||||
html += `
|
html += `
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="card h-100 shadow-sm">
|
<div class="card h-100 shadow-sm">
|
||||||
@ -45,7 +65,7 @@ function fetchMenu(filter = {}) {
|
|||||||
<div class="col-md-7 d-flex flex-column p-3">
|
<div class="col-md-7 d-flex flex-column p-3">
|
||||||
<div class="flex-grow-1">
|
<div class="flex-grow-1">
|
||||||
<h5 class="card-title mb-1">${menu.nama}</h5>
|
<h5 class="card-title mb-1">${menu.nama}</h5>
|
||||||
<p class="mb-1">Rp ${parseInt(menu.harga_public).toLocaleString('id-ID')}</p>
|
<p class="mb-1">Rp ${parseInt(hargaResult).toLocaleString('id-ID')}</p>
|
||||||
<p class="text-muted small">${menu.deskripsi || ''}</p>
|
<p class="text-muted small">${menu.deskripsi || ''}</p>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
${(menu.klasifikasiMenu || []).map(tag => `<span class="badge bg-secondary me-1 mb-1">${tag.nama_kategori_diet}</span>`).join('')}
|
${(menu.klasifikasiMenu || []).map(tag => `<span class="badge bg-secondary me-1 mb-1">${tag.nama_kategori_diet}</span>`).join('')}
|
||||||
@ -55,9 +75,11 @@ function fetchMenu(filter = {}) {
|
|||||||
<!-- Tombol selalu di bawah -->
|
<!-- Tombol selalu di bawah -->
|
||||||
<div class="col-md-12 mt-auto p-2">
|
<div class="col-md-12 mt-auto p-2">
|
||||||
<button class="btn btn-success w-100" onclick="orderMenu(this)"
|
<button class="btn btn-success w-100" onclick="orderMenu(this)"
|
||||||
data-id="${menu.master_menu_id}"
|
data-id="${menu.master_menu_id ?? menu.master_paket_menu_id}"
|
||||||
data-nama_menu="${menu.nama_menu}"
|
data-nama_menu="${menu.nama}"
|
||||||
data-harga="${menu.harga_public}"
|
data-harga="${hargaResult}"
|
||||||
|
data-jenis_menu="${menu.jenis_menu}"
|
||||||
|
data-klasifikasi_menu="${(menu.klasifikasiMenu || []).map(tag => tag.nama_kategori_diet).join(', ')}"
|
||||||
data-foto="${menu.foto}">Order</button>
|
data-foto="${menu.foto}">Order</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -66,21 +88,19 @@ function fetchMenu(filter = {}) {
|
|||||||
`;
|
`;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
html += '</div></div>';
|
html += '</div></div>';
|
||||||
|
|
||||||
// Pagination buttons
|
|
||||||
if (res.data.last_page > 1) {
|
|
||||||
html += `<div class="col-md-12 d-flex justify-content-between align-items-center mt-3">
|
html += `<div class="col-md-12 d-flex justify-content-between align-items-center mt-3">
|
||||||
<div>
|
<div>
|
||||||
<label for="perPageSelect" class="me-2">Tampilkan:</label>
|
<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)">
|
<select id="perPageSelect" class="form-select form-select-sm d-inline-block w-auto" onchange="changePerPage(this)">
|
||||||
<option value="6" ${filter.perPage == 6 ? 'selected' : ''}>6</option>
|
<option value="6" ${filter.per_page == 6 ? 'selected' : ''}>6</option>
|
||||||
<option value="10" ${filter.perPage == 10 ? 'selected' : ''}>10</option>
|
<option value="10" ${filter.per_page == 10 ? 'selected' : ''}>10</option>
|
||||||
<option value="20" ${filter.perPage == 20 ? 'selected' : ''}>20</option>
|
<option value="20" ${filter.per_page == 20 ? 'selected' : ''}>20</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>`
|
||||||
|
// Pagination buttons
|
||||||
|
if (res.data.last_page > 1) {
|
||||||
|
html += `
|
||||||
<div class="d-flex gap-2">`;
|
<div class="d-flex gap-2">`;
|
||||||
for (let i = 1; i <= res.data.last_page; i++) {
|
for (let i = 1; i <= res.data.last_page; i++) {
|
||||||
html += `
|
html += `
|
||||||
@ -98,7 +118,250 @@ function fetchMenu(filter = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const modalCheckout = $("#checkoutModal")
|
||||||
|
function orderMenu(e){
|
||||||
|
const klasifikasiStr = $(e).data('klasifikasi_menu') || '';
|
||||||
|
const tags = klasifikasiStr.split(',').map(tag => tag.trim()).filter(tag => tag !== '')
|
||||||
|
|
||||||
function orderMenu(data){
|
const klasifikasiMenu =tags.map(tag => `
|
||||||
|
<span class="badge bg-secondary me-1 mb-1">${tag}</span>
|
||||||
|
`).join('');
|
||||||
|
|
||||||
|
modalCheckout.modal("show")
|
||||||
|
$('#cathering_order_photo').attr('src', `/gambar/${$(e).data('foto')}`)
|
||||||
|
$('#cathering_order_name').text($(e).data('nama_menu'))
|
||||||
|
$('#cathering_order_price').text("Rp " + parseInt($(e).data('harga')).toLocaleString('id-ID'))
|
||||||
|
$("#tag_klasifikasi_menu").html(klasifikasiMenu)
|
||||||
|
$('#order_input_wrapper').empty();
|
||||||
|
addOrderRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let orderIndex = 0;
|
||||||
|
function addOrderRow(data = {}) {
|
||||||
|
orderIndex++;
|
||||||
|
|
||||||
|
const html = `
|
||||||
|
<div class="row g-2 align-items-center mb-2" data-row="${orderIndex}">
|
||||||
|
<div class="col-md-5 col-sm-12">
|
||||||
|
<input type="date" name="orders[${orderIndex}][tanggal]" value="${data.tanggal || ''}" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5 col-sm-10">
|
||||||
|
<input type="number" name="orders[${orderIndex}][jumlah]" value="${data.jumlah || ''}" class="form-control" placeholder="Masukkan Jumlah" required min="1">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 col-sm-2 d-flex">
|
||||||
|
<button type="button" class="btn btn-danger btn-sm" onclick="removeOrderRow(${orderIndex})"><i class="fa-solid fa-trash"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
$('#order_input_wrapper').append(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeOrderRow(index) {
|
||||||
|
$(`#order_input_wrapper [data-row="${index}"]`).remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function updateCartCount(count) {
|
||||||
|
const $cartCount = $('#cartCount');
|
||||||
|
if (count > 0) {
|
||||||
|
$cartCount.text(count).show();
|
||||||
|
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
|
||||||
|
let totalHarga = cart.reduce((total, item) => {
|
||||||
|
const harga = parseInt(item.harga.replace(/[^\d]/g, '')) || 0;
|
||||||
|
const subtotal = item.pesanan.reduce((sum, p) => sum + (p.jumlah * harga), 0);
|
||||||
|
return total + subtotal;
|
||||||
|
}, 0);
|
||||||
|
$('#floatingCartButton').removeClass('d-none');
|
||||||
|
$('#floatingCartCount').text(count);
|
||||||
|
$('#floatingCartTotal').text('Rp ' + totalHarga.toLocaleString('id-ID'));
|
||||||
|
$('#floatingCartDesc').text(cart[0].nama_menu);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$cartCount.hide();
|
||||||
|
$('#floatingCartButton').addClass('d-none');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#checkoutForm").on('submit', function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
const orders = [];
|
||||||
|
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
|
||||||
|
$("#order_input_wrapper .row").each(function(){
|
||||||
|
const tgl = $(this).find('input[type="date"]').val();
|
||||||
|
const jumlah = $(this).find('input[type="number"]').val();
|
||||||
|
if(tgl && jumlah > 0){
|
||||||
|
orders.push({ tgl, jumlah})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let existingItem = cart.find(item => item.nama_menu === $("#cathering_order_name").text());
|
||||||
|
if(existingItem){
|
||||||
|
orders.forEach(newOrder => {
|
||||||
|
const existingOrder =existingItem.pesanan.find(p => p.tgl === newOrder.tgl)
|
||||||
|
if(existingOrder){
|
||||||
|
existingOrder.jumlah += newOrder.jumlah;
|
||||||
|
}else{
|
||||||
|
existingItem.pesanan.push(newOrder)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
const orderItem ={
|
||||||
|
id:Date.now(),
|
||||||
|
nama_menu : $("#cathering_order_name").text(),
|
||||||
|
harga : $("#cathering_order_price").text(),
|
||||||
|
foto: $('#cathering_order_photo').attr('src'),
|
||||||
|
pesanan : orders
|
||||||
|
}
|
||||||
|
cart.push(orderItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionStorage.setItem('cart', JSON.stringify(cart))
|
||||||
|
updateCartCount(cart.length)
|
||||||
|
modalCheckout.modal('hide')
|
||||||
|
})
|
||||||
|
|
||||||
|
function renderCartList() {
|
||||||
|
$("#cartSidebar").offcanvas('show')
|
||||||
|
$('#floatingCartButton').addClass('d-none');
|
||||||
|
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
|
||||||
|
let total = 0;
|
||||||
|
|
||||||
|
const html = cart.map(item => {
|
||||||
|
const hargaNum = parseInt(item.harga.replace(/[^\d]/g, ''));
|
||||||
|
let pesananHTML = '';
|
||||||
|
|
||||||
|
item.pesanan.forEach((p, i) => {
|
||||||
|
pesananHTML += `
|
||||||
|
<div class="row align-items-center mb-2" data-item-id="${item.id}" data-index="${i}">
|
||||||
|
<div class="col-5">
|
||||||
|
<input type="date" class="form-control form-control-sm tanggal-input" value="${p.tgl}" oninput="onTanggalChange(${item.id}, ${i})">
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<input type="number" class="form-control form-control-sm jumlah-input" value="${p.jumlah}" min="1" oninput="onJumlahChange(${item.id}, ${i})">
|
||||||
|
</div>
|
||||||
|
<div class="col-3 text-end">
|
||||||
|
<button class="btn btn-sm btn-danger" onclick="removeOrderDate(${item.id}, ${i})"><i class="fa-solid fa-trash"></i></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const itemTotal = item.pesanan.reduce((sum, p) => sum + (p.jumlah * hargaNum), 0);
|
||||||
|
total += itemTotal;
|
||||||
|
|
||||||
|
return `
|
||||||
|
<div class="card mb-2 p-2">
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<img src="${item.foto}" class="me-3 rounded" style="width: 60px; height: 60px; object-fit: cover;">
|
||||||
|
<div>
|
||||||
|
<div><strong>${item.nama_menu}</strong></div>
|
||||||
|
<div class="text-muted small">${item.harga}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-2">
|
||||||
|
${pesananHTML}
|
||||||
|
<button class="btn btn-sm btn-outline-primary mt-2" onclick="addOrderDate(${item.id})">+ Tambah Tanggal</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-3 d-flex justify-content-between align-items-center">
|
||||||
|
<div><strong>Total:</strong> <span class="total-per-item" data-item-id="${item.id}">Rp ${itemTotal.toLocaleString('id-ID')}</span></div>
|
||||||
|
<button class="btn btn-sm btn-outline-danger" onclick="removeCartItem(${item.id})">
|
||||||
|
<i class="fa-solid fa-trash"></i> Hapus Pesanan
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
$('#cartListContainer').html(html);
|
||||||
|
$('#cartTotal').text('Rp ' + total.toLocaleString('id-ID'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function addOrderDate(itemId) {
|
||||||
|
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
|
||||||
|
const item = cart.find(i => i.id === itemId);
|
||||||
|
if (item) {
|
||||||
|
item.pesanan.push({ tgl: '', jumlah: 1 });
|
||||||
|
sessionStorage.setItem('cart', JSON.stringify(cart));
|
||||||
|
renderCartList();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeOrderDate(itemId, index) {
|
||||||
|
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
|
||||||
|
const item = cart.find(i => i.id === itemId);
|
||||||
|
if (item && item.pesanan.length > index) {
|
||||||
|
item.pesanan.splice(index, 1);
|
||||||
|
sessionStorage.setItem('cart', JSON.stringify(cart));
|
||||||
|
renderCartList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeCartItem(itemId){
|
||||||
|
let cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
|
||||||
|
cart = cart.filter(i => i.id !== itemId);
|
||||||
|
sessionStorage.setItem('cart', JSON.stringify(cart));
|
||||||
|
updateCartCount(cart.length);
|
||||||
|
renderCartList()
|
||||||
|
}
|
||||||
|
|
||||||
|
function onJumlahChange(itemId, index) {
|
||||||
|
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
|
||||||
|
const jumlahInput = document.querySelector(`div[data-item-id='${itemId}'][data-index='${index}'] .jumlah-input`).value;
|
||||||
|
if (!isNaN(jumlahInput)) {
|
||||||
|
cart.forEach(item => {
|
||||||
|
if (item.id === itemId) {
|
||||||
|
item.pesanan[index].jumlah = parseInt(jumlahInput);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sessionStorage.setItem('cart', JSON.stringify(cart));
|
||||||
|
renderCartList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onTanggalChange(itemId, index) {
|
||||||
|
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
|
||||||
|
const tanggalInput = document.querySelector(`div[data-item-id='${itemId}'][data-index='${index}'] .tanggal-input`).value;
|
||||||
|
cart.forEach(item => {
|
||||||
|
if (item.id === itemId) {
|
||||||
|
item.pesanan[index].tgl = tanggalInput;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sessionStorage.setItem('cart', JSON.stringify(cart));
|
||||||
|
validateCheckoutButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderCartTotalOnly() {
|
||||||
|
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
|
||||||
|
let total = 0;
|
||||||
|
cart.forEach(item => {
|
||||||
|
const hargaNum = parseInt(item.harga.replace(/[^\d]/g, ''));
|
||||||
|
const itemTotal = item.pesanan.reduce((sum, p) => sum + (p.jumlah * hargaNum), 0);
|
||||||
|
total += itemTotal;
|
||||||
|
});
|
||||||
|
$('#cartTotal').text('Rp ' + total.toLocaleString('id-ID'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateFloatingCartButton() {
|
||||||
|
const cart = JSON.parse(sessionStorage.getItem('cart') || '[]');
|
||||||
|
const totalItem = cart.reduce((sum, item) => {
|
||||||
|
return sum + item.pesanan.reduce((s, p) => s + p.jumlah, 0);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
const totalHarga = cart.reduce((sum, item) => {
|
||||||
|
const harga = parseInt(item.harga.replace(/[^\d]/g, ''));
|
||||||
|
return sum + item.pesanan.reduce((s, p) => s + (p.jumlah * harga), 0);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
if (cart.length > 0) {
|
||||||
|
$('#floatingCartButton').removeClass('d-none');
|
||||||
|
$('#floatingCartCount').text(totalItem);
|
||||||
|
$('#floatingCartTotal').text('Rp ' + totalHarga.toLocaleString('id-ID'));
|
||||||
|
$('#floatingCartDesc').text(`Total pesanan dari ${cart[0].nama_menu}`);
|
||||||
|
} else {
|
||||||
|
$('#floatingCartButton').addClass('d-none');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
24
public/js/order_guest/register.js
Normal file
24
public/js/order_guest/register.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
$(document).ready(function(){
|
||||||
|
const modal = new bootstrap.Modal(document.getElementById('registerModal'), {
|
||||||
|
backdrop: 'static', // Tidak bisa klik luar
|
||||||
|
keyboard: false // Tidak bisa ESC
|
||||||
|
});
|
||||||
|
if(!sessionStorage.getItem('customerData')){
|
||||||
|
modal.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#formRegister").on('submit', function(e){
|
||||||
|
e.preventDefault()
|
||||||
|
if(this.checkValidity()){
|
||||||
|
const formData =Object.fromEntries(new FormData(this).entries())
|
||||||
|
sessionStorage.setItem('customerData', JSON.stringify(formData))
|
||||||
|
|
||||||
|
modal.hide()
|
||||||
|
if(formData.nama_customer){
|
||||||
|
$("#welcomeMessage").html(`Selamat Datang, <strong>${formData.nama_customer}</strong> !`)
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
this.reportValidity()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
@ -0,0 +1,43 @@
|
|||||||
|
<div class="modal fade"
|
||||||
|
id="checkoutModal"
|
||||||
|
tabindex="-1"
|
||||||
|
aria-labelledby="exampleModalLabel"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1 class="modal-title fs-5" id="exampleModalLabel">Website Cathering RSAB Harapan Kita</h1>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<form id="checkoutForm">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mt-3">
|
||||||
|
<div class="col-md-4 text-center mb-3 mb-md-0">
|
||||||
|
<img alt="Foto Menu" id="cathering_order_photo" lass="img-fluid rounded shadow" style="max-width: 250px; height: auto;">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h5 id="cathering_order_name" class="mb-2"></h5>
|
||||||
|
<p class="mb-0">
|
||||||
|
<strong>Harga:</strong> <span id="cathering_order_price"></span>
|
||||||
|
</p>
|
||||||
|
<div id="tag_klasifikasi_menu" class="mt-2"></div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-12">
|
||||||
|
<label class="form-label mt-3">Tanggal & Jumlah Pengambilan</label>
|
||||||
|
<div id="order_input_wrapper">
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn btn-sm btn-primary mt-2" onclick="addOrderRow()">+ Tambah Tanggal</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="submit" class="btn btn-success">Lanjutkan</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@ -4,6 +4,9 @@
|
|||||||
<section class="section py-5 bg-light">
|
<section class="section py-5 bg-light">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
<div class="col-md-12 mb-2">
|
||||||
|
<div id="welcomeMessage"></div>
|
||||||
|
</div>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<ul class="nav nav-tabs mb-4 " id="tabJenisMenu">
|
<ul class="nav nav-tabs mb-4 " id="tabJenisMenu">
|
||||||
<li class="nav-item"><a class="nav-link active text-success" href="#" data-filter="makanan">Makanan</a></li>
|
<li class="nav-item"><a class="nav-link active text-success" href="#" data-filter="makanan">Makanan</a></li>
|
||||||
@ -19,10 +22,35 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="order_guest_id"></div>
|
<div id="order_guest_id"></div>
|
||||||
|
<div id="floatingCartButton"
|
||||||
|
class="cart-floating bg-success text-white rounded d-none shadow-lg"
|
||||||
|
onclick="renderCartList()"
|
||||||
|
style="cursor: pointer; position: fixed; bottom: 15px; left: 50%; transform: translateX(-50%); z-index: 1050; width: 90%; max-width: 500px;">
|
||||||
|
<div class="d-flex justify-content-between align-items-center px-3 py-2">
|
||||||
|
<div>
|
||||||
|
<strong><span id="floatingCartCount">0</span> item</strong><br>
|
||||||
|
<small id="floatingCartDesc">Isi keranjang anda</small>
|
||||||
|
</div>
|
||||||
|
<div class="d-flex align-items-center">
|
||||||
|
<strong class="me-3 text-white" id="floatingCartTotal">Rp 0</strong>
|
||||||
|
<div class="btn btn-light btn-sm">
|
||||||
|
<i class="fa-solid fa-cart-shopping text-success"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<script src="{{ ver('/js/order_guest/_init.js') }}"></script>
|
@include('guest.register')
|
||||||
|
@include('guest.checkout_order')
|
||||||
|
@include('guest.keranjang')
|
||||||
|
|
||||||
|
<script src="{{ ver('/js/order_guest/register.js') }}"></script>
|
||||||
|
<script src="{{ ver('/js/order_guest/functions.js') }}"></script>
|
||||||
<script src="{{ ver('/js/order_guest/index.js') }}"></script>
|
<script src="{{ ver('/js/order_guest/index.js') }}"></script>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
22
resources/views/guest/keranjang.blade.php
Normal file
22
resources/views/guest/keranjang.blade.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<div class="offcanvas offcanvas-end" tabindex="-1" id="cartSidebar">
|
||||||
|
<div class="offcanvas-header">
|
||||||
|
<h5 class="offcanvas-title">Keranjang Saya</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="offcanvas"></button>
|
||||||
|
</div>
|
||||||
|
<div class="offcanvas-body" id="cartListContainer">
|
||||||
|
<!-- Daftar pesanan akan muncul di sini -->
|
||||||
|
<div class="mt-auto border-top pt-3">
|
||||||
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<strong>Total:</strong>
|
||||||
|
<strong id="cartTotal">Rp 0</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="border-top p-3">
|
||||||
|
<div class="d-flex justify-content-between mb-2">
|
||||||
|
<strong>Total Bayar:</strong>
|
||||||
|
<strong id="cartTotal">Rp 0</strong>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-success w-100" onclick="checkoutCart()">Checkout</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@ -12,7 +12,12 @@
|
|||||||
|
|
||||||
<nav id="navmenu" class="navmenu">
|
<nav id="navmenu" class="navmenu">
|
||||||
{{-- <i class="mobile-nav-toggle d-xl-none bi bi-list"></i> --}}
|
{{-- <i class="mobile-nav-toggle d-xl-none bi bi-list"></i> --}}
|
||||||
<button type="button" class="btn btn-sm btn-success"><i class="fa-solid fa-cart-shopping"></i></button>
|
<button type="button" class="btn btn-sm btn-success position-relative" id="cartButton" data-bs-toggle="offcanvas" onclick="renderCartList()">
|
||||||
|
<i class="fa-solid fa-cart-shopping"></i>
|
||||||
|
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger" id="cartCount" style="display: none;">
|
||||||
|
0
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,67 @@
|
|||||||
|
<div class="modal fade"
|
||||||
|
id="registerModal"
|
||||||
|
tabindex="-1"
|
||||||
|
aria-labelledby="exampleModalLabel"
|
||||||
|
aria-hidden="true"
|
||||||
|
>
|
||||||
|
<div class="modal-dialog modal-lg modal-dialog-centered">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1 class="modal-title fs-5" id="exampleModalLabel">Website Cathering RSAB Harapan Kita</h1>
|
||||||
|
</div>
|
||||||
|
<form id="formRegister">
|
||||||
|
<div class="modal-body">
|
||||||
|
<div class="mb-3">
|
||||||
|
<h5>Selamat Datang Di Website Cathering RSAB Harapan Kita, <br>
|
||||||
|
Bantu Kami Menemukan Referensi Makanan Terbaik untuk Kesehatan Anda.</h5>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="exampleInputEmail1" class="form-label">Apakah Anda Seorang</label>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio" name="jenis_customer" id="radio_karyawan" value="Karyawan RSAB Harapan Kita" required>
|
||||||
|
<label class="form-check-label" for="radio_karyawan" >
|
||||||
|
Karyawan RSAB Harapan Kita
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio" name="jenis_customer" id="radio_kp" value="Keluarga Pasien / Penunggu Pasien" required>
|
||||||
|
<label class="form-check-label" for="radio_kp">
|
||||||
|
Keluarga Pasien / Penunggu Pasien
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input class="form-check-input" type="radio" name="jenis_customer" id="radio_public" value="Masyarakat Umum" required>
|
||||||
|
<label class="form-check-label" for="radio_public">
|
||||||
|
Masyarakat Umum
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="exampleInputPassword1" class="form-label">Nama Anda ?</label>
|
||||||
|
<input type="text" class="form-control" name="nama_customer" id="nama_customer" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="exampleInputPassword1" class="form-label">Jenis Kelamin ?</label>
|
||||||
|
<select class="form-select" aria-label="Default select example" name="jenis_kelamin_customer" id="jenis_kelamin_customer" required>
|
||||||
|
<option value="" selected disabled>Pilih Jenis Kelamin</option>
|
||||||
|
<option value="Laki Laki">Laki Laki</option>
|
||||||
|
<option value="Perempuan">Perempuan</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="exampleInputPassword1" class="form-label">Tinggi Badan ?</label>
|
||||||
|
<input type="number" class="form-control" name="tinggi_badan_customer" id="tinggi_badan_customer">
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="exampleInputPassword1" class="form-label">Berat Badan ?</label>
|
||||||
|
<input type="number" class="form-control" name="berat_badan_customer" id="berat_badan_customer">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="submit" class="btn btn-primary">Lanjutkan</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@ -3,8 +3,6 @@
|
|||||||
use App\Http\Controllers\CustomerController;
|
use App\Http\Controllers\CustomerController;
|
||||||
use App\Http\Controllers\KlasifikasiMenuController;
|
use App\Http\Controllers\KlasifikasiMenuController;
|
||||||
use App\Http\Controllers\MenuController;
|
use App\Http\Controllers\MenuController;
|
||||||
use App\Models\Menu;
|
|
||||||
use Illuminate\Pagination\LengthAwarePaginator;
|
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user