PWEB EAS

 

muhammad rafi budi purnama

5025221307

pweb 


📚 DOKUMENTASI LENGKAP E-COMMERCE SYSTEM

With Payment System, Order Tracking & Live Search API

CODE : https://github.com/mbahbud/ecomerce-with-api.git




fitur fiturnya seeprti ini

BISA DIBACA UNTUK TABLE OF CONTENTNYA


📖 TABLE OF CONTENTS

  1. Overview
  2. Arsitektur Sistem
  3. Frontend Explanation
  4. Backend Explanation
  5. Database Implementation
  6. API Integration
  7. Testing Guide
  8. Diagram Sistem
  9. User Guide

1️⃣ OVERVIEW

Teknologi Stack

Frontend:  HTML5, CSS3, JavaScript (Vanilla), Bootstrap 5
Backend:   PHP Native (No Framework)
Database:  MySQL
API:       REST API (JSON Response)

Fitur Utama

✅ User Management (Register, Login, Profile)
✅ Product Management (CRUD)
✅ Shopping Cart (AJAX)
✅ Payment System (Upload Proof & Verification)
✅ Order Tracking (Real-time Timeline)
✅ Live Search (Search as you type) (API)
✅ Admin Dashboard

2️⃣ ARSITEKTUR SISTEM

System Architecture

┌─────────────┐
│   Browser   │
│  (Client)   │
└──────┬──────┘
       │
       │ HTTP Request
       ▼
┌─────────────────────────┐
│    Web Server (Apache)   │
│   ┌─────────────────┐   │
│   │   PHP Engine    │   │
│   └─────────────────┘   │
└──────────┬──────────────┘
           │
           │ Query
           ▼
    ┌─────────────┐
    │    MySQL    │
    │  Database   │
    └─────────────┘

Folder Structure

ecommerce/
├── 📁 admin/              → Admin Panel
├── 📁 ajax/               → AJAX Endpoints
├── 📁 api/                → REST API Endpoints ⭐
├── 📁 assets/             → CSS, JS, Images
├── 📁 config/             → Database Config
├── 📁 includes/           → Reusable Components
├── 📄 index.php           → Homepage
├── 📄 products.php        → Product Listing
├── 📄 cart.php            → Shopping Cart
├── 📄 checkout.php        → Checkout Page
├── 📄 payment.php         → Payment Page ⭐
├── 📄 order_tracking.php  → Order Tracking ⭐
└── 📄 database.sql        → Database Schema

3️⃣ FRONTEND EXPLANATION

A. HTML Structure

1. products.php (Product Listing with Live Search)

<!-- Search Input -->
<input type="text" 
       id="liveSearchInput" 
       placeholder="Type to search..."
       autocomplete="off">

<!-- Loading Indicator -->
<div id="loadingIndicator" style="display: none;">
    Searching...
</div>

<!-- Products Container -->
<div id="productsContainer">
    <!-- Dynamic content dari JS -->
</div>

Penjelasan:

  • Search Input: User ketik keyword → trigger search
  • Loading: Muncul saat fetching data
  • Container: Tempat render hasil search

2. payment.php (Payment Upload)

<form method="POST" action="payment_confirm.php" enctype="multipart/form-data">
    <input type="text" name="account_name" placeholder="Nama Pengirim">
    <input type="text" name="bank_account" placeholder="No. Rekening">
    <input type="file" name="payment_proof" accept="image/*,.pdf">
    <button type="submit">Upload Payment Proof</button>
</form>

Penjelasan:

  • Form: Upload bukti transfer
  • enctype: Wajib untuk file upload
  • accept: Limit file type (image/pdf only)

3. order_tracking.php (Tracking Timeline)

<div class="tracking-timeline">
    <div class="tracking-item active">
        <h6>Order Shipped</h6>
        <p>Jakarta Hub</p>
        <small>15 Dec 2024, 10:30</small>
    </div>
    <div class="tracking-item">
        <h6>Order Processed</h6>
        <p>Warehouse</p>
        <small>14 Dec 2024, 14:00</small>
    </div>
</div>

Penjelasan:

  • Timeline: Vertical timeline dengan CSS
  • Active: Item terbaru highlighted
  • Dynamic: Data dari database

