// ======================= // DATA SETUP // ======================= let checkout_biodata = JSON.parse(sessionStorage.getItem('checkout_biodata') || '{}'); let order_id = sessionStorage.getItem('order_id') || '[]'; // ======================= // EVENT ON LOAD // ======================= document.addEventListener('DOMContentLoaded', () => { $("#cartButton").addClass('d-none'); $("#no_order_result").val(order_id) let currentStep = 0; let orderDate='' let deadline='' let time_order='' // Setup button step document.querySelectorAll('.next-step').forEach(btn => { btn.addEventListener('click', async () => { let cart = JSON.parse(sessionStorage.getItem('cart') || '[]'); if (cart.length === 0) { window.location.href = "/"; return; } if (currentStep === 0){ if(!validateStepOne()) return isiKonfirmasi(); currentStep++; showStep(currentStep); }else if(currentStep === 1){ const {isValid, errorMessage} =validateCartBeforeSubmit(); if (!isValid) { alert(errorMessage); return } let checkout_biodata = JSON.parse(sessionStorage.getItem('checkout_biodata') || '{}'); if (!checkout_biodata.nama_pemesan) { Swal.fire({ title: 'Biodata Belum Terisi!', text: 'Lakukan Pengisian biodata terlebih dahulu.', icon: 'warning', confirmButtonText: 'oke!', }).then(() => { window.location.href = "/checkout"; }); return } let cart = JSON.parse(sessionStorage.getItem('cart') || '[]'); for (const item of cart) { for (const p of item.pesanan) { const result = validateTanggalPemesanan(item, p.tgl); if (!result.valid) { alert(result.message); return; // hentikan di sini, tidak lanjut } } } if (!sessionStorage.getItem('order_id')) { await submitOrderToServer(); // async function simpan ke server } time_order = sessionStorage.getItem('time_order') orderDate = new Date(time_order); deadline = new Date(orderDate.getTime() + 10 * 60 * 1000) updateCountdown() currentStep++; showStep(currentStep) }else if(currentStep === 2){ renderCartSummary() } }); }); document.querySelectorAll('.prev-step').forEach(btn => { btn.addEventListener('click', () => { let cart = JSON.parse(sessionStorage.getItem('cart') || '[]'); if (cart.length === 0) { window.location.href = "/"; return; } if (currentStep > 0) { currentStep--; showStep(currentStep); } }); }); // Inisialisasi tampilan dan data renderCartSummary(); showStep(currentStep); isiKonfirmasi(); toggleCustomerFields() document.getElementById('no_order_display').textContent = order_id const countDownPayment = document.getElementById('countdownPayment') function updateCountdown(){ const now = new Date(); orderDate = new Date(time_order); deadline = new Date(orderDate.getTime() + 10 * 60 * 1000) const distance = deadline - now if(distance <= 0){ countDownPayment.textContent = "Waktu Habis Lakukan Pemesanan Ulang"; return; } const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)) const seconds = Math.floor((distance % (1000 * 60)) / 1000) countDownPayment.textContent = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}` } updateCountdown(); const interval = setInterval(() => { updateCountdown() if(new Date() >= deadline) clearInterval(interval) }, 1000) }); // ======================= // FUNGSI STEP // ======================= const steps = document.querySelectorAll('.form-step'); const progressBar = document.getElementById('stepProgressBar'); function showStep(index) { steps.forEach((step, i) => { step.classList.toggle('active', i === index); step.classList.toggle('d-none', i !== index); }); const total = steps.length; const progress = ((index + 1) / total) * 100; progressBar.style.width = progress + '%'; progressBar.innerText = `Langkah ${index + 1} dari ${total}`; for(let i = 1; i <= total; i++){ const circle = document.getElementById(`step-circle-${i}`) if(circle){ circle.classList.toggle('active', i === index + 1) } } } // ======================= // FUNGSI BIODATA // ======================= function toggleCustomerFields() { const selected = $('input[name="jenis_customer"]:checked').val(); if (selected === 'Karyawan RSAB Harapan Kita') { $('.karyawan').show(); $('.pasien, .umum').hide(); } else if (selected === 'Keluarga Pasien / Penunggu Pasien') { $('.pasien').show(); $('.karyawan, .umum').hide(); } else { $('.umum').show(); $('.karyawan, .pasien').hide(); } } $('input[name="jenis_customer"]').on('change', toggleCustomerFields); toggleCustomerFields(); if (typeof checkout_biodata === 'object') { if (checkout_biodata.jenis_customer) { $(`input[name="jenis_customer"][value="${checkout_biodata.jenis_customer}"]`).prop('checked', true); } if(checkout_biodata.jenis_kelamin){ $(`input[name="jenis_kelamin"][value="${checkout_biodata.jenis_kelamin}"]`).prop('checked', true); } $('#nama_pemesan').val(checkout_biodata.nama_pemesan); // $('#tanggal_lahir').val(checkout_biodata.tanggal_lahir); $('#tinggi_badan').val(checkout_biodata.tinggi_badan); $('#berat_badan').val(checkout_biodata.berat_badan); $('#no_whatsapp').val(checkout_biodata.no_whatsapp); $('#nama_pasien').val(checkout_biodata.nama_pasien); $('#ruang_perawatan').val(checkout_biodata.ruang_perawatan); $('#no_kamar').val(checkout_biodata.no_kamar); $('#kelas_perawatan').val(checkout_biodata.kelas_perawatan); $('#bagian_instalasi').val(checkout_biodata.bagian_instalasi); $('#no_ekstensien').val(checkout_biodata.no_ekstensien); $('#email').val(checkout_biodata.email); $('#alamat').val(checkout_biodata.alamat); } function isiKonfirmasi() { const biodata = { jenis_customer: $('input[name="jenis_customer"]:checked').val(), nama_pemesan: $('#nama_pemesan').val(), jenis_kelamin: $('input[name="jenis_kelamin"]:checked').val(), // tanggal_lahir: $('#tanggal_lahir').val(), tinggi_badan: $('#tinggi_badan').val(), berat_badan: $('#berat_badan').val(), no_whatsapp: $('#no_whatsapp').val(), nama_pasien: $('#nama_pasien').val(), ruang_perawatan: $('#ruang_perawatan').val(), no_kamar: $('#no_kamar').val(), kelas_perawatan: $('#kelas_perawatan').val(), bagian_instalasi: $('#bagian_instalasi').val(), no_ekstensien: $('#no_ekstensien').val(), email: $('#email').val(), alamat: $('#alamat').val(), }; sessionStorage.setItem('checkout_biodata', JSON.stringify(biodata)); checkout_biodata = biodata; renderCartSummary(); } // ======================= // FUNGSI CART / PESANAN // ======================= function renderCartSummary() { const container = document.getElementById('checkout_cart_summary'); container.innerHTML = ''; let totalKeseluruhan = 0; const carts = JSON.parse(sessionStorage.getItem('cart') || '[]'); carts.forEach((item) => { const pesananList = Array.isArray(item.pesanan) ? item.pesanan : []; let pesananHTML = ''; const harga = checkout_biodata.jenis_customer === 'Karyawan RSAB Harapan Kita' ? item.harga_karyawan || 0 : item.harga_public || 0; const itemTotal = pesananList.reduce((sum, p) => sum + (p.jumlah * harga), 0); totalKeseluruhan += itemTotal; pesananList.forEach((p, i) => { const selectedDate = new Date(p.tgl); const now = new Date(); const isToday = selectedDate.toDateString() === now.toDateString(); const jam = now.getHours(); const disableSiang = isToday && jam >= 10; const disableSore = isToday && jam >= 13; const countDate = pesananList.length; pesananHTML += `
${item.apakah_someday ? `` : `
`}
${countDate > 1 ? `` : ''}
`; }); const itemHTML = `
${item.nama_menu}
${item.nama_menu}
Rp ${parseInt(harga).toLocaleString('id-ID')}
${item.deskripsi ? `

${item.deskripsi}

` : ''}
${item.apakah_someday ? 'Tersedia setiap hari (Senin - Minggu)' : (item.tgl_tersedia ? `Tersedia pada tanggal: ${item.tgl_tersedia}` : 'Tidak ada info tanggal tersedia')}
Menu: ${item.apakah_someday ? 'Someday' : 'Menu Normal'}
${item.kalori ? `
Kalori: ${item.kalori} kkal
` : ''}
Silakan isi tanggal pemesanan dan pilih karbohidrat yang diinginkan
${pesananHTML}
'
Total: Rp ${itemTotal.toLocaleString('id-ID')}
`; container.insertAdjacentHTML('beforeend', itemHTML); pesananList.forEach((p, i) => initFlatpickrTersedia(item, i)); }); container.insertAdjacentHTML('beforeend', `

