E-commerce #

Admindek 3.4 ships a complete e-commerce flow — every page a buyer or admin would touch, from product discovery through checkout and order management.

New in 3.4

All e-commerce pages are new in Admindek 3.4. They share a common SCSS partial (_ecommerce.scss) and follow Bootstrap 5 conventions throughout.

Page catalog #

PageFilePurpose
Product Listingapplication/ec-product-list.htmlCatalog grid/list with filters
Product Detailapplication/ec-product-detail.htmlSingle product with gallery, variants, reviews
Cartapplication/ec-cart.htmlShopping cart with quantity controls
Checkoutapplication/ec-checkout.htmlMulti-step address → payment → review
Order Listapplication/ec-order-list.htmlOrder history with status
Order Detailapplication/ec-order-detail.htmlSingle order with timeline
Add Productapplication/ec-add-product.htmlAdmin product creation form

Product Listing #

A faceted catalog with filters, sorting, and view toggle.

File: src/html/application/ec-product-list.html

Features #

  • Sidebar filters: Categories, price range (noUiSlider), brand, rating
  • Sort dropdown: Featured, Price (low → high), Price (high → low), Newest, Best rated
  • View toggle: Grid (default) or list
  • Pagination: Bootstrap pagination, configurable per-page count
  • Quick add to cart: Hover the product card for a quick "Add to cart" button

Markup #

<div class="ec-listing">
  <aside class="ec-filters">
    <div class="ec-filter-group">
      <h6>Category</h6>
      <ul class="list-unstyled">
        <li><label><input type="checkbox" /> Electronics <span class="text-muted">(248)</span></label></li>
        <li><label><input type="checkbox" /> Clothing <span class="text-muted">(412)</span></label></li>
      </ul>
    </div>
 
    <div class="ec-filter-group">
      <h6>Price</h6>
      <div id="priceRange"></div>
      <small class="text-muted">$<span id="priceMin">0</span> – $<span id="priceMax">500</span></small>
    </div>
 
    <div class="ec-filter-group">
      <h6>Rating</h6>
      <!-- 5/4/3/2/1 star checkboxes with star-rating.js -->
    </div>
  </aside>
 
  <main class="ec-products">
    <div class="ec-toolbar">
      <select class="form-select w-auto"><!-- sort --></select>
      <div class="btn-group ec-view-toggle">
        <button class="btn btn-outline-secondary active" data-view="grid"><i class="ti ti-layout-grid"></i></button>
        <button class="btn btn-outline-secondary" data-view="list"><i class="ti ti-list"></i></button>
      </div>
    </div>
 
    <div class="row g-3 ec-product-grid">
      <div class="col-6 col-md-4 col-xl-3">
        <article class="ec-product-card">
          <div class="ec-product-image">
            <img src="/images/products/sneaker.jpg" alt="" />
            <button class="ec-quick-add btn btn-primary">Add to cart</button>
          </div>
          <h6 class="ec-product-name">Air Runner</h6>
          <div class="ec-product-rating"><!-- stars --></div>
          <div class="ec-product-price">
            <span class="ec-price-current">$129</span>
            <span class="ec-price-old">$159</span>
          </div>
        </article>
      </div>
    </div>
  </main>
</div>

Product Detail #

Single-product page with image gallery, variants, reviews, and related products.

File: src/html/application/ec-product-detail.html

Features #

  • Image gallery with thumbnail nav (Swiper)
  • Variant selectors (size, color) — disabled when out of stock
  • Quantity stepper
  • Add to cart + Buy now CTAs
  • Tabs for Description, Specifications, Reviews, Q&A
  • Related products carousel
  • Recently viewed strip
  • Sticky add-to-cart bar on mobile
