OmahCitra store template: catalog, cart, checkout, shipping, payment (HTML/CSS/jQuery)

This commit is contained in:
cania
2026-08-11 11:44:51 +02:00
commit a3b20e1de4
7 changed files with 751 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
# OS / editor junk
.DS_Store
*.swp
*~
.idea/
.vscode/

41
README.md Normal file
View File

@@ -0,0 +1,41 @@
# OmahCitra Store
Template **toko online** statis (HTML + CSS + jQuery) — katalog produk terlaris
di Indonesia dengan keranjang belanja, checkout, pengiriman, dan pembayaran.
> Built as a rebuild of www.omahcitra.com into an online-store layout.
## Fitur
- **Katalog** — 12 produk paling laku (elektronik, fashion, kecantikan, makanan,
rumah tangga) dengan filter kategori & pencarian.
- **Shopping Cart** — tambah/hapus, ubah qty, subtotal real-time.
- **Checkout (Order)** — data penerima (nama, alamat, HP).
- **Pengiriman** — 4 kurir: JNE, SiCepat, POS, GoSend (ongkir + ETD).
- **Pembayaran** — 6 metode: QRIS, GoPay, OVO, DANA, Transfer Bank, COD.
- **Konfirmasi** — nomor pesanan + ringkasan order.
## Struktur
```
omahcitra-store/
├── index.html # halaman toko (semua view)
├── css/style.css # styling layout toko online
└── js/
├── jquery-3.7.1.min.js # jQuery (lokal, jalan offline)
├── products.js # data 12 produk + opsi kurir & pembayaran
└── app.js # logika jQuery: cart, checkout, shipping, payment
```
## Cara pakai
Buka `index.html` langsung di browser (double-click). jQuery sudah lokal, jadi
**tidak butuh internet**.
## Catatan
- Ini template front-end statis (simulasi order, tanpa backend/database).
- Data produk adalah contoh "paling laku di Indonesia", bukan data real-time.
## License
MIT — bebas dipakai & dimodifikasi.

168
css/style.css Normal file
View File

