fix(pos): rewrite catalog.js to match design system HTML structure + add cart sidebar

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-01 08:09:21 +00:00
parent 6ec3a90d57
commit 3ea6f181ff
2 changed files with 419 additions and 121 deletions

View File

@@ -1483,6 +1483,134 @@
padding: var(--space-1); opacity: 0.7; color: inherit;
}
.banner__dismiss:hover { opacity: 1; }
/* =========================================================================
CART SIDEBAR
========================================================================= */
.cart-fab {
position: fixed;
bottom: var(--space-6);
right: var(--space-6);
z-index: var(--z-modal);
width: 56px;
height: 56px;
border-radius: var(--radius-full);
background: var(--color-primary);
color: var(--color-text-inverse);
border: none;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
box-shadow: var(--shadow-lg);
transition: var(--transition-fast);
}
.cart-fab:hover {
transform: scale(1.08);
box-shadow: var(--shadow-xl);
}
.cart-fab__badge {
position: absolute;
top: -4px;
right: -4px;
min-width: 20px;
height: 20px;
padding: 0 5px;
border-radius: var(--radius-full);
background: var(--color-error, #ef4444);
color: #fff;
font-size: 11px;
font-weight: var(--font-weight-bold);
display: none;
align-items: center;
justify-content: center;
line-height: 1;
}
.cart-sidebar {
position: fixed;
top: 0;
right: 0;
bottom: 0;
width: 360px;
max-width: 100vw;
z-index: var(--z-modal);
background: var(--color-bg-elevated);
border-left: 1px solid var(--color-border);
box-shadow: var(--shadow-xl);
display: flex;
flex-direction: column;
transform: translateX(100%);
transition: transform var(--duration-normal) var(--ease-in-out);
}
.cart-sidebar.open {
transform: translateX(0);
}
.cart-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: var(--space-4) var(--space-5);
border-bottom: 1px solid var(--color-border);
flex-shrink: 0;
}
.cart-header h3 {
font-family: var(--font-heading);
font-size: var(--text-h5);
font-weight: var(--heading-weight-secondary);
color: var(--color-text-primary);
}
.cart-items {
flex: 1;
overflow-y: auto;
padding: var(--space-3) var(--space-4);
}
.cart-item {
display: flex;
gap: var(--space-3);
padding: var(--space-3) 0;
border-bottom: 1px solid var(--color-border);
}
.cart-item:last-child {
border-bottom: none;
}
.cart-footer {
padding: var(--space-4) var(--space-5);
border-top: 1px solid var(--color-border);
flex-shrink: 0;
background: var(--color-bg-elevated);
}
.cart-totals {
display: flex;
flex-direction: column;
gap: var(--space-1);
font-size: var(--text-body-sm);
color: var(--color-text-secondary);
}
.cart-overlay {
position: fixed;
inset: 0;
z-index: calc(var(--z-modal) - 1);
background: rgba(0, 0, 0, 0.3);
backdrop-filter: blur(2px);
display: none;
}
.cart-overlay.open {
display: block;
}
</style>
</head>
@@ -2172,6 +2300,33 @@
});
</script>
<!-- Cart FAB (floating action button) -->
<button class="cart-fab" id="cartFab" onclick="CatalogApp.toggleCart()" aria-label="Abrir carrito">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/><path d="M1 1h4l2.68 13.39a2 2 0 002 1.61h9.72a2 2 0 002-1.61L23 6H6"/></svg>
<span class="cart-fab__badge" id="cartBadge">0</span>
</button>
<!-- Cart overlay -->
<div class="cart-overlay" id="cartOverlay" onclick="CatalogApp.toggleCart()"></div>
<!-- Cart sidebar -->
<aside class="cart-sidebar" id="cartSidebar">
<div class="cart-header">
<h3>Carrito</h3>
<button onclick="CatalogApp.toggleCart()" class="btn btn-ghost" aria-label="Cerrar carrito" style="background:none;border:none;cursor:pointer;font-size:1.4rem;color:var(--color-text-secondary);padding:var(--space-1);">&#10005;</button>
</div>
<div class="cart-items" id="cartItems"></div>
<div class="cart-empty" id="cartEmpty" style="display:none;padding:2rem;text-align:center;color:var(--color-text-muted);">Carrito vacio</div>
<div class="cart-footer">
<div class="cart-totals">
<div>Subtotal: <span id="cartSubtotal">$0.00</span></div>
<div>IVA 16%: <span id="cartTax">$0.00</span></div>
<div style="font-weight:bold;font-size:1.2em;">Total: <span id="cartTotal">$0.00</span></div>
</div>
<button id="checkoutBtn" class="btn btn-primary" style="width:100%;margin-top:var(--space-3);padding:var(--space-3);font-size:var(--text-body);font-weight:var(--font-weight-semibold);cursor:pointer;" onclick="CatalogApp.goToCheckout()">Ir a cobrar &rarr;</button>
</div>
</aside>
<!-- Offline Banner -->
<div id="offlineBanner" class="banner banner--warning" style="display:none;position:fixed;top:0;left:0;right:0;z-index:9999;border-radius:0;animation:none;">
<span class="banner__icon"></span>
@@ -2179,6 +2334,7 @@
<button class="banner__dismiss" onclick="document.getElementById('offlineBanner').style.display='none'" aria-label="Cerrar">&times;</button>
</div>
<script src="/pos/static/js/catalog.js"></script>
<script src="/pos/static/js/offline-banner.js"></script>
</body>
</html>