<div class="ec-product-detail row g-4">
  <div class="col-md-6">
    <!-- Swiper image gallery -->
    <div class="swiper ec-product-gallery">
      <div class="swiper-wrapper">
        <div class="swiper-slide"><img src="/images/products/sneaker-1.jpg" alt="" /></div>
        <div class="swiper-slide"><img src="/images/products/sneaker-2.jpg" alt="" /></div>
      </div>
    </div>
    <!-- Thumbnails -->
    <div class="swiper ec-product-thumbs">
      <div class="swiper-wrapper"><!-- thumb slides --></div>
    </div>
  </div>
 
  <div class="col-md-6">
    <h1 class="ec-product-title">Air Runner</h1>
    <div class="ec-product-rating"><!-- ★★★★☆ 4.6 (213 reviews) --></div>
    <div class="ec-product-price-large">$129</div>
 
    <div class="ec-variants">
      <div class="ec-variant-group">
        <label>Size</label>
        <div class="ec-size-swatches">
          <button class="ec-swatch">7</button>
          <button class="ec-swatch active">8</button>
          <button class="ec-swatch disabled">9</button>
        </div>
      </div>
 
      <div class="ec-variant-group">
        <label>Color</label>
        <div class="ec-color-swatches">
          <button class="ec-color" style="background: #1d2939"></button>
          <button class="ec-color active" style="background: #d92d20"></button>
        </div>
      </div>
    </div>
 
    <div class="ec-quantity">
      <button class="btn btn-outline-secondary">−</button>
      <input type="number" value="1" min="1" />
      <button class="btn btn-outline-secondary">+</button>
    </div>
 
    <div class="d-flex gap-2 mt-3">
      <button class="btn btn-primary flex-grow-1">Add to cart</button>
      <button class="btn btn-outline-secondary"><i class="ti ti-heart"></i></button>
    </div>
  </div>
</div>

Cart #

Shopping cart with line items, quantity controls, coupon input, and totals summary.

File: src/html/application/ec-cart.html

<div class="row g-4">
  <div class="col-lg-8">
    <div class="card">
      <table class="table ec-cart-table">
        <thead>
          <tr><th>Product</th><th>Price</th><th>Quantity</th><th>Total</th><th></th></tr>
        </thead>
        <tbody>
          <tr class="ec-cart-row">
            <td>
              <div class="d-flex gap-3 align-items-center">
                <img src="/images/products/sneaker.jpg" class="ec-cart-image" alt="" />
                <div>
                  <h6 class="mb-0">Air Runner</h6>
                  <small class="text-muted">Size 8 · Red</small>
                </div>
              </div>
            </td>
            <td>$129</td>
            <td>
              <div class="ec-quantity ec-quantity-sm">
                <button>−</button><input type="number" value="1" /><button>+</button>
              </div>
            </td>
            <td>$129</td>
            <td><button class="btn btn-link text-danger"><i class="ti ti-x"></i></button></td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
 
  <div class="col-lg-4">
    <div class="card ec-cart-summary">
      <div class="card-body">
        <h5>Order summary</h5>
        <div class="d-flex justify-content-between"><span>Subtotal</span><strong>$129.00</strong></div>
        <div class="d-flex justify-content-between"><span>Shipping</span><strong>$5.00</strong></div>
        <div class="d-flex justify-content-between"><span>Tax</span><strong>$10.32</strong></div>
        <hr />
        <div class="d-flex justify-content-between"><span>Total</span><strong class="text-primary">$144.32</strong></div>
 
        <div class="input-group mt-3">
          <input type="text" class="form-control" placeholder="Coupon code" />
          <button class="btn btn-outline-primary">Apply</button>
        </div>
 
        <a href="ec-checkout.html" class="btn btn-primary w-100 mt-3">Proceed to checkout</a>
      </div>
    </div>
  </div>
</div>

Checkout #

Multi-step checkout flow with address, payment, and review.

File: src/html/application/ec-checkout.html

Steps #

  1. Shipping address — name, street, city, state, ZIP, country
  2. Payment — credit card (with imask formatting), or PayPal/Apple Pay
  3. Review — line items, shipping method, totals
  4. Confirmation — order number, ETA, "Continue shopping"

The stepper uses vanilla-wizard:

import VanillaWizard from 'vanilla-wizard'
 