B. CSS Styling

1. Live Search Styling

#liveSearchInput {
    border: 2px solid #dee2e6;
    transition: border-color 0.3s ease;
}

#liveSearchInput:focus {
    border-color: #0d6efd;
    box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.25);
}

Penjelasan:

  • Focus effect saat user click search box
  • Smooth transition 0.3s

2. Tracking Timeline CSS

.tracking-timeline {
    position: relative;
    padding-left: 40px;
}

.tracking-timeline::before {
    content: '';
    position: absolute;
    left: 12px;
    width: 3px;
    height: 100%;
    background: linear-gradient(to bottom, #0d6efd, #dee2e6);
}

.tracking-item::before {
    content: '';
    position: absolute;
    left: -32px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: #fff;
    border: 4px solid #dee2e6;
}

.tracking-item.active::before {
    border-color: #0d6efd;
    background: #0d6efd;
    box-shadow: 0 0 0 4px rgba(13, 110, 253, 0.2);
}

Penjelasan:

  • ::before: Pseudo-element untuk garis vertical
  • Circle: Bullet point untuk setiap status
  • Active: Highlight status terbaru

3. Payment Status Badge

.payment-status {
    padding: 8px 16px;
    border-radius: 20px;
    font-weight: 600;
}

.payment-unpaid { background: #dc3545; color: white; }
.payment-pending { background: #ffc107; color: #000; }
.payment-verified { background: #198754; color: white; }

Penjelasan:

  • Badge dengan warna berbeda per status
  • Border-radius untuk rounded corners

C. JavaScript Logic

1. Live Search Function

let searchTimeout;

liveSearchInput.addEventListener('input', function() {
    clearTimeout(searchTimeout);
    
    const keyword = this.value.trim();
    
    // Minimal 2 karakter
    if (keyword.length < 2) return;
    
    // Debounce: Tunggu 500ms
    searchTimeout = setTimeout(() => {
        performLiveSearch(keyword);
    }, 500);
});

async function performLiveSearch(keyword) {
    loadingIndicator.style.display = 'block';
    
    const response = await fetch(`api/search_products.php?q=${keyword}`);
    const data = await response.json();
    
    loadingIndicator.style.display = 'none';
    displayProducts(data.products);
}

Penjelasan:

  • Debounce: Delay 500ms agar tidak spam request
  • Async/Await: Modern JavaScript untuk async operation
  • Fetch API: HTTP request ke backend
  • JSON: Parse response dari server

2. Display Products Function

function displayProducts(products) {
    let html = '<div class="row g-4">';
    
    products.forEach(product => {
        html += `
            <div class="col-md-4">
                <div class="card">
                    <img src="${product.image_url}">
                    <h5>${product.name}</h5>
                    <p>${product.price_formatted}</p>
                    <button onclick="addToCart(${product.id})">
                        Add to Cart
                    </button>
                </div>
            </div>
        `;
    });
    
    html += '</div>';
    productsContainer.innerHTML = html;
}

Penjelasan:

  • Template Literals: ES6 syntax untuk string interpolation
  • forEach: Loop through products array
  • innerHTML: Update DOM dengan HTML baru

3. Add to Cart (AJAX)

async function addToCart(productId) {
    const response = await fetch('ajax/add_to_cart.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: `product_id=${productId}`
    });
    
    const data = await response.json();
    
    if (data.success) {
        alert('Product added to cart!');
        updateCartCount();
    }
}

Penjelasan:

  • POST request: Kirim product_id ke server
  • Headers: Set content type
  • Response handling: Check success status

4️⃣ BACKEND EXPLANATION

A. Database Connection

config/database.php

<?php
define('DB_HOST', 'localhost');
define('DB_USER', 'root');
define('DB_PASS', '');
define('DB_NAME', 'ecommerce_db');

function getDBConnection() {
    $conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
    
    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }
    
    $conn->set_charset("utf8mb4");
    return $conn;
}

function sanitize($data) {
    $data = trim($data);
    $data = stripslashes($data);
    $data = htmlspecialchars($data);
    return $data;
}
?>

Penjelasan:

  • MySQLi: PHP extension untuk MySQL
  • utf8mb4: Support emoji & special characters
  • sanitize(): Clean user input (XSS protection)

B. API Endpoint

api/search_products.php

<?php
header('Content-Type: application/json');

$keyword = sanitize($_GET['q']);
$conn = getDBConnection();

$query = "SELECT p.*, c.name as category_name 
          FROM products p 
          LEFT JOIN categories c ON p.category_id = c.id 
          WHERE p.name LIKE ? OR p.description LIKE ?
          LIMIT 20";

$stmt = $conn->prepare($query);
$search = "%$keyword%";
$stmt->bind_param("ss", $search, $search);
$stmt->execute();
$products = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);

echo json_encode([
    'success' => true,
    'count' => count($products),
    'products' => $products
]);
?>

Penjelasan:

  • JSON Header: Tell browser response is JSON
  • Prepared Statement: Prevent SQL injection
  • LIKE: Search pattern matching
  • LEFT JOIN: Get category name
  • json_encode: Convert array to JSON

C. Payment Processing

payment_confirm.php

<?php
// Handle file upload
if (isset($_FILES['payment_proof'])) {
    $allowed = ['image/jpeg', 'image/png', 'application/pdf'];
    $file_type = $_FILES['payment_proof']['type'];
    
    if (!in_array($file_type, $allowed)) {
        die('Invalid file type');
    }
    
    $filename = 'payment_' . $order_id . '_' . time() . '.jpg';
    $upload_path = 'assets/uploads/payments/' . $filename;
    
    move_uploaded_file($_FILES['payment_proof']['tmp_name'], $upload_path);
    
    // Save to database
    $query = "INSERT INTO payments (order_id, payment_proof, payment_status) 
              VALUES (?, ?, 'pending')";
    $stmt->bind_param("is", $order_id, $filename);
    $stmt->execute();
}
?>

Penjelasan:

  • File validation: Check type & size
  • Unique filename: Timestamp untuk avoid conflict
  • move_uploaded_file: PHP function untuk upload
  • Database insert: Save filename reference

D. Order Tracking

order_tracking.php (Backend Query)

<?php
// Get shipping info
$query = "SELECT o.*, s.tracking_number, s.courier, s.shipping_status
          FROM orders o 
          LEFT JOIN shipping s ON o.id = s.order_id
          WHERE o.id = ? AND o.user_id = ?";
$stmt->bind_param("ii", $order_id, $user_id);
$stmt->execute();
$order = $stmt->get_result()->fetch_assoc();

// Get tracking history
$history_query = "SELECT * FROM tracking_history 
                  WHERE shipping_id = ? 
                  ORDER BY created_at DESC";
$history = $conn->query($history_query)->fetch_all(MYSQLI_ASSOC);
?>

Penjelasan:

  • LEFT JOIN: Ambil data shipping
  • ORDER BY DESC: Latest first
  • Two queries: Order info + history

5️⃣ DATABASE IMPLEMENTATION

Database Schema

-- Products Table
CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    category_id INT,
    name VARCHAR(200) NOT NULL,
    description TEXT,
    price DECIMAL(10,2) NOT NULL,
    stock INT DEFAULT 0,
    image VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (category_id) REFERENCES categories(id)
);