Total Keseluruhan: Rp ${totalKeseluruhan.toLocaleString('id-ID')}
`); document.getElementById('no_order_price').textContent = 'Rp ' + totalKeseluruhan.toLocaleString('id-ID'); } // ======================= // EVENT HANDLER FIELD // ======================= function onJumlahChange(itemId, index) { let cart = JSON.parse(sessionStorage.getItem('cart') || '[]'); const input = document.querySelector(`div[data-item-id='${itemId}'][data-index='${index}'] .jumlah-input`); if (!isNaN(input.value)) { cart.find(item => item.id === itemId).pesanan[index].jumlah = parseInt(input.value); sessionStorage.setItem('cart', JSON.stringify(cart)); isiKonfirmasi(); } } function onTanggalChange(itemId, index) { let cart = JSON.parse(sessionStorage.getItem('cart') || '[]'); const input = document.querySelector(`div[data-item-id='${itemId}'][data-index='${index}'] .tanggal-input`); cart.find(item => item.id === itemId).pesanan[index].tgl = input.value; sessionStorage.setItem('cart', JSON.stringify(cart)); renderCartSummary(); } function onKarbohidratChange(itemId, index){ let cart = JSON.parse(sessionStorage.getItem('cart') || '[]'); const input = document.querySelector(`div[data-item-id='${itemId}'][data-index='${index}'] .karbohidrat-input`); cart.find(item => item.id === itemId).pesanan[index].karbohidrat_id = parseInt(input.value); sessionStorage.setItem('cart', JSON.stringify(cart)); renderCartSummary(); } function onKategoriChange(itemId, index, isToday) { let cart = JSON.parse(sessionStorage.getItem('cart') || '[]'); const selectEl = document.querySelector(`.kategori-pemesanan-input[data-item-id='${itemId}'][data-index='${index}']`); const kategori = selectEl.value; let now = new Date(); let jam = now.getHours(); console.log(isToday); if (kategori === "Makan Siang" && isToday && jam >= 10) { batasLewat = true; alert("Pemesanan Makan Siang hanya bisa dilakukan sebelum jam 10:00."); } else if (kategori === "Makan Sore" && isToday && jam >= 15) { batasLewat = true; alert("Pemesanan Makan Sore hanya bisa dilakukan sebelum jam 13:00."); } if (batasLewat) { // Kembalikan ke value sebelumnya const previous = selectEl.dataset.previousValue || ''; selectEl.value = previous; return; } const item = cart.find(item => item.id === itemId); if (item && item.pesanan && item.pesanan[index]) { item.pesanan[index].kategoriPemesanan = kategori; sessionStorage.setItem('cart', JSON.stringify(cart)); renderCartSummary(); } } // ======================= // TAMBAH / HAPUS PESANAN // ======================= function addOrderDate(itemId, sore) { let cart = JSON.parse(sessionStorage.getItem('cart') || '[]'); const item = cart.find(i => i.id === itemId); if (item && Array.isArray(item.pesanan)) { item.pesanan.push({ tgl: '', jumlah: 1, kategoriPemesanan: sore ? 'Makan Sore' : 'Makan Siang' }); sessionStorage.setItem('cart', JSON.stringify(cart)); renderCartSummary(); } } function removeOrderDate(itemId, index, count) { let cart = JSON.parse(sessionStorage.getItem('cart') || '[]'); const item = cart.find(i => i.id === itemId); if(count == 1){ cart = cart.filter(i => i.id !== itemId); sessionStorage.setItem('cart', JSON.stringify(cart)); }else if(item && Array.isArray(item.pesanan) && item.pesanan.length > index) { item.pesanan.splice(index, 1); sessionStorage.setItem('cart', JSON.stringify(cart)); } renderCartSummary(); } function removeCartItem(itemId){ let cart = JSON.parse(sessionStorage.getItem('cart') || '[]'); cart = cart.filter(i => i.id !== itemId); sessionStorage.setItem('cart', JSON.stringify(cart)); renderCartSummary() } // validasi step one dan sebelum submit function validateStepOne() { const jenisCustomer = document.querySelector('input[name="jenis_customer"]:checked'); const jenisKelamin = document.querySelector('input[name="jenis_kelamin"]:checked'); const namaPemesan = document.getElementById('nama_pemesan').value.trim(); const noWA = document.getElementById('no_whatsapp').value.trim(); const email = document.getElementById('email').value.trim(); if (!jenisCustomer) { alert('Silakan pilih jenis customer.'); return false; } if (!namaPemesan) { alert('Silakan isi nama pemesan.'); return false; } if (!jenisKelamin) { alert('Silakan pilih jenis kelamin.'); return false; } if (!noWA) { alert('Silakan isi nomor WhatsApp.'); return false; } if (!email) { alert('Silakan isi email terlebih dahulu.'); return false; } // Validasi tambahan sesuai jenis customer const selected = jenisCustomer.value; if (selected === 'Karyawan RSAB Harapan Kita') { const bagian = document.getElementById('bagian_instalasi').value.trim(); if (!bagian) { alert('Silakan lengkapi data karyawan.'); return false; } } else if (selected === 'Keluarga Pasien / Penunggu Pasien') { const namaPasien = document.getElementById('nama_pasien').value.trim(); const ruang = document.getElementById('ruang_perawatan').value; const noKamar = document.getElementById('no_kamar').value.trim(); const kelas = document.getElementById('kelas_perawatan').value; if (!namaPasien || !ruang || !noKamar || !kelas) { alert('Silakan lengkapi data pasien.'); return false; } }else if(selected === "Masyarakat Umum"){ const alamat = document.getElementById('alamat').value; if(!alamat){ alert('Silahkan lengkapi alamat') return false } } return true; } function validateCartBeforeSubmit() { const cart = JSON.parse(sessionStorage.getItem('cart') || '[]'); let isValid = true; let errorMessage = ""; cart.forEach((item, index) => { const pesananList = item.pesanan || []; pesananList.forEach((pesanan, i) => { if (!pesanan.tgl) { isValid = false; errorMessage = `Tanggal belum diisi pada item "${item.nama_menu}" (baris ${i + 1})`; } else if (!pesanan.kategoriPemesanan) { isValid = false; errorMessage = `Kategori pemesanan belum dipilih pada item "${item.nama_menu}" (baris ${i + 1})`; } else if (!pesanan.jumlah || pesanan.jumlah <= 0) { isValid = false; errorMessage = `Jumlah harus lebih dari 0 pada item "${item.nama_menu}" (baris ${i + 1})`; }else if(!pesanan.karbohidrat_id){ isValid = false; errorMessage = `Karbohidrat belum diisi pada item "${item.nama_menu}" (baris ${i + 1})` } }); }); return { isValid, errorMessage }; } function hitungTotalHarga(){ const biodata = JSON.parse(sessionStorage.getItem('checkout_biodata') || '{}'); const cart = JSON.parse(sessionStorage.getItem('cart') || '[]'); let total =0; cart.forEach(item => { const harga = biodata.jenis_customer === "Karyawan RSAB Harapan Kita" ? item.harga_karyawan || 0 : item.harga_public || 0 const itemTotal = item.pesanan?.reduce((sum, p) => sum + (p.jumlah * harga), 0); total += itemTotal }) return total; } function copyNoRek() { const text = document.getElementById('noRekText').innerText; navigator.clipboard.writeText(text).then(() => { alert("Nomor rekening berhasil disalin: " + text); }).catch(err => { console.error('Gagal menyalin: ', err); alert("Gagal menyalin teks."); }); } function copyNoOrder() { const text = document.getElementById('no_order_display').innerText; navigator.clipboard.writeText(text).then(() => { alert("Nomor order berhasil disalin: " + text); }).catch(err => { console.error('Gagal menyalin: ', err); alert("Gagal menyalin teks."); }); } function initFlatpickrTersedia(item, i) { const now = new Date(); const jamFlat = now.getHours(); const menitFlat = now.getMinutes(); const totalMenitFlatSekarang = jamFlat * 60 + menitFlat; const menitBatasFlat = 13 * 60; const lewatBatasNormal = totalMenitFlatSekarang >= menitBatasFlat; // Ambil string tgl_tersedia dan ubah jadi array tanggal lengkap const dayNumbers = (item.tgl_tersedia || "") .split(',') .map(s => s.trim()) .filter(s => s !== '' && !isNaN(s)) .map(s => parseInt(s)); // Generate tanggal dalam format YYYY-MM-DD untuk 3 bulan ke depan let availableDates = []; const bulanKeDepan = 3; for (let bulanOffset = 0; bulanOffset < bulanKeDepan; bulanOffset++) { const baseDate = new Date(now.getFullYear(), now.getMonth() + bulanOffset, 1); const year = baseDate.getFullYear(); const month = String(baseDate.getMonth() + 1).padStart(2, '0'); dayNumbers.forEach(day => { const dayStr = String(day).padStart(2, '0'); const fullDateStr = `${year}-${month}-${dayStr}`; const fullDate = new Date(`${fullDateStr}T23:00:00`); // Jika bukan menu someday, cek aturan H-1 dan jam batas if (item.apakah_someday) { availableDates.push(fullDateStr); } else { const selisihHari = Math.floor((fullDate - now) / (1000 * 60 * 60 * 24)); if (selisihHari >= 1 || (selisihHari === 1 && !lewatBatasNormal)) { availableDates.push(fullDateStr); } } }); } let minTanggal = 'today'; // Jika item adalah someday dan waktu sekarang sudah lewat 13:00 if (item?.apakah_someday && totalMenitFlatSekarang >= 13 * 60) { const besok = new Date(now); besok.setDate(now.getDate() + 1); minTanggal = besok.toISOString().split("T")[0]; // format YYYY-MM-DD } if(!item.apakah_someday){ availableDates = availableDates.filter(dateStr => { const dateObj = new Date(dateStr); const selisihHari = Math.floor((dateObj - now) / (1000 * 60 * 60 * 24)); return selisihHari >= 1 || (selisihHari === 1 && !lewatBatasNormal); }); } flatpickr(`#tanggal-${item.id}-${i}`, { dateFormat: "Y-m-d", ...(item?.apakah_someday ? { minDate: minTanggal,} : {enable : availableDates}), defaultDate: item.pesanan[i]?.tgl || null, onChange: function(selectedDates, dateStr) { onTanggalChange(item.id, i, dateStr); } }); } function increment(itemId, index) { const input = document.getElementById(`jumlah-${itemId}-${index}`); input.value = parseInt(input.value || "0") + 1; onJumlahChange(itemId, index); // Tetap panggil function milikmu } function decrement(itemId, index) { const input = document.getElementById(`jumlah-${itemId}-${index}`); let current = parseInt(input.value || "0"); console.log(current); if (current > 1) { input.value = current - 1; onJumlahChange(itemId, index); }else{ return } } function toggleBuktiPembayaran() { const metode = document.getElementById("cara_pembayaran").value; const buktiSection = document.getElementById("bukti_section"); const buktiInput = document.getElementById("bukti_pembayaran"); buktiInput.required = true; if (metode === "billing") { buktiSection.style.display = "none"; buktiInput.required = false; } else { buktiSection.style.display = "block"; buktiInput.required = true; } } function validateTanggalPemesanan(item, tglDipilih) { const now = new Date(); const jam = now.getHours(); const menit = now.getMinutes(); const totalMenit = jam * 60 + menit; const batasWaktu = 13 * 60; const tglSekarang = now.toISOString().split("T")[0]; if (item.apakah_someday && totalMenit >= batasWaktu && tglDipilih === tglSekarang) { return { valid: false, message: `Maaf, Anda tidak bisa memilih hari ini (${tglDipilih}) untuk menu sameday karena sudah lewat jam 13:00` }; } return { valid: true }; }