diff --git a/app/Http/Controllers/CustomerController.php b/app/Http/Controllers/CustomerController.php
index 2afd6d7..d53a1e0 100644
--- a/app/Http/Controllers/CustomerController.php
+++ b/app/Http/Controllers/CustomerController.php
@@ -18,7 +18,7 @@ class CustomerController extends Controller
public function dataOrder(){
$search = request('search');
$jenis_menu = request('jenis_menu');
- $perPage = request()->get('perPage', 1);
+ $perPage = request()->get('per_page', 6);
if($jenis_menu === "paket"){
return self::dataPaketMenuOrder($search, $perPage);
}
@@ -102,53 +102,65 @@ class CustomerController extends Controller
- private static function dataPaketMenuOrder($search = null){
- $query = DB::connection('dbOrderGizi')->table('public.master_paket_menu as mpn')
- ->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);
+ private static function dataPaketMenuOrder($search = null, $perPage){
+ $query = DB::connection('dbOrderGizi')->table('public.master_paket_menu as mpn')->where('mpn.statusenabled', true);
+
+ if(!empty($search)){
+ $query->where('mpn.nama_paket', 'ILIKE', '%' . $search . '%');
+ }
- if(!empty($search)){
- $query->where(function($q) use($search){
- $q->where('mpn.nama_paket', 'ILIKE', '%' . $search . '%')
- ->orWhere('kd.nama_kategori_diet', 'ILIKE', '%'. $search . '%');
- });
- }
+ $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();
+
+ $klasifikasi = DB::connection('dbOrderGizi')
+ ->table('public.klasifikasi_menu_diet as kmd')
+ ->join('public.kategori_diet as kd', 'kd.kategori_diet_id', '=', 'kmd.kategori_diet_id')
+ ->whereIn('kmd.master_paket_menu_id', $paketMenuIds)
+ ->select('kmd.master_paket_menu_id', 'kd.kategori_diet_id', 'kd.nama_kategori_diet')
+ ->get()
+ ->groupBy('master_paket_menu_id');
- $paketMenu = $query->get();
-
-
- $grouped = $paketMenu->groupBy('master_paket_menu_id')->map(function($items){
- $first = $items->first();
- $klasifikasiMenu = $items->filter(fn($d) => $d->kategori_diet_id !== null)
- ->unique('kategori_diet_id')
- ->map(function($items) {
- return [
- 'kategori_diet_id' => $items->kategori_diet_id,
- 'nama_kategori_diet'=> $items->nama_kategori_diet
- ];
- })->values();
- return [
- 'master_paket_menu_id' => $first->master_paket_menu_id,
- 'nama' => $first->nama_paket,
- 'foto' => $first->foto,
- 'jenis_menu' => "paket",
- 'harga_public' => $first->harga_public,
- 'harga_karyawan' => $first->harga_karyawan,
- 'harga_keluarga_pasien' => $first->harga_keluarga_pasien,
- 'status' => $first->status,
- 'deskripsi' => $first->deskripsi,
- 'klasifikasiMenu' => $klasifikasiMenu
- ];
- })->values();
+ $result = collect($paginated->items())->map(function ($paketMenu) use ($klasifikasi) {
+ return [
+ 'master_paket_menu_id' => $paketMenu->master_paket_menu_id,
+ 'nama' => $paketMenu->nama_paket,
+ 'foto' => $paketMenu->foto,
+ 'jenis_menu' => "paket",
+ 'harga_public' => $paketMenu->harga_public,
+ 'harga_karyawan' => $paketMenu->harga_karyawan,
+ 'harga_keluarga_pasien' => $paketMenu->harga_keluarga_pasien,
+ 'status' => $paketMenu->status,
+ 'deskripsi' => $paketMenu->deskripsi,
+ '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() : [],
+ ];
+ });
+
return response()->json([
- 'status' => true,
- 'message' => 'Berhasil mendapatkan data',
- 'data' => $grouped
- ], 200);
+ 'status' => true,
+ 'message' => 'Berhasil mendapatkan data',
+ 'data' => [
+ 'data' => $result,
+ 'current_page' => $paginated->currentPage(),
+ 'last_page' => $paginated->lastPage(),
+ 'per_page' => $paginated->perPage(),
+ 'total' => $paginated->total(),
+ ]
+ ]);
}
}
diff --git a/public/asset_guests/css/main.css b/public/asset_guests/css/main.css
index 3791bc1..b51efa3 100644
--- a/public/asset_guests/css/main.css
+++ b/public/asset_guests/css/main.css
@@ -65,6 +65,24 @@ body {
color: var(--default-color);
background-color: var(--background-color);
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 {
@@ -612,7 +630,6 @@ h6 {
background-color: var(--background-color);
border-top: 1px solid color-mix(in srgb, var(--accent-color), transparent 75%);
font-size: 14px;
- position: relative;
}
.footer .footer-top {
@@ -1729,3 +1746,13 @@ section,
.starter-section {
/* 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);
+}
diff --git a/public/js/order_guest/_init.js b/public/js/order_guest/functions.js
similarity index 86%
rename from public/js/order_guest/_init.js
rename to public/js/order_guest/functions.js
index 1daead8..e705c8f 100644
--- a/public/js/order_guest/_init.js
+++ b/public/js/order_guest/functions.js
@@ -1,8 +1,10 @@
+let filterState = {};
$(document).ready(function(){
const jenisMenuAwal = $("#tabJenisMenu .nav-link.active").data("filter")
- let filterState ={
+ filterState ={
jenis_menu: jenisMenuAwal,
- search:''
+ search:'',
+ per_page: 6,
}
fetchMenu(filterState)
@@ -33,7 +35,8 @@ $(document).ready(function(){
function changePerPage(select) {
const newPerPage = parseInt(select.value);
- console.log(newPerPage);
-
+ filterState.per_page = newPerPage
+ fetchMenu(filterState)
}
+
diff --git a/public/js/order_guest/index.js b/public/js/order_guest/index.js
index e2dfe8c..359f5d2 100644
--- a/public/js/order_guest/index.js
+++ b/public/js/order_guest/index.js
@@ -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 = {}) {
const containerGuest = $("#order_guest_id");
@@ -7,31 +20,38 @@ function fetchMenu(filter = {}) {
search: filter.search || '',
jenis_menu: filter.jenis_menu || ''
}).toString();
-
+
containerGuest.html('
Memuat data....
');
fetch(`/datamenu?${params}`)
.then(res => res.json())
.then(res => {
- if (!res.status)
+ if (!res.status){
return containerGuest.html('Gagal Memuat Data...
');
-
- const menus = res.data.data || [];
-
- if (menus.length === 0)
- return containerGuest.html('Pencarian tidak ditemukan.
');
-
- let html = '';
- if (res.data.last_page > 1) {
- html += `
`;
- for (let i = 1; i <= res.data.last_page; i++) {
- html += `
- ${i} `;
- }
- html += `
`;
}
+ 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,
${session.nama_customer} !`)
+ }
+ const menus = res.data.data || [];
+
+ if (menus.length === 0){
+ return containerGuest.html('
Pencarian tidak ditemukan.
');
+ }
+ let html = '
';
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 += `
@@ -45,7 +65,7 @@ function fetchMenu(filter = {}) {
${menu.nama}
-
Rp ${parseInt(menu.harga_public).toLocaleString('id-ID')}
+
Rp ${parseInt(hargaResult).toLocaleString('id-ID')}
${menu.deskripsi || ''}
${(menu.klasifikasiMenu || []).map(tag => `
${tag.nama_kategori_diet} `).join('')}
@@ -55,9 +75,11 @@ function fetchMenu(filter = {}) {
Order
@@ -65,22 +87,20 @@ function fetchMenu(filter = {}) {
`;
});
-
-
-
- html += '
';
-
- // Pagination buttons
- if (res.data.last_page > 1) {
- html += `
+
+ html += '
';
+ html += `
Tampilkan:
- 6
- 10
- 20
+ 6
+ 10
+ 20
-
+
`
+ // Pagination buttons
+ if (res.data.last_page > 1) {
+ html += `
`;
for (let i = 1; i <= res.data.last_page; i++) {
html += `
@@ -98,7 +118,250 @@ function fetchMenu(filter = {}) {
}
-
-function orderMenu(data){
-
+const modalCheckout = $("#checkoutModal")
+function orderMenu(e){
+ const klasifikasiStr = $(e).data('klasifikasi_menu') || '';
+ const tags = klasifikasiStr.split(',').map(tag => tag.trim()).filter(tag => tag !== '')
+
+ const klasifikasiMenu =tags.map(tag => `
+
${tag}
+ `).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 = `
+
+ `;
+ $('#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 += `
+
+ `;
+ });
+
+ const itemTotal = item.pesanan.reduce((sum, p) => sum + (p.jumlah * hargaNum), 0);
+ total += itemTotal;
+
+ return `
+
+
+
+
+
${item.nama_menu}
+
${item.harga}
+
+
+
+
+ ${pesananHTML}
+ + Tambah Tanggal
+
+
+
+
Total: Rp ${itemTotal.toLocaleString('id-ID')}
+
+ Hapus Pesanan
+
+
+
+ `;
+ }).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');
+ }
+ }
diff --git a/public/js/order_guest/register.js b/public/js/order_guest/register.js
new file mode 100644
index 0000000..bf77ebd
--- /dev/null
+++ b/public/js/order_guest/register.js
@@ -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,
${formData.nama_customer} !`)
+ }
+ }else{
+ this.reportValidity()
+ }
+ })
+})
\ No newline at end of file
diff --git a/resources/views/guest/checkout_order.blade.php b/resources/views/guest/checkout_order.blade.php
index e69de29..044b097 100644
--- a/resources/views/guest/checkout_order.blade.php
+++ b/resources/views/guest/checkout_order.blade.php
@@ -0,0 +1,43 @@
+
\ No newline at end of file
diff --git a/resources/views/guest/index.blade.php b/resources/views/guest/index.blade.php
index abdf49d..45793c6 100644
--- a/resources/views/guest/index.blade.php
+++ b/resources/views/guest/index.blade.php
@@ -4,6 +4,9 @@
+
+
+
+ 0 item
+ Isi keranjang anda
+
+
+
+
+
+
+
-
+@include('guest.register')
+@include('guest.checkout_order')
+@include('guest.keranjang')
+
+
+
@endsection
diff --git a/resources/views/guest/keranjang.blade.php b/resources/views/guest/keranjang.blade.php
new file mode 100644
index 0000000..992749c
--- /dev/null
+++ b/resources/views/guest/keranjang.blade.php
@@ -0,0 +1,22 @@
+
diff --git a/resources/views/guest/layout/partials/header.blade.php b/resources/views/guest/layout/partials/header.blade.php
index 7a21583..b6bf4fb 100644
--- a/resources/views/guest/layout/partials/header.blade.php
+++ b/resources/views/guest/layout/partials/header.blade.php
@@ -12,7 +12,12 @@
diff --git a/resources/views/guest/register.blade.php b/resources/views/guest/register.blade.php
index e69de29..c8a93ff 100644
--- a/resources/views/guest/register.blade.php
+++ b/resources/views/guest/register.blade.php
@@ -0,0 +1,67 @@
+
\ No newline at end of file
diff --git a/routes/web.php b/routes/web.php
index 03f4b3f..3ea3d87 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -3,8 +3,6 @@
use App\Http\Controllers\CustomerController;
use App\Http\Controllers\KlasifikasiMenuController;
use App\Http\Controllers\MenuController;
-use App\Models\Menu;
-use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\Route;