N
G
Coffee Shop Mobile App

BrewBuddy Logic.

UI/UX Implementation JavaScript DOM State Management MySQL Architecture

The Challenge

Context: Proyek ini berawal dari desain UI/UX yang kompleks yang mencakup alur pemesanan lengkap: dari memilih menu, mengatur varian (Ice/Hot, Sugar Level), hingga pelacakan status pesanan.

Tantangannya adalah menerjemahkan desain statis tersebut menjadi logika aplikasi yang fungsional. Bagaimana memastikan item yang dipilih di menu tersimpan dengan benar di keranjang (cart) dan terhubung ke sistem pembayaran tanpa *data loss*.

Technical Solution

Saya menerapkan logika State Management di sisi frontend menggunakan Vanilla JS untuk menangani keranjang belanja secara dinamis sebelum data dikirim ke server via *form submission* atau AJAX.

  • Persistent Cart: Menggunakan tabel database cart (bukan hanya session browser) agar keranjang user tidak hilang saat berganti perangkat.
  • Order Tracking Logic: Status pesanan (Pending -> Processing -> Completed) diatur melalui logika backend yang ketat.

Database & Relational Logic

Berdasarkan arsitektur data db_brewbuddy.sql, saya merancang skema relasional yang efisien untuk menangani transaksi kedai kopi secara komprehensif.

  • products: Menyimpan menu dengan kategori spesifik (Coffee, Non-Coffee, Pastry).
  • cart: Tabel sementara untuk menampung item yang dipilih sebelum masuk ke proses checkout.
  • orders & order_details: Menyimpan riwayat transaksi yang sudah final (immutable) beserta relasi detail pesanannya.

SQL Logic Snapshot:

CREATE TABLE orders (
  id INT PK,
  user_id INT FK,
  total_amount INT,
  payment_method VARCHAR(50),
  status ENUM('Pending','Processing','Completed')
);
CartManager.js (Frontend Cart Calculation)

Contoh logika JavaScript untuk memanipulasi DOM dan menghitung total harga secara real-time saat user menambah kuantitas pesanan, sebelum dikirim ke backend.

const updateCartTotal = () => {
    let total = 0;
    const cartItems = document.querySelectorAll('.cart-item');

    cartItems.forEach(item => {
        const price = parseFloat(item.dataset.price);
        const quantity = parseInt(item.querySelector('.qty-input').value);
        
        // Kalkulasi Subtotal per Item
        const subtotal = price * quantity;
        item.querySelector('.subtotal').innerText = formatRupiah(subtotal);
        
        // Akumulasi Total
        total += subtotal;
    });

    // Update UI Total Pembayaran
    document.getElementById('grand-total').innerText = formatRupiah(total);
    
    // Enable/Disable tombol Checkout agar tidak bisa submit kosong
    const checkoutBtn = document.getElementById('btn-checkout');
    checkoutBtn.disabled = total === 0;
};