EcomLib Product Render Feature Documentation


1. Prerequisites

Before starting, make sure you have:

2. Firebase Setup

Steps to configure Firebase Firestore:

  1. Go to Firebase Console and create a new project.
  2. Register a web app in your project and copy the Firebase config object:
const firebaseConfig = {
        apiKey: "AIzaSyCUad2MwdykedKqSWG7AOx9iIN5ePYxDg8",
        authDomain: "ecommerce-products-573ce.firebaseapp.com",
        projectId: "ecommerce-products-573ce",
        storageBucket: "ecommerce-products-573ce.firebasestorage.app",
        messagingSenderId: "875506405938",
        appId: "1:875506405938:web:815042d0daf81941ae622b",
        measurementId: "G-LTEMTLNB9E"
    };
  1. Enable Cloud Firestore in test mode to allow writing data during development.

3. Shop Product Template

Combine the HTML, CSS, and JS above into a single HTML file for immediate use in development. This template is ready to drop into Live Server and start uploading products.

<!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Shop</title>
            <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
            <style>
                /* Products Section */
                .container-products {
                    max-width: 1200px;
                    margin: 0 auto;
                    padding: 40px 20px;
                }

                .section-title-products {
                    text-align: center;
                    font-size: 2.5rem;
                    font-weight: 300;
                    letter-spacing: 2px;
                    margin-bottom: 50px;
                    color: #222;
                    position: relative;
                }

                .section-title-products::after {
                    content: '';
                    position: absolute;
                    bottom: -15px;
                    left: 50%;
                    transform: translateX(-50%);
                    width: 80px;
                    height: 2px;
                    background-color: #d4af37;
                }

                .collections-grid {
                    display: grid;
                    grid-template-columns: repeat(1, 1fr);
                    gap: 30px;
                }

                .all-btn {
                    text-align: center;
                    margin-top: 30px;
                }

                @media (min-width: 768px) {
                    .collections-grid {
                        grid-template-columns: repeat(2, 1fr);
                    }
                }

                @media (min-width: 1024px) {
                    .collections-grid {
                        grid-template-columns: repeat(3, 1fr);
                    }
                }

                .product-card {
                    background: white;
                    border-radius: 8px;
                    overflow: hidden;
                    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
                    transition: transform 0.3s ease, box-shadow 0.3s ease;
                    position: relative;
                }

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

                .product-image {
                    padding: 10px;
                    width: 100%;
                    height: 280px;
                    object-fit: contain;
                    display: block;
                }

                .divider {
                    height: 1px;
                    background-color: #d4af37;
                    width: 100%;
                    margin: 0;
                }

                .product-info {
                    padding: 20px;
                }

                .product-name {
                    font-size: 1.2rem;
                    font-weight: 500;
                    margin-bottom: 8px;
                    color: #222;
                }

                .product-price {
                    font-size: 1.1rem;
                    font-weight: 600;
                    color: #d4af37;
                }

                .overlay-products {
                    position: absolute;
                    bottom: 0;
                    left: 0;
                    right: 0;
                    background-color: rgba(0, 0, 0, 0.7);
                    overflow: hidden;
                    width: 100%;
                    height: 0;
                    transition: height 0.3s ease;
                    display: flex;
                    flex-direction: column;
                    justify-content: center;
                    align-items: center;
                    gap: 15px;
                }

                /* Show overlay when hovering on product card */
                .product-card:hover .overlay-products {
                    height: 100%;
                }

                .view-details-btn {
                    background-color: transparent;
                    border: 2px solid white;
                    color: white;
                    padding: 12px 25px;
                    font-size: 0.9rem;
                    cursor: pointer;
                    border-radius: 4px;
                    transition: all 0.3s ease;
                    letter-spacing: 1px;
                    font-weight: 500;
                    text-decoration: none;
                }

                .view-details-btn:hover {
                    background-color: white;
                    color: #222;
                    transform: scale(1.05);
                }

                .cart-icon {
                    color: white;
                    font-size: 1.5rem;
                    cursor: pointer;
                    transition: all 0.3s ease;
                    background: rgba(255, 255, 255, 0.2);
                    width: 50px;
                    height: 50px;
                    border-radius: 50%;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                }

                .cart-icon:hover {
                    background: rgba(255, 255, 255, 0.3);
                    transform: scale(1.1);
                }

                .notification {
                    position: fixed;
                    top: 20px;
                    right: 20px;
                    background: #222;
                    color: white;
                    padding: 15px 25px;
                    border-radius: 4px;
                    box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2);
                    transform: translateX(150%);
                    transition: transform 0.4s ease;
                    z-index: 1000;
                }

                .notification.show {
                    transform: translateX(0);
                }
            </style>
        </head>
        <body>
            <!-- Products -->
            <div class="container-products">
                <h1 class="section-title-products">Product Collections</h1>
                <div class="collections-grid" id="productsGrid">
                    <!-- Product cards will be appended here dynamically -->
                </div>
            </div>

            <!-- Font Awesome for cart icons -->
            <script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
            <script type="module">
                import { initializeApp } from "https://www.gstatic.com/firebasejs/10.12.0/firebase-app.js";
                import { getFirestore, collection, getDocs } from "https://www.gstatic.com/firebasejs/10.12.0/firebase-firestore.js";

                const firebaseConfig = {
                    apiKey: "AIzaSyCUad2MwdykedKqSWG7AOx9iIN5ePYxDg8",
                    authDomain: "ecommerce-products-573ce.firebaseapp.com",
                    projectId: "ecommerce-products-573ce",
                    storageBucket: "ecommerce-products-573ce.firebasestorage.app",
                    messagingSenderId: "875506405938",
                    appId: "1:875506405938:web:815042d0daf81941ae622b",
                    measurementId: "G-LTEMTLNB9E"
                };

                const app = initializeApp(firebaseConfig);
                const db = getFirestore(app);

                const productsGrid = document.getElementById("productsGrid");

                async function fetchProducts() {
                    try {
                        const querySnapshot = await getDocs(collection(db, "products"));
                        querySnapshot.forEach(doc => {
                            const product = doc.data();

                            const card = document.createElement("div");
                            card.classList.add("product-card");

                            card.innerHTML = `
                                <img src="${product.mainImage}" alt="${product.name}" class="product-image">
                                <div class="divider"></div>
                                <div class="product-info">
                                    <h3 class="product-name">${product.name}</h3>
                                    <p class="product-price">Ksh ${product.price}</p>
                                </div>
                                <div class="overlay-products">
                                    <a href="product.html?id=${doc.id}" class="view-details-btn">VIEW DETAILS</a>
                                    <div class="cart-icon" data-product="${product.name}">
                                        <i class="fas fa-shopping-cart"></i>
                                    </div>
                                </div>
                            `;

                            productsGrid.appendChild(card);
                        });
                    } catch (err) {
                        console.error("Error fetching products:", err);
                        productsGrid.innerHTML = "<p>Failed to load products. Please try again later.</p>";
                    }
                }

                fetchProducts();
            </script>
        </body>
        </html>
    
All code blocks above are fully copyable. Follow the Firebase and Cloudinary setup carefully to ensure uploads work correctly.