organizar menu lateral, bases de datos y algunas funciones de trabajaodres y configuracion
This commit is contained in:
Binary file not shown.
@@ -110,3 +110,291 @@ body {
|
|||||||
color: #666;
|
color: #666;
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.section-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.65rem 1.25rem;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
border: none;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #1abc9c;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #16a085;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary {
|
||||||
|
background-color: #95a5a6;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background-color: #7f8c8d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-icon {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-icon:hover {
|
||||||
|
background-color: #ecf0f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-container {
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table th,
|
||||||
|
.data-table td {
|
||||||
|
padding: 1rem;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid #ecf0f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table th {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
color: #2c3e50;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table tbody tr:hover {
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.data-table .empty {
|
||||||
|
text-align: center;
|
||||||
|
color: #7f8c8d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.35rem 0.7rem;
|
||||||
|
border-radius: 12px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-active {
|
||||||
|
background-color: #d5f5e3;
|
||||||
|
color: #1e8449;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge-inactive {
|
||||||
|
background-color: #fadbd8;
|
||||||
|
color: #c0392b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-backdrop {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
position: relative;
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
width: 90%;
|
||||||
|
max-width: 700px;
|
||||||
|
max-height: 90vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 1001;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1.25rem 1.5rem;
|
||||||
|
border-bottom: 1px solid #ecf0f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header h2 {
|
||||||
|
color: #2c3e50;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-close {
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
color: #7f8c8d;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-close:hover {
|
||||||
|
color: #2c3e50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal form {
|
||||||
|
padding: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
gap: 1rem 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #555;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label.readonly-label {
|
||||||
|
color: #95a5a6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input,
|
||||||
|
.form-group select {
|
||||||
|
padding: 0.65rem 0.75rem;
|
||||||
|
border: 1px solid #d5d8dc;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input:focus,
|
||||||
|
.form-group select:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #1abc9c;
|
||||||
|
box-shadow: 0 0 0 2px rgba(26, 188, 156, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 0.75rem;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
padding-top: 1rem;
|
||||||
|
border-top: 1px solid #ecf0f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-inline {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #555;
|
||||||
|
font-weight: normal;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox-inline input[type="checkbox"] {
|
||||||
|
width: auto;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:disabled,
|
||||||
|
input[readonly] {
|
||||||
|
background-color: #ecf0f1;
|
||||||
|
cursor: not-allowed;
|
||||||
|
color: #7f8c8d;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input[readonly] + label,
|
||||||
|
.form-group label.readonly-label {
|
||||||
|
color: #95a5a6;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-card {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||||
|
padding: 2rem;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-header {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
border-bottom: 1px solid #ecf0f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-header h3 {
|
||||||
|
color: #2c3e50;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
margin-bottom: 0.35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-header p {
|
||||||
|
color: #7f8c8d;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-card .form-grid {
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-top: 1.5rem;
|
||||||
|
padding-top: 1rem;
|
||||||
|
border-top: 1px solid #ecf0f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mensaje {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #1e8449;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pesos-input {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|||||||
+167
-3
@@ -8,12 +8,17 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="app-layout">
|
<div class="app-layout">
|
||||||
|
<!-- // SIDEBAR (MENU LATERAL) -->
|
||||||
<aside class="sidebar">
|
<aside class="sidebar">
|
||||||
<div class="logo">
|
<div class="logo">
|
||||||
<h2>Sistema de Nóminas</h2>
|
<h2>Sistema de Nóminas</h2>
|
||||||
</div>
|
</div>
|
||||||
<nav class="menu">
|
<nav class="menu">
|
||||||
<button class="menu-btn active" data-section="trabajadores">
|
<button class="menu-btn active" data-section="seguimiento">
|
||||||
|
<span class="icon">⏰</span>
|
||||||
|
Seguimiento
|
||||||
|
</button>
|
||||||
|
<button class="menu-btn" data-section="trabajadores">
|
||||||
<span class="icon">👷</span>
|
<span class="icon">👷</span>
|
||||||
Trabajadores
|
Trabajadores
|
||||||
</button>
|
</button>
|
||||||
@@ -25,24 +30,120 @@
|
|||||||
<span class="icon">📄</span>
|
<span class="icon">📄</span>
|
||||||
Liquidaciones
|
Liquidaciones
|
||||||
</button>
|
</button>
|
||||||
|
<button class="menu-btn" data-section="historial">
|
||||||
|
<span class="icon">📖</span>
|
||||||
|
Historial
|
||||||
|
</button>
|
||||||
</nav>
|
</nav>
|
||||||
<div class="sidebar-footer">
|
<div class="sidebar-footer">
|
||||||
|
<button class="menu-btn" data-section="configuraciones">
|
||||||
|
<span class="icon">⚙️</span>
|
||||||
|
Configuraciones
|
||||||
|
</button>
|
||||||
<button class="menu-btn" data-section="licencia">
|
<button class="menu-btn" data-section="licencia">
|
||||||
<span class="icon">🔑</span>
|
<span class="icon">🔑</span>
|
||||||
Licencia
|
Licencia
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
<!-- // CIERRE DE SIDEBAR (MENU LATERAL) -->
|
||||||
|
|
||||||
|
<!-- // INICIO DEL MAIN (CONTENIDO) -->
|
||||||
<main class="main-content">
|
<main class="main-content">
|
||||||
|
<!--N INICIO DE LOS TRABAJADORES -->
|
||||||
<header class="top-bar">
|
<header class="top-bar">
|
||||||
<h1 id="section-title">Trabajadores</h1>
|
<h1 id="section-title">Trabajadores</h1>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<section id="trabajadores" class="section active">
|
<section id="seguimiento" class="section active">
|
||||||
<p>Gestión de trabajadores.</p>
|
<p>Seguimiento de nóminas y empleados.</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section id="trabajadores" class="section">
|
||||||
|
<div class="section-actions">
|
||||||
|
<button id="btn-nuevo-trabajador" class="btn btn-primary">+ Nuevo trabajador</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-container">
|
||||||
|
<table id="tabla-trabajadores" class="data-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Documento</th>
|
||||||
|
<th>Nombre completo</th>
|
||||||
|
<th>Puesto</th>
|
||||||
|
<th>Salario mensual</th>
|
||||||
|
<th>Estado</th>
|
||||||
|
<th>Acciones</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="empty">No hay trabajadores registrados.</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="modal-trabajador" class="modal hidden">
|
||||||
|
<div class="modal-backdrop"></div>
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h2 id="modal-titulo-trabajador">Nuevo trabajador</h2>
|
||||||
|
<button type="button" class="btn-close" id="btn-cerrar-modal-trabajador">×</button>
|
||||||
|
</div>
|
||||||
|
<form id="form-trabajador">
|
||||||
|
<input type="hidden" id="trabajador-id-original">
|
||||||
|
<div class="form-grid">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="trabajador-id">Documento de identidad</label>
|
||||||
|
<input type="text" id="trabajador-id" name="id" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="trabajador-nombre">Nombre</label>
|
||||||
|
<input type="text" id="trabajador-nombre" name="nombre" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="trabajador-apellidos">Apellidos</label>
|
||||||
|
<input type="text" id="trabajador-apellidos" name="apellidos" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="trabajador-puesto">Puesto</label>
|
||||||
|
<input type="text" id="trabajador-puesto" name="puesto">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="trabajador-salario">Salario mensual</label>
|
||||||
|
<input type="number" id="trabajador-salario" name="salario_mensual" step="0.01" min="0">
|
||||||
|
<label class="checkbox-inline">
|
||||||
|
<input type="checkbox" id="chk-smv">
|
||||||
|
SMV (Salario Mínimo Vigente)
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="trabajador-fecha">Fecha de ingreso</label>
|
||||||
|
<input type="date" id="trabajador-fecha" name="fecha_ingreso">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="trabajador-seguridad">Seguridad social</label>
|
||||||
|
<input type="text" id="trabajador-seguridad" name="seguridad_social">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="trabajador-activo">Estado</label>
|
||||||
|
<select id="trabajador-activo" name="activo">
|
||||||
|
<option value="1">Activo</option>
|
||||||
|
<option value="0">Inactivo</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" id="btn-cancelar-trabajador">Cancelar</button>
|
||||||
|
<button type="submit" class="btn btn-primary">Guardar</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!--N CIERRE DE TRABAJADORES -->
|
||||||
|
|
||||||
<section id="nominas" class="section">
|
<section id="nominas" class="section">
|
||||||
<p>Gestión de nóminas.</p>
|
<p>Gestión de nóminas.</p>
|
||||||
</section>
|
</section>
|
||||||
@@ -51,9 +152,72 @@
|
|||||||
<p>Gestión de liquidaciones.</p>
|
<p>Gestión de liquidaciones.</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!--N INICIO DE CONFIGURACIONES -->
|
||||||
|
<section id="configuraciones" class="section">
|
||||||
|
<div class="config-card">
|
||||||
|
<div class="config-header">
|
||||||
|
<h3>Parámetros de la empresa</h3>
|
||||||
|
<p>Configura los valores generales que se usarán en las nóminas.</p>
|
||||||
|
</div>
|
||||||
|
<form id="form-configuraciones">
|
||||||
|
<div class="form-grid">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cfg-nombre-empresa">Nombre de la empresa</label>
|
||||||
|
<input type="text" id="cfg-nombre-empresa" name="nombre_empresa">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cfg-salario-minimo">Salario mínimo</label>
|
||||||
|
<input type="text" id="cfg-salario-minimo" name="salario_minimo" class="pesos-input">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cfg-auxilio-transporte">Auxilio de transporte</label>
|
||||||
|
<input type="text" id="cfg-auxilio-transporte" name="auxilio_transporte" class="pesos-input">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cfg-horas-semanales">Horas semanales</label>
|
||||||
|
<input type="number" id="cfg-horas-semanales" name="horas_semanales" step="0.01" min="0">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cfg-horas-mensuales" class="readonly-label">Horas mensuales</label>
|
||||||
|
<input type="text" id="cfg-horas-mensuales" name="horas_mensuales" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cfg-dia-inicio">Día inicio mes</label>
|
||||||
|
<input type="number" id="cfg-dia-inicio" name="dia_inicio_mes" min="1" max="31">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cfg-dia-fin">Día fin mes</label>
|
||||||
|
<input type="number" id="cfg-dia-fin" name="dia_fin_mes" min="1" max="31">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cfg-hora-ordinaria">Valor hora ordinaria</label>
|
||||||
|
<input type="text" id="cfg-hora-ordinaria" name="valor_hora_ordinaria" class="pesos-input">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cfg-hora-extra" class="readonly-label">Valor hora extra</label>
|
||||||
|
<input type="text" id="cfg-hora-extra" name="valor_hora_extra" class="pesos-input" readonly>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cfg-hora-extra-nocturna" class="readonly-label">Valor hora extra nocturna</label>
|
||||||
|
<input type="text" id="cfg-hora-extra-nocturna" name="valor_hora_extra_nocturna" class="pesos-input" readonly>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="config-footer">
|
||||||
|
<button type="submit" class="btn btn-primary" id="btn-guardar-configuraciones">Guardar configuraciones</button>
|
||||||
|
<span id="cfg-mensaje" class="mensaje"></span>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<!--N FIN DE CONFIGURACIONES -->
|
||||||
|
|
||||||
<section id="licencia" class="section">
|
<section id="licencia" class="section">
|
||||||
<p>Información de licencia.</p>
|
<p>Información de licencia.</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section id="historial" class="section">
|
||||||
|
<p>Historial de cambios y movimientos.</p>
|
||||||
|
</section>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
+273
-1
@@ -1,13 +1,17 @@
|
|||||||
|
//// PASAR DE UN BOTON A OTRO BOTON
|
||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
const menuButtons = document.querySelectorAll('.menu-btn');
|
const menuButtons = document.querySelectorAll('.menu-btn');
|
||||||
const sections = document.querySelectorAll('.section');
|
const sections = document.querySelectorAll('.section');
|
||||||
const sectionTitle = document.getElementById('section-title');
|
const sectionTitle = document.getElementById('section-title');
|
||||||
|
|
||||||
const titles = {
|
const titles = {
|
||||||
|
seguimiento: 'Seguimiento',
|
||||||
trabajadores: 'Trabajadores',
|
trabajadores: 'Trabajadores',
|
||||||
nominas: 'Nóminas',
|
nominas: 'Nóminas',
|
||||||
liquidaciones: 'Liquidaciones',
|
liquidaciones: 'Liquidaciones',
|
||||||
licencia: 'Licencia'
|
configuraciones: 'Configuraciones',
|
||||||
|
licencia: 'Licencia',
|
||||||
|
historial: 'Historial'
|
||||||
};
|
};
|
||||||
|
|
||||||
menuButtons.forEach(button => {
|
menuButtons.forEach(button => {
|
||||||
@@ -23,4 +27,272 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
sectionTitle.textContent = titles[target] || '';
|
sectionTitle.textContent = titles[target] || '';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//// MODULO DE TRABAJADORES
|
||||||
|
const trabajadores = [];
|
||||||
|
let editandoId = null;
|
||||||
|
|
||||||
|
const modalTrabajador = document.getElementById('modal-trabajador');
|
||||||
|
const formTrabajador = document.getElementById('form-trabajador');
|
||||||
|
const btnNuevoTrabajador = document.getElementById('btn-nuevo-trabajador');
|
||||||
|
const btnCerrarModal = document.getElementById('btn-cerrar-modal-trabajador');
|
||||||
|
const btnCancelar = document.getElementById('btn-cancelar-trabajador');
|
||||||
|
const modalTitulo = document.getElementById('modal-titulo-trabajador');
|
||||||
|
const tablaBody = document.querySelector('#tabla-trabajadores tbody');
|
||||||
|
const chkSmv = document.getElementById('chk-smv');
|
||||||
|
const inputSalario = document.getElementById('trabajador-salario');
|
||||||
|
|
||||||
|
let configuracionGlobal = {
|
||||||
|
id: null,
|
||||||
|
nombre_empresa: '',
|
||||||
|
salario_minimo: '',
|
||||||
|
auxilio_transporte: '',
|
||||||
|
horas_semanales: '',
|
||||||
|
horas_mensuales: '',
|
||||||
|
dia_inicio_mes: '',
|
||||||
|
dia_fin_mes: '',
|
||||||
|
valor_hora_ordinaria: '',
|
||||||
|
valor_hora_extra: '',
|
||||||
|
valor_hora_extra_nocturna: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
function formatearPesos(valor) {
|
||||||
|
const partes = Number(valor).toFixed(2).split('.');
|
||||||
|
const entera = partes[0].replace(/\B(?=(\d{3})+(?!\d))/g, '.');
|
||||||
|
const decimal = ',' + partes[1];
|
||||||
|
return entera + decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatearPesosSinDecimales(valor) {
|
||||||
|
const numero = Number(valor);
|
||||||
|
if (isNaN(numero)) return '';
|
||||||
|
return numero.toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function limpiarFormatoPesos(valor) {
|
||||||
|
return String(valor || '').replace(/\./g, '').replace(',', '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function abrirModal(modo = 'nuevo') {
|
||||||
|
modalTrabajador.classList.remove('hidden');
|
||||||
|
modalTitulo.textContent = modo === 'editar' ? 'Editar trabajador' : 'Nuevo trabajador';
|
||||||
|
}
|
||||||
|
|
||||||
|
function cerrarModal() {
|
||||||
|
modalTrabajador.classList.add('hidden');
|
||||||
|
formTrabajador.reset();
|
||||||
|
document.getElementById('trabajador-id-original').value = '';
|
||||||
|
editandoId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTabla() {
|
||||||
|
tablaBody.innerHTML = '';
|
||||||
|
|
||||||
|
if (trabajadores.length === 0) {
|
||||||
|
tablaBody.innerHTML = '<tr><td colspan="6" class="empty">No hay trabajadores registrados.</td></tr>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
trabajadores.forEach(t => {
|
||||||
|
const tr = document.createElement('tr');
|
||||||
|
tr.innerHTML = `
|
||||||
|
<td>${t.id}</td>
|
||||||
|
<td>${t.nombre} ${t.apellidos}</td>
|
||||||
|
<td>${t.puesto || '-'}</td>
|
||||||
|
<td>${t.salario_mensual ? formatearPesos(Number(t.salario_mensual)) : '-'}</td>
|
||||||
|
<td>
|
||||||
|
<span class="badge ${t.activo == 1 ? 'badge-active' : 'badge-inactive'}">
|
||||||
|
${t.activo == 1 ? 'Activo' : 'Inactivo'}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<button class="btn-icon btn-editar" title="Editar">✏️</button>
|
||||||
|
<button class="btn-icon btn-eliminar" title="Eliminar">🗑️</button>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
tr.querySelector('.btn-editar').addEventListener('click', () => cargarEdicion(t.id));
|
||||||
|
tr.querySelector('.btn-eliminar').addEventListener('click', () => eliminarTrabajador(t.id));
|
||||||
|
|
||||||
|
tablaBody.appendChild(tr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function guardarTrabajador(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const datos = {
|
||||||
|
id: document.getElementById('trabajador-id').value.trim(),
|
||||||
|
nombre: document.getElementById('trabajador-nombre').value.trim(),
|
||||||
|
apellidos: document.getElementById('trabajador-apellidos').value.trim(),
|
||||||
|
puesto: document.getElementById('trabajador-puesto').value.trim(),
|
||||||
|
salario_mensual: document.getElementById('trabajador-salario').value,
|
||||||
|
fecha_ingreso: document.getElementById('trabajador-fecha').value,
|
||||||
|
seguridad_social: document.getElementById('trabajador-seguridad').value.trim(),
|
||||||
|
activo: document.getElementById('trabajador-activo').value
|
||||||
|
};
|
||||||
|
|
||||||
|
if (editandoId !== null) {
|
||||||
|
const index = trabajadores.findIndex(t => t.id === editandoId);
|
||||||
|
if (index !== -1) {
|
||||||
|
trabajadores[index] = { ...datos, idOriginal: editandoId };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const existe = trabajadores.some(t => t.id === datos.id);
|
||||||
|
if (existe) {
|
||||||
|
alert('Ya existe un trabajador con ese documento de identidad.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
trabajadores.push(datos);
|
||||||
|
}
|
||||||
|
|
||||||
|
cerrarModal();
|
||||||
|
renderTabla();
|
||||||
|
}
|
||||||
|
|
||||||
|
function cargarEdicion(id) {
|
||||||
|
const t = trabajadores.find(item => item.id === id);
|
||||||
|
if (!t) return;
|
||||||
|
|
||||||
|
editandoId = id;
|
||||||
|
document.getElementById('trabajador-id-original').value = id;
|
||||||
|
document.getElementById('trabajador-id').value = t.id;
|
||||||
|
document.getElementById('trabajador-nombre').value = t.nombre;
|
||||||
|
document.getElementById('trabajador-apellidos').value = t.apellidos;
|
||||||
|
document.getElementById('trabajador-puesto').value = t.puesto;
|
||||||
|
document.getElementById('trabajador-salario').value = t.salario_mensual;
|
||||||
|
document.getElementById('trabajador-fecha').value = t.fecha_ingreso;
|
||||||
|
document.getElementById('trabajador-seguridad').value = t.seguridad_social;
|
||||||
|
document.getElementById('trabajador-activo').value = t.activo;
|
||||||
|
|
||||||
|
abrirModal('editar');
|
||||||
|
}
|
||||||
|
|
||||||
|
function eliminarTrabajador(id) {
|
||||||
|
if (!confirm('¿Estás seguro de eliminar este trabajador?')) return;
|
||||||
|
const index = trabajadores.findIndex(t => t.id === id);
|
||||||
|
if (index !== -1) {
|
||||||
|
trabajadores.splice(index, 1);
|
||||||
|
renderTabla();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
btnNuevoTrabajador.addEventListener('click', () => abrirModal('nuevo'));
|
||||||
|
btnCerrarModal.addEventListener('click', cerrarModal);
|
||||||
|
btnCancelar.addEventListener('click', cerrarModal);
|
||||||
|
formTrabajador.addEventListener('submit', guardarTrabajador);
|
||||||
|
|
||||||
|
if (chkSmv && inputSalario) {
|
||||||
|
chkSmv.addEventListener('change', function () {
|
||||||
|
if (this.checked) {
|
||||||
|
const smv = configuracionGlobal.salario_minimo;
|
||||||
|
if (!smv) {
|
||||||
|
alert('No hay un salario mínimo configurado. Ve a Configuraciones y guárdalo primero.');
|
||||||
|
this.checked = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
inputSalario.value = smv;
|
||||||
|
inputSalario.disabled = true;
|
||||||
|
} else {
|
||||||
|
inputSalario.disabled = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
renderTabla();
|
||||||
|
|
||||||
|
// --- Módulo de Configuraciones ---
|
||||||
|
const formConfiguraciones = document.getElementById('form-configuraciones');
|
||||||
|
const btnGuardarConfiguraciones = document.getElementById('btn-guardar-configuraciones');
|
||||||
|
const cfgMensaje = document.getElementById('cfg-mensaje');
|
||||||
|
|
||||||
|
const camposPesosSinDecimales = [
|
||||||
|
'cfg-salario-minimo',
|
||||||
|
'cfg-auxilio-transporte',
|
||||||
|
'cfg-hora-ordinaria'
|
||||||
|
];
|
||||||
|
|
||||||
|
const inputHorasSemanales = document.getElementById('cfg-horas-semanales');
|
||||||
|
const inputHorasMensuales = document.getElementById('cfg-horas-mensuales');
|
||||||
|
const inputHoraOrdinaria = document.getElementById('cfg-hora-ordinaria');
|
||||||
|
const inputHoraExtra = document.getElementById('cfg-hora-extra');
|
||||||
|
const inputHoraExtraNocturna = document.getElementById('cfg-hora-extra-nocturna');
|
||||||
|
|
||||||
|
function aplicarFormatoPesosSinDecimales(input) {
|
||||||
|
const limpio = limpiarFormatoPesos(input.value);
|
||||||
|
const numero = Number(limpio);
|
||||||
|
input.value = isNaN(numero) ? '' : formatearPesosSinDecimales(numero);
|
||||||
|
}
|
||||||
|
|
||||||
|
function calcularCamposDependientes() {
|
||||||
|
const horasSemanales = Number(inputHorasSemanales.value);
|
||||||
|
if (!isNaN(horasSemanales) && inputHorasMensuales) {
|
||||||
|
inputHorasMensuales.value = (horasSemanales * 5).toFixed(0).replace(/\B(?=(\d{3})+(?!\d))/g, '.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const horaOrdinaria = Number(limpiarFormatoPesos(inputHoraOrdinaria.value));
|
||||||
|
if (!isNaN(horaOrdinaria)) {
|
||||||
|
if (inputHoraExtra) {
|
||||||
|
inputHoraExtra.value = formatearPesosSinDecimales(horaOrdinaria * 1.25);
|
||||||
|
}
|
||||||
|
if (inputHoraExtraNocturna) {
|
||||||
|
inputHoraExtraNocturna.value = formatearPesosSinDecimales(horaOrdinaria * 1.75);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cargarConfiguracionEnFormulario() {
|
||||||
|
document.getElementById('cfg-nombre-empresa').value = configuracionGlobal.nombre_empresa;
|
||||||
|
document.getElementById('cfg-salario-minimo').value = configuracionGlobal.salario_minimo ? formatearPesosSinDecimales(configuracionGlobal.salario_minimo) : '';
|
||||||
|
document.getElementById('cfg-auxilio-transporte').value = configuracionGlobal.auxilio_transporte ? formatearPesosSinDecimales(configuracionGlobal.auxilio_transporte) : '';
|
||||||
|
document.getElementById('cfg-horas-semanales').value = configuracionGlobal.horas_semanales;
|
||||||
|
document.getElementById('cfg-horas-mensuales').value = configuracionGlobal.horas_mensuales;
|
||||||
|
document.getElementById('cfg-dia-inicio').value = configuracionGlobal.dia_inicio_mes;
|
||||||
|
document.getElementById('cfg-dia-fin').value = configuracionGlobal.dia_fin_mes;
|
||||||
|
document.getElementById('cfg-hora-ordinaria').value = configuracionGlobal.valor_hora_ordinaria ? formatearPesosSinDecimales(configuracionGlobal.valor_hora_ordinaria) : '';
|
||||||
|
calcularCamposDependientes();
|
||||||
|
}
|
||||||
|
|
||||||
|
function guardarConfiguracion(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
configuracionGlobal = {
|
||||||
|
id: configuracionGlobal.id || 1,
|
||||||
|
nombre_empresa: document.getElementById('cfg-nombre-empresa').value.trim(),
|
||||||
|
salario_minimo: limpiarFormatoPesos(document.getElementById('cfg-salario-minimo').value),
|
||||||
|
auxilio_transporte: limpiarFormatoPesos(document.getElementById('cfg-auxilio-transporte').value),
|
||||||
|
horas_semanales: document.getElementById('cfg-horas-semanales').value,
|
||||||
|
horas_mensuales: document.getElementById('cfg-horas-mensuales').value,
|
||||||
|
dia_inicio_mes: document.getElementById('cfg-dia-inicio').value,
|
||||||
|
dia_fin_mes: document.getElementById('cfg-dia-fin').value,
|
||||||
|
valor_hora_ordinaria: limpiarFormatoPesos(document.getElementById('cfg-hora-ordinaria').value),
|
||||||
|
valor_hora_extra: limpiarFormatoPesos(document.getElementById('cfg-hora-extra').value),
|
||||||
|
valor_hora_extra_nocturna: limpiarFormatoPesos(document.getElementById('cfg-hora-extra-nocturna').value)
|
||||||
|
};
|
||||||
|
|
||||||
|
cargarConfiguracionEnFormulario();
|
||||||
|
|
||||||
|
if (cfgMensaje) {
|
||||||
|
cfgMensaje.textContent = 'Configuración guardada correctamente.';
|
||||||
|
setTimeout(() => { cfgMensaje.textContent = ''; }, 3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formConfiguraciones) {
|
||||||
|
camposPesosSinDecimales.forEach(id => {
|
||||||
|
const input = document.getElementById(id);
|
||||||
|
if (input) {
|
||||||
|
input.addEventListener('blur', () => aplicarFormatoPesosSinDecimales(input));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
inputHorasSemanales.addEventListener('input', calcularCamposDependientes);
|
||||||
|
inputHoraOrdinaria.addEventListener('blur', function () {
|
||||||
|
aplicarFormatoPesosSinDecimales(this);
|
||||||
|
calcularCamposDependientes();
|
||||||
|
});
|
||||||
|
|
||||||
|
formConfiguraciones.addEventListener('submit', guardarConfiguracion);
|
||||||
|
cargarConfiguracionEnFormulario();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user