-- Orders Table
CREATE TABLE orders (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id INT NOT NULL,
    total_amount DECIMAL(10,2) NOT NULL,
    status ENUM('pending', 'processing', 'shipped', 'delivered', 'cancelled'),
    payment_status ENUM('unpaid', 'pending', 'verified', 'rejected'),
    shipping_address TEXT NOT NULL,
    payment_method VARCHAR(50),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (user_id) REFERENCES users(id)
);

-- Payments Table ⭐ NEW
CREATE TABLE payments (
    id INT AUTO_INCREMENT PRIMARY KEY,
    order_id INT NOT NULL,
    amount DECIMAL(10,2) NOT NULL,
    payment_method VARCHAR(50),
    payment_status ENUM('unpaid', 'pending', 'verified', 'rejected'),
    payment_proof VARCHAR(255),
    bank_account VARCHAR(100),
    account_name VARCHAR(100),
    payment_date DATETIME,
    verified_by INT,
    verified_at DATETIME,
    rejection_reason TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (order_id) REFERENCES orders(id)
);

-- Shipping Table ⭐ NEW
CREATE TABLE shipping (
    id INT AUTO_INCREMENT PRIMARY KEY,
    order_id INT NOT NULL,
    tracking_number VARCHAR(100),
    courier VARCHAR(50),
    shipping_status ENUM('processing', 'picked_up', 'in_transit', 'out_for_delivery', 'delivered'),
    estimated_delivery DATE,
    actual_delivery DATETIME,
    notes TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (order_id) REFERENCES orders(id)
);