@@ -0,0 +1,168 @@
/* ============================================================
OmahCitra Store - Stylesheet
============================================================ */
:root{
--primary:#e63946;
--primary-dark:#c1121f;
--accent:#ffb703;
--bg:#f6f7f9;
--card:#ffffff;
--text:#1d1d1f;
--muted:#6b7280;
--line:#e5e7eb;
--radius:14px;
--shadow:0 4px 18px rgba(0,0,0,.07);
}
*{box-sizing:border-box;margin:0;padding:0}
body{
font-family:'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
background:var(--bg);color:var(--text);line-height:1.5;
}
.container{max-width:1100px;margin:0 auto;padding:0 16px}
a{text-decoration:none;color:inherit}
/* ===== Topbar ===== */
.topbar{background:var(--primary);color:#fff;position:sticky;top:0;z-index:50;box-shadow:var(--shadow)}
.topbar-inner{display:flex;align-items:center;gap:18px;padding:12px 16px}
.brand{display:flex;align-items:center;gap:8px;font-weight:800;font-size:20px}
.brand-logo{font-size:24px}
.brand-dot{color:var(--accent)}
.search-box{flex:1}
.search-box input{
width:100%;padding:10px 14px;border:none;border-radius:30px;font-size:14px;outline:none;
}
.cart-btn{
background:#fff;color:var(--primary);border:none;border-radius:30px;
padding:9px 16px;font-weight:700;cursor:pointer;font-size:14px;display:flex;align-items:center;gap:6px;
}
.cart-count{
background:var(--accent);color:#000;border-radius:50%;min-width:20px;height:20px;
display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:800;
}
/* ===== Category nav ===== */
.catnav{background:#fff;border-bottom:1px solid var(--line)}
.catnav-inner{display:flex;gap:8px;overflow-x:auto;padding:10px 16px}
.cat-pill{
white-space:nowrap;padding:7px 14px;border-radius:30px;background:var(--bg);
border:1px solid var(--line);cursor:pointer;font-size:13px;font-weight:600;color:var(--muted);
}
.cat-pill.active{background:var(--primary);color:#fff;border-color:var(--primary)}
/* ===== Main / views ===== */
.main{padding:22px 16px 60px}
.view{display:none}
.view.active{display:block;animation:fade .25s ease}
@keyframes fade{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
.hero{
background:linear-gradient(120deg,var(--primary),var(--accent));
color:#fff;border-radius:var(--radius);padding:28px;margin-bottom:22px;text-align:center;
}
.hero h1{font-size:26px;margin-bottom:6px}
.hero p{opacity:.95}
/* ===== Product grid ===== */
.product-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:16px}
.product-card{
background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);
overflow:hidden;display:flex;flex-direction:column;transition:transform .15s;
}
.product-card:hover{transform:translateY(-4px)}
.pc-thumb{
height:130px;display:flex;align-items:center;justify-content:center;font-size:60px;
background:linear-gradient(135deg,#fff3f3,#ffe9e9);
}
.pc-body{padding:12px;display:flex;flex-direction:column;gap:6px;flex:1}
.pc-cat{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.5px}
.pc-name{font-weight:700;font-size:15px;line-height:1.3}
.pc-meta{font-size:12px;color:var(--muted)}
.pc-badge{display:inline-block;background:var(--accent);color:#000;font-size:10px;font-weight:800;
padding:2px 7px;border-radius:20px;margin-left:6px}
.pc-rating{color:#f59e0b;font-size:12px}
.pc-price{font-size:17px;font-weight:800;color:var(--primary);margin-top:auto}
.pc-btn{
margin-top:8px;background:var(--primary);color:#fff;border:none;border-radius:8px;
padding:9px;font-weight:700;cursor:pointer;font-size:13px;
}
.pc-btn:hover{background:var(--primary-dark)}
.empty-note{text-align:center;color:var(--muted);padding:40px}
/* ===== Cart ===== */
.cart-list{display:flex;flex-direction:column;gap:12px}
.cart-row{
background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);
padding:14px;display:flex;align-items:center;gap:14px;
}
.cart-emoji{font-size:40px;width:60px;text-align:center}
.cart-info{flex:1}
.cart-info h4{font-size:15px}
.cart-info small{color:var(--muted)}
.qty{display:flex;align-items:center;gap:8px}
.qty button{width:28px;height:28px;border-radius:6px;border:1px solid var(--line);
background:#fff;cursor:pointer;font-size:16px;font-weight:700}
.qty span{min-width:24px;text-align:center;font-weight:700}
.cart-row .price{font-weight:800;color:var(--primary);min-width:110px;text-align:right}
.cart-row .rm{background:none;border:none;color:var(--muted);cursor:pointer;font-size:18px}
.cart-empty{text-align:center;padding:40px;background:#fff;border-radius:var(--radius);box-shadow:var(--shadow)}
.cart-summary{margin-top:18px;background:var(--card);border-radius:var(--radius);
box-shadow:var(--shadow);padding:16px;display:flex;justify-content:space-between;align-items:center}
.summary-row{display:flex;justify-content:space-between;padding:6px 0;font-size:14px}
.summary-row.total{font-size:18px;font-weight:800;color:var(--primary);border-top:1px solid var(--line);margin-top:6px;padding-top:10px}
/* ===== Buttons ===== */
.btn-primary{background:var(--primary);color:#fff;border:none;border-radius:8px;
padding:11px 22px;font-weight:700;cursor:pointer;font-size:14px}
.btn-primary:hover{background:var(--primary-dark)}
.btn-primary.full{width:100%;margin-top:12px}
/* ===== Checkout ===== */
.checkout-grid{display:grid;grid-template-columns:1fr 320px;gap:18px;align-items:start}
.card{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);padding:18px;margin-bottom:18px}
.card h3{margin-bottom:14px;font-size:16px}
.card label{display:block;font-size:13px;font-weight:600;margin:12px 0 5px;color:var(--muted)}
.card input,.card textarea{
width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:8px;font-size:14px;
font-family:inherit;outline:none;resize:vertical;
}
.card input:focus,.card textarea:focus{border-color:var(--primary)}
.opt-list{display:flex;flex-direction:column;gap:8px}
.opt{
display:flex;align-items:center;gap:10px;border:1px solid var(--line);border-radius:8px;
padding:11px 13px;cursor:pointer;font-size:14px;
}
.opt:hover{border-color:var(--primary)}
.opt.selected{border-color:var(--primary);background:#fff5f5}
.opt input{width:auto}
.opt small{color:var(--muted);margin-left:auto}
.summary-card{position:sticky;top:90px}
.order-items{display:flex;flex-direction:column;gap:8px;margin-bottom:10px}
.order-item{display:flex;justify-content:space-between;font-size:13px}
.order-item small{color:var(--muted)}
/* ===== Done ===== */
.done-box{background:var(--card);border-radius:var(--radius);box-shadow:var(--shadow);
padding:40px;text-align:center;max-width:520px;margin:30px auto}
.done-icon{font-size:64px}
.done-box h2{margin:10px 0}
.done-detail{text-align:left;background:var(--bg);border-radius:10px;padding:16px;margin:18px 0;font-size:14px}
.done-detail div{padding:4px 0}
/* ===== Footer ===== */
.footer{background:#fff;border-top:1px solid var(--line);padding:20px 0;text-align:center;color:var(--muted);font-size:13px}
/* ===== Toast ===== */
.toast{
position:fixed;bottom:24px;left:50%;transform:translateX(-50%) translateY(120px);
background:#1d1d1f;color:#fff;padding:12px 22px;border-radius:30px;font-size:14px;
font-weight:600;opacity:0;transition:.3s;z-index:100;box-shadow:var(--shadow);
}
.toast.show{transform:translateX(-50%) translateY(0);opacity:1}
/* ===== Responsive ===== */
@media(max-width:760px){
.checkout-grid{grid-template-columns:1fr}
.summary-card{position:static}
.topbar-inner{gap:10px}
.search-box{order:3;flex-basis:100%}
}

121
index.html Normal file
View File

@@ -0,0 +1,121 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OmahCitra Store — Toko Online Terlaris Indonesia</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<!-- ===== HEADER ===== -->
<header class="topbar">
<div class="container topbar-inner">
<a href="#" class="brand" data-view="catalog">
<span class="brand-logo">🛍️</span>
<span class="brand-name">OmahCitra<span class="brand-dot">Store</span></span>
</a>
<div class="search-box">
<input type="text" id="searchInput" placeholder="Cari produk terlaris...">
</div>
<button class="cart-btn" id="cartBtn">
🛒 Keranjang <span class="cart-count" id="cartCount">0</span>
</button>
</div>
</header>
<!-- ===== CATEGORY NAV ===== -->
<nav class="catnav">
<div class="container catnav-inner" id="catNav"></div>
</nav>
<main class="container main">
<!-- ===== VIEW: KATALOG ===== -->
<section id="view-catalog" class="view active">
<div class="hero">
<h1>Produk Paling Laku di Indonesia 🇮🇩</h1>
<p>Belanja koleksi terlaris — elektronik, fashion, makanan, & rumah tangga.</p>
</div>
<div class="product-grid" id="productGrid"></div>
<p class="empty-note" id="emptyNote" style="display:none">Produk tidak ditemukan.</p>
</section>
<!-- ===== VIEW: KERANJANG ===== -->
<section id="view-cart" class="view">
<h2>🛒 Keranjang Belanja</h2>
<div id="cartItems" class="cart-list"></div>
<div id="cartEmpty" class="cart-empty" style="display:none">
<p>Keranjang kamu masih kosong.</p>
<button class="btn-primary" data-view="catalog">← Lanjut Belanja</button>
</div>
<div class="cart-summary" id="cartSummary" style="display:none">
<div class="summary-row"><span>Subtotal</span><span id="sumSubtotal">Rp0</span></div>
<button class="btn-primary" id="toCheckout">Lanjut ke Pembayaran →</button>
</div>
</section>
<!-- ===== VIEW: CHECKOUT (ORDER / PAYMENT / SHIPPING) ===== -->
<section id="view-checkout" class="view">
<h2>📦 Checkout</h2>
<div class="checkout-grid">
<div class="checkout-left">
<div class="card">
<h3>1. Data Penerima & Pengiriman</h3>
<label>Nama Lengkap</label>
<input type="text" id="custName" placeholder="Nama penerima">
<label>Alamat Lengkap</label>
<textarea id="custAddr" placeholder="Jalan, nomor, RT/RW, kelurahan, kecamatan, kota"></textarea>
<label>No. HP / WhatsApp</label>
<input type="text" id="custPhone" placeholder="08xxxxxxxxxx">
<label>Pilih Kurir</label>
<div id="courierOptions" class="opt-list"></div>
</div>
<div class="card">
<h3>2. Metode Pembayaran</h3>
<div id="paymentOptions" class="opt-list"></div>
</div>
</div>
<aside class="checkout-right">
<div class="card summary-card">
<h3>Ringkasan Order</h3>
<div id="orderItems" class="order-items"></div>
<div class="summary-row"><span>Subtotal</span><span id="coSubtotal">Rp0</span></div>
<div class="summary-row"><span>Ongkos Kirim</span><span id="coShipping">Rp0</span></div>
<div class="summary-row total"><span>Total Bayar</span><span id="coTotal">Rp0</span></div>
<button class="btn-primary full" id="placeOrder">Buat Pesanan</button>
</div>
</aside>
</div>
</section>
<!-- ===== VIEW: KONFIRMASI ORDER ===== -->
<section id="view-done" class="view">
<div class="done-box">
<div class="done-icon"></div>
<h2>Pesanan Berhasil Dibuat!</h2>
<p>No. Pesanan: <strong id="orderNo"></strong></p>
<div id="doneDetail" class="done-detail"></div>
<button class="btn-primary" data-view="catalog">Belanja Lagi</button>
</div>
</section>
</main>
<footer class="footer">
<div class="container">
<p>© 2026 OmahCitra Store — Demo toko online. Dibangun dengan HTML, CSS & jQuery.</p>
</div>
</footer>
<!-- Toast -->
<div class="toast" id="toast"></div>
<script src="js/jquery-3.7.1.min.js"></script>
<script src="js/products.js"></script>
<script src="js/app.js"></script>
</body>
</html>

250
js/app.js Normal file
View File

@@ -0,0 +1,250 @@
/* ============================================================
OmahCitra Store - Aplikasi (jQuery)
Fitur: Katalog, Keranjang, Checkout, Pengiriman, Pembayaran
============================================================ */
$(function () {
"use strict";
// ---------- State ----------
const cart = {}; // { id: qty }
let activeCat = "Semua";
let searchTerm = "";
let selectedCourier = null;
let selectedPayment = null;
// ---------- Helpers ----------
const rupiah = (n) => "Rp" + Number(n).toLocaleString("id-ID");
const $view = (name) => {
$(".view").removeClass("active");
$("#view-" + name).addClass("active");
window.scrollTo(0, 0);
};
const toast = (msg) => {
const $t = $("#toast").text(msg).addClass("show");
clearTimeout(toast._t);
toast._t = setTimeout(() => $t.removeClass("show"), 1800);
};
// ---------- Category nav ----------
function buildCats() {
const cats = ["Semua", ...new Set(PRODUCTS.map(p => p.category))];
const $nav = $("#catNav").empty();
cats.forEach(c => {
$("<div>")
.addClass("cat-pill" + (c === activeCat ? " active" : ""))
.text(c)
.on("click", function () {
activeCat = c;
buildCats();
renderCatalog();
})
.appendTo($nav);
});
}
// ---------- Catalog ----------
function renderCatalog() {
const grid = $("#productGrid").empty();
const term = searchTerm.toLowerCase();
const list = PRODUCTS.filter(p => {
const okCat = activeCat === "Semua" || p.category === activeCat;
const okSearch = !term ||
p.name.toLowerCase().includes(term) ||
p.category.toLowerCase().includes(term) ||
p.desc.toLowerCase().includes(term);
return okCat && okSearch;
});
$("#emptyNote").toggle(list.length === 0);
list.forEach(p => {
const card = $(`
<div class="product-card">
<div class="pc-thumb">${p.emoji}</div>
<div class="pc-body">
<span class="pc-cat">${p.category}${p.badge ? `<span class="pc-badge">${p.badge}</span>` : ""}</span>
<div class="pc-name">${p.name}</div>
<div class="pc-rating">★ ${p.rating} · ${p.sold.toLocaleString("id-ID")} terjual</div>
<div class="pc-price">${rupiah(p.price)}</div>
<button class="pc-btn" data-id="${p.id}">+ Keranjang</button>
</div>
</div>`);
card.find(".pc-btn").on("click", () => addToCart(p.id));
card.appendTo(grid);
});
}
// ---------- Cart ops ----------
function addToCart(id) {
cart[id] = (cart[id] || 0) + 1;
updateCartCount();
toast("Ditambahkan ke keranjang");
}
function setQty(id, qty) {
if (qty <= 0) delete cart[id];
else cart[id] = qty;
updateCartCount();
renderCart();
}
function updateCartCount() {
const n = Object.values(cart).reduce((a, b) => a + b, 0);
$("#cartCount").text(n);
}
function cartSubtotal() {
return Object.entries(cart).reduce((sum, [id, q]) => {
const p = PRODUCTS.find(x => x.id === id);
return sum + (p ? p.price * q : 0);
}, 0);
}
// ---------- Render cart ----------
function renderCart() {
const $list = $("#cartItems").empty();
const ids = Object.keys(cart);
if (ids.length === 0) {
$("#cartEmpty").show();
$("#cartSummary").hide();
return;
}
$("#cartEmpty").hide();
$("#cartSummary").show();
ids.forEach(id => {
const p = PRODUCTS.find(x => x.id === id);
const qty = cart[id];
const row = $(`
<div class="cart-row">
<div class="cart-emoji">${p.emoji}</div>
<div class="cart-info">
<h4>${p.name}</h4>
<small>${rupiah(p.price)} / pcs</small>
</div>
<div class="qty">
<button class="dec"></button>
<span>${qty}</span>
<button class="inc">+</button>
</div>
<div class="price">${rupiah(p.price * qty)}</div>
<button class="rm" title="Hapus">🗑️</button>
</div>`);
row.find(".inc").on("click", () => setQty(id, qty + 1));
row.find(".dec").on("click", () => setQty(id, qty - 1));
row.find(".rm").on("click", () => { delete cart[id]; updateCartCount(); renderCart(); toast("Dihapus"); });
row.appendTo($list);
});
$("#sumSubtotal").text(rupiah(cartSubtotal()));
}
// ---------- Checkout ----------
function buildCheckout() {
// couriers
const $c = $("#courierOptions").empty();
COURIERS.forEach(co => {
const opt = $(`
<label class="opt">
<input type="radio" name="courier" value="${co.id}">
<span>${co.name} · ${rupiah(co.fee)}</span>
<small>(${co.etd})</small>
</label>`);
opt.find("input").on("change", () => {
selectedCourier = co;
$(".opt", $c).removeClass("selected");
opt.addClass("selected");
updateOrderSummary();
});
opt.appendTo($c);
});
// payments
const $p = $("#paymentOptions").empty();
PAYMENTS.forEach(pm => {
const opt = $(`
<label class="opt">
<input type="radio" name="payment" value="${pm.id}">
<span>${pm.name}</span>
</label>`);
opt.find("input").on("change", () => {
selectedPayment = pm;
$(".opt", $p).removeClass("selected");
opt.addClass("selected");
});
opt.appendTo($p);
});
renderOrderItems();
updateOrderSummary();
}
function renderOrderItems() {
const $o = $("#orderItems").empty();
Object.entries(cart).forEach(([id, q]) => {
const p = PRODUCTS.find(x => x.id === id);
$(`<div class="order-item"><span>${p.emoji} ${p.name} ×${q}</span><span>${rupiah(p.price * q)}</span></div>`).appendTo($o);
});
}
function updateOrderSummary() {
const sub = cartSubtotal();
const ship = selectedCourier ? selectedCourier.fee : 0;
$("#coSubtotal").text(rupiah(sub));
$("#coShipping").text(selectedCourier ? rupiah(ship) : "Pilih kurir");
$("#coTotal").text(rupiah(sub + ship));
}
// ---------- Place order ----------
function placeOrder() {
if (Object.keys(cart).length === 0) { toast("Keranjang kosong"); return; }
const name = $("#custName").val().trim();
const addr = $("#custAddr").val().trim();
const phone = $("#custPhone").val().trim();
if (!name || !addr || !phone) { toast("Lengkapi data penerima"); return; }
if (!selectedCourier) { toast("Pilih kurir pengiriman"); return; }
if (!selectedPayment) { toast("Pilih metode pembayaran"); return; }
const orderNo = "OC" + Date.now().toString().slice(-8);
const sub = cartSubtotal();
const total = sub + selectedCourier.fee;
$("#orderNo").text(orderNo);
$("#doneDetail").html(`
<div><strong>Nama:</strong> ${name}</div>
<div><strong>Alamat:</strong> ${addr}</div>
<div><strong>HP:</strong> ${phone}</div>
<div><strong>Kurir:</strong> ${selectedCourier.name} (${selectedCourier.etd})</div>
<div><strong>Pembayaran:</strong> ${selectedPayment.name}</div>
<div><strong>Total:</strong> ${rupiah(total)}</div>
`);
// reset
for (const k in cart) delete cart[k];
updateCartCount();
selectedCourier = null; selectedPayment = null;
$("#custName,#custAddr,#custPhone").val("");
$view("done");
}
// ---------- Events ----------
$("#cartBtn").on("click", () => { renderCart(); $view("cart"); });
$("#toCheckout").on("click", () => {
if (Object.keys(cart).length === 0) { toast("Keranjang kosong"); return; }
buildCheckout(); $view("checkout");
});
$("#placeOrder").on("click", placeOrder);
$("#searchInput").on("input", function () { searchTerm = $(this).val(); renderCatalog(); });
// navigasi via data-view (brand & tombol)
$(document).on("click", "[data-view]", function (e) {
e.preventDefault();
const v = $(this).data("view");
if (v === "cart") renderCart();
if (v === "checkout") buildCheckout();
$view(v);
});
// ---------- Init ----------
buildCats();
renderCatalog();
updateCartCount();
});

2
js/jquery-3.7.1.min.js vendored Normal file

File diff suppressed because one or more lines are too long

163
js/products.js Normal file
View File

@@ -0,0 +1,163 @@
/* ============================================================
OmahCitra Store - Daftar produk paling laku di Indonesia
Data statis (simulasi) - diurutkan berdasar kategori terlaris
============================================================ */
const PRODUCTS = [
// --- Elektronik & Smartphone (kategori paling laku) ---
{
id: "p01",
name: "Samsung Galaxy A55 5G",
category: "Elektronik",
price: 4299000,
rating: 4.7,
sold: 12400,
badge: "Terlaris",
emoji: "📱",
desc: "HP 5G RAM 8GB/256GB, kamera 50MP, layar Super AMOLED 120Hz."
},
{
id: "p02",
name: "Xiaomi Redmi Note 13 Pro",
category: "Elektronik",
price: 3299000,
rating: 4.6,
sold: 9820,
badge: "Populer",
emoji: "📱",
desc: "Snapdragon 7s Gen 2, kamera 200MP, baterai 5000mAh fast charge."
},
{
id: "p03",
name: "Apple AirPods Gen 2",
category: "Elektronik",
price: 1499000,
rating: 4.8,
sold: 15600,
badge: "Terlaris",
emoji: "🎧",
desc: "Earbuds nirkabel dengan chip H1, audio berkualitas & low latency."
},
{
id: "p04",
name: "Charger Adaptor 33W Fast Charge",
category: "Elektronik",
price: 129000,
rating: 4.5,
sold: 22100,
badge: "",
emoji: "🔌",
desc: "Adaptor GAN cepat universal, kompatibel banyak merek HP."
},
// --- Fashion & Kecantikan ---
{
id: "p05",
name: "Hoodie Unisex Oversize",
category: "Fashion",
price: 189000,
rating: 4.4,
sold: 18900,
badge: "Trending",
emoji: "👕",
desc: "Hoodie katun tebal nyaman, cocok pria & wanita, banyak warna."
},
{
id: "p06",
name: "Skincare Serum Vitamin C",
category: "Kecantikan",
price: 95000,
rating: 4.6,
sold: 27300,
badge: "Terlaris",
emoji: "🧴",
desc: "Serum wajah brightening 30ml, cerahkan & haluskan kulit."
},
{
id: "p07",
name: "Sneakers Casual Pria",
category: "Fashion",
price: 259000,
rating: 4.3,
sold: 11200,
badge: "",
emoji: "👟",
desc: "Sepatu sneakers ringan anti-slip, sol empuk untuk daily use."
},
// --- Makanan & Minuman (FMCG paling laku) ---
{
id: "p08",
name: "Indomie Goreng 40 Pcs",
category: "Makanan",
price: 138000,
rating: 4.9,
sold: 41200,
badge: "Terlaris",
emoji: "🍜",
desc: "Mi instan goreng kemasan ekonomis, rasa favorit Indonesia."
},
{
id: "p09",
name: "Kopi Susu ABC 10 Sachet",
category: "Makanan",
price: 45000,
rating: 4.7,
sold: 33800,
badge: "",
emoji: "☕",
desc: "Kopi susu kemasan sachet, praktis & nikmat untuk sahur/ngopi."
},
{
id: "p10",
name: "Teh Botol Sosro 350ml (12 botol)",
category: "Makanan",
price: 72000,
rating: 4.8,
sold: 29500,
badge: "Populer",
emoji: "🍵",
desc: "Teh hijau siap minum original, segar dan tanpa pengawet berlebih."
},
// --- Rumah Tangga ---
{
id: "p11",
name: "Rice Cooker 1.8L Anti Lengket",
category: "Rumah Tangga",
price: 265000,
rating: 4.5,
sold: 14300,
badge: "",
emoji: "🍚",
desc: "Magic com hemat listrik, memasak otomatis & keep warm."
},
{
id: "p12",
name: "Deterjen Bubuk 3kg",
category: "Rumah Tangga",
price: 58000,
rating: 4.6,
sold: 26700,
badge: "Populer",
emoji: "🧼",
desc: "Deterjen wangi tahan lama, cocok mesin cuci & cuci tangan."
}
];
// Opsi kurir / pengiriman
const COURIERS = [
{ id: "jne", name: "JNE Regular", fee: 15000, etd: "2-3 hari" },
{ id: "sicepat", name: "SiCepat BEST", fee: 18000, etd: "1-2 hari" },
{ id: "pos", name: "POS Indonesia", fee: 12000, etd: "3-5 hari" },
{ id: "gosend", name: "GoSend Same Day", fee: 35000, etd: "Hari ini" }
];
// Opsi metode pembayaran
const PAYMENTS = [
{ id: "qris", name: "QRIS (All e-wallet & m-banking)" },
{ id: "gopay", name: "GoPay" },
{ id: "ovo", name: "OVO" },
{ id: "dana", name: "DANA" },
{ id: "transfer", name: "Transfer Bank (BCA / Mandiri / BRI)" },
{ id: "cod", name: "Bayar di Tempat (COD)" }
];