feat(pos): configuracion funcional — sucursales, empleados, tema
Replace hardcoded demo data in the config page with real API calls. Branches and employees now load from /pos/api/config/* endpoints, with create modals for both. Business data tab reads tenant_config (read-only). Theme selector was already working and is preserved. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1332,40 +1332,34 @@
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label class="form-label">Razón Social</label>
|
||||
<input class="form-input" type="text" value="Nexus Autoparts S.A. de C.V." />
|
||||
<input class="form-input" id="biz-razon-social" type="text" value="" readonly />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Nombre Comercial</label>
|
||||
<input class="form-input" type="text" value="Nexus Autoparts" />
|
||||
<input class="form-input" id="biz-nombre" type="text" value="" readonly />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">RFC</label>
|
||||
<input class="form-input" type="text" value="NAU260101ABC" />
|
||||
<input class="form-input" id="biz-rfc" type="text" value="" readonly />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Régimen Fiscal</label>
|
||||
<select class="form-select">
|
||||
<option selected>601 - General de Ley Personas Morales</option>
|
||||
<option>603 - Personas Morales con Fines no Lucrativos</option>
|
||||
<option>612 - Personas Físicas con Actividades Empresariales</option>
|
||||
</select>
|
||||
<input class="form-input" id="biz-regimen" type="text" value="" readonly />
|
||||
</div>
|
||||
<div class="form-group form-group--full">
|
||||
<label class="form-label">Dirección Fiscal</label>
|
||||
<input class="form-input" type="text" value="Av. Insurgentes Sur 1234, Col. Del Valle, Benito Juárez, CDMX, C.P. 03100" />
|
||||
<input class="form-input" id="biz-direccion" type="text" value="" readonly />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Teléfono</label>
|
||||
<input class="form-input" type="tel" value="(55) 1234-5678" />
|
||||
<input class="form-input" id="biz-telefono" type="tel" value="" readonly />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Email</label>
|
||||
<input class="form-input" type="email" value="contacto@nexusautoparts.mx" />
|
||||
<input class="form-input" id="biz-email" type="email" value="" readonly />
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn--primary btn--sm">Guardar</button>
|
||||
</div>
|
||||
<p class="form-hint" style="margin-top: var(--space-3);">Datos configurados durante el aprovisionamiento del tenant. Contacta soporte para cambios.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1385,10 +1379,10 @@
|
||||
|
||||
<div class="settings-card" style="padding: 0;">
|
||||
<div style="padding: var(--space-4) var(--space-5); display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid var(--color-border);">
|
||||
<span style="font-weight: var(--font-weight-semibold); color: var(--color-text-primary);">5 usuarios activos</span>
|
||||
<button class="btn btn--primary btn--sm">
|
||||
<span id="employees-count" style="font-weight: var(--font-weight-semibold); color: var(--color-text-primary);">Cargando...</span>
|
||||
<button class="btn btn--primary btn--sm" id="btn-new-employee">
|
||||
<svg viewBox="0 0 24 24"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||
Nuevo Usuario
|
||||
Nuevo Empleado
|
||||
</button>
|
||||
</div>
|
||||
<div class="table-wrapper" style="border: none; border-radius: 0; box-shadow: none;">
|
||||
@@ -1400,81 +1394,12 @@
|
||||
<th>Rol</th>
|
||||
<th>Sucursal</th>
|
||||
<th>Estado</th>
|
||||
<th>Último Acceso</th>
|
||||
<th>Desc. Max</th>
|
||||
<th>Acciones</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="user-cell">
|
||||
<div class="user-cell__avatar">AM</div>
|
||||
<span class="user-cell__name">Adrián Morales</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>admin@nexusautoparts.mx</td>
|
||||
<td><span class="badge badge--admin">Admin</span></td>
|
||||
<td>Todas</td>
|
||||
<td><span class="badge badge--ok">Activo</span></td>
|
||||
<td>Hoy, 14:32</td>
|
||||
<td><button class="btn btn--ghost btn--sm">Editar</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="user-cell">
|
||||
<div class="user-cell__avatar">CM</div>
|
||||
<span class="user-cell__name">Carlos Mendoza</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>carlos@nexusautoparts.mx</td>
|
||||
<td><span class="badge badge--pending">Contador</span></td>
|
||||
<td>Matriz</td>
|
||||
<td><span class="badge badge--ok">Activo</span></td>
|
||||
<td>Hoy, 12:15</td>
|
||||
<td><button class="btn btn--ghost btn--sm">Editar</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="user-cell">
|
||||
<div class="user-cell__avatar">LR</div>
|
||||
<span class="user-cell__name">Laura Ríos</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>laura@nexusautoparts.mx</td>
|
||||
<td><span class="badge badge--ok">Vendedor</span></td>
|
||||
<td>Matriz</td>
|
||||
<td><span class="badge badge--ok">Activo</span></td>
|
||||
<td>Hoy, 15:48</td>
|
||||
<td><button class="btn btn--ghost btn--sm">Editar</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="user-cell">
|
||||
<div class="user-cell__avatar">JP</div>
|
||||
<span class="user-cell__name">Jorge Pérez</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>jorge@nexusautoparts.mx</td>
|
||||
<td><span class="badge badge--ok">Vendedor</span></td>
|
||||
<td>Sucursal Norte</td>
|
||||
<td><span class="badge badge--ok">Activo</span></td>
|
||||
<td>Ayer, 18:20</td>
|
||||
<td><button class="btn btn--ghost btn--sm">Editar</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<div class="user-cell">
|
||||
<div class="user-cell__avatar">RG</div>
|
||||
<span class="user-cell__name">Roberto García</span>
|
||||
</div>
|
||||
</td>
|
||||
<td>roberto@nexusautoparts.mx</td>
|
||||
<td><span class="badge badge--ok">Bodega</span></td>
|
||||
<td>Matriz</td>
|
||||
<td><span class="badge badge--ok">Activo</span></td>
|
||||
<td>Hoy, 09:30</td>
|
||||
<td><button class="btn btn--ghost btn--sm">Editar</button></td>
|
||||
</tr>
|
||||
<tbody id="employees-tbody">
|
||||
<tr><td colspan="7" style="text-align:center; padding: var(--space-5);">Cargando empleados...</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -1568,50 +1493,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="device-grid">
|
||||
<div class="device-card">
|
||||
<div class="device-card__icon">
|
||||
<svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
</div>
|
||||
<div class="device-card__body">
|
||||
<div class="device-card__name">Matriz — Centro</div>
|
||||
<div class="device-card__detail">
|
||||
<span class="badge badge--ok" style="padding: 0 4px; font-size: 0.625rem;">Principal</span>
|
||||
</div>
|
||||
<div class="device-card__detail">Av. Insurgentes Sur 1234, Col. Del Valle</div>
|
||||
<div class="device-card__detail">3 empleados · 2 terminales POS</div>
|
||||
<div class="device-card__actions">
|
||||
<button class="btn btn--ghost btn--sm">Editar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="device-card">
|
||||
<div class="device-card__icon">
|
||||
<svg viewBox="0 0 24 24"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg>
|
||||
</div>
|
||||
<div class="device-card__body">
|
||||
<div class="device-card__name">Sucursal Norte</div>
|
||||
<div class="device-card__detail">
|
||||
<span class="badge badge--ok" style="padding: 0 4px; font-size: 0.625rem;">Activa</span>
|
||||
</div>
|
||||
<div class="device-card__detail">Blvd. Ávila Camacho 456, Naucalpan</div>
|
||||
<div class="device-card__detail">2 empleados · 1 terminal POS</div>
|
||||
<div class="device-card__actions">
|
||||
<button class="btn btn--ghost btn--sm">Editar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="device-card" style="border-style: dashed; cursor: pointer;">
|
||||
<div class="device-card__icon" style="background: transparent; border: 2px dashed var(--color-border);">
|
||||
<svg viewBox="0 0 24 24" style="stroke: var(--color-text-muted);"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||
</div>
|
||||
<div class="device-card__body">
|
||||
<div class="device-card__name" style="color: var(--color-text-muted);">Agregar Sucursal</div>
|
||||
<div class="device-card__detail">Configura una nueva ubicación</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="device-grid" id="branches-grid">
|
||||
<div class="device-card"><div class="device-card__body" style="text-align:center;">Cargando sucursales...</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1823,6 +1706,176 @@
|
||||
</main>
|
||||
</div><!-- /app-shell -->
|
||||
|
||||
<!-- =====================================================================
|
||||
MODALS
|
||||
===================================================================== -->
|
||||
|
||||
<!-- Modal: Nueva Sucursal -->
|
||||
<div class="cfg-modal-overlay" id="modal-branch" style="display:none;">
|
||||
<div class="cfg-modal">
|
||||
<div class="cfg-modal__header">
|
||||
<h3 class="cfg-modal__title">Nueva Sucursal</h3>
|
||||
<button class="cfg-modal__close" onclick="Config.closeModal('modal-branch')">×</button>
|
||||
</div>
|
||||
<div class="cfg-modal__body">
|
||||
<div class="form-grid">
|
||||
<div class="form-group form-group--full">
|
||||
<label class="form-label">Nombre</label>
|
||||
<input class="form-input" id="branch-name" type="text" placeholder="Ej. Sucursal Norte" />
|
||||
</div>
|
||||
<div class="form-group form-group--full">
|
||||
<label class="form-label">Direccion</label>
|
||||
<input class="form-input" id="branch-address" type="text" placeholder="Calle, Colonia, Ciudad" />
|
||||
</div>
|
||||
<div class="form-group form-group--full">
|
||||
<label class="form-label">Telefono</label>
|
||||
<input class="form-input" id="branch-phone" type="tel" placeholder="(55) 1234-5678" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cfg-modal__footer">
|
||||
<button class="btn btn--ghost" onclick="Config.closeModal('modal-branch')">Cancelar</button>
|
||||
<button class="btn btn--primary" id="btn-save-branch">Guardar Sucursal</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal: Nuevo Empleado -->
|
||||
<div class="cfg-modal-overlay" id="modal-employee" style="display:none;">
|
||||
<div class="cfg-modal">
|
||||
<div class="cfg-modal__header">
|
||||
<h3 class="cfg-modal__title">Nuevo Empleado</h3>
|
||||
<button class="cfg-modal__close" onclick="Config.closeModal('modal-employee')">×</button>
|
||||
</div>
|
||||
<div class="cfg-modal__body">
|
||||
<div class="form-grid">
|
||||
<div class="form-group">
|
||||
<label class="form-label">Nombre Completo *</label>
|
||||
<input class="form-input" id="emp-name" type="text" placeholder="Nombre y apellido" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Email</label>
|
||||
<input class="form-input" id="emp-email" type="email" placeholder="correo@empresa.mx" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Telefono</label>
|
||||
<input class="form-input" id="emp-phone" type="tel" placeholder="(55) 1234-5678" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Rol *</label>
|
||||
<select class="form-select" id="emp-role">
|
||||
<option value="">-- Seleccionar --</option>
|
||||
<option value="admin">Administrador</option>
|
||||
<option value="cashier">Cajero</option>
|
||||
<option value="warehouse">Almacenista</option>
|
||||
<option value="accountant">Contador</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">PIN (4 digitos) *</label>
|
||||
<input class="form-input" id="emp-pin" type="password" maxlength="4" pattern="\d{4}" placeholder="0000" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Sucursal</label>
|
||||
<select class="form-select" id="emp-branch">
|
||||
<option value="">-- Todas --</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Descuento Max. (%)</label>
|
||||
<input class="form-input" id="emp-discount" type="number" min="0" max="100" value="0" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cfg-modal__footer">
|
||||
<button class="btn btn--ghost" onclick="Config.closeModal('modal-employee')">Cancelar</button>
|
||||
<button class="btn btn--primary" id="btn-save-employee">Guardar Empleado</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
/* Modal styles */
|
||||
.cfg-modal-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 9999;
|
||||
background: rgba(0,0,0,0.6);
|
||||
backdrop-filter: blur(4px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
animation: fadeIn var(--duration-fast) var(--ease-in-out);
|
||||
}
|
||||
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
||||
|
||||
.cfg-modal {
|
||||
background: var(--color-bg-elevated);
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-lg);
|
||||
width: 520px;
|
||||
max-width: 90vw;
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
.cfg-modal__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: var(--space-4) var(--space-5);
|
||||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
.cfg-modal__title {
|
||||
font-family: var(--font-heading);
|
||||
font-weight: var(--heading-weight-secondary);
|
||||
font-size: var(--text-h5);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
.cfg-modal__close {
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 1.5rem;
|
||||
color: var(--color-text-muted);
|
||||
cursor: pointer;
|
||||
line-height: 1;
|
||||
}
|
||||
.cfg-modal__close:hover { color: var(--color-text-primary); }
|
||||
.cfg-modal__body { padding: var(--space-5); }
|
||||
.cfg-modal__footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: var(--space-3);
|
||||
padding: var(--space-4) var(--space-5);
|
||||
border-top: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
/* Extra badge colors for roles */
|
||||
.badge--owner { background: rgba(245,166,35,0.15); color: var(--color-primary); }
|
||||
.badge--blue { background: rgba(99,102,241,0.15); color: #818cf8; }
|
||||
.badge--green { background: rgba(34,197,94,0.15); color: var(--color-success); }
|
||||
.badge--yellow { background: rgba(234,179,8,0.15); color: #eab308; }
|
||||
.badge--purple { background: rgba(168,85,247,0.15); color: #a855f7; }
|
||||
|
||||
/* Toast notification */
|
||||
.cfg-toast {
|
||||
position: fixed;
|
||||
bottom: var(--space-5);
|
||||
right: var(--space-5);
|
||||
z-index: 10000;
|
||||
padding: var(--space-3) var(--space-5);
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--text-body-sm);
|
||||
font-weight: var(--font-weight-semibold);
|
||||
color: var(--color-text-inverse);
|
||||
animation: slideUp var(--duration-normal) var(--ease-in-out);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
.cfg-toast--ok { background: var(--color-success); }
|
||||
.cfg-toast--error { background: var(--color-error, #ef4444); }
|
||||
@keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
|
||||
</style>
|
||||
|
||||
<script src="/pos/static/js/app-init.js"></script>
|
||||
<script src="/pos/static/js/sidebar.js"></script>
|
||||
<script src="/pos/static/js/config.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user