File "carga_masiva.php"

Full Path: C:/wamp64/www/AVIDOTAPP/views/registro/carga_masiva.php
File size: 9.97 KB
MIME-type: text/html
Charset: utf-8

<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Carga Masiva de Empleados – CSV</title>
  <link rel="icon" type="image/png" href="assets/img/icono.png">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
  <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
  <style>
    body { background:linear-gradient(225deg,#d0101d,#752b2a); min-height:100vh; padding:20px; }
    .card { border:none; border-radius:15px; box-shadow:0 8px 25px rgba(0,0,0,.2); margin-bottom:20px; }
    .card-header { border-radius:15px 15px 0 0 !important; padding:16px 22px; }

    /* Drop zone */
    .drop-zone { border:3px dashed #d0101d; border-radius:12px; padding:40px 20px;
                 text-align:center; cursor:pointer; transition:background .2s; }
    .drop-zone:hover, .drop-zone.dragover { background:#fff5f5; }
    .drop-zone i { font-size:3rem; color:#d0101d; }

    /* Tabla plantilla */
    .plantilla-col { font-family:monospace; background:#e9ecef; padding:3px 8px;
                     border-radius:4px; font-size:.85rem; }

    /* Resultados */
    .resultado-ok  { color:#28a745; }
    .resultado-err { color:#dc3545; }
    .progress { height:10px; border-radius:5px; }
  </style>
</head>
<body>
<div class="container" style="max-width:900px">

  <a href="index.php?controller=Registro&action=index" class="btn btn-secondary mb-3">
    <i class="fas fa-arrow-left me-1"></i> Volver al Registro
  </a>
  <a href="index.php?controller=Legal&action=cargaMasiva" class="btn btn-success mb-3">
    <i class="fas fa-file-upload me-1"></i> Carga Masiva Legal
  </a>
  <a href="index.php?controller=Dashboard&action=index" class="btn btn-outline-light mb-3 ms-2">
    <i class="fas fa-home me-1"></i> Menú
  </a>

  <!-- ── Instrucciones + plantilla ──────────────────────────── -->
  <div class="card">
    <div class="card-header" style="background:#8d8c8c; color:#fff;">
      <h5 class="mb-0"><i class="fas fa-file-csv me-2"></i>Carga Masiva de Empleados por CSV</h5>
    </div>
    <div class="card-body">
      <p class="mb-2">Suba un archivo <strong>.csv</strong> con los datos de los empleados.
        El sistema los registrará automáticamente en la tabla <code>empleado</code>.</p>

      <!-- Columnas requeridas -->
      <div class="table-responsive mb-3">
        <table class="table table-sm table-bordered">
          <thead class="table-dark">
            <tr>
              <th>Columna CSV</th><th>Descripción</th><th>Ejemplo</th><th>¿Obligatorio?</th>
            </tr>
          </thead>
          <tbody>
            <?php
            $cols = [
              ['fingreso',   'Fecha de ingreso',   '2024-01-15',       'Sí'],
              ['cedula',     'Número de cédula',   '12345678',         'Sí'],
              ['nombre',     'Nombre completo',    'JUAN PEREZ',       'Sí'],
              ['ccosto',     'Centro de costo',    'LOGISTICA',        'Sí'],
              ['area',       'Área',               'BODEGAS',          'Sí'],
              ['cargo',      'Cargo',              'AUXILIAR BODEGA',  'Sí'],
              ['tallaPant',  'Talla pantalón',     'M',                'No (def: NO APLICA)'],
              ['tallaCami',  'Talla camiseta',     'M',                'No (def: NO APLICA)'],
              ['tallaBot',   'Talla botas',        '38',               'No (def: NO APLICA)'],
              ['tallaChaq',  'Talla chaqueta',     'L',                'No (def: NO APLICA)'],
              ['tallaImp',   'Talla impermeable',  'M',                'No (def: NO APLICA)'],
              ['tpEntrega',  'Tipo de entrega',    'Primera Entrega',  'No (def: Primera Entrega)'],
              ['tpContrato', 'Tipo de contrato',   'DIRECTO',          'No (def: DIRECTO)'],
            ];
            foreach ($cols as $c):
            ?>
            <tr>
              <td><span class="plantilla-col"><?= $c[0] ?></span></td>
              <td><?= $c[1] ?></td>
              <td><code><?= $c[2] ?></code></td>
              <td><?= $c[3] ?></td>
            </tr>
            <?php endforeach; ?>
          </tbody>
        </table>
      </div>

      <div class="alert alert-info">
        <i class="fas fa-lightbulb me-2"></i>
        <strong>Tip:</strong> La primera fila del CSV debe ser el encabezado con los nombres de columna exactos.
        Descargue la plantilla de ejemplo para comenzar más rápido.
      </div>

      <!-- Descargar plantilla -->
      <a href="index.php?controller=Registro&action=descargarPlantilla"
         class="btn btn-success mb-4">
        <i class="fas fa-download me-2"></i>Descargar Plantilla CSV
      </a>

      <!-- Formulario subida -->
      <form id="csvForm" method="post" action="index.php?controller=Registro&action=cargaMasiva"
            enctype="multipart/form-data">

        <div class="drop-zone" id="dropZone" onclick="document.getElementById('csvInput').click()">
          <i class="fas fa-file-csv d-block mb-2"></i>
          <p class="fw-bold mb-1">Haz clic o arrastra el archivo CSV aquí</p>
          <small class="text-muted" id="fileLabel">Solo archivos .csv</small>
          <input type="file" id="csvInput" name="archivo_csv" accept=".csv"
                 required style="display:none">
        </div>

        <div class="d-flex gap-2 mt-4 flex-wrap">
          <button type="submit" class="btn btn-danger btn-lg" id="btnProcesar" disabled>
            <i class="fas fa-upload me-2"></i>Procesar CSV
          </button>
          <a href="index.php?controller=Registro&action=index" class="btn btn-secondary btn-lg">
            Cancelar
          </a>
        </div>
      </form>
    </div>
  </div>

  <!-- ── Resultados del procesamiento ──────────────────────── -->
  <?php if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($resultados)): ?>
  <div class="card">
    <div class="card-header" style="background:#495057; color:#fff;">
      <h5 class="mb-0">
        <i class="fas fa-chart-bar me-2"></i>Resultado del Procesamiento
      </h5>
    </div>
    <div class="card-body">

      <!-- Resumen -->
      <div class="row text-center mb-4">
        <div class="col-md-4">
          <div class="card border-0 bg-light p-3">
            <div class="fs-2 fw-bold text-dark"><?= count($resultados) ?></div>
            <div class="text-muted">Total procesados</div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="card border-0 bg-light p-3">
            <div class="fs-2 fw-bold text-success"><?= $procesados ?></div>
            <div class="text-muted">Exitosos</div>
          </div>
        </div>
        <div class="col-md-4">
          <div class="card border-0 bg-light p-3">
            <div class="fs-2 fw-bold text-danger"><?= count($resultados) - $procesados ?></div>
            <div class="text-muted">Con error</div>
          </div>
        </div>
      </div>

      <!-- Barra de éxito -->
      <?php $pct = count($resultados) > 0 ? round($procesados/count($resultados)*100) : 0; ?>
      <div class="progress mb-4">
        <div class="progress-bar bg-success" style="width:<?= $pct ?>%"><?= $pct ?>%</div>
      </div>

      <!-- Errores globales -->
      <?php if (!empty($errores)): ?>
      <div class="alert alert-danger">
        <strong><i class="fas fa-exclamation-triangle me-2"></i>Errores:</strong>
        <ul class="mb-0 mt-2">
          <?php foreach ($errores as $e) echo '<li>'.htmlspecialchars($e).'</li>'; ?>
        </ul>
      </div>
      <?php endif; ?>

      <!-- Tabla detallada -->
      <div class="table-responsive">
        <table class="table table-sm table-striped table-bordered">
          <thead class="table-dark">
            <tr><th>Cédula</th><th>Nombre</th><th>Estado</th></tr>
          </thead>
          <tbody>
            <?php foreach ($resultados as $r): ?>
            <tr>
              <td class="fw-bold"><?= htmlspecialchars($r['cedula']) ?></td>
              <td><?= htmlspecialchars($r['nombre']) ?></td>
              <td>
                <?php if ($r['ok']): ?>
                  <span class="badge bg-success"><i class="fas fa-check me-1"></i>Registrado</span>
                <?php else: ?>
                  <span class="badge bg-danger"><i class="fas fa-times me-1"></i>Error</span>
                  <?php if (!empty($r['error'])): ?>
                    <small class="text-danger ms-2"><?= htmlspecialchars($r['error']) ?></small>
                  <?php endif; ?>
                <?php endif; ?>
              </td>
            </tr>
            <?php endforeach; ?>
          </tbody>
        </table>
      </div>
    </div>
  </div>
  <?php endif; ?>

</div>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
const dropZone  = document.getElementById('dropZone');
const csvInput  = document.getElementById('csvInput');
const fileLabel = document.getElementById('fileLabel');
const btnProc   = document.getElementById('btnProcesar');

function onFile(file) {
  if (!file) return;
  fileLabel.textContent = '📄 ' + file.name + ' (' + (file.size/1024).toFixed(1) + ' KB)';
  fileLabel.style.color = '#28a745';
  btnProc.disabled = false;
}

csvInput.addEventListener('change', () => onFile(csvInput.files[0]));

dropZone.addEventListener('dragover',  e => { e.preventDefault(); dropZone.classList.add('dragover'); });
dropZone.addEventListener('dragleave', () => dropZone.classList.remove('dragover'));
dropZone.addEventListener('drop', e => {
  e.preventDefault(); dropZone.classList.remove('dragover');
  const dt = new DataTransfer();
  Array.from(e.dataTransfer.files).forEach(f => dt.items.add(f));
  csvInput.files = dt.files;
  onFile(csvInput.files[0]);
});

document.getElementById('csvForm').addEventListener('submit', function(){
  btnProc.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>Procesando...';
  btnProc.disabled  = true;
});
</script>
</body>
</html>