-- Tracking History Table ⭐ NEW
CREATE TABLE tracking_history (
    id INT AUTO_INCREMENT PRIMARY KEY,
    shipping_id INT NOT NULL,
    status VARCHAR(50) NOT NULL,
    location VARCHAR(200),
    description TEXT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (shipping_id) REFERENCES shipping(id)
);

Key Relationships

users (1) ──→ (N) orders
orders (1) ──→ (N) order_items
orders (1) ──→ (1) payments
orders (1) ──→ (1) shipping
shipping (1) ──→ (N) tracking_history
products (1) ──→ (N) order_items
categories (1) ──→ (N) products

6️⃣ API INTEGRATION

REST API Endpoints

1. Search Products

GET /api/search_products.php?q=keyword

Response:
{
  "success": true,
  "count": 3,
  "products": [
    {
      "id": 1,
      "name": "Laptop Gaming",
      "price": 15000000,
      "price_formatted": "Rp 15.000.000",
      "stock": 10,
      "in_stock": true,
      "category_name": "Electronics"
    }
  ]
}

2. Add to Cart

POST /ajax/add_to_cart.php
Body: product_id=1

Response:
{
  "success": true,
  "message": "Product added to cart"
}

3. Get Cart Count

GET /ajax/get_cart_count.php

Response:
{
  "count": 3
}

API Flow Diagram

┌────────┐    HTTP GET     ┌──────────────┐
│Browser │ ───────────────→│ API Endpoint │
└────────┘                  └──────┬───────┘
                                   │
                                   │ SQL Query
                                   ▼
                            ┌──────────────┐
                            │   Database   │
                            └──────┬───────┘
                                   │
                                   │ Result Set
┌────────┐    JSON Response       │
│Browser │ ←──────────────────────┘
└────────┘

7️⃣ TESTING GUIDE

A. Manual Testing Checklist

User Flow Testing

✅ 1. Register Account
   - Buka register.php
   - Isi form lengkap
   - Klik Register
   - Expected: Redirect ke login

✅ 2. Login
   - Username: admin / Password: admin123
   - Expected: Redirect ke dashboard (admin) atau home (user)

✅ 3. Browse Products
   - Buka products.php
   - Expected: Muncul list products

✅ 4. Live Search ⭐
   - Ketik "laptop" di search box
   - Expected: Hasil muncul tanpa reload
   - Ketik "phone"
   - Expected: Update hasil real-time

✅ 5. Add to Cart
   - Klik "Add to Cart" pada product
   - Expected: Alert "Product added"
   - Badge cart bertambah

✅ 6. Checkout
   - Buka cart.php
   - Klik "Proceed to Checkout"
   - Isi shipping address
   - Pilih payment method
   - Expected: Redirect ke payment.php

✅ 7. Payment Upload
   - Upload bukti transfer
   - Isi nama & no rekening
   - Expected: Status "Pending Verification"

✅ 8. Admin Verify Payment
   - Login sebagai admin
   - Buka admin/payments.php
   - Klik "View" payment
   - Klik "Verify"
   - Expected: Payment status → "Verified"

✅ 9. Admin Add Tracking
   - Buka admin/shipping.php
   - Input tracking number & courier
   - Update shipping status
   - Expected: Tracking visible di user

✅ 10. User Track Order
    - Login sebagai user
    - Buka order_tracking.php?order_id=X
    - Expected: Muncul timeline tracking

B. API Testing

Test Live Search API

# Test 1: Valid search
curl "http://localhost/ecommerce/api/search_products.php?q=laptop"

# Expected Response:
{
  "success": true,
  "count": 1,
  "products": [...]
}

