This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="es" data-theme="light">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>{% block title %}Backoffice{% endblock %}</title>
|
||||
<script src="https://unpkg.com/htmx.org@2.0.3"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css"/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/daisyui@5/themes.css" rel="stylesheet" type="text/css"/>
|
||||
<link rel="stylesheet" href="{% static 'css/styles.css' %}">
|
||||
{% block extra_js %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body class="min-h-screen bg-base-200">
|
||||
<div class="flex min-h-screen">
|
||||
<aside class="w-64 shrink-0 bg-base-100 border-r border-base-300">
|
||||
<a href="{% url 'backoffice:dashboard' %}" class="text-xl font-semibold block p-4">Backoffice</a>
|
||||
<ul class="menu w-full">
|
||||
<li>
|
||||
<a href="{% url 'backoffice:product_list' %}" class="{% if section == 'products' %}menu-active{% endif %}">Productos</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'backoffice:order_list' %}" class="{% if section == 'orders' %}menu-active{% endif %}">Pedidos</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'backoffice:payment_list' %}" class="{% if section == 'payments' %}menu-active{% endif %}">Pagos</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'backoffice:customer_list' %}" class="{% if section == 'customers' %}menu-active{% endif %}">Clientes</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'backoffice:provider_list' %}" class="{% if section == 'providers' %}menu-active{% endif %}">Proveedores</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'backoffice:tax_list' %}" class="{% if section == 'taxes' %}menu-active{% endif %}">Impuestos</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{% url 'backoffice:brand_settings' %}" class="{% if section == 'settings' %}menu-active{% endif %}">Marca y ajustes</a>
|
||||
</li>
|
||||
</ul>
|
||||
</aside>
|
||||
<main class="flex-1 p-6">
|
||||
{% block main %}
|
||||
{% endblock %}
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<dialog id="backoffice-modal" class="modal">
|
||||
<div class="modal-box" id="backoffice-modal-box"></div>
|
||||
<form method="dialog" class="modal-backdrop">
|
||||
<button>close</button>
|
||||
</form>
|
||||
</dialog>
|
||||
|
||||
<script>
|
||||
document.body.addEventListener('htmx:afterSwap', function (event) {
|
||||
if (event.detail.target && event.detail.target.id === 'backoffice-modal-box') {
|
||||
document.getElementById('backoffice-modal').showModal();
|
||||
}
|
||||
});
|
||||
document.body.addEventListener('backoffice:modal-close', function () {
|
||||
document.getElementById('backoffice-modal').close();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,44 @@
|
||||
{% extends 'backoffice/base.html' %}
|
||||
|
||||
{% block title %}{{ object.email }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<h1 class="text-2xl font-semibold mb-1">{{ object.email }}</h1>
|
||||
<p class="mb-6 opacity-70">{{ object.first_name }} {{ object.last_name }}</p>
|
||||
|
||||
<h2 class="text-xl font-semibold mb-2">Direcciones</h2>
|
||||
<div class="overflow-x-auto bg-base-100 rounded-box border border-base-300 mb-6">
|
||||
<table class="table">
|
||||
<thead><tr><th>Tipo</th><th>Dirección</th><th>Localidad</th></tr></thead>
|
||||
<tbody>
|
||||
{% for address in addresses %}
|
||||
<tr class="hover">
|
||||
<td><span class="badge badge-ghost">{{ address.get_address_type_display }}</span></td>
|
||||
<td>{{ address.address }}</td>
|
||||
<td>{{ address.address_town }}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="3" class="text-center py-6">Sin direcciones registradas.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mb-2">Pedidos</h2>
|
||||
<div class="overflow-x-auto bg-base-100 rounded-box border border-base-300">
|
||||
<table class="table">
|
||||
<thead><tr><th>Código</th><th>Estado</th><th>Total</th></tr></thead>
|
||||
<tbody>
|
||||
{% for order in orders %}
|
||||
<tr class="hover">
|
||||
<td><a class="link" href="{% url 'backoffice:order_detail' order.pk %}">{{ order.code }}</a></td>
|
||||
<td><span class="badge badge-ghost">{{ order.get_status_display }}</span></td>
|
||||
<td>{{ order.total }} €</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="3" class="text-center py-6">Sin pedidos.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,17 @@
|
||||
{% extends 'backoffice/base.html' %}
|
||||
|
||||
{% block title %}Backoffice{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<h1 class="text-2xl font-semibold mb-6">Backoffice</h1>
|
||||
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
{% for section in sections %}
|
||||
<a href="{% url section.url_name %}" class="card bg-base-100 border border-base-300 shadow-sm hover:shadow-md transition-shadow">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title">{{ section.label }}</h2>
|
||||
</div>
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,10 @@
|
||||
<h3 class="text-lg font-bold mb-4">Confirmar borrado</h3>
|
||||
<p class="mb-4">¿Seguro que quieres borrar «{{ object }}»?</p>
|
||||
|
||||
<form method="post" hx-post="{{ request.path }}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">
|
||||
{% csrf_token %}
|
||||
<div class="modal-action">
|
||||
<button class="btn btn-error">Borrar</button>
|
||||
<button type="button" class="btn" onclick="document.getElementById('backoffice-modal').close()">Cancelar</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,10 @@
|
||||
<h3 class="text-lg font-bold mb-4">{{ title }}</h3>
|
||||
|
||||
<form method="post" enctype="multipart/form-data" hx-encoding="multipart/form-data" hx-post="{{ request.path }}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<div class="modal-action">
|
||||
<button class="btn btn-primary">Guardar</button>
|
||||
<button type="button" class="btn" onclick="document.getElementById('backoffice-modal').close()">Cancelar</button>
|
||||
</div>
|
||||
</form>
|
||||
@@ -0,0 +1,52 @@
|
||||
{% load backoffice_extras %}
|
||||
|
||||
<div id="backoffice-list"
|
||||
hx-trigger="backoffice:list-changed from:body"
|
||||
hx-get="{{ request.get_full_path }}"
|
||||
hx-target="#backoffice-list"
|
||||
hx-swap="outerHTML">
|
||||
<div class="overflow-x-auto bg-base-100 rounded-box border border-base-300">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
{% for label, attr in columns %}<th>{{ label }}</th>{% endfor %}
|
||||
{% if update_url_name or delete_url_name or detail_url_name %}<th></th>{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for object in object_list %}
|
||||
<tr class="hover">
|
||||
{% for label, attr in columns %}<td>{{ object|getattribute:attr }}</td>{% endfor %}
|
||||
{% if update_url_name or delete_url_name or detail_url_name %}
|
||||
<td class="text-right whitespace-nowrap">
|
||||
{% if detail_url_name %}
|
||||
<a class="btn btn-ghost btn-xs" href="{% url detail_url_name object.pk %}">Ver</a>
|
||||
{% endif %}
|
||||
{% if update_url_name %}
|
||||
<button class="btn btn-ghost btn-xs" hx-get="{% url update_url_name object.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Editar</button>
|
||||
{% endif %}
|
||||
{% if delete_url_name %}
|
||||
<button class="btn btn-ghost btn-xs text-error" hx-get="{% url delete_url_name object.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Borrar</button>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="{{ columns|length|add:1 }}" class="text-center py-6">No hay resultados.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% if is_paginated %}
|
||||
<div class="join mt-4">
|
||||
{% if page_obj.has_previous %}
|
||||
<a class="join-item btn" href="?page={{ page_obj.previous_page_number }}">«</a>
|
||||
{% endif %}
|
||||
<span class="join-item btn btn-disabled">{{ page_obj.number }} / {{ page_obj.paginator.num_pages }}</span>
|
||||
{% if page_obj.has_next %}
|
||||
<a class="join-item btn" href="?page={{ page_obj.next_page_number }}">»</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -0,0 +1,16 @@
|
||||
{% extends 'backoffice/base.html' %}
|
||||
|
||||
{% block title %}Confirmar borrado{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<h1 class="text-2xl font-semibold mb-4">Confirmar borrado</h1>
|
||||
<p class="mb-4">¿Seguro que quieres borrar «{{ object }}»?</p>
|
||||
|
||||
<form method="post" class="max-w-xl">
|
||||
{% csrf_token %}
|
||||
<div class="flex gap-2">
|
||||
<button class="btn btn-error">Borrar</button>
|
||||
{% if cancel_url %}<a class="btn" href="{{ cancel_url }}">Cancelar</a>{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,16 @@
|
||||
{% extends 'backoffice/base.html' %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<h1 class="text-2xl font-semibold mb-4">{{ title }}</h1>
|
||||
|
||||
<form method="post" enctype="multipart/form-data" class="max-w-xl">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<div class="flex gap-2">
|
||||
<button class="btn btn-primary">Guardar</button>
|
||||
{% if cancel_url %}<a class="btn" href="{{ cancel_url }}">Cancelar</a>{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,14 @@
|
||||
{% extends 'backoffice/base.html' %}
|
||||
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h1 class="text-2xl font-semibold">{{ title }}</h1>
|
||||
{% if create_url %}
|
||||
<button class="btn btn-primary" hx-get="{{ create_url }}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Añadir</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% include 'backoffice/generic/_list_fragment.html' %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,74 @@
|
||||
{% extends 'backoffice/base.html' %}
|
||||
|
||||
{% block title %}Pedido {{ object.code }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<h1 class="text-2xl font-semibold mb-4">Pedido {{ object.code }}</h1>
|
||||
|
||||
<div class="stats shadow mb-6 bg-base-100">
|
||||
<div class="stat">
|
||||
<div class="stat-title">Cliente</div>
|
||||
<div class="stat-value text-lg">{{ object.email }}</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">Estado</div>
|
||||
<div class="stat-value text-lg"><span class="badge badge-lg">{{ object.get_status_display }}</span></div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">Total</div>
|
||||
<div class="stat-value text-lg">{{ object.total }} €</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="mb-6">
|
||||
<span class="font-medium">Dirección de envío:</span>
|
||||
{{ object.shipping_address }}, {{ object.shipping_city }}, {{ object.shipping_zip }}
|
||||
</p>
|
||||
|
||||
<h2 class="text-xl font-semibold mb-2">Estado de envío</h2>
|
||||
<form method="post" action="{% url 'backoffice:order_update_shipping_status' object.pk %}" class="mb-6 max-w-sm">
|
||||
{% csrf_token %}
|
||||
{{ shipping_status_form.as_p }}
|
||||
<button class="btn btn-primary btn-sm">Actualizar</button>
|
||||
</form>
|
||||
|
||||
<h2 class="text-xl font-semibold mb-2">Líneas</h2>
|
||||
<div class="overflow-x-auto bg-base-100 rounded-box border border-base-300 mb-6">
|
||||
<table class="table">
|
||||
<thead><tr><th>Producto</th><th>Cantidad</th><th>Precio</th><th>Total</th></tr></thead>
|
||||
<tbody>
|
||||
{% for line in lines %}
|
||||
<tr class="hover">
|
||||
<td>
|
||||
{{ line.product.name }}
|
||||
{% if line.variant %}
|
||||
{% for attribute_value in line.variant.attribute_values.all %}<span class="badge badge-ghost ml-1">{{ attribute_value }}</span>{% endfor %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{{ line.quantity }}</td>
|
||||
<td>{{ line.price }} €</td>
|
||||
<td>{{ line.total }} €</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<h2 class="text-xl font-semibold mb-2">Pagos</h2>
|
||||
<div class="overflow-x-auto bg-base-100 rounded-box border border-base-300">
|
||||
<table class="table">
|
||||
<thead><tr><th>Fecha</th><th>Importe</th><th>Método</th></tr></thead>
|
||||
<tbody>
|
||||
{% for payment in payments %}
|
||||
<tr class="hover">
|
||||
<td>{{ payment.creation_date }}</td>
|
||||
<td>{{ payment.amount }} €</td>
|
||||
<td>{{ payment.get_method_display }}</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="3" class="text-center py-6">Sin pagos registrados.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,33 @@
|
||||
<div id="backoffice-detail"
|
||||
hx-trigger="backoffice:list-changed from:body"
|
||||
hx-get="{{ request.path }}"
|
||||
hx-target="#backoffice-detail"
|
||||
hx-swap="outerHTML">
|
||||
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h1 class="text-2xl font-semibold">{{ object.name }}</h1>
|
||||
<button class="btn btn-sm" hx-get="{% url 'backoffice:product_attribute_update' object.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Editar nombre</button>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between items-center mb-2">
|
||||
<h2 class="text-xl font-semibold">Valores</h2>
|
||||
<button class="btn btn-sm btn-primary" hx-get="{% url 'backoffice:product_attribute_value_create' object.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Añadir valor</button>
|
||||
</div>
|
||||
<div class="overflow-x-auto bg-base-100 rounded-box border border-base-300">
|
||||
<table class="table">
|
||||
<thead><tr><th>Valor</th><th></th></tr></thead>
|
||||
<tbody>
|
||||
{% for value in values %}
|
||||
<tr class="hover">
|
||||
<td>{{ value.value }}</td>
|
||||
<td class="text-right">
|
||||
<button class="btn btn-ghost btn-xs text-error" hx-get="{% url 'backoffice:product_attribute_value_delete' value.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Borrar</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="2" class="text-center py-6">Este atributo no tiene valores todavía.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,105 @@
|
||||
{% load static %}
|
||||
<div id="backoffice-detail"
|
||||
hx-trigger="backoffice:list-changed from:body"
|
||||
hx-get="{{ request.path }}"
|
||||
hx-target="#backoffice-detail"
|
||||
hx-swap="outerHTML">
|
||||
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h1 class="text-2xl font-semibold">{{ product.name }}</h1>
|
||||
<div class="flex gap-2">
|
||||
<button class="btn btn-sm" hx-get="{% url 'backoffice:product_update' product.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Editar</button>
|
||||
<button class="btn btn-sm btn-error" hx-get="{% url 'backoffice:product_delete' product.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Borrar</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats shadow mb-6 bg-base-100">
|
||||
<div class="stat">
|
||||
<div class="stat-title">SKU</div>
|
||||
<div class="stat-value text-lg">{{ product.sku }}</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">Stock</div>
|
||||
<div class="stat-value text-lg">{{ product.stock }}</div>
|
||||
</div>
|
||||
<div class="stat">
|
||||
<div class="stat-title">Precio actual</div>
|
||||
<div class="stat-value text-lg">
|
||||
{% if product.price %}{{ product.price.price_with_tax }} €{% else %}—{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between items-center mb-2">
|
||||
<h2 class="text-xl font-semibold">Imágenes</h2>
|
||||
<button class="btn btn-sm btn-primary" hx-get="{% url 'backoffice:product_image_create' product.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Añadir imagen</button>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-4 mb-6">
|
||||
{% for image in images %}
|
||||
<div class="relative">
|
||||
<img class="w-24 h-24 object-cover rounded-box border border-base-300" src="{{ image.s.url }}" alt="">
|
||||
<button class="btn btn-xs btn-error absolute -top-2 -right-2" hx-get="{% url 'backoffice:product_image_delete' image.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">✕</button>
|
||||
</div>
|
||||
{% empty %}
|
||||
<p class="opacity-70">Este producto no tiene imágenes.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between items-center mb-2">
|
||||
<h2 class="text-xl font-semibold">Variantes</h2>
|
||||
<button class="btn btn-sm btn-primary" hx-get="{% url 'backoffice:product_variant_create' product.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Añadir variante</button>
|
||||
</div>
|
||||
<div class="overflow-x-auto bg-base-100 rounded-box border border-base-300 mb-6">
|
||||
<table class="table">
|
||||
<thead><tr><th>SKU</th><th>Atributos</th><th>Stock</th><th>Precio</th><th></th></tr></thead>
|
||||
<tbody>
|
||||
{% for variant in variants %}
|
||||
<tr class="hover">
|
||||
<td>{{ variant.sku }}</td>
|
||||
<td>{% for attribute_value in variant.attribute_values.all %}<span class="badge badge-ghost mr-1">{{ attribute_value }}</span>{% endfor %}</td>
|
||||
<td>{{ variant.stock }}</td>
|
||||
<td>
|
||||
{% if variant.price %}{{ variant.price.price_with_tax }} €{% else %}—{% endif %}
|
||||
<button class="link text-sm ml-2" hx-get="{% url 'backoffice:product_variant_price_create' variant.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">+ precio</button>
|
||||
</td>
|
||||
<td class="text-right whitespace-nowrap">
|
||||
<button class="btn btn-ghost btn-xs" hx-get="{% url 'backoffice:product_variant_update' variant.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Editar</button>
|
||||
<button class="btn btn-ghost btn-xs text-error" hx-get="{% url 'backoffice:product_variant_delete' variant.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Borrar</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="5" class="text-center py-6">Este producto no tiene variantes.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="mb-6">
|
||||
<button class="btn btn-sm" hx-get="{% url 'backoffice:product_price_create' product.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Añadir precio al producto</button>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between items-center mb-2">
|
||||
<h2 class="text-xl font-semibold">Remesas</h2>
|
||||
<button class="btn btn-sm btn-primary" hx-get="{% url 'backoffice:product_batch_create' product.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Añadir remesa</button>
|
||||
</div>
|
||||
<div class="overflow-x-auto bg-base-100 rounded-box border border-base-300">
|
||||
<table class="table">
|
||||
<thead><tr><th>Código</th><th>Cantidad</th><th>Caducidad</th><th>Proveedor</th><th></th></tr></thead>
|
||||
<tbody>
|
||||
{% for batch in batches %}
|
||||
<tr class="hover">
|
||||
<td>{{ batch.code }}</td>
|
||||
<td>{{ batch.quantity }}</td>
|
||||
<td>{{ batch.expiration_date|default:'—' }}</td>
|
||||
<td>{{ batch.provider|default:'—' }}</td>
|
||||
<td class="text-right">
|
||||
<button class="btn btn-ghost btn-xs text-error" hx-get="{% url 'backoffice:product_batch_delete' batch.pk %}" hx-target="#backoffice-modal-box" hx-swap="innerHTML">Borrar</button>
|
||||
</td>
|
||||
</tr>
|
||||
{% empty %}
|
||||
<tr><td colspan="5" class="text-center py-6">Este producto no tiene remesas.</td></tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,7 @@
|
||||
{% extends 'backoffice/base.html' %}
|
||||
|
||||
{% block title %}{{ object.name }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'backoffice/products/_attribute_detail_fragment.html' %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,7 @@
|
||||
{% extends 'backoffice/base.html' %}
|
||||
|
||||
{% block title %}{{ product.name }}{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{% include 'backoffice/products/_product_detail_fragment.html' %}
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user