605 lines
30 KiB
PHP
605 lines
30 KiB
PHP
<?php
|
|
session_start();
|
|
|
|
$userRole = $_SESSION['user_role'] ?? '';
|
|
if (!isset($_SESSION['user_id']) || ($userRole !== 'Administrador' && $userRole !== 'admin')) {
|
|
header('Location: dashboard.php');
|
|
exit;
|
|
}
|
|
|
|
require_once 'db/config.php';
|
|
$pdo = db();
|
|
|
|
$schemaInitError = null;
|
|
require_once 'includes/hr_bootstrap.php';
|
|
try {
|
|
hr_ensure_schema($pdo);
|
|
} catch (Throwable $e) {
|
|
$schemaInitError = $e->getMessage();
|
|
}
|
|
|
|
$pageTitle = "Recursos Humanos - Reclutamiento";
|
|
$pageDescription = "Gestión de postulantes: CV, portafolio, indicadores y estado del proceso de reclutamiento.";
|
|
|
|
$estadosValidos = [
|
|
'Postulación Recibida',
|
|
'Entrevista Pendiente',
|
|
'Entrevista Realizada',
|
|
'Aprobado',
|
|
'Contratado',
|
|
'No Seleccionado',
|
|
];
|
|
|
|
function hr_move_uploaded_file(array $file, string $uploadDirAbs, array $allowedExts): string
|
|
{
|
|
$error = $file['error'] ?? UPLOAD_ERR_NO_FILE;
|
|
if ($error !== UPLOAD_ERR_OK) {
|
|
throw new RuntimeException('Error al cargar el archivo.');
|
|
}
|
|
|
|
$size = (int)($file['size'] ?? 0);
|
|
$maxBytes = 8 * 1024 * 1024;
|
|
if ($size <= 0) {
|
|
throw new RuntimeException('Archivo vacío.');
|
|
}
|
|
if ($size > $maxBytes) {
|
|
throw new RuntimeException('El archivo excede el tamaño máximo permitido (8MB).');
|
|
}
|
|
|
|
$origName = (string)($file['name'] ?? 'archivo');
|
|
$ext = strtolower(pathinfo($origName, PATHINFO_EXTENSION));
|
|
if ($ext === '' || !in_array($ext, $allowedExts, true)) {
|
|
throw new RuntimeException('Tipo de archivo no permitido.');
|
|
}
|
|
|
|
if (!is_dir($uploadDirAbs)) {
|
|
mkdir($uploadDirAbs, 0775, true);
|
|
}
|
|
|
|
$base = pathinfo($origName, PATHINFO_FILENAME);
|
|
$base = preg_replace('/[^A-Za-z0-9._-]+/', '_', $base);
|
|
if (!$base) {
|
|
$base = 'archivo';
|
|
}
|
|
|
|
$newName = time() . '_' . $base . '.' . $ext;
|
|
$targetAbs = rtrim($uploadDirAbs, '/\\') . DIRECTORY_SEPARATOR . $newName;
|
|
|
|
if (!move_uploaded_file($file['tmp_name'], $targetAbs)) {
|
|
throw new RuntimeException('No se pudo guardar el archivo en el servidor.');
|
|
}
|
|
|
|
$uploadDirRel = str_replace(__DIR__ . DIRECTORY_SEPARATOR, '', rtrim($uploadDirAbs, '/\\'));
|
|
return $uploadDirRel . '/' . $newName;
|
|
}
|
|
|
|
$notice = null;
|
|
$noticeType = 'success';
|
|
|
|
if (!empty($schemaInitError)) {
|
|
$notice = 'Error al preparar las tablas de Recursos Humanos.';
|
|
$noticeType = 'danger';
|
|
error_log('HR schema init error (reclutamiento): ' . $schemaInitError);
|
|
}
|
|
|
|
if (isset($_GET['success']) && $_GET['success'] === '1') {
|
|
$notice = 'Postulante guardado correctamente.';
|
|
$noticeType = 'success';
|
|
}
|
|
if (isset($_GET['estado_updated']) && $_GET['estado_updated'] === '1') {
|
|
$notice = 'Estado actualizado correctamente.';
|
|
$noticeType = 'success';
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$action = $_POST['action'] ?? '';
|
|
|
|
if ($action === 'add_reclutamiento') {
|
|
try {
|
|
$fecha_registro = $_POST['fecha_registro'] ?? date('Y-m-d');
|
|
$nombre_completo = trim((string)($_POST['nombre_completo'] ?? ''));
|
|
$dni = trim((string)($_POST['dni'] ?? ''));
|
|
$celular = trim((string)($_POST['celular'] ?? ''));
|
|
$correo = trim((string)($_POST['correo'] ?? ''));
|
|
// Truncamos para evitar errores de longitud en BD (cuando el campo no es obligatorio).
|
|
$dni = $dni === '' ? '' : substr($dni, 0, 20);
|
|
$correo = $correo === '' ? '' : substr($correo, 0, 255);
|
|
$ciudad = trim((string)($_POST['ciudad'] ?? ''));
|
|
$puesto_postulado = trim((string)($_POST['puesto_postulado'] ?? ''));
|
|
$estado = (string)($_POST['estado'] ?? 'Postulación Recibida');
|
|
$observaciones = trim((string)($_POST['observaciones'] ?? ''));
|
|
|
|
// Indicadores (opcionales)
|
|
$edad_hijos_estudia_trabaja = trim((string)($_POST['edad_hijos_estudia_trabaja'] ?? ''));
|
|
if ($edad_hijos_estudia_trabaja === '') {
|
|
$edad_hijos_estudia_trabaja = null;
|
|
}
|
|
|
|
// Indicadores (opcionales) - se guardan como LETRAS (A/B/C...).
|
|
$organizacion_personal = strtoupper(trim((string)($_POST['organizacion_personal'] ?? '')));
|
|
$claridad_expresarse = strtoupper(trim((string)($_POST['claridad_expresarse'] ?? '')));
|
|
$manejo_objeciones = strtoupper(trim((string)($_POST['manejo_objeciones'] ?? '')));
|
|
$experiencia_otros_trabajos = strtoupper(trim((string)($_POST['experiencia_otros_trabajos'] ?? '')));
|
|
$experiencia_relevante_ventas = strtoupper(trim((string)($_POST['experiencia_relevante_ventas'] ?? '')));
|
|
$empatia_trato = strtoupper(trim((string)($_POST['empatia_trato'] ?? '')));
|
|
|
|
$organizacion_personal = $organizacion_personal === '' ? null : substr($organizacion_personal, 0, 50);
|
|
$claridad_expresarse = $claridad_expresarse === '' ? null : substr($claridad_expresarse, 0, 50);
|
|
$manejo_objeciones = $manejo_objeciones === '' ? null : substr($manejo_objeciones, 0, 50);
|
|
$experiencia_otros_trabajos = $experiencia_otros_trabajos === '' ? null : substr($experiencia_otros_trabajos, 0, 50);
|
|
$experiencia_relevante_ventas = $experiencia_relevante_ventas === '' ? null : substr($experiencia_relevante_ventas, 0, 50);
|
|
$empatia_trato = $empatia_trato === '' ? null : substr($empatia_trato, 0, 50);
|
|
|
|
if ($nombre_completo === '' || $celular === '' || $ciudad === '' || $puesto_postulado === '') {
|
|
throw new RuntimeException('Faltan campos obligatorios.');
|
|
}
|
|
if ($correo !== '' && !filter_var($correo, FILTER_VALIDATE_EMAIL)) {
|
|
throw new RuntimeException('Correo inválido.');
|
|
}
|
|
if (!in_array($estado, $estadosValidos, true)) {
|
|
throw new RuntimeException('Estado inválido.');
|
|
}
|
|
|
|
$cvPdfFile = $_FILES['cv_pdf'] ?? null;
|
|
if (!$cvPdfFile || ($cvPdfFile['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
|
|
throw new RuntimeException('El CV (PDF) es obligatorio.');
|
|
}
|
|
|
|
$cvUploadDirAbs = __DIR__ . '/assets/uploads/hr/reclutamiento/cv/';
|
|
$cv_pdf_path = hr_move_uploaded_file($cvPdfFile, $cvUploadDirAbs, ['pdf']);
|
|
|
|
$portafolio_path = null;
|
|
$portFile = $_FILES['portafolio'] ?? null;
|
|
if ($portFile && !empty($portFile['name']) && ($portFile['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_OK) {
|
|
$portUploadDirAbs = __DIR__ . '/assets/uploads/hr/reclutamiento/portafolio/';
|
|
// Portafolio opcional: permitimos PDF o documentos comunes.
|
|
$portafolio_path = hr_move_uploaded_file($portFile, $portUploadDirAbs, ['pdf', 'doc', 'docx']);
|
|
}
|
|
|
|
$stmt = $pdo->prepare('INSERT INTO hr_reclutamiento (fecha_registro, edad_hijos_estudia_trabaja, organizacion_personal, claridad_expresarse, manejo_objeciones, experiencia_otros_trabajos, experiencia_relevante_ventas, empatia_trato, nombre_completo, dni, celular, correo, ciudad, puesto_postulado, estado, observaciones, cv_pdf_path, portafolio_path) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
|
|
$stmt->execute([
|
|
$fecha_registro,
|
|
$edad_hijos_estudia_trabaja,
|
|
$organizacion_personal,
|
|
$claridad_expresarse,
|
|
$manejo_objeciones,
|
|
$experiencia_otros_trabajos,
|
|
$experiencia_relevante_ventas,
|
|
$empatia_trato,
|
|
$nombre_completo,
|
|
$dni,
|
|
$celular,
|
|
$correo,
|
|
$ciudad,
|
|
$puesto_postulado,
|
|
$estado,
|
|
$observaciones,
|
|
$cv_pdf_path,
|
|
$portafolio_path,
|
|
]);
|
|
|
|
header('Location: hr_reclutamiento.php?success=1');
|
|
exit;
|
|
} catch (Throwable $e) {
|
|
$notice = 'No se pudo guardar el postulante: ' . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8');
|
|
$noticeType = 'danger';
|
|
}
|
|
}
|
|
|
|
if ($action === 'update_reclutamiento_estado') {
|
|
try {
|
|
$id = (int)($_POST['id'] ?? 0);
|
|
$nuevoEstado = (string)($_POST['estado'] ?? '');
|
|
|
|
if ($id <= 0) {
|
|
throw new RuntimeException('ID inválido.');
|
|
}
|
|
if (!in_array($nuevoEstado, $estadosValidos, true)) {
|
|
throw new RuntimeException('Estado inválido.');
|
|
}
|
|
|
|
$stmt = $pdo->prepare('UPDATE hr_reclutamiento SET estado = ? WHERE id = ?');
|
|
$stmt->execute([$nuevoEstado, $id]);
|
|
|
|
header('Location: hr_reclutamiento.php?estado_updated=1');
|
|
exit;
|
|
} catch (Throwable $e) {
|
|
$notice = 'No se pudo actualizar el estado.';
|
|
$noticeType = 'danger';
|
|
}
|
|
}
|
|
}
|
|
|
|
// --- Filtros ---
|
|
$filter_puesto = trim((string)($_GET['puesto'] ?? ''));
|
|
$filter_estado = (string)($_GET['estado'] ?? 'Todos');
|
|
$fecha_desde = trim((string)($_GET['fecha_desde'] ?? ''));
|
|
$fecha_hasta = trim((string)($_GET['fecha_hasta'] ?? ''));
|
|
|
|
if ($filter_estado !== 'Todos' && !in_array($filter_estado, $estadosValidos, true)) {
|
|
$filter_estado = 'Todos';
|
|
}
|
|
|
|
$where = [];
|
|
$params = [];
|
|
|
|
if ($filter_puesto !== '') {
|
|
$where[] = 'puesto_postulado LIKE ?';
|
|
$params[] = '%' . $filter_puesto . '%';
|
|
}
|
|
if ($filter_estado !== 'Todos') {
|
|
$where[] = 'estado = ?';
|
|
$params[] = $filter_estado;
|
|
}
|
|
if ($fecha_desde !== '') {
|
|
$where[] = 'fecha_registro >= ?';
|
|
$params[] = $fecha_desde;
|
|
}
|
|
if ($fecha_hasta !== '') {
|
|
$where[] = 'fecha_registro <= ?';
|
|
$params[] = $fecha_hasta;
|
|
}
|
|
|
|
$sql = 'SELECT id, fecha_registro, edad_hijos_estudia_trabaja, organizacion_personal, claridad_expresarse, manejo_objeciones, experiencia_otros_trabajos, experiencia_relevante_ventas, empatia_trato, nombre_completo, dni, celular, correo, ciudad, puesto_postulado, estado, observaciones, cv_pdf_path, portafolio_path FROM hr_reclutamiento';
|
|
if (!empty($where)) {
|
|
$sql .= ' WHERE ' . implode(' AND ', $where);
|
|
}
|
|
$sql .= ' ORDER BY fecha_registro DESC, id DESC';
|
|
|
|
$candidatos = [];
|
|
try {
|
|
$stmt = $pdo->prepare($sql);
|
|
$stmt->execute($params);
|
|
$candidatos = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
} catch (PDOException $e) {
|
|
error_log('HR Reclutamiento DB error: ' . $e->getMessage());
|
|
$notice = 'No se pudo cargar la lista de postulantes.';
|
|
$noticeType = 'danger';
|
|
}
|
|
|
|
$fechaHoy = date('Y-m-d');
|
|
|
|
include 'layout_header.php';
|
|
?>
|
|
|
|
<div class="container-fluid mt-4">
|
|
<?php if ($notice): ?>
|
|
<div class="alert alert-<?= htmlspecialchars($noticeType, ENT_QUOTES, 'UTF-8'); ?> mb-4" role="alert">
|
|
<?= $notice; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="row g-4">
|
|
<!-- NUEVO POSTULANTE (arriba, ancho completo) -->
|
|
<div class="col-12">
|
|
<div class="card shadow-sm mb-2">
|
|
<div class="card-header bg-light">
|
|
<h2 class="h5 mb-0">Nuevo Postulante</h2>
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="POST" enctype="multipart/form-data">
|
|
<input type="hidden" name="action" value="add_reclutamiento">
|
|
|
|
<div class="row g-3">
|
|
<div class="col-lg-2 col-md-3">
|
|
<label class="form-label">Fecha de Registro</label>
|
|
<input type="date" name="fecha_registro" class="form-control" value="<?= htmlspecialchars($fechaHoy, ENT_QUOTES, 'UTF-8'); ?>" required>
|
|
</div>
|
|
|
|
<div class="col-lg-4 col-md-6">
|
|
<label class="form-label">Edad, Hijos/Estudia Trabaja</label>
|
|
<input type="text" name="edad_hijos_estudia_trabaja" class="form-control" placeholder="Ej: 28 años, 1 hijo, trabaja" >
|
|
</div>
|
|
|
|
<div class="col-lg-2 col-md-3">
|
|
<label class="form-label">OCUPACION</label>
|
|
<input type="text" name="organizacion_personal" class="form-control" maxlength="50" placeholder="Ej: CARRERA/ESTUDIANTE" >
|
|
</div>
|
|
|
|
<div class="col-lg-2 col-md-3">
|
|
<label class="form-label">Estado</label>
|
|
<select name="estado" class="form-select" required>
|
|
<?php foreach ($estadosValidos as $e): ?>
|
|
<option value="<?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8'); ?>" <?= $e === 'Postulación Recibida' ? 'selected' : ''; ?>>
|
|
<?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8'); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-3 mt-1">
|
|
<div class="col-lg-2 col-md-4">
|
|
<label class="form-label">Claridad en Expresarse</label>
|
|
<input type="text" name="claridad_expresarse" class="form-control" maxlength="50" placeholder="Ej: A/B/C" >
|
|
</div>
|
|
|
|
<div class="col-lg-2 col-md-4">
|
|
<label class="form-label">Manejo de Objeciones</label>
|
|
<input type="text" name="manejo_objeciones" class="form-control" maxlength="50" placeholder="Ej: A/B/C" >
|
|
</div>
|
|
|
|
<div class="col-lg-2 col-md-4">
|
|
<label class="form-label">EXPERIENCIA LABORAL</label>
|
|
<input type="text" name="experiencia_otros_trabajos" class="form-control" maxlength="50" placeholder="Ej: VENTAS" >
|
|
</div>
|
|
|
|
<div class="col-lg-3 col-md-6">
|
|
<label class="form-label">RESPONSABILIDAD/COMPROMISO</label>
|
|
<input type="text" name="experiencia_relevante_ventas" class="form-control" maxlength="50" placeholder="Ej: ORGANIZACION" >
|
|
</div>
|
|
|
|
<div class="col-lg-3 col-md-6">
|
|
<label class="form-label">DISPONIBILIDAD INMEDIATA</label>
|
|
<input type="text" name="empatia_trato" class="form-control" maxlength="50" placeholder="Ej: EQUIPOS/INMEDIATES" >
|
|
</div>
|
|
</div>
|
|
|
|
<hr class="my-4">
|
|
|
|
<div class="row g-3">
|
|
<div class="col-lg-4 col-md-6">
|
|
<label class="form-label">Nombre Completo</label>
|
|
<input type="text" name="nombre_completo" class="form-control" required>
|
|
</div>
|
|
|
|
<div class="col-lg-2 col-md-3">
|
|
<label class="form-label">DNI (Opcional)</label>
|
|
<input type="text" name="dni" class="form-control" maxlength="20" placeholder="Opcional">
|
|
</div>
|
|
|
|
<div class="col-lg-3 col-md-6">
|
|
<label class="form-label">Celular</label>
|
|
<input type="text" name="celular" class="form-control" required>
|
|
</div>
|
|
|
|
<div class="col-lg-3 col-md-6">
|
|
<label class="form-label">Correo (Opcional)</label>
|
|
<input type="email" name="correo" class="form-control" maxlength="255" placeholder="tu@email.com">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-3">
|
|
<div class="col-lg-4 col-md-6">
|
|
<label class="form-label">Ciudad</label>
|
|
<input type="text" name="ciudad" class="form-control" required>
|
|
</div>
|
|
|
|
<div class="col-lg-4 col-md-6">
|
|
<label class="form-label">Puesto Postulado</label>
|
|
<input type="text" name="puesto_postulado" class="form-control" required>
|
|
</div>
|
|
|
|
<div class="col-lg-4 col-md-12">
|
|
<label class="form-label">CV (PDF)</label>
|
|
<input type="file" name="cv_pdf" class="form-control" accept="application/pdf" required>
|
|
<div class="form-text">Sube el PDF del CV.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-3">
|
|
<div class="col-lg-6 col-md-12">
|
|
<label class="form-label">Portafolio (Opcional)</label>
|
|
<input type="file" name="portafolio" class="form-control" accept="application/pdf,.doc,.docx">
|
|
<div class="form-text">PDF o documento Word (si aplica).</div>
|
|
</div>
|
|
|
|
<div class="col-lg-6 col-md-12">
|
|
<label class="form-label">Observaciones</label>
|
|
<textarea name="observaciones" class="form-control" rows="3"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-primary w-100 mt-3">
|
|
<i class="fas fa-save me-1"></i> Guardar
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- FILTROS + TABLA (ancho completo) -->
|
|
<div class="col-12">
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-header bg-light d-flex justify-content-between align-items-center">
|
|
<h2 class="h5 mb-0">Postulantes</h2>
|
|
<span class="badge bg-secondary">Total: <?= count($candidatos); ?></span>
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="GET" class="row g-2 align-items-end">
|
|
<div class="col-sm-5">
|
|
<label class="form-label">Puesto</label>
|
|
<input type="text" name="puesto" class="form-control" placeholder="Ej: Ventas" value="<?= htmlspecialchars($filter_puesto, ENT_QUOTES, 'UTF-8'); ?>">
|
|
</div>
|
|
<div class="col-sm-3">
|
|
<label class="form-label">Estado</label>
|
|
<select name="estado" class="form-select">
|
|
<option value="Todos">Todos</option>
|
|
<?php foreach ($estadosValidos as $e): ?>
|
|
<option value="<?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8'); ?>" <?= $filter_estado === $e ? 'selected' : ''; ?>>
|
|
<?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8'); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
<div class="col-sm-2">
|
|
<label class="form-label">Desde</label>
|
|
<input type="date" name="fecha_desde" class="form-control" value="<?= htmlspecialchars($fecha_desde, ENT_QUOTES, 'UTF-8'); ?>">
|
|
</div>
|
|
<div class="col-sm-2">
|
|
<label class="form-label">Hasta</label>
|
|
<input type="date" name="fecha_hasta" class="form-control" value="<?= htmlspecialchars($fecha_hasta, ENT_QUOTES, 'UTF-8'); ?>">
|
|
</div>
|
|
<div class="col-12 d-flex justify-content-end gap-2 mt-2">
|
|
<a class="btn btn-outline-secondary" href="hr_reclutamiento.php">Limpiar</a>
|
|
<button class="btn btn-primary" type="submit">
|
|
<i class="fas fa-filter me-1"></i> Filtrar
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="table-responsive">
|
|
<table class="table table-bordered table-striped align-middle">
|
|
<thead class="table-light">
|
|
<tr>
|
|
<th>ID</th>
|
|
<th>Fecha Registro</th>
|
|
<th>Edad, Hijos/Estudia Trabaja</th>
|
|
<th>OCUPACION</th>
|
|
<th>Claridad en Expresarse</th>
|
|
<th>Manejo de Objeciones</th>
|
|
<th>EXPERIENCIA LABORAL</th>
|
|
<th>RESPONSABILIDAD/COMPROMISO</th>
|
|
<th>DISPONIBILIDAD INMEDIATA</th>
|
|
<th>Nombre Completo</th>
|
|
<th>DNI</th>
|
|
<th>Celular</th>
|
|
<th>Correo</th>
|
|
<th>Ciudad</th>
|
|
<th>Puesto</th>
|
|
<th>Estado</th>
|
|
<th>CV</th>
|
|
<th>Portafolio</th>
|
|
<th>Observaciones</th>
|
|
<th>Acciones</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php if (empty($candidatos)): ?>
|
|
<tr>
|
|
<td colspan="20" class="text-center py-4 text-muted">No hay postulantes para los filtros seleccionados.</td>
|
|
</tr>
|
|
<?php else: ?>
|
|
<?php foreach ($candidatos as $c): ?>
|
|
<tr>
|
|
<td><?= (int)$c['id']; ?></td>
|
|
<td><?= htmlspecialchars($c['fecha_registro'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
|
|
|
|
<td>
|
|
<?php $edad = $c['edad_hijos_estudia_trabaja'] ?? null; ?>
|
|
<?php if ($edad === null || $edad === ''): ?>
|
|
<span class="text-muted">—</span>
|
|
<?php else: ?>
|
|
<div style="white-space: pre-wrap; word-break: break-word; max-width: 240px;"><?= htmlspecialchars($edad, ENT_QUOTES, 'UTF-8'); ?></div>
|
|
<?php endif; ?>
|
|
</td>
|
|
|
|
<td>
|
|
<?php $v = $c['organizacion_personal'] ?? null; ?>
|
|
<?php if ($v === null || $v === ''): ?>
|
|
<span class="text-muted">—</span>
|
|
<?php else: ?>
|
|
<span class="badge bg-primary text-white"><?= htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); ?></span>
|
|
<?php endif; ?>
|
|
</td>
|
|
|
|
<td>
|
|
<?php $v = $c['claridad_expresarse'] ?? null; ?>
|
|
<?php if ($v === null || $v === ''): ?>
|
|
<span class="text-muted">—</span>
|
|
<?php else: ?>
|
|
<span class="badge bg-primary text-white"><?= htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); ?></span>
|
|
<?php endif; ?>
|
|
</td>
|
|
|
|
<td>
|
|
<?php $v = $c['manejo_objeciones'] ?? null; ?>
|
|
<?php if ($v === null || $v === ''): ?>
|
|
<span class="text-muted">—</span>
|
|
<?php else: ?>
|
|
<span class="badge bg-primary text-white"><?= htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); ?></span>
|
|
<?php endif; ?>
|
|
</td>
|
|
|
|
<td>
|
|
<?php $v = $c['experiencia_otros_trabajos'] ?? null; ?>
|
|
<?php if ($v === null || $v === ''): ?>
|
|
<span class="text-muted">—</span>
|
|
<?php else: ?>
|
|
<span class="badge bg-primary text-white"><?= htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); ?></span>
|
|
<?php endif; ?>
|
|
</td>
|
|
|
|
<td>
|
|
<?php $v = $c['experiencia_relevante_ventas'] ?? null; ?>
|
|
<?php if ($v === null || $v === ''): ?>
|
|
<span class="text-muted">—</span>
|
|
<?php else: ?>
|
|
<span class="badge bg-primary text-white"><?= htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); ?></span>
|
|
<?php endif; ?>
|
|
</td>
|
|
|
|
<td>
|
|
<?php $v = $c['empatia_trato'] ?? null; ?>
|
|
<?php if ($v === null || $v === ''): ?>
|
|
<span class="text-muted">—</span>
|
|
<?php else: ?>
|
|
<span class="badge bg-primary text-white"><?= htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); ?></span>
|
|
<?php endif; ?>
|
|
</td>
|
|
|
|
<td><?= htmlspecialchars($c['nombre_completo'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
|
|
<td><?= htmlspecialchars($c['dni'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
|
|
<td><?= htmlspecialchars($c['celular'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
|
|
<td><?= htmlspecialchars($c['correo'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
|
|
<td><?= htmlspecialchars($c['ciudad'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
|
|
<td><?= htmlspecialchars($c['puesto_postulado'] ?? '', ENT_QUOTES, 'UTF-8'); ?></td>
|
|
|
|
<td>
|
|
<span class="badge bg-info text-dark"><?= htmlspecialchars($c['estado'] ?? '', ENT_QUOTES, 'UTF-8'); ?></span>
|
|
</td>
|
|
|
|
<td>
|
|
<?php if (!empty($c['cv_pdf_path'])): ?>
|
|
<a href="<?= htmlspecialchars($c['cv_pdf_path'], ENT_QUOTES, 'UTF-8'); ?>" download class="btn btn-sm btn-outline-primary">
|
|
<i class="fas fa-file-pdf"></i>
|
|
</a>
|
|
<?php else: ?>
|
|
<span class="text-muted">—</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
|
|
<td>
|
|
<?php if (!empty($c['portafolio_path'])): ?>
|
|
<a href="<?= htmlspecialchars($c['portafolio_path'], ENT_QUOTES, 'UTF-8'); ?>" download class="btn btn-sm btn-outline-secondary">
|
|
<i class="fas fa-file"></i>
|
|
</a>
|
|
<?php else: ?>
|
|
<span class="text-muted">—</span>
|
|
<?php endif; ?>
|
|
</td>
|
|
|
|
<td style="max-width: 220px;">
|
|
<div style="white-space: pre-wrap;"><?= htmlspecialchars($c['observaciones'] ?? '', ENT_QUOTES, 'UTF-8'); ?></div>
|
|
</td>
|
|
|
|
<td>
|
|
<form method="POST" class="d-flex flex-column gap-1">
|
|
<input type="hidden" name="action" value="update_reclutamiento_estado">
|
|
<input type="hidden" name="id" value="<?= (int)$c['id']; ?>">
|
|
<select name="estado" class="form-select form-select-sm">
|
|
<?php foreach ($estadosValidos as $e): ?>
|
|
<option value="<?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8'); ?>" <?= ($c['estado'] ?? '') === $e ? 'selected' : ''; ?>>
|
|
<?= htmlspecialchars($e, ENT_QUOTES, 'UTF-8'); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<button type="submit" class="btn btn-sm btn-success">
|
|
<i class="fas fa-save me-1"></i> Guardar
|
|
</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php include 'layout_footer.php'; ?>
|