# Test 2: Empty search
curl "http://localhost/ecommerce/api/search_products.php?q="

# Expected Response:
{
  "success": false,
  "message": "Search keyword required"
}

# Test 3: No results
curl "http://localhost/ecommerce/api/search_products.php?q=xyz123"

# Expected Response:
{
  "success": true,
  "count": 0,
  "products": []
}

C. Database Testing

-- Test 1: Check products exist
SELECT * FROM products;

-- Test 2: Check search query
SELECT * FROM products WHERE name LIKE '%laptop%';

-- Test 3: Check orders with payment
SELECT o.*, p.payment_status 
FROM orders o 
LEFT JOIN payments p ON o.id = p.order_id;

-- Test 4: Check tracking history
SELECT * FROM tracking_history WHERE shipping_id = 1;

8️⃣ DIAGRAM SISTEM

A. System Flow Diagram

┌──────────────────────────────────────────────────┐
│                  USER ACTIONS                     │
└───────────┬──────────────────────────────────────┘
            │
            ▼
    ┌──────────────┐
    │   Browse     │
    │  Products    │
    └──────┬───────┘
           │
           ▼
    ┌──────────────┐     ┌──────────────┐
    │ Live Search  │────→│  Search API  │
    │   (AJAX)     │     │   Endpoint   │
    └──────┬───────┘     └──────────────┘
           │
           ▼
    ┌──────────────┐
    │  Add to Cart │
    │   (AJAX)     │
    └──────┬───────┘
           │
           ▼
    ┌──────────────┐
    │   Checkout   │
    └──────┬───────┘
           │
           ▼
    ┌──────────────┐
    │Payment Upload│
    └──────┬───────┘
           │
           ▼
┌──────────────────────┐
│  ADMIN VERIFICATION  │
└──────────┬───────────┘
           │
           ▼
    ┌──────────────┐
    │Admin Verify  │
    │   Payment    │
    └──────┬───────┘
           │
           ▼
    ┌──────────────┐
    │  Admin Add   │
    │   Tracking   │
    └──────┬───────┘
           │
           ▼
    ┌──────────────┐
    │  User Track  │
    │    Order     │
    └──────────────┘

B. Database ER Diagram

┌─────────┐       ┌──────────┐       ┌─────────────┐
│  users  │───1:N─│  orders  │───1:1─│  payments   │
└─────────┘       └────┬─────┘       └─────────────┘
                       │
                       │1:1
                       ▼
                 ┌───────────┐
                 │  shipping │
                 └─────┬─────┘
                       │
                       │1:N
                       ▼
              ┌─────────────────┐
              │tracking_history │
              └─────────────────┘

┌────────────┐       ┌──────────┐
│ categories │───1:N─│ products │
└────────────┘       └────┬─────┘
                          │
                          │N:M (via order_items)
                          ▼
                    ┌──────────┐
                    │  orders  │
                    └──────────┘

C. Payment Flow Diagram

USER SIDE                    SYSTEM                    ADMIN SIDE
    │                           │                          │
    │ 1. Checkout               │                          │
    ├──────────────────────────→│                          │
    │                           │                          │
    │ 2. Upload Payment Proof   │                          │
    ├──────────────────────────→│                          │
    │                           │ Save to DB               │
    │                           │ Status: PENDING          │
    │                           ├─────────────────────────→│
    │                           │                          │
    │                           │      3. Admin View       │
    │                           │←─────────────────────────│
    │                           │                          │
    │                           │      4. Admin Verify     │
    │                           │←─────────────────────────│
    │                           │ Status: VERIFIED         │
    │                           │                          │
    │ 5. Notification           │                          │
    │←──────────────────────────│                          │
    │ "Payment Verified!"       │                          │
    │                           │                          │

9️⃣ USER GUIDE

A. User Registration & Login

Step 1: Register

1. Buka http://localhost/ecommerce/register.php
2. Isi form:
   - Username: johndoe
   - Email: john@example.com
   - Password: 123456
   - Full Name: John Doe
   - Phone: 081234567890
3. Klik "Register"
4. Redirect ke login page

Step 2: Login

1. Buka http://localhost/ecommerce/login.php
2. Isi credentials:
   - Username: johndoe
   - Password: 123456
