Project HTML CSS & JavaScript: Website Marketplace Sederhana

Project HTML CSS & JavaScript: Website Marketplace Sederhana

Project HTML CSS & JavaScript: Website Marketplace Sederhana

Membuat website marketplace sederhana menggunakan HTML, CSS, dan JavaScript adalah proyek yang bagus untuk mempelajari pengembangan web front-end. Dalam panduan ini, kita akan membuat sebuah mini marketplace dengan fitur:

✅ Daftar produk dengan gambar
✅ Keranjang belanja sederhana
✅ Animasi hover dan transisi
✅ Tampilan responsif (mobile-friendly)
✅ Filter produk berdasarkan kategori

Mari kita mulai langkah demi langkah!

Persiapan Proyek

Struktur File

/marketplace
│── index.html
│── cart.html
│── style.css
│── script.js
│── script-cart.js
└── assets/
    └── images/

Tools yang Dibutuhkan

  • Visual Studio Code (atau teks editor lainnya)
  • Browser modern (Chrome, Firefox, Edge)
  • Gambar produk (opsional)

1. File index.html

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Marketplace - Azroi</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <header>
        <div class="logo">
            <i class="fas fa-store"></i>
            <span>MarketPlace</span>
        </div>
        <div class="search-cart">
            <div class="cart-icon">
                <i class="fas fa-shopping-cart"></i>
                <span class="cart-count">0</span>
            </div>
        </div>
    </header>

    <main>
        <section class="categories">
            <button class="category-btn active" data-category="all">Semua</button>
            <button class="category-btn" data-category="elektronik">Elektronik</button>
            <button class="category-btn" data-category="fashion">Fashion</button>
            <button class="category-btn" data-category="makanan">Makanan</button>
        </section>

        <section class="products" id="productsContainer">
            <!-- Produk akan dimuat via JavaScript -->
        </section>
    </main>

    <script src="script.js"></script>
</body>
</html>

2. File cart.html

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Keranjang Belanja - Azroi</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <header>
        <div class="logo">
            <i class="fas fa-store"></i>
            <span>MarketPlace</span>
        </div>
        <div class="cart-icon">
            <i class="fas fa-shopping-cart"></i>
            <span class="cart-count">0</span>
        </div>
    </header>

    <main class="cart-container">
        <h1><i class="fas fa-shopping-cart"></i> Keranjang Belanja</h1>
        <div class="cart-items" id="cartItems">
            <!-- Item akan dimuat via JavaScript -->
        </div>
        <div class="cart-summary">
            <h3>Ringkasan Belanja</h3>
            <div class="summary-item">
                <span>Total Item:</span>
                <span id="totalItems">0</span>
            </div>
            <div class="summary-item">
                <span>Total Harga:</span>
                <span id="totalPrice">Rp 0</span>
            </div>
            <button class="checkout-btn">Proses Checkout</button>
        </div>
    </main>

    <script src="script-cart.js"></script>
</body>
</html>

3. File style.css

css
/* Global Styles */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Poppins', sans-serif;
}

body {
    background: #f5f5f5;
    color: #333;
}

header {
    background: #4CAF50;
    color: white;
    padding: 1rem 2rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
    position: sticky;
    top: 0;
    z-index: 100;
}

.logo {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1.5rem;
    font-weight: bold;
    cursor: pointer;
}

.search-cart {
    display: flex;
    align-items: center;
    gap: 20px;
}

.cart-icon {
    position: relative;
    cursor: pointer;
    font-size: 1.2rem;
}

.cart-count {
    position: absolute;
    top: -10px;
    right: -10px;
    background: #FF5722;
    color: white;
    border-radius: 50%;
    width: 20px;
    height: 20px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 0.7rem;
}

/* Categories */
.categories {
    display: flex;
    gap: 10px;
    padding: 1rem 2rem;
    overflow-x: auto;
    background: white;
    position: sticky;
    top: 70px;
    z-index: 90;
}

.category-btn {
    background: white;
    border: 1px solid #ddd;
    padding: 0.5rem 1rem;
    border-radius: 20px;
    cursor: pointer;
    transition: all 0.3s;
    white-space: nowrap;
}

