trabajando en la vista del carro de la compra

This commit is contained in:
2025-10-14 21:52:25 +02:00
parent a33ba3256b
commit 9f33db4055
12 changed files with 528 additions and 76 deletions

View File

@ -0,0 +1,74 @@
<!-- _cartItem.html -->
<div th:fragment="cartItem(item)" class="card product mb-3 shadow-sm">
<div class="card-body">
<div class="row gy-3">
<div class="col-sm-auto">
<div class="avatar-lg bg-light rounded p-1">
<img th:src="${item.imagen != null ? item.imagen : '/assets/images/products/placeholder.png'}"
alt="portada" class="img-fluid d-block rounded">
</div>
</div>
<!-- Detalles -->
<div class="col-sm">
<!-- Título / enlace -->
<h5 class="fs-18 text-truncate mb-1">
<a th:href="@{|presupuesto/edit/${item.presupuestoId}|}" class="text-dark"
th:text="${item.titulo != null ? item.titulo : 'Presupuesto #'}">
Presupuesto
</a>
</h5>
<h5 class="fs-14 text-truncate mb-1">
<span th:text="#{cart.item.presupuesto-numero}">Presupuesto #</span>
<span th:text="${item.presupuestoId != null ? item.presupuestoId : ''}">#</span>
</h5>
<!-- Detalles opcionales (ej: cliente, fecha, etc.) -->
<ul class="list-inline text-muted mb-2">
<div th:each="linea : ${item.lineas}">
<li class="list-inline-item me-3">
<div th:utext="${linea['descripcion']}"></div>
</li>
</div>
</ul>
</div>
<!-- Precio o totales (si los tienes) -->
<div class="col-sm-auto text-end">
<p class="text-muted mb-1">Precio estimado</p>
<h5 class="fs-14 mb-0">
<span th:text="${item.price != null ? #numbers.formatDecimal(item.price, 1, 2) : '-'}">0,00</span>
</h5>
</div>
</div>
</div>
<div class="card-footer bg-light">
<div class="row align-items-center gy-3">
<div class="col-sm">
<div class="d-flex flex-wrap my-n1">
<!-- Botón eliminar -->
<div>
<form th:action="@{|/cart/${item.id}/remove|}" method="post" class="d-inline">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />
<button type="submit" class="btn btn-sm btn-link text-body p-1 px-2">
<i class="ri-delete-bin-fill text-muted align-bottom me-1"></i> Eliminar
</button>
</form>
</div>
</div>
</div>
<div class="col-sm-auto text-end">
<div class="d-flex align-items-center gap-2 text-muted">
<div>Total:</div>
<h5 class="fs-14 mb-0">
<span
th:text="${item.price != null ? #numbers.formatDecimal(item.price, 1, 2) : '-'}">0,00</span>
</h5>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,55 @@
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{imprimelibros/layout}">
<head>
<th:block layout:fragment="pagetitle" />
<th:block th:replace="~{imprimelibros/partials/head-css :: head-css}" />
<th:block layout:fragment="pagecss">
<link th:href="@{/assets/libs/datatables/dataTables.bootstrap5.min.css}" rel="stylesheet" />
</th:block>
<th:block layout:fragment="pagecss">
<link th:href="@{/assets/css/presupuestador.css}" rel="stylesheet" />
</th:block>
</head>
<body>
<div th:replace="~{imprimelibros/partials/topbar :: topbar}" />
<div th:replace="~{imprimelibros/partials/sidebar :: sidebar}"
sec:authorize="isAuthenticated() and hasAnyRole('SUPERADMIN','ADMIN')">
<th:block layout:fragment="content">
<div th:if="${#authorization.expression('isAuthenticated()')}">
<div class="container-fluid">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/"><i class="ri-home-5-fill"></i></a></li>
<li class="breadcrumb-item active" aria-current="page" th:text="#{cart.title}">Cesta de la
compra</li>
</ol>
</nav>
</div>
<div class="container-fluid">
<div th:if="${items.isEmpty()}">
<div class="alert alert-info" role="alert" th:text="#{cart.empty}"></div>
</div>
<div th:unless="${#lists.isEmpty(items)}">
<div th:each="item : ${items}" th:insert="~{imprimelibros/cart/_cartItem :: cartItem(${item})}">
</div>
</div>
</div>
</th:block>
<th:block th:replace="~{theme/partials/vendor-scripts :: scripts}" />
<th:block layout:fragment="pagejs">
<script th:inline="javascript">
window.languageBundle = /*[[${languageBundle}]]*/ {};
</script>
</th:block>
</body>
</html>

View File

@ -68,7 +68,9 @@
class="ms-1 header-item d-none d-sm-flex">
<button type="button" id="btn_cart"
class="btn btn-icon btn-topbar material-shadow-none btn-ghost-secondary rounded-circle light-dark-mode">
<i class="bx bx-cart fs-22"></i>
<a href="/cart">
<i class="ri-shopping-cart-2-line fs-22"></i>
</a>
<span id="cart-item-count"
class="position-absolute topbar-badge cartitem-badge fs-10 translate-middle badge rounded-pill bg-info d-none">
0

View File

@ -7,6 +7,12 @@
<span th:text="#{presupuesto.guardar}">Guardar</span>
</button>
<button th:if="${appMode == 'add' or appMode == 'edit'}" id="btn-add-cart" type="button"
class="btn btn-secondary d-flex align-items-center mx-2 add-cart-btn">
<i class="ri-shopping-cart-line me-2"></i>
<span th:text="#{presupuesto.add-to-cart}">Añadir al carrito</span>
</button>
<button id="btn-imprimir" type="button"
class="btn btn-secondary d-flex align-items-center mx-2 imprimir-presupuesto">
<i class="ri-printer-line me-2"></i>

View File

@ -2,7 +2,7 @@
<table id="presupuestos-clientes-user-datatable" class="table table-striped table-nowrap responsive w-100">
<thead>
<tr>
<th scope="col" th:text="#{presupuesto.tabla.id}">ID</th>
<th scope="col" th:text="#{presupuesto.tabla.numero}">Número</th>
<th scope="col" th:text="#{presupuesto.tabla.titulo}">Título</th>
<th scope="col" th:text="#{presupuesto.tabla.encuadernacion}">Encuadernación</th>
<th scope="col" th:text="#{presupuesto.tabla.cubierta}">Cubierta</th>