Skip to main content

Overview

The POS cart system provides a two-column interface with a product catalog grid and a shopping cart with real-time calculations.

Layout Structure

The POS interface uses a grid layout with catalog and cart sections.

HTML Structure

<div class="pos">
  <!-- Catálogo -->
  <div>
    <!-- Product catalog -->
  </div>
  
  <!-- Carrito -->
  <div class="cart">
    <!-- Shopping cart -->
  </div>
</div>
Source: panel_nueva-venta.html:56-127

CSS Classes

.pos

Main POS layout container
  • Display: Grid
  • Grid columns: 1fr 360px
  • Gap: 18px
  • Align items: Start
Source: nueva-venta.css:3-8

Product Catalog

Grid Container

<div class="prod-grid">
  <div class="prod-card" onclick="agregar('AUD-001','Audífonos Bluetooth Pro','🎧',89.99)">
    <span class="emo">🎧</span>
    <h4>Audífonos Bluetooth Pro</h4>
    <b>$89.99</b>
    <small>Stock: 42</small>
  </div>
  <!-- Additional products... -->
</div>
Source: panel_nueva-venta.html:70-95

CSS Classes

.prod-grid

  • Display: Grid
  • Grid columns: repeat(auto-fill, minmax(130px, 1fr))
  • Gap: 10px
  • Max height: 470px
  • Overflow Y: Auto
  • Padding: 2px
Source: nueva-venta.css:10-17

.prod-card

Individual product card
  • Background: White (var(--bl))
  • Border: 1px solid light gray
  • Border radius: 8px
  • Padding: 14px 10px
  • Text align: Center
  • Cursor: Pointer
  • Box shadow: 0 2px 12px rgba(0, 0, 0, .08)
  • Transition: Border, shadow, transform
Source: nueva-venta.css:19-28

Product Card Hover

.prod-card:hover {
  border-color: var(--rojo);
  box-shadow: 0 4px 14px rgba(208,2,27,.12);
  transform: translateY(-2px);
}
Source: nueva-venta.css:29

Product Card Elements

.prod-card .emo  { font-size: 30px; display: block; margin-bottom: 6px; }
.prod-card h4    { font-size: 12px; font-weight: 600; margin-bottom: 3px; }
.prod-card b     { font-size: 12.5px; color: var(--rojo); font-weight: 700; }
.prod-card small { display: block; font-size: 10.5px; color: var(--gm); margin-top: 2px; }
Source: nueva-venta.css:30-33

Product Card Examples

In Stock Product

<div class="prod-card" onclick="agregar('AUD-001','Audífonos Bluetooth Pro','🎧',89.99)">
  <span class="emo">🎧</span>
  <h4>Audífonos Bluetooth Pro</h4>
  <b>$89.99</b>
  <small>Stock: 42</small>
</div>
Source: panel_nueva-venta.html:71-73

Out of Stock Product

<div class="prod-card" style="opacity:.5;cursor:not-allowed">
  <span class="emo">🖥️</span>
  <h4>Monitor 27" 144Hz</h4>
  <b>$399.00</b>
  <small style="color:var(--rojo)">Sin stock</small>
</div>
Source: panel_nueva-venta.html:86-88

Shopping Cart

Cart Container

<div class="cart">
  <div class="cart-head">🛒 Ticket de Venta <small># Auto</small></div>
  <div class="cart-client">
    <div class="fg" style="margin-bottom:0">
      <label>Cliente (opcional)</label>
      <input type="text" placeholder="Nombre o buscar cliente...">
    </div>
  </div>
  <div class="cart-items" id="cart-items"></div>
  <div class="cart-summary">
    <!-- Summary content -->
  </div>
</div>
Source: panel_nueva-venta.html:100-126

CSS Classes

.cart

Main cart container
  • Background: White
  • Border: 1px solid light gray
  • Border radius: 8px
  • Box shadow: 0 2px 12px rgba(0, 0, 0, .08)
  • Display: Flex column
  • Min height: 540px
Source: nueva-venta.css:35-43

.cart-head

Cart header
  • Padding: 16px 18px
  • Border bottom: 1px solid gray
  • Font size: 14.5px
  • Font weight: 700
  • Display: Flex
  • Justify: Space-between
Source: nueva-venta.css:44-52

.cart-client

Client input section
  • Padding: 10px 18px
  • Border bottom: 1px solid gray
Source: nueva-venta.css:54

.cart-items

Scrollable items container
  • Flex: 1
  • Padding: 12px 18px
  • Overflow Y: Auto
Source: nueva-venta.css:55

Cart Items

Cart Item Structure

<div class="cart-item">
  <span class="cart-item-name">🎧 Audífonos Bluetooth Pro</span>
  <div class="cart-qty">
    <button class="q-btn" onclick="cambiar('AUD-001',-1)"></button>
    <span>2</span>
    <button class="q-btn" onclick="cambiar('AUD-001',1)">+</button>
  </div>
  <span class="cart-price">$179.98</span>
</div>
Source: Generated by nueva-venta.js:16-25

CSS Classes

.cart-item

Individual cart item
  • Display: Flex
  • Align items: Center
  • Gap: 8px
  • Padding: 9px 0
  • Border bottom: 1px solid gray
  • Font size: 12.5px
Source: nueva-venta.css:57-64

.cart-item-name

  • Flex: 1
  • Font weight: 500
Source: nueva-venta.css:66

.cart-qty

Quantity controls
  • Display: Flex
  • Align items: Center
  • Gap: 5px
Source: nueva-venta.css:67

.q-btn

Quantity adjustment button
  • Width: 22px
  • Height: 22px
  • Border: 1px solid gray
  • Border radius: 4px
  • Background: Light gray
  • Cursor: Pointer
  • Font size: 13px
  • Font weight: 700
  • Display: Flex center
Source: nueva-venta.css:68-77

.cart-price

Item total price
  • Font weight: 700
  • Min width: 56px
  • Text align: Right
Source: nueva-venta.css:78

Cart Summary

HTML Structure

<div class="cart-summary">
  <div class="sum-row"><span>Subtotal</span><span id="lbl-sub">$0.00</span></div>
  <div class="sum-row"><span>Descuento</span><span>— $0.00</span></div>
  <div class="sum-row"><span>IVA (16%)</span><span id="lbl-iva">$0.00</span></div>
  <div class="sum-total"><span>TOTAL</span><span id="lbl-total">$0.00</span></div>
  <div class="fg" style="margin-bottom:12px">
    <label>Método de pago</label>
    <select>
      <option>💵 Efectivo</option>
      <option>💳 Tarjeta de Crédito</option>
      <option>💳 Tarjeta de Débito</option>
      <option>📱 Transferencia / QR</option>
    </select>
  </div>
  <button id="btn-cobrar" class="btn btn-p" style="width:100%;justify-content:center;padding:12px;font-size:14.5px;margin-bottom:7px">✅ Cobrar $0.00</button>
  <button id="btn-limpiar" class="btn btn-s" style="width:100%;justify-content:center">🗑️ Limpiar carrito</button>
</div>
Source: panel_nueva-venta.html:109-125

CSS Classes

.cart-summary

Summary section
  • Padding: 14px 18px
  • Border top: 1px solid gray
  • Background: Light gray (var(--gf))
  • Border radius: 0 0 8px 8px
Source: nueva-venta.css:80-85

.sum-row

Summary line item
  • Display: Flex
  • Justify: Space-between
  • Font size: 12.5px
  • Color: Medium gray
  • Margin bottom: 7px
Source: nueva-venta.css:86

.sum-total

Total line
  • Font size: 16px
  • Font weight: 800
  • Color: Black
  • Border top: 2px solid gray
  • Padding top: 9px
  • Margin top: 3px
  • Margin bottom: 12px
  • Display: Flex
  • Justify: Space-between
Source: nueva-venta.css:87-92

JavaScript API

Constants

const IVA = 0.16;
let carrito = [];
Source: nueva-venta.js:2-3

DOM Element References

const itemsEl    = document.getElementById('cart-items');
const lblSub     = document.getElementById('lbl-sub');
const lblIva     = document.getElementById('lbl-iva');
const lblTotal   = document.getElementById('lbl-total');
const btnCobrar  = document.getElementById('btn-cobrar');
Source: nueva-venta.js:5-9

Core Functions

render()

Renders the cart items and updates totals.
function render() {
  if (!carrito.length) {
    itemsEl.innerHTML = '<p style="text-align:center;color:#ccc;font-size:12px;margin-top:10px;">· Agrega productos desde el catálogo ·</p>';
    actualizar(0); return;
  }
  itemsEl.innerHTML = carrito.map(p => `
    <div class="cart-item">
      <span class="cart-item-name">${p.emo} ${p.nombre}</span>
      <div class="cart-qty">
        <button class="q-btn" onclick="cambiar('${p.id}',-1)">−</button>
        <span>${p.qty}</span>
        <button class="q-btn" onclick="cambiar('${p.id}',1)">+</button>
      </div>
      <span class="cart-price">$${(p.precio * p.qty).toFixed(2)}</span>
    </div>`).join('');
  actualizar(carrito.reduce((s, p) => s + p.precio * p.qty, 0));
}
Source: nueva-venta.js:11-27

actualizar(sub)

Updates summary totals with IVA calculation.
function actualizar(sub) {
  const iva = sub * IVA, total = sub + iva;
  lblSub.textContent   = `$${sub.toFixed(2)}`;
  lblIva.textContent   = `$${iva.toFixed(2)}`;
  lblTotal.textContent = `$${total.toFixed(2)}`;
  btnCobrar.textContent = `✅ Cobrar $${total.toFixed(2)}`;
}
Parameters:
  • sub (number) - Subtotal before tax
Calculations:
  • IVA: subtotal * 0.16
  • Total: subtotal + IVA
Source: nueva-venta.js:29-35

agregar(id, nombre, emo, precio)

Adds a product to the cart or increments quantity.
window.agregar = (id, nombre, emo, precio) => {
  const p = carrito.find(x => x.id === id);
  p ? p.qty++ : carrito.push({ id, nombre, emo, precio, qty: 1 });
  render();
};
Parameters:
  • id (string) - Product SKU
  • nombre (string) - Product name
  • emo (string) - Product emoji icon
  • precio (number) - Unit price
Behavior:
  • If product exists in cart, increments quantity
  • If new product, adds with quantity 1
  • Re-renders cart
Source: nueva-venta.js:37-41

cambiar(id, d)

Changes product quantity in cart.
window.cambiar = (id, d) => {
  const p = carrito.find(x => x.id === id);
  if (!p) return;
  p.qty += d;
  if (p.qty <= 0) carrito = carrito.filter(x => x.id !== id);
  render();
};
Parameters:
  • id (string) - Product SKU
  • d (number) - Delta (-1 to decrease, +1 to increase)
Behavior:
  • Updates quantity by delta
  • Removes product if quantity reaches 0
  • Re-renders cart
Source: nueva-venta.js:43-49

Event Listeners

Clear Cart Button

document.getElementById('btn-limpiar').addEventListener('click', () => { 
  carrito = []; 
  render(); 
});
Source: nueva-venta.js:51

Checkout Button

btnCobrar.addEventListener('click', () => {
  if (!carrito.length) { alert('El carrito está vacío.'); return; }
  // TODO: integrar con Firebase
  alert('Venta registrada.');
  carrito = []; render();
});
Source: nueva-venta.js:53-58

Cart Data Structure

Cart Item Object

{
  id: "AUD-001",        // Product SKU
  nombre: "Audífonos Bluetooth Pro",  // Product name
  emo: "🎧",            // Product icon
  precio: 89.99,        // Unit price
  qty: 2                // Quantity
}

Usage Examples

Adding a Product

<div class="prod-card" onclick="agregar('TEC-007','Teclado Mecánico RGB','⌨️',149.00)">
  <span class="emo">⌨️</span>
  <h4>Teclado Mecánico RGB</h4>
  <b>$149.00</b>
  <small>Stock: 78</small>
</div>
Source: panel_nueva-venta.html:77-79

Quantity Controls

<div class="cart-qty">
  <button class="q-btn" onclick="cambiar('MOU-003',-1)"></button>
  <span>3</span>
  <button class="q-btn" onclick="cambiar('MOU-003',1)">+</button>
</div>
Generated by render() function

Responsive Behavior

On screens below 860px:
  • POS grid switches to single column
  • Cart appears below catalog
  • Both sections use full width
Source: nueva-venta.css:94-96

Initialization

The cart renders on page load:
render();
Source: nueva-venta.js:60

Build docs developers (and LLMs) love