.category-btn:hover {
    background: #f0f0f0;
}

.category-btn.active {
    background: #4CAF50;
    color: white;
    border-color: #4CAF50;
}

/* Products */
.products {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 20px;
    padding: 1rem 2rem;
}

.product-card {
    background: white;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 0 3px 10px rgba(0,0,0,0.1);
    transition: all 0.3s;
    animation: fadeIn 0.5s ease forwards;
    opacity: 0;
}

.product-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 10px 20px rgba(0,0,0,0.15);
}

.product-image {
    width: 100%;
    height: 180px;
    object-fit: cover;
    border-bottom: 1px solid #eee;
}

.product-info {
    padding: 1rem;
}

.product-title {
    font-size: 1rem;
    margin-bottom: 0.5rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.product-price {
    color: #4CAF50;
    font-weight: bold;
    font-size: 1.2rem;
    margin-bottom: 1rem;
}

.add-to-cart {
    width: 100%;
    padding: 0.5rem;
    background: #4CAF50;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    transition: background 0.3s;
    font-weight: 500;
}

.add-to-cart:hover {
    background: #388E3C;
}

/* Cart Page */
.cart-container {
    max-width: 800px;
    margin: 2rem auto;
    padding: 1rem;
}

.cart-items {
    margin-top: 2rem;
}

.cart-item {
    display: flex;
    gap: 1rem;
    padding: 1rem;
    border-bottom: 1px solid #eee;
    align-items: center;
    background: white;
    border-radius: 5px;
    margin-bottom: 10px;
    box-shadow: 0 2px 5px rgba(0,0,0,0.05);
}

.cart-item-image {
    width: 80px;
    height: 80px;
    object-fit: cover;
    border-radius: 5px;
}

.cart-item-details {
    flex-grow: 1;
}

.cart-item h3 {
    margin-bottom: 0.5rem;
}

.quantity-controls {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

.quantity-btn {
    width: 25px;
    height: 25px;
    border: none;
    background: #4CAF50;
    color: white;
    border-radius: 3px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}

.remove-item {
    background: transparent;
    border: none;
    color: #f44336;
    cursor: pointer;
    font-size: 1.2rem;
    padding: 0.5rem;
}

.cart-summary {
    margin-top: 2rem;
    padding: 1.5rem;
    background: white;
    border-radius: 10px;
    box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

.summary-item {
    display: flex;
    justify-content: space-between;
    margin-bottom: 1rem;
    font-size: 1.1rem;
}

.total-price {
    font-weight: bold;
    color: #4CAF50;
    font-size: 1.2rem;
}

.checkout-btn {
    width: 100%;
    padding: 1rem;
    background: #4CAF50;
    color: white;
    border: none;
    border-radius: 5px;
    font-size: 1rem;
    cursor: pointer;
    transition: background 0.3s;
    margin-top: 1rem;
    font-weight: bold;
}

.checkout-btn:hover {
    background: #388E3C;
}

/* Animations */
@keyframes fadeIn {
    from { opacity: 0; transform: translateY(20px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes bounce {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.2); }
}

.bounce {
    animation: bounce 0.3s ease;
}

/* Responsive */
@media (max-width: 768px) {
    header {
        padding: 1rem;
    }
    
    .products {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        padding: 1rem;
    }
    
    .cart-item {
        flex-direction: column;
        text-align: center;
    }
    
    .quantity-controls {
        justify-content: center;
    }
}

4. File script.js

javascript
// Data Produk
const products = [
    {
        id: 1,
        name: "Smartphone X",
        price: 4999000,
        category: "elektronik",
        image: "https://images.unsplash.com/photo-1592899677977-9c10ca588bbd?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80"
    },
    {
        id: 2,
        name: "Laptop Pro",
        price: 12999000,
        category: "elektronik",
        image: "https://images.unsplash.com/photo-1496181133206-80ce9b88a853?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80"
    },
    {
        id: 3,
        name: "Kemeja Flanel",
        price: 299000,
        category: "fashion",
        image: "https://images.unsplash.com/photo-1529374255404-311a2a4f1fd9?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80"
    },
    {
        id: 4,
        name: "Sepatu Sneakers",
        price: 599000,
        category: "fashion",
        image: "https://images.unsplash.com/photo-1542291026-7eec264c27ff?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80"
    },
    {
        id: 5,
        name: "Kopi Premium",
        price: 99000,
        category: "makanan",
        image: "https://images.unsplash.com/photo-1517705008128-361805f42e86?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80"
    },
    {
        id: 6,
        name: "Coklat Belgia",
        price: 129000,
        category: "makanan",
        image: "https://images.unsplash.com/photo-1606313564200-e75d5e30476c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=500&q=80"
    }
];

// Variabel Global
let cart = JSON.parse(localStorage.getItem('cart')) || [];
const productsContainer = document.getElementById('productsContainer');
const categoryButtons = document.querySelectorAll('.category-btn');
const cartCount = document.querySelector('.cart-count');
const cartIcon = document.querySelector('.cart-icon');

// Fungsi untuk menampilkan produk
function displayProducts(filteredProducts = products) {
    productsContainer.innerHTML = '';
    
    filteredProducts.forEach((product, index) => {
        const productCard = document.createElement('div');
        productCard.classList.add('product-card');
        productCard.style.animationDelay = `${index * 0.1}s`;
        
        productCard.innerHTML = `
            <img src="${product.image}" alt="${product.name}" class="product-image">
            <div class="product-info">
                <h3 class="product-title">${product.name}</h3>
                <p class="product-price">Rp ${product.price.toLocaleString('id-ID')}</p>
                <button class="add-to-cart" data-id="${product.id}">Tambah ke Keranjang</button>
            </div>
        `;
        
        productsContainer.appendChild(productCard);
    });
    
    // Tambahkan event listener ke tombol
    document.querySelectorAll('.add-to-cart').forEach(button => {
        button.addEventListener('click', function() {
            const productId = parseInt(this.dataset.id);
            addToCart(productId);
            
            // Animasi feedback
            this.textContent = "✓ Ditambahkan";
            this.style.backgroundColor = "#388E3C";
            setTimeout(() => {
                this.textContent = "Tambah ke Keranjang";
                this.style.backgroundColor = "#4CAF50";
            }, 1000);
        });
    });
}

// Fungsi untuk menambahkan produk ke keranjang
function addToCart(productId) {
    const product = products.find(p => p.id === productId);
    const existingItem = cart.find(item => item.id === productId);
    
    if (existingItem) {
        existingItem.quantity += 1;
    } else {
        cart.push({ ...product, quantity: 1 });
    }
    
    updateCartCount();
    saveCart();
}

// Fungsi untuk memperbarui jumlah keranjang
function updateCartCount() {
    const totalItems = cart.reduce((total, item) => total + item.quantity, 0);
    cartCount.textContent = totalItems;
    
    // Animasi
    cartCount.classList.add('bounce');
    setTimeout(() => {
        cartCount.classList.remove('bounce');
    }, 300);
}

// Fungsi untuk menyimpan keranjang ke localStorage
function saveCart() {
    localStorage.setItem('cart', JSON.stringify(cart));
}

// Filter produk berdasarkan kategori
categoryButtons.forEach(button => {
    button.addEventListener('click', () => {
        // Update tombol aktif
        categoryButtons.forEach(btn => btn.classList.remove('active'));
        button.classList.add('active');
        
        const category = button.dataset.category;
        if (category === 'all') {
            displayProducts();
        } else {
            const filteredProducts = products.filter(product => product.category === category);
            displayProducts(filteredProducts);
        }
    });
});

// Navigasi ke keranjang
cartIcon.addEventListener('click', () => {
    window.location.href = 'cart.html';
});

// Navigasi ke beranda saat logo diklik
document.querySelector('.logo').addEventListener('click', () => {
    window.location.href = 'index.html';
});

// Inisialisasi
displayProducts();
updateCartCount();

5. File script-cart.js

javascript
// Ambil data dari localStorage
let cart = JSON.parse(localStorage.getItem('cart')) || [];
const cartItemsContainer = document.getElementById('cartItems');
const totalItemsElement = document.getElementById('totalItems');
const totalPriceElement = document.getElementById('totalPrice');
const cartCount = document.querySelector('.cart-count');
const checkoutBtn = document.querySelector('.checkout-btn');

// Fungsi untuk menampilkan keranjang
function displayCart() {
    cartItemsContainer.innerHTML = '';
    
    if (cart.length === 0) {
        cartItemsContainer.innerHTML = `
            <div class="empty-cart">
                <i class="fas fa-shopping-cart" style="font-size: 3rem; opacity: 0.3;"></i>
                <p>Keranjang belanja kosong</p>
                <a href="index.html" class="back-to-shop">Kembali Berbelanja</a>
            </div>
        `;
        totalItemsElement.textContent = '0';
        totalPriceElement.textContent = 'Rp 0';
        checkoutBtn.style.display = 'none';
        return;
    }
    
    let totalItems = 0;
    let totalPrice = 0;
    
    cart.forEach(item => {
        totalItems += item.quantity;
        totalPrice += item.price * item.quantity;
        
        const cartItem = document.createElement('div');
        cartItem.classList.add('cart-item');
        cartItem.innerHTML = `
            <img src="${item.image}" alt="${item.name}" class="cart-item-image">
            <div class="cart-item-details">
                <h3>${item.name}</h3>
                <p>Rp ${item.price.toLocaleString('id-ID')}</p>
                <div class="quantity-controls">
                    <button class="quantity-btn" data-id="${item.id}" data-action="decrease">-</button>
                    <span class="quantity">${item.quantity}</span>
                    <button class="quantity-btn" data-id="${item.id}" data-action="increase">+</button>
                </div>
            </div>
            <button class="remove-item" data-id="${item.id}">
                <i class="fas fa-trash"></i>
            </button>
        `;
        
        cartItemsContainer.appendChild(cartItem);
    });
    
    // Update total
    totalItemsElement.textContent = totalItems;
    totalPriceElement.textContent = `Rp ${totalPrice.toLocaleString('id-ID')}`;
    checkoutBtn.style.display = 'block';
    
    // Tambahkan event listeners
    document.querySelectorAll('.quantity-btn').forEach(button => {
        button.addEventListener('click', updateQuantity);
    });
    
    document.querySelectorAll('.remove-item').forEach(button => {
        button.addEventListener('click', removeItem);
    });
}

// Fungsi untuk memperbarui kuantitas
function updateQuantity(e) {
    const productId = parseInt(e.target.dataset.id);
    const action = e.target.dataset.action;
    const item = cart.find(item => item.id === productId);
    
    if (action === 'increase') {
        item.quantity += 1;
    } else if (action === 'decrease' && item.quantity > 1) {
        item.quantity -= 1;
    }
    
    updateCart();
}

// Fungsi untuk menghapus item
function removeItem(e) {
    const productId = parseInt(e.target.closest('button').dataset.id);
    cart = cart.filter(item => item.id !== productId);
    updateCart();
}

// Fungsi untuk memperbarui keranjang
function updateCart() {
    saveCart();
    displayCart();
    updateCartCount();
}

// Fungsi untuk menyimpan keranjang
function saveCart() {
    localStorage.setItem('cart', JSON.stringify(cart));
}

// Fungsi untuk update counter keranjang
function updateCartCount() {
    const total = cart.reduce((sum, item) => sum + item.quantity, 0);
    cartCount.textContent = total;
}

// Proses checkout
checkoutBtn.addEventListener('click', () => {
    alert(`Checkout berhasil! Total belanja: Rp ${totalPriceElement.textContent}`);
    cart = [];
    updateCart();
});

// Inisialisasi
displayCart();
updateCartCount();

Fitur Utama yang Telah Dibangun

  1. Sistem Produk:
    • Menampilkan daftar produk dengan gambar
    • Filter produk berdasarkan kategori


Kesimpulan

Kita telah berhasil membuat website marketplace sederhana dengan:
✅ HTML untuk struktur
✅ CSS untuk styling dan animasi
✅ JavaScript untuk interaktivitas

Proyek ini cocok untuk pemula yang ingin belajar pengembangan web front-end.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *