Desarrollo de views + frontend
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
<!-- /partials/_footer.html -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* (Solo si usas HTML estático)
|
||||
* Carga “partials” desde elementos con [data-include="/partials/..."].
|
||||
* Si usas EJS/templating, podés quitar esto.
|
||||
*/
|
||||
async function scLoadPartials(){
|
||||
const includes = document.querySelectorAll("[data-include]");
|
||||
for (const el of includes) {
|
||||
const url = el.getAttribute("data-include");
|
||||
try {
|
||||
const res = await fetch(url, {cache:"no-store"});
|
||||
el.innerHTML = await res.text();
|
||||
} catch (e) {
|
||||
el.innerHTML = `<div class="text-danger small">No se pudo cargar ${url}</div>`;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Export util por si querés llamarlo manualmente
|
||||
window.scLoadPartials = scLoadPartials;
|
||||
|
||||
// Eventos genéricos que el sidebar dispara (ajustá a tu lógica real)
|
||||
window.addEventListener("sc:toggle-abiertas", () => {
|
||||
// Ej.: togglear checkbox/estado en páginas que lo usen
|
||||
const chk = document.getElementById("soloAbiertas");
|
||||
if (chk) { chk.checked = !chk.checked; chk.dispatchEvent(new Event("change")); }
|
||||
});
|
||||
|
||||
window.addEventListener("sc:export-csv", () => {
|
||||
// Implementá tu export acá
|
||||
if (window.scExportCsv) return window.scExportCsv();
|
||||
alert("Exportar CSV: implementame 😄");
|
||||
});
|
||||
|
||||
window.addEventListener("sc:refresh-list", () => {
|
||||
if (window.scRefreshList) return window.scRefreshList();
|
||||
location.reload();
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,22 @@
|
||||
<!-- /partials/_head.html -->
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title><%= typeof pageTitle !== "undefined" ? pageTitle : "SuiteCoffee" %></title>
|
||||
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
|
||||
<style>
|
||||
:root { --navbar-h: 56px; }
|
||||
body { padding-top: var(--navbar-h); background: #f7f8fb; }
|
||||
.brand-mini { font-weight: 700; letter-spacing: .2px; }
|
||||
/* Layout contenedor principal */
|
||||
main { padding-block: 1rem 2rem; }
|
||||
/* Tabla compacta */
|
||||
.table-sm th, .table-sm td { padding: .5rem .6rem; }
|
||||
/* Chips/etiquetas de estado */
|
||||
.badge-outline { border: 1px solid #dee2e6; background: #fff; color: #495057; }
|
||||
.badge-estado-abierta { border-color:#198754; color:#198754; }
|
||||
.badge-estado-cerrada { border-color:#6c757d; color:#6c757d; }
|
||||
.badge-estado-anulada { border-color:#dc3545; color:#dc3545; }
|
||||
.badge-estado-pagada { border-color:#146c43; color:#146c43; }
|
||||
</style>
|
||||
@@ -0,0 +1,29 @@
|
||||
<!-- /partials/_navbar.html -->
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-white border-bottom fixed-top">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand brand-mini" href="/">SuiteCoffee</a>
|
||||
|
||||
<!-- Links principales (colapsables en mobile) -->
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#scNav" aria-controls="scNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span> <!-- hamburguesa principal -->
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="scNav">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0 small">
|
||||
<li class="nav-item"><a class="nav-link" href="/comandas">Comandas</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/estadoComandas">Estado</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/productos">Productos</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/mesas">Mesas</a></li>
|
||||
<li class="nav-item"><a class="nav-link" href="/reportes">Reportes</a></li>
|
||||
<!-- agrega las que necesites -->
|
||||
</ul>
|
||||
|
||||
<!-- Botón “hamburguesa” para abrir el menú contextual (sidebar derecha) -->
|
||||
<button class="btn btn-outline-secondary btn-sm d-flex align-items-center" type="button"
|
||||
data-bs-toggle="offcanvas" data-bs-target="#scSidebar" aria-controls="scSidebar">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" class="me-1" viewBox="0 0 24 24" fill="none" stroke="currentColor"><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></svg>
|
||||
Opciones
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@@ -0,0 +1,62 @@
|
||||
<!-- /partials/_sidebar.html -->
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" id="scSidebar" aria-labelledby="scSidebarLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="scSidebarLabel">Opciones</h5>
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Cerrar"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<!-- Contenido se inyecta según la página actual -->
|
||||
<div id="scSidebarContent" class="list-group list-group-flush small"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Map de opciones por página. Usa body[data-page] o window.scPageId.
|
||||
const SC_SIDEBAR_ITEMS = {
|
||||
// === ejemplos ===
|
||||
"estadoComandas": [
|
||||
{ text: "➕ Nueva comanda", href: "/comandas" },
|
||||
{ text: "Solo abiertas", href: "#", attr: { "data-action": "toggle-abiertas" } },
|
||||
{ text: "Exportar (CSV)", href: "#", attr: { "data-action": "export-csv" } },
|
||||
{ text: "Actualizar listado", href: "#", attr: { "data-action": "refresh-list" } },
|
||||
],
|
||||
"comandas": [
|
||||
{ text: "Volver a Estado", href: "/estadoComandas" },
|
||||
{ text: "Cargar productos", href: "/productos" },
|
||||
{ text: "Mesas", href: "/mesas" },
|
||||
],
|
||||
"productos": [
|
||||
{ text: "Nuevo producto", href: "/productos/nuevo" },
|
||||
{ text: "Importar catálogo", href: "/productos/importar" },
|
||||
{ text: "Reportes", href: "/reportes" },
|
||||
]
|
||||
};
|
||||
|
||||
(function initSidebar(){
|
||||
const page = (document.body.dataset.page || window.scPageId || "").trim();
|
||||
const items = SC_SIDEBAR_ITEMS[page] || [
|
||||
{ text: "Inicio", href: "/" }
|
||||
];
|
||||
const box = document.getElementById("scSidebarContent");
|
||||
box.innerHTML = "";
|
||||
for (const it of items) {
|
||||
const a = document.createElement("a");
|
||||
a.className = "list-group-item list-group-item-action";
|
||||
a.textContent = it.text;
|
||||
a.href = it.href || "#";
|
||||
if (it.attr) for (const [k,v] of Object.entries(it.attr)) a.setAttribute(k,v);
|
||||
box.appendChild(a);
|
||||
}
|
||||
|
||||
// Acciones ejemplo (opcionales). Adaptá a tus funciones reales.
|
||||
box.addEventListener("click", (ev) => {
|
||||
const a = ev.target.closest("a[data-action]");
|
||||
if (!a) return;
|
||||
ev.preventDefault();
|
||||
const action = a.getAttribute("data-action");
|
||||
if (action === "toggle-abiertas") window.dispatchEvent(new CustomEvent("sc:toggle-abiertas"));
|
||||
if (action === "export-csv") window.dispatchEvent(new CustomEvent("sc:export-csv"));
|
||||
if (action === "refresh-list") window.dispatchEvent(new CustomEvent("sc:refresh-list"));
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
Reference in New Issue
Block a user