297 lines
11 KiB
HTML
297 lines
11 KiB
HTML
<!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>SekiPOS - Dicom</title>
|
|
<link rel="shortcut icon" href="./static/favicon.png" type="image/x-icon">
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
|
|
<style>
|
|
:root {
|
|
--bg: #ebedef;
|
|
--card-bg: #ffffff;
|
|
--text-main: #2e3338;
|
|
--text-muted: #4f5660;
|
|
--border: #e3e5e8;
|
|
--navbar-bg: #ffffff;
|
|
--accent: #5865f2;
|
|
--input-bg: #e3e5e8;
|
|
--danger: #ed4245;
|
|
}
|
|
|
|
[data-theme="dark"] {
|
|
--bg: #36393f;
|
|
--card-bg: #2f3136;
|
|
--text-main: #dcddde;
|
|
--text-muted: #b9bbbe;
|
|
--border: #202225;
|
|
--navbar-bg: #202225;
|
|
--input-bg: #202225;
|
|
}
|
|
|
|
body {
|
|
background: var(--bg);
|
|
color: var(--text-main);
|
|
font-family: "gg sans", "Segoe UI", sans-serif;
|
|
transition: background 0.2s;
|
|
}
|
|
|
|
.navbar {
|
|
background: var(--navbar-bg) !important;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.navbar-brand {
|
|
color: var(--text-main) !important;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.discord-card {
|
|
background: var(--card-bg);
|
|
border: 1px solid var(--border);
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.form-control,
|
|
.form-control:focus {
|
|
background-color: var(--input-bg) !important;
|
|
color: var(--text-main) !important;
|
|
border: 1px solid var(--border) !important;
|
|
box-shadow: none !important;
|
|
}
|
|
|
|
.form-control:focus {
|
|
border-color: var(--accent) !important;
|
|
}
|
|
|
|
.form-control::placeholder {
|
|
color: var(--text-muted) !important;
|
|
opacity: 1;
|
|
}
|
|
|
|
.table {
|
|
color: var(--text-main) !important;
|
|
--bs-table-bg: transparent;
|
|
--bs-table-border-color: var(--border);
|
|
}
|
|
|
|
.table thead th {
|
|
background: var(--bg);
|
|
color: var(--text-muted);
|
|
font-size: 0.75rem;
|
|
text-transform: uppercase;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
|
|
.table td {
|
|
border-bottom: 1px solid var(--border);
|
|
vertical-align: middle;
|
|
}
|
|
|
|
.btn-accent {
|
|
background: var(--accent);
|
|
color: #fff;
|
|
border: none;
|
|
}
|
|
|
|
.dropdown-menu {
|
|
background: var(--card-bg);
|
|
border: 1px solid var(--border);
|
|
}
|
|
|
|
.dropdown-item {
|
|
color: var(--text-main) !important;
|
|
}
|
|
|
|
.dropdown-item:hover {
|
|
background: var(--input-bg);
|
|
}
|
|
|
|
[data-theme="dark"] .table {
|
|
--bs-table-color: var(--text-main);
|
|
color: var(--text-main) !important;
|
|
}
|
|
|
|
[data-theme="dark"] .table thead th {
|
|
background: #292b2f;
|
|
color: var(--text-muted);
|
|
}
|
|
|
|
[data-theme="dark"] .text-muted {
|
|
color: var(--text-muted) !important;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
{% with active_page='dicom' %}{% include 'navbar.html' %}{% endwith %}
|
|
|
|
<div class="container-fluid px-3">
|
|
<div class="row g-3">
|
|
|
|
<div class="col-md-4">
|
|
<div class="discord-card p-3 mb-3">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<h5 class="mb-0 fw-bold">Registrar Movimiento</h5>
|
|
<button class="btn btn-sm btn-outline-secondary" onclick="clearDicomForm()"
|
|
title="Limpiar Formulario">
|
|
<i class="bi bi-eraser"></i> Nuevo
|
|
</button>
|
|
</div>
|
|
<div class="mb-2">
|
|
<label class="small text-muted mb-1">Nombre del Cliente</label>
|
|
<input type="text" id="dicom-name" class="form-control" placeholder="Ej: Doña Juanita">
|
|
</div>
|
|
<div class="mb-2">
|
|
<label class="small text-muted mb-1">Monto (CLP)</label>
|
|
<input type="number" id="dicom-amount" class="form-control" placeholder="Ej: 5000">
|
|
</div>
|
|
<div class="mb-4">
|
|
<label class="small text-muted mb-1">Nota (Opcional)</label>
|
|
<input type="text" id="dicom-notes" class="form-control" placeholder="Ej: Pan y bebida"
|
|
onkeydown="if(event.key === 'Enter') submitDicom('add')">
|
|
</div>
|
|
|
|
<div class="d-flex flex-column gap-2">
|
|
<button class="btn btn-danger py-2 fw-bold" onclick="submitDicom('add')">
|
|
<i class="bi bi-cart-plus me-1"></i> Fiar (Sumar Deuda)
|
|
</button>
|
|
<button class="btn btn-success py-2 fw-bold" onclick="submitDicom('pay')">
|
|
<i class="bi bi-cash-coin me-1"></i> Abonar (Restar Deuda)
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-8">
|
|
<div class="discord-card p-3">
|
|
|
|
<div class="position-relative mb-3">
|
|
<input type="text" id="dicom-search" class="form-control ps-5"
|
|
placeholder="Buscar cliente por nombre..." onkeyup="filterDicom()">
|
|
<i class="bi bi-search position-absolute top-50 start-0 translate-middle-y ms-3 text-muted"></i>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table mb-0" id="dicom-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Nombre</th>
|
|
<th>Deuda Total</th>
|
|
<th>Última Nota</th>
|
|
<th>Actualizado</th>
|
|
<th class="text-end">Acciones</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for d in debtors %}
|
|
<tr>
|
|
<td class="fw-bold">{{ d[1] }}</td>
|
|
<td class="fw-bold price-cell" data-value="{{ d[2] }}"></td>
|
|
<td class="text-muted small">{{ d[3] }}</td>
|
|
<td class="text-muted small">{{ d[4] }}</td>
|
|
<td class="text-end">
|
|
<button class="btn btn-sm btn-outline-secondary"
|
|
onclick="selectClient('{{ d[1] }}')" title="Seleccionar">
|
|
<i class="bi bi-pencil"></i>
|
|
</button>
|
|
<button class="btn btn-sm btn-outline-danger ms-1"
|
|
onclick="forgiveDebt({{ d[0] }}, '{{ d[1] }}')" title="Eliminar Registro">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
|
<script>
|
|
const clp = new Intl.NumberFormat('es-CL', { style: 'currency', currency: 'CLP', minimumFractionDigits: 0 });
|
|
|
|
// Smart color formatting for the debt column
|
|
document.querySelectorAll('.price-cell').forEach(td => {
|
|
const val = parseFloat(td.getAttribute('data-value'));
|
|
td.innerText = clp.format(val);
|
|
|
|
// Reversing the logic: Negative is debt (red), Positive is credit (green)
|
|
if (val < 0) {
|
|
td.classList.add('text-danger');
|
|
} else if (val > 0) {
|
|
td.classList.add('text-success');
|
|
} else {
|
|
td.classList.add('text-muted');
|
|
}
|
|
});
|
|
|
|
function clearDicomForm() {
|
|
document.getElementById('dicom-name').value = '';
|
|
document.getElementById('dicom-amount').value = '';
|
|
document.getElementById('dicom-notes').value = '';
|
|
document.getElementById('dicom-name').focus();
|
|
}
|
|
|
|
// Search Filter
|
|
function filterDicom() {
|
|
const q = document.getElementById('dicom-search').value.toLowerCase();
|
|
document.querySelectorAll('#dicom-table tbody tr').forEach(row => {
|
|
const name = row.cells[0].innerText.toLowerCase();
|
|
row.style.display = name.includes(q) ? '' : 'none';
|
|
});
|
|
}
|
|
|
|
// Just pre-fills the form so you don't accidentally click the wrong action
|
|
function selectClient(name) {
|
|
document.getElementById('dicom-name').value = name;
|
|
document.getElementById('dicom-amount').focus();
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
}
|
|
|
|
async function submitDicom(action) {
|
|
const name = document.getElementById('dicom-name').value;
|
|
const amount = document.getElementById('dicom-amount').value;
|
|
const notes = document.getElementById('dicom-notes').value;
|
|
|
|
if (!name || amount <= 0) {
|
|
alert('Ingresa un nombre y monto válido.');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const res = await fetch('/api/dicom/update', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ name, amount, notes, action })
|
|
});
|
|
|
|
if (res.ok) {
|
|
window.location.reload();
|
|
} else {
|
|
alert('Error actualizando la base de datos.');
|
|
}
|
|
} catch (e) {
|
|
alert("Error de conexión.");
|
|
}
|
|
}
|
|
|
|
async function forgiveDebt(id, name) {
|
|
if (!confirm(`¿Estás seguro de que quieres eliminar completamente a ${name} del registro?`)) return;
|
|
|
|
const res = await fetch(`/api/dicom/${id}`, { method: 'DELETE' });
|
|
if (res.ok) window.location.reload();
|
|
}
|
|
</script>
|
|
<script src="./static/cookieStuff.js"></script>
|
|
<script src="./static/themeStuff.js"></script>
|
|
</body>
|
|
|
|
</html> |