3. Klik "Login"
4. Redirect ke homepage

B. Shopping Flow

Step 1: Browse & Search Products

1. Buka products.php
2. Cara 1: Filter by category (klik sidebar)
3. Cara 2: Live Search
   - Ketik "laptop" di search box
   - Hasil muncul otomatis
   - Tidak perlu klik search button

Step 2: View Product Detail

1. Klik "View Details" pada product card
2. Lihat informasi lengkap
3. Klik "Add to Cart"
4. Alert muncul: "Product added to cart!"

Step 3: Manage Cart

1. Klik icon cart di navbar
2. Lihat items di cart
3. Ubah quantity:
   - Klik (+) untuk tambah
   - Klik (-) untuk kurang
4. Klik (🗑️) untuk hapus item
5. Klik "Proceed to Checkout"

Step 4: Checkout

1. Review order summary
2. Isi/edit shipping address
3. Pilih payment method:
   - Bank Transfer
   - Credit Card
   - E-Wallet
   - COD
4. Klik "Place Order"
5. Redirect ke payment page

C. Payment Process

Step 1: Upload Payment Proof

1. Transfer ke rekening toko
2. Screenshot/foto bukti transfer
3. Isi form payment:
   - Nama Pengirim: John Doe
   - No. Rekening: 1234567890
   - Tanggal Transfer: 15-12-2024 10:30
   - Upload File: bukti_transfer.jpg
4. Klik "Submit Payment Proof"
5. Status: "Pending Verification"

Step 2: Wait for Verification

1. Buka "My Orders"
2. Klik order yang sudah upload payment
3. Status Payment: "PENDING"
4. Keterangan: "Payment verification in progress"
5. Tunggu admin verify (biasanya < 1 jam)

Step 3: Payment Verified

1. Refresh page / cek orders
2. Status Payment: "VERIFIED"
3. Button "Track Order" muncul
4. Order masuk processing

D. Order Tracking

View Tracking Information

1. Buka "My Orders"
2. Klik "Track Order" pada order verified
3. Lihat informasi:
   - Tracking Number: JNE123456789
   - Courier: JNE
   - Status: In Transit
   - Estimated Delivery: 20-12-2024
4. Lihat Timeline:
   - [Active] In Transit - Jakarta Hub
   - [Done] Order Picked Up - Warehouse
   - [Done] Order Processing
5. Auto-refresh setiap update admin

E. Admin Guide

Admin Login

Username: admin
Password: admin123
URL: http://localhost/ecommerce/admin/

Manage Payments

1. Menu "Payments"
2. Lihat list pending payments
3. Klik "View" untuk lihat bukti transfer
4. Verify:
   - Jika valid: Klik "Verify"
   - Jika invalid: Klik "Reject" + isi reason

Manage Shipping

1. Menu "Shipping"
2. Pilih order yang sudah verified payment
3. Klik "Update"
4. Isi form:
   - Tracking Number: JNE123456789
   - Courier: JNE
   - Shipping Status: In Transit
   - Estimated Delivery: 20-12-2024
   - Description: Package on the way
5. Klik "Update Shipping"
6. User bisa langsung track!

🎯 KESIMPULAN

What We Built

✅ E-Commerce System lengkap
✅ Payment Upload & Verification
✅ Order Tracking System
✅ Live Search API
✅ Admin Management Panel
✅ Responsive Design

Technologies Used

Frontend: HTML5, CSS3, Vanilla JS, Bootstrap 5
Backend:  PHP Native, MySQLi
Database: MySQL
API:      REST API, JSON

Key Features

🔍 Live Search - Instant search tanpa reload
💳 Payment System - Upload & verify payment
📦 Order Tracking - Real-time timeline
🛒 Shopping Cart - AJAX operations
👥 User Management - Register, Login, Profile
🎨 Admin Panel - Complete management

📚 ADDITIONAL RESOURCES

File Structure Summary














Komentar

Postingan populer dari blog ini

TUGAS 2 : Jettpack compose : Hello, World!

Pertemuan 3 PPB (A) - Mengenal Composable Aplikasi Selamat Ulang Tahun

Pertemuan 5 - Aplikasi Kalkulator Sederhana