Membuat Aplikasi Cart dengan Fitur Checkout

Galih Setiawan Nurohim
4 min readNov 26, 2024

--

aplikasi kasir untuk toko alat kesehatan

Seperti sebelumnya yang saya ceritakan tentang proses saya membuat aplikasi kasir dan manajemen toko dengan next js. saya ingin lebih detail cerita tentang bagaimana membuat bagian cart cekout produk atau bagian kasirnya lah. Jadi di page ini user bisa menambahkan barang ke keranjang, mengubah jumlah barang, mengedit harga untuk diskon, dan melakukan checkout. Saat checkout, data akan disimpan dalam tiga tabel utama: penjualanbrg, detail_penjualan, dan barang. Untuk update stok, trigger yang sebelumnya dibuat secara otomatis akan menyesuaikan stok barang di database.

Berikut adalah penjelasan logika dan proses pembuatan aplikasi ini:

1. Membuat Tabel Database

Tabel utama dalam aplikasi ini meliputi:

  • Tabel barang: Menyimpan data barang dan stok.
  • Tabel penjualanbrg: Menyimpan informasi transaksi.
  • Tabel detail_penjualan: Menyimpan rincian barang yang dibeli dalam setiap transaksi.

Untuk mempermudah pemeliharaan stok, trigger di database akan mengurangi stok secara otomatis berdasarkan jumlah barang yang ditambahkan ke detail_penjualan.

2. Menampilkan Peta Barang Berdasarkan Kategori

Aplikasi ini menggunakan state barangList yang diambil dari tabel barang di Supabase. Untuk memudahkan pengguna, barang ditampilkan berdasarkan kategori yang dipilih oleh pengguna, dan fitur pencarian memudahkan pencarian barang tertentu.

Contoh Logika Pencarian Barang Berdasarkan Kategori dan Nama:

const filteredBarangList = barangList.filter(
(barang) =>
(barang.barang && barang.barang.toLowerCase().includes(searchTerm.toLowerCase())) ||
(barang.kode_barang && barang.kode_barang.toLowerCase().includes(searchTerm.toLowerCase()))
);

3. Menambahkan Barang ke Keranjang (Cart)

Pengguna dapat menambah barang ke keranjang jika stok masih tersedia. Jika barang yang sama sudah ada di keranjang, maka jumlahnya akan bertambah. Jika stok tidak cukup, aplikasi akan menampilkan peringatan.

Logika Menambahkan Barang ke Keranjang:

const addToCart = (barang) => {
if (barang.stok <= 0) {
alert('Stok barang ini kosong. Tidak dapat menambah ke keranjang.');
return;
}
setCartItems((prevItems) => {
const itemExists = prevItems.find((item) => item.kode_barang === barang.kode_barang);
if (itemExists) {
return prevItems.map((item) =>
item.kode_barang === barang.kode_barang && item.jumlah < barang.stok
? { ...item, jumlah: item.jumlah + 1 }
: item
);
} else {
return [...prevItems, { ...barang, jumlah: 1, totalHarga: barang.harga_jual }];
}
});
};

4. Mengedit Harga untuk Diskon

Aplikasi menyediakan input untuk pengguna mengedit harga barang di keranjang, yang bisa digunakan saat memberi diskon. Saat harga diubah, total harga keseluruhan akan diperbarui secara otomatis.

const handleTotalPriceChange = (kode_barang, newPrice) => {
setCartItems((prevItems) =>
prevItems.map((item) =>
item.kode_barang === kode_barang ? { ...item, totalHarga: newPrice } : item
)
);
};

5. Menghitung Total Harga

Setiap perubahan dalam keranjang, termasuk penambahan, pengurangan, atau perubahan harga, akan memicu perhitungan ulang total harga menggunakan fungsi reduce.

useEffect(() => {
const total = cartItems.reduce((acc, item) => acc + item.totalHarga * item.jumlah, 0);
setTotalHarga(total);
}, [cartItems]);

6. Proses Checkout dan Penyimpanan Transaksi

Saat pengguna mengklik tombol Checkout, aplikasi akan menyimpan transaksi ke database. Proses ini mencakup langkah-langkah berikut:

  • Membuat entri baru di tabel penjualanbrg dengan total_harga, nama_pelanggan, dan waktu transaksi.
  • Menyimpan setiap barang dalam keranjang ke tabel detail_penjualan.
  • Karena tabel barang memiliki trigger, stok barang akan berkurang secara otomatis setiap kali barang ditambahkan ke detail_penjualan.
const handleCheckout = async () => {
if (cartItems.length === 0) {
alert("Keranjang kosong. Tambahkan barang terlebih dahulu.");
return;
}

setLoading(true);
const { data: penjualanData, error: penjualanError } = await supabase
.from('penjualanbrg')
.insert([{ total_harga: totalHarga, nama_pelanggan: namaPelanggan, tanggal: timestamp }])
.select()
.single();

if (penjualanError) {
alert('Gagal membuat transaksi penjualan. Silakan coba lagi.');
setLoading(false);
return;
}

const detailPenjualanData = cartItems.map((item) => ({
id_penjualanbrg: penjualanData.id_penjualanbrg,
kode_barang: item.kode_barang,
jumlah: item.jumlah,
harga_jual: item.totalHarga,
}));

const { error: detailError } = await supabase
.from('detail_penjualan')
.insert(detailPenjualanData);

if (detailError) {
alert('Gagal menyimpan detail transaksi penjualan.');
} else {
alert("Transaksi berhasil disimpan.");
setCartItems([]);
setTotalHarga(0);
setNamaPelanggan('');
router.push('/cart/laporan');
}

setLoading(false);
};

Selesai sudah bagian logic nya, Sekarang untuk tampilannya

  1. Komponen Pencarian Barang
    Buat input teks untuk memfilter barang berdasarkan nama atau kode barang. Pencarian ini memudahkan pengguna untuk menemukan barang tertentu.
<input
type="text"
placeholder="Cari barang atau kode..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>

2. Daftar Barang Berdasarkan Kategori
Tampilkan barang berdasarkan hasil pencarian atau kategori tertentu. Setiap barang akan memiliki tombol tambah untuk menambahkannya ke keranjang.

<div className="grid grid-cols-2 gap-4">
{filteredBarangList.map((barang) => (
<div key={barang.kode_barang}>
<h3>{barang.barang}</h3>
<p>Rp {barang.harga_jual}</p>
<p>Stok: {barang.stok}</p>
<button onClick={() => addToCart(barang)}>+</button>
</div>
))}
</div>

3. Tampilan Keranjang
Di keranjang, pengguna dapat melihat barang yang sudah ditambahkan, mengubah jumlah atau mengedit harga jika ada diskon.

<div className="cart">
{cartItems.map((item) => (
<div key={item.kode_barang}>
<h3>{item.barang}</h3>
<p>Jumlah: {item.jumlah}</p>
<input
type="number"
value={item.totalHarga}
onChange={(e) => handleTotalPriceChange(item.kode_barang, Number(e.target.value))}
/>
<button onClick={() => removeFromCart(item.kode_barang)}>−</button>
</div>
))}
<p>Total: Rp {totalHarga}</p>
</div>

4. Tombol Checkout
Tombol checkout akan menyimpan data transaksi ke database dan mengarahkan pengguna ke halaman laporan jika berhasil.

<button onClick={handleCheckout}>Checkout</button>

Dengan gini tampilan dinamis dan reaktif proses perpindahan dari mobile app ke web app harusnya mulus, karena usernya yaitu kasir , gamau yang lemot lemot macam php

--

--

Galih Setiawan Nurohim
Galih Setiawan Nurohim

No responses yet