new VanillaWizard('#checkoutWizard', {
  steps: [
    { id: 'address', title: 'Shipping' },
    { id: 'payment', title: 'Payment' },
    { id: 'review', title: 'Review' },
  ],
  onStepChange: (current, next) => validateStep(current, next),
})

Form fields use Bootstrap 5 native validation (see Form Validation).


Order List #

Buyer-facing order history with status badges and filters.

File: src/html/application/ec-order-list.html

<table class="table table-hover ec-order-list">
  <thead>
    <tr><th>Order #</th><th>Date</th><th>Items</th><th>Total</th><th>Status</th><th></th></tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="ec-order-detail.html">#10245</a></td>
      <td>Mar 28, 2026</td>
      <td>3 items</td>
      <td>$432.00</td>
      <td><span class="badge bg-success">Delivered</span></td>
      <td><button class="btn btn-sm btn-outline-secondary">Track</button></td>
    </tr>
    <tr>
      <td><a href="ec-order-detail.html">#10246</a></td>
      <td>Mar 30, 2026</td>
      <td>1 item</td>
      <td>$129.00</td>
      <td><span class="badge bg-warning">In transit</span></td>
      <td><button class="btn btn-sm btn-outline-secondary">Track</button></td>
    </tr>
  </tbody>
</table>

Status variants: bg-success (delivered), bg-warning (in transit), bg-info (processing), bg-danger (cancelled), bg-secondary (pending).


Order Detail #

Single order with item breakdown and timeline.

File: src/html/application/ec-order-detail.html

Sections #

  • Order summary — number, date, status, total
  • Line items with quantity and per-item subtotal
  • Shipping address + Billing address
  • Payment method
  • Timeline — Placed → Confirmed → Packed → Shipped → Out for delivery → Delivered (each step with timestamp when reached)
  • Actions — Track, Reorder, Return / Refund, Print receipt

The timeline uses a vertical stepper with completed/current/pending styling:

<ul class="ec-timeline">
  <li class="ec-timeline-step completed">
    <div class="ec-timeline-marker"><i class="ti ti-check"></i></div>
    <div class="ec-timeline-body">
      <strong>Placed</strong>
      <small class="text-muted">Mar 28, 10:42 AM</small>
    </div>
  </li>
  <li class="ec-timeline-step completed">
    <div class="ec-timeline-marker"><i class="ti ti-check"></i></div>
    <div class="ec-timeline-body">
      <strong>Shipped</strong>
      <small class="text-muted">Mar 29, 2:15 PM</small>
    </div>
  </li>
  <li class="ec-timeline-step current">
    <div class="ec-timeline-marker"><i class="ti ti-truck"></i></div>
    <div class="ec-timeline-body">
      <strong>In transit</strong>
      <small class="text-muted">ETA Mar 31</small>
    </div>
  </li>
  <li class="ec-timeline-step">
    <div class="ec-timeline-marker"></div>
    <div class="ec-timeline-body">
      <strong>Delivered</strong>
    </div>
  </li>
</ul>

Add Product #

Admin form for creating a new product.

File: src/html/application/ec-add-product.html

Fields #

  • Basic info: Name, SKU, description (Quill rich text)
  • Pricing: Regular price, sale price, tax class
  • Images: Multi-file upload with FilePond — drag-and-drop, preview, reorder
  • Variants: Size, color matrix with per-variant SKU and inventory
  • Inventory: Stock count, low-stock threshold, allow backorders
  • Shipping: Weight, dimensions, shipping class
  • SEO: Meta title, meta description, slug
  • Status: Draft / Published / Scheduled

Image upload uses FilePond with the image preview plugin:

import * as FilePond from 'filepond'
import FilePondPluginImagePreview from 'filepond-plugin-image-preview'
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type'
 
FilePond.registerPlugin(FilePondPluginImagePreview, FilePondPluginFileValidateType)
 
FilePond.create(document.querySelector('#productImages'), {
  allowMultiple: true,
  maxFiles: 8,
  acceptedFileTypes: ['image/*'],
  server: '/api/products/upload',
})

See also #