Spaces:
Running
Running
Tengo una interfaz ya creada con menú lateral. Quiero reemplazar las secciones “Vacantes” y “Candidatos” por una única sección llamada “ATS” y rediseñar completamente la vista asociada. 🧱 Vista general del ATS Mostrar un listado de vacantes creadas por el usuario. Cada vacante debe tener un estado: Activa, Pausada o Finalizada. Deben poder eliminarse. Incluir un botón para crear nuevas vacantes. ➕ Creación de nueva vacante Al hacer clic en “Crear nueva vacante”, se debe mostrar un formulario con los siguientes campos: 📝 Campos del formulario: Título del puesto (obligatorio) Requisitos deseables (texto largo) Requisitos excluyentes (texto largo) Remuneración nominal (campo numérico) Mostrar nota aclaratoria: “Este valor no será visible para los postulantes, pero nos permite generar una mejor estimación del perfil. Es importante que completes este campo aunque no publiques el sueldo.” Descripción del puesto (texto largo editable) Incluir botón: “Generar descripción con IA” que autocompleta según los requisitos ingresados. ✅ Al enviar el formulario: La vacante se guarda y aparece en el listado del ATS. Se genera automáticamente un formulario interno personalizado para que los postulantes se inscriban (similar a Google Forms o Typeform). Mostrar al usuario el link del formulario con dos opciones: 🔗 Postulación a través del formulario ✅ Opción A: Publicar en portales externos El usuario copia la vacante y la pega en sitios como LinkedIn, Computrabajo, etc. Pega el link del formulario generado en el campo “Postularse aquí”. 🔄 Opción B: Ya tiene una vacante publicada Selecciona “La vacante ya está publicada”. Pega el link de la publicación existente. El sistema igualmente genera el link del formulario interno para postulación. 🎨 Estilo del formulario: Simple, ordenado y claro. Mostrar ayudas contextuales. Validar campos obligatorios con mensajes amigables. 🧩 Visualización del proceso por nodos Al hacer clic en una vacante activa, se abre un workflow visual que representa las etapas del proceso de selección mediante nodos fijos. El usuario puede duplicar estos nodos la cantidad de veces que quiera. Estructura de los nodos: Los nodos tienen una función interna fija (para lógica y automatización), pero su nombre visible puede editarse. Cada nodo tiene un campo de fecha estimada de realización y un campo de comentarios. Nodos sugeridos: postulantes preseleccionados entrevista finalistas oferta descartados standby 👤 Gestión de postulantes Cada candidato muestra: Nombre Puntaje IA del 1 al 10 Etapa actual Botón para ver resumen de CV generado por IA (fortalezas, debilidades, conclusión) Los candidatos pueden moverse entre nodos fácilmente (drag & drop o menú rápido). ✉️ Emails automáticos con IA Cada nodo tiene un botón “Enviar email”. El sistema genera un email sugerido por IA, personalizado según el tipo de nodo (ej. entrevista, rechazo, oferta, etc.). El contenido puede ser editado por el usuario antes de enviarlo. Incluir datos dinámicos como nombre del candidato, nombre de vacante y fecha pactada. 🎨 Estilo visual general Diseño moderno, limpio y minimalista. Tipografía legible, colores neutros con acentos suaves. Mantener consistencia visual con el resto del sistema. Compatible con escritorio y pantallas medianas. Workflow visual claro con jerarquía definida e iconografía sutil para representar estado y acciones. - Follow Up Deployment
ab534c0 verified Download index.html from Nicolasvila/m: direct link, hf CLI and curl.
- Browser
- Download file 52.5 kB
-
https://huggingface.co/spaces/Nicolasvila/m/resolve/main/index.html
- Command line
-
hf download hf://spaces/Nicolasvila/m/index.html
-
curl -L -o index.html https://huggingface.co/spaces/Nicolasvila/m/resolve/main/index.html
52.5 kB
| <html lang="es"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>ATS - Sistema de Seguimiento de Candidatos</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| .sidebar { | |
| transition: all 0.3s ease; | |
| } | |
| .node { | |
| transition: all 0.2s ease; | |
| } | |
| .node:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); | |
| } | |
| .candidate-card { | |
| transition: all 0.2s ease; | |
| } | |
| .candidate-card:hover { | |
| transform: translateX(2px); | |
| } | |
| .form-control:focus { | |
| box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5); | |
| } | |
| .workflow-column { | |
| min-height: 500px; | |
| } | |
| .drag-over { | |
| background-color: rgba(59, 130, 246, 0.1); | |
| border: 2px dashed #3b82f6; | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-gray-50 font-sans"> | |
| <div class="flex h-screen overflow-hidden"> | |
| <!-- Sidebar --> | |
| <div class="sidebar bg-indigo-800 text-white w-64 flex-shrink-0"> | |
| <div class="p-4 border-b border-indigo-700"> | |
| <h1 class="text-xl font-bold">RecruitingPro</h1> | |
| </div> | |
| <nav class="p-4"> | |
| <ul> | |
| <li class="mb-2"> | |
| <a href="#" class="block py-2 px-4 rounded hover:bg-indigo-700 transition"> | |
| <i class="fas fa-home mr-2"></i> Dashboard | |
| </a> | |
| </li> | |
| <li class="mb-2"> | |
| <a href="#" class="block py-2 px-4 rounded bg-indigo-900 transition"> | |
| <i class="fas fa-tasks mr-2"></i> ATS | |
| </a> | |
| </li> | |
| <li class="mb-2"> | |
| <a href="#" class="block py-2 px-4 rounded hover:bg-indigo-700 transition"> | |
| <i class="fas fa-envelope mr-2"></i> Mensajes | |
| </a> | |
| </li> | |
| <li class="mb-2"> | |
| <a href="#" class="block py-2 px-4 rounded hover:bg-indigo-700 transition"> | |
| <i class="fas fa-chart-bar mr-2"></i> Reportes | |
| </a> | |
| </li> | |
| <li class="mb-2"> | |
| <a href="#" class="block py-2 px-4 rounded hover:bg-indigo-700 transition"> | |
| <i class="fas fa-cog mr-2"></i> Configuración | |
| </a> | |
| </li> | |
| </ul> | |
| </nav> | |
| </div> | |
| <!-- Main Content --> | |
| <div class="flex-1 overflow-auto"> | |
| <!-- Header --> | |
| <header class="bg-white shadow-sm p-4 flex justify-between items-center"> | |
| <h2 class="text-xl font-semibold text-gray-800">Sistema de Seguimiento de Candidatos (ATS)</h2> | |
| <div class="flex items-center space-x-4"> | |
| <div class="relative"> | |
| <input type="text" placeholder="Buscar..." class="pl-10 pr-4 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
| <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i> | |
| </div> | |
| <div class="flex items-center"> | |
| <img src="https://randomuser.me/api/portraits/women/44.jpg" alt="Profile" class="w-8 h-8 rounded-full"> | |
| <span class="ml-2 text-sm font-medium">Ana Pérez</span> | |
| </div> | |
| </div> | |
| </header> | |
| <!-- Main Content Area --> | |
| <main class="p-6"> | |
| <!-- ATS Dashboard --> | |
| <div id="atsDashboard"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h3 class="text-lg font-semibold text-gray-800">Mis Vacantes</h3> | |
| <button id="createVacancyBtn" class="bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-lg flex items-center"> | |
| <i class="fas fa-plus mr-2"></i> Crear nueva vacante | |
| </button> | |
| </div> | |
| <!-- Vacancy Status Tabs --> | |
| <div class="mb-6"> | |
| <div class="flex border-b"> | |
| <button class="vacancy-tab active px-4 py-2 font-medium text-indigo-600 border-b-2 border-indigo-600">Activas</button> | |
| <button class="vacancy-tab px-4 py-2 font-medium text-gray-500 hover:text-gray-700">Pausadas</button> | |
| <button class="vacancy-tab px-4 py-2 font-medium text-gray-500 hover:text-gray-700">Finalizadas</button> | |
| </div> | |
| </div> | |
| <!-- Vacancies List --> | |
| <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> | |
| <!-- Vacancy Card 1 --> | |
| <div class="bg-white rounded-lg shadow overflow-hidden border border-gray-200"> | |
| <div class="p-4"> | |
| <div class="flex justify-between items-start"> | |
| <div> | |
| <h4 class="font-semibold text-lg">Desarrollador Frontend React</h4> | |
| <span class="inline-block px-2 py-1 text-xs font-semibold rounded-full bg-green-100 text-green-800 mt-1">Activa</span> | |
| </div> | |
| <div class="dropdown relative"> | |
| <button class="text-gray-400 hover:text-gray-600"> | |
| <i class="fas fa-ellipsis-v"></i> | |
| </button> | |
| <div class="dropdown-menu absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg z-10 hidden"> | |
| <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Editar</a> | |
| <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Pausar</a> | |
| <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Finalizar</a> | |
| <a href="#" class="block px-4 py-2 text-sm text-red-600 hover:bg-gray-100">Eliminar</a> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <div class="flex items-center text-sm text-gray-600 mb-1"> | |
| <i class="fas fa-dollar-sign mr-2"></i> | |
| <span>Remuneración: $1,800 - $2,200</span> | |
| </div> | |
| <div class="flex items-center text-sm text-gray-600 mb-1"> | |
| <i class="fas fa-users mr-2"></i> | |
| <span>12 candidatos en proceso</span> | |
| </div> | |
| <div class="flex items-center text-sm text-gray-600"> | |
| <i class="fas fa-calendar-alt mr-2"></i> | |
| <span>Creada: 15/06/2023</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-50 px-4 py-3 flex justify-between items-center border-t"> | |
| <a href="#" class="text-indigo-600 hover:text-indigo-800 text-sm font-medium view-workflow" data-vacancy-id="1"> | |
| Ver workflow | |
| </a> | |
| <a href="#" class="text-gray-600 hover:text-gray-800 text-sm"> | |
| <i class="fas fa-external-link-alt mr-1"></i> Formulario | |
| </a> | |
| </div> | |
| </div> | |
| <!-- Vacancy Card 2 --> | |
| <div class="bg-white rounded-lg shadow overflow-hidden border border-gray-200"> | |
| <div class="p-4"> | |
| <div class="flex justify-between items-start"> | |
| <div> | |
| <h4 class="font-semibold text-lg">Diseñador UX/UI Senior</h4> | |
| <span class="inline-block px-2 py-1 text-xs font-semibold rounded-full bg-yellow-100 text-yellow-800 mt-1">Pausada</span> | |
| </div> | |
| <div class="dropdown relative"> | |
| <button class="text-gray-400 hover:text-gray-600"> | |
| <i class="fas fa-ellipsis-v"></i> | |
| </button> | |
| <div class="dropdown-menu absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg z-10 hidden"> | |
| <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Editar</a> | |
| <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Reactivar</a> | |
| <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Finalizar</a> | |
| <a href="#" class="block px-4 py-2 text-sm text-red-600 hover:bg-gray-100">Eliminar</a> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <div class="flex items-center text-sm text-gray-600 mb-1"> | |
| <i class="fas fa-dollar-sign mr-2"></i> | |
| <span>Remuneración: $2,000 - $2,500</span> | |
| </div> | |
| <div class="flex items-center text-sm text-gray-600 mb-1"> | |
| <i class="fas fa-users mr-2"></i> | |
| <span>8 candidatos en proceso</span> | |
| </div> | |
| <div class="flex items-center text-sm text-gray-600"> | |
| <i class="fas fa-calendar-alt mr-2"></i> | |
| <span>Creada: 05/06/2023</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-50 px-4 py-3 flex justify-between items-center border-t"> | |
| <a href="#" class="text-indigo-600 hover:text-indigo-800 text-sm font-medium view-workflow" data-vacancy-id="2"> | |
| Ver workflow | |
| </a> | |
| <a href="#" class="text-gray-600 hover:text-gray-800 text-sm"> | |
| <i class="fas fa-external-link-alt mr-1"></i> Formulario | |
| </a> | |
| </div> | |
| </div> | |
| <!-- Vacancy Card 3 --> | |
| <div class="bg-white rounded-lg shadow overflow-hidden border border-gray-200"> | |
| <div class="p-4"> | |
| <div class="flex justify-between items-start"> | |
| <div> | |
| <h4 class="font-semibold text-lg">Gerente de Marketing Digital</h4> | |
| <span class="inline-block px-2 py-1 text-xs font-semibold rounded-full bg-blue-100 text-blue-800 mt-1">Finalizada</span> | |
| </div> | |
| <div class="dropdown relative"> | |
| <button class="text-gray-400 hover:text-gray-600"> | |
| <i class="fas fa-ellipsis-v"></i> | |
| </button> | |
| <div class="dropdown-menu absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg z-10 hidden"> | |
| <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Ver historial</a> | |
| <a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Reabrir</a> | |
| <a href="#" class="block px-4 py-2 text-sm text-red-600 hover:bg-gray-100">Eliminar</a> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <div class="flex items-center text-sm text-gray-600 mb-1"> | |
| <i class="fas fa-dollar-sign mr-2"></i> | |
| <span>Remuneración: $3,000 - $3,500</span> | |
| </div> | |
| <div class="flex items-center text-sm text-gray-600 mb-1"> | |
| <i class="fas fa-users mr-2"></i> | |
| <span>5 candidatos contratados</span> | |
| </div> | |
| <div class="flex items-center text-sm text-gray-600"> | |
| <i class="fas fa-calendar-alt mr-2"></i> | |
| <span>Finalizada: 10/06/2023</span> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-gray-50 px-4 py-3 flex justify-between items-center border-t"> | |
| <a href="#" class="text-indigo-600 hover:text-indigo-800 text-sm font-medium view-workflow" data-vacancy-id="3"> | |
| Ver historial | |
| </a> | |
| <a href="#" class="text-gray-600 hover:text-gray-800 text-sm"> | |
| <i class="fas fa-chart-bar mr-1"></i> Reporte | |
| </a> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Create Vacancy Form (Hidden by default) --> | |
| <div id="createVacancyForm" class="hidden bg-white rounded-lg shadow overflow-hidden p-6 max-w-3xl mx-auto"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <h3 class="text-xl font-semibold text-gray-800">Crear nueva vacante</h3> | |
| <button id="closeFormBtn" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <form id="vacancyForm"> | |
| <div class="mb-6"> | |
| <label for="jobTitle" class="block text-sm font-medium text-gray-700 mb-1">Título del puesto *</label> | |
| <input type="text" id="jobTitle" name="jobTitle" required class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
| <p class="mt-1 text-xs text-gray-500">Ejemplo: "Desarrollador Frontend React Senior"</p> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6"> | |
| <div> | |
| <label for="desirableRequirements" class="block text-sm font-medium text-gray-700 mb-1">Requisitos deseables</label> | |
| <textarea id="desirableRequirements" name="desirableRequirements" rows="4" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"></textarea> | |
| </div> | |
| <div> | |
| <label for="exclusiveRequirements" class="block text-sm font-medium text-gray-700 mb-1">Requisitos excluyentes</label> | |
| <textarea id="exclusiveRequirements" name="exclusiveRequirements" rows="4" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"></textarea> | |
| </div> | |
| </div> | |
| <div class="mb-6"> | |
| <label for="salary" class="block text-sm font-medium text-gray-700 mb-1">Remuneración nominal ($) *</label> | |
| <input type="number" id="salary" name="salary" required class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
| <p class="mt-1 text-xs text-gray-500 bg-blue-50 p-2 rounded">Este valor no será visible para los postulantes, pero nos permite generar una mejor estimación del perfil. Es importante que completes este campo aunque no publiques el sueldo.</p> | |
| </div> | |
| <div class="mb-6"> | |
| <label for="jobDescription" class="block text-sm font-medium text-gray-700 mb-1">Descripción del puesto *</label> | |
| <div class="flex justify-between items-center mb-2"> | |
| <span class="text-xs text-gray-500">Describe las responsabilidades y características del puesto</span> | |
| <button type="button" id="generateDescriptionBtn" class="text-xs bg-indigo-50 text-indigo-600 px-3 py-1 rounded hover:bg-indigo-100"> | |
| <i class="fas fa-magic mr-1"></i> Generar descripción con IA | |
| </button> | |
| </div> | |
| <textarea id="jobDescription" name="jobDescription" rows="6" required class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"></textarea> | |
| </div> | |
| <div class="flex justify-end space-x-3"> | |
| <button type="button" id="cancelFormBtn" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50"> | |
| Cancelar | |
| </button> | |
| <button type="submit" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
| Guardar y continuar | |
| </button> | |
| </div> | |
| </form> | |
| </div> | |
| <!-- Form Submission Options (Hidden by default) --> | |
| <div id="formOptions" class="hidden bg-white rounded-lg shadow overflow-hidden p-6 max-w-3xl mx-auto"> | |
| <div class="mb-6"> | |
| <div class="flex items-center justify-between mb-4"> | |
| <h3 class="text-xl font-semibold text-gray-800">¡Vacante creada exitosamente!</h3> | |
| <span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-green-100 text-green-800"> | |
| <i class="fas fa-check-circle mr-1"></i> Listo | |
| </span> | |
| </div> | |
| <p class="text-gray-600">Hemos generado automáticamente un formulario personalizado para que los postulantes se inscriban.</p> | |
| </div> | |
| <div class="mb-6"> | |
| <label class="block text-sm font-medium text-gray-700 mb-2">Link del formulario:</label> | |
| <div class="flex"> | |
| <input type="text" value="https://recruitingpro.com/form/desarrollador-frontend-react" readonly class="flex-1 px-3 py-2 border border-gray-300 rounded-l-md focus:outline-none bg-gray-50"> | |
| <button class="px-4 py-2 bg-indigo-600 text-white rounded-r-md hover:bg-indigo-700"> | |
| <i class="fas fa-copy"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6"> | |
| <div class="border border-gray-200 rounded-lg p-4 hover:border-indigo-300 transition"> | |
| <div class="flex items-start mb-3"> | |
| <div class="bg-indigo-100 p-2 rounded-full mr-3"> | |
| <i class="fas fa-external-link-alt text-indigo-600"></i> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800">Opción A: Publicar en portales externos</h4> | |
| <p class="text-sm text-gray-600 mt-1">Copia esta vacante y pégala en sitios como LinkedIn, Computrabajo, etc.</p> | |
| </div> | |
| </div> | |
| <div class="bg-gray-50 p-3 rounded text-sm"> | |
| <p class="font-medium mb-1">Instrucciones:</p> | |
| <ol class="list-decimal pl-5 space-y-1"> | |
| <li>Crea la publicación en el portal de empleo</li> | |
| <li>Pega el link del formulario en el campo "Postularse aquí"</li> | |
| <li>Publica la vacante</li> | |
| </ol> | |
| </div> | |
| </div> | |
| <div class="border border-gray-200 rounded-lg p-4 hover:border-indigo-300 transition"> | |
| <div class="flex items-start mb-3"> | |
| <div class="bg-indigo-100 p-2 rounded-full mr-3"> | |
| <i class="fas fa-link text-indigo-600"></i> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800">Opción B: Ya tiene una vacante publicada</h4> | |
| <p class="text-sm text-gray-600 mt-1">Si ya publicaste esta vacante en otro sitio.</p> | |
| </div> | |
| </div> | |
| <div class="mt-4"> | |
| <label class="block text-sm font-medium text-gray-700 mb-2">Link de la publicación existente:</label> | |
| <input type="url" placeholder="https://" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="flex justify-end"> | |
| <button id="finishBtn" class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500"> | |
| Finalizar y ver vacante | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Workflow View (Hidden by default) --> | |
| <div id="workflowView" class="hidden"> | |
| <div class="flex justify-between items-center mb-6"> | |
| <div> | |
| <h3 class="text-lg font-semibold text-gray-800">Workflow: Desarrollador Frontend React</h3> | |
| <p class="text-sm text-gray-600">Administra las etapas del proceso de selección</p> | |
| </div> | |
| <div class="flex space-x-3"> | |
| <button class="px-3 py-1 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 text-sm"> | |
| <i class="fas fa-cog mr-1"></i> Configurar | |
| </button> | |
| <button class="px-3 py-1 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 text-sm"> | |
| <i class="fas fa-plus mr-1"></i> Agregar etapa | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Workflow Columns --> | |
| <div class="grid grid-cols-1 md:grid-cols-5 gap-4"> | |
| <!-- Postulantes Column --> | |
| <div class="workflow-column bg-gray-50 rounded-lg p-4" data-stage="postulantes"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h4 class="font-medium text-gray-800 flex items-center"> | |
| <span class="w-4 h-4 bg-blue-500 rounded-full mr-2"></span> | |
| Postulantes | |
| </h4> | |
| <span class="bg-white text-xs font-medium px-2 py-1 rounded-full">14</span> | |
| </div> | |
| <div class="space-y-3 candidate-list"> | |
| <!-- Candidate Card 1 --> | |
| <div class="candidate-card bg-white rounded-lg shadow-sm p-3 border border-gray-200 cursor-move" draggable="true" data-candidate-id="1"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <h5 class="font-medium">Carlos Mendoza</h5> | |
| <span class="bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full">8.5</span> | |
| </div> | |
| <div class="flex items-center text-xs text-gray-500 mb-2"> | |
| <i class="fas fa-file-alt mr-1"></i> | |
| <span>CV recibido: 12/06</span> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <button class="text-indigo-600 hover:text-indigo-800 text-xs font-medium view-summary"> | |
| Ver resumen IA | |
| </button> | |
| <button class="text-gray-500 hover:text-gray-700 text-xs"> | |
| <i class="fas fa-envelope"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <!-- Candidate Card 2 --> | |
| <div class="candidate-card bg-white rounded-lg shadow-sm p-3 border border-gray-200 cursor-move" draggable="true" data-candidate-id="2"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <h5 class="font-medium">Laura González</h5> | |
| <span class="bg-yellow-100 text-yellow-800 text-xs px-2 py-1 rounded-full">7.2</span> | |
| </div> | |
| <div class="flex items-center text-xs text-gray-500 mb-2"> | |
| <i class="fas fa-file-alt mr-1"></i> | |
| <span>CV recibido: 10/06</span> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <button class="text-indigo-600 hover:text-indigo-800 text-xs font-medium view-summary"> | |
| Ver resumen IA | |
| </button> | |
| <button class="text-gray-500 hover:text-gray-700 text-xs"> | |
| <i class="fas fa-envelope"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Preseleccionados Column --> | |
| <div class="workflow-column bg-gray-50 rounded-lg p-4" data-stage="preseleccionados"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h4 class="font-medium text-gray-800 flex items-center"> | |
| <span class="w-4 h-4 bg-purple-500 rounded-full mr-2"></span> | |
| Preseleccionados | |
| </h4> | |
| <span class="bg-white text-xs font-medium px-2 py-1 rounded-full">5</span> | |
| </div> | |
| <div class="space-y-3 candidate-list"> | |
| <!-- Candidate Card 3 --> | |
| <div class="candidate-card bg-white rounded-lg shadow-sm p-3 border border-gray-200 cursor-move" draggable="true" data-candidate-id="3"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <h5 class="font-medium">Miguel Sánchez</h5> | |
| <span class="bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full">9.1</span> | |
| </div> | |
| <div class="flex items-center text-xs text-gray-500 mb-2"> | |
| <i class="fas fa-file-alt mr-1"></i> | |
| <span>CV recibido: 08/06</span> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <button class="text-indigo-600 hover:text-indigo-800 text-xs font-medium view-summary"> | |
| Ver resumen IA | |
| </button> | |
| <button class="text-gray-500 hover:text-gray-700 text-xs"> | |
| <i class="fas fa-envelope"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Entrevista Column --> | |
| <div class="workflow-column bg-gray-50 rounded-lg p-4" data-stage="entrevista"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h4 class="font-medium text-gray-800 flex items-center"> | |
| <span class="w-4 h-4 bg-orange-500 rounded-full mr-2"></span> | |
| Entrevista | |
| </h4> | |
| <span class="bg-white text-xs font-medium px-2 py-1 rounded-full">3</span> | |
| </div> | |
| <div class="space-y-3 candidate-list"> | |
| <!-- Candidate Card 4 --> | |
| <div class="candidate-card bg-white rounded-lg shadow-sm p-3 border border-gray-200 cursor-move" draggable="true" data-candidate-id="4"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <h5 class="font-medium">Ana Rodríguez</h5> | |
| <span class="bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full">8.8</span> | |
| </div> | |
| <div class="flex items-center text-xs text-gray-500 mb-2"> | |
| <i class="fas fa-calendar-alt mr-1"></i> | |
| <span>Programada: 20/06</span> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <button class="text-indigo-600 hover:text-indigo-800 text-xs font-medium view-summary"> | |
| Ver resumen IA | |
| </button> | |
| <button class="text-gray-500 hover:text-gray-700 text-xs"> | |
| <i class="fas fa-envelope"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Finalistas Column --> | |
| <div class="workflow-column bg-gray-50 rounded-lg p-4" data-stage="finalistas"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h4 class="font-medium text-gray-800 flex items-center"> | |
| <span class="w-4 h-4 bg-teal-500 rounded-full mr-2"></span> | |
| Finalistas | |
| </h4> | |
| <span class="bg-white text-xs font-medium px-2 py-1 rounded-full">2</span> | |
| </div> | |
| <div class="space-y-3 candidate-list"> | |
| <!-- Candidate Card 5 --> | |
| <div class="candidate-card bg-white rounded-lg shadow-sm p-3 border border-gray-200 cursor-move" draggable="true" data-candidate-id="5"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <h5 class="font-medium">Jorge López</h5> | |
| <span class="bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full">9.4</span> | |
| </div> | |
| <div class="flex items-center text-xs text-gray-500 mb-2"> | |
| <i class="fas fa-check-circle mr-1"></i> | |
| <span>Entrevista: 15/06</span> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <button class="text-indigo-600 hover:text-indigo-800 text-xs font-medium view-summary"> | |
| Ver resumen IA | |
| </button> | |
| <button class="text-gray-500 hover:text-gray-700 text-xs"> | |
| <i class="fas fa-envelope"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Oferta Column --> | |
| <div class="workflow-column bg-gray-50 rounded-lg p-4" data-stage="oferta"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h4 class="font-medium text-gray-800 flex items-center"> | |
| <span class="w-4 h-4 bg-green-500 rounded-full mr-2"></span> | |
| Oferta | |
| </h4> | |
| <span class="bg-white text-xs font-medium px-2 py-1 rounded-full">1</span> | |
| </div> | |
| <div class="space-y-3 candidate-list"> | |
| <!-- Candidate Card 6 --> | |
| <div class="candidate-card bg-white rounded-lg shadow-sm p-3 border border-gray-200 cursor-move" draggable="true" data-candidate-id="6"> | |
| <div class="flex justify-between items-start mb-2"> | |
| <h5 class="font-medium">Sofía Martínez</h5> | |
| <span class="bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full">9.7</span> | |
| </div> | |
| <div class="flex items-center text-xs text-gray-500 mb-2"> | |
| <i class="fas fa-file-signature mr-1"></i> | |
| <span>Oferta enviada: 18/06</span> | |
| </div> | |
| <div class="flex justify-between items-center"> | |
| <button class="text-indigo-600 hover:text-indigo-800 text-xs font-medium view-summary"> | |
| Ver resumen IA | |
| </button> | |
| <button class="text-gray-500 hover:text-gray-700 text-xs"> | |
| <i class="fas fa-envelope"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Candidate Summary Modal (Hidden by default) --> | |
| <div id="candidateSummaryModal" class="hidden fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"> | |
| <div class="bg-white rounded-lg shadow-xl max-w-2xl w-full max-h-[90vh] overflow-y-auto"> | |
| <div class="p-6"> | |
| <div class="flex justify-between items-start mb-4"> | |
| <div> | |
| <h3 class="text-xl font-semibold">Resumen de Candidato</h3> | |
| <p class="text-gray-600">Generado por IA - Carlos Mendoza</p> | |
| </div> | |
| <button id="closeSummaryModal" class="text-gray-500 hover:text-gray-700"> | |
| <i class="fas fa-times"></i> | |
| </button> | |
| </div> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-6"> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2 flex items-center"> | |
| <i class="fas fa-thumbs-up text-green-500 mr-2"></i> Fortalezas | |
| </h4> | |
| <ul class="list-disc pl-5 space-y-1 text-sm text-gray-700"> | |
| <li>5 años de experiencia con React y Redux</li> | |
| <li>Excelentes habilidades de comunicación</li> | |
| <li>Portafolio con proyectos complejos implementados</li> | |
| <li>Certificaciones en desarrollo frontend</li> | |
| <li>Experiencia trabajando en equipos ágiles</li> | |
| </ul> | |
| </div> | |
| <div> | |
| <h4 class="font-medium text-gray-800 mb-2 flex items-center"> | |
| <i class="fas fa-thumbs-down text-red-500 mr-2"></i> Debilidades | |
| </h4> | |
| <ul class="list-disc pl-5 space-y-1 text-sm text-gray-700"> | |
| <li>Experiencia limitada con TypeScript</li> | |
| <li>No ha trabajado en proyectos a gran escala</li> | |
| <li>Salario esperado ligeramente superior al rango</li> | |
| </ul> | |
| </div> | |
| </div> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2 flex items-center"> | |
| <i class="fas fa-star text-yellow-500 mr-2"></i> Puntuación IA | |
| </h4> | |
| <div class="flex items-center"> | |
| <div class="w-full bg-gray-200 rounded-full h-4"> | |
| <div class="bg-green-500 h-4 rounded-full" style="width: 85%"></div> | |
| </div> | |
| <span class="ml-3 font-medium">8.5/10</span> | |
| </div> | |
| </div> | |
| <div class="mb-6"> | |
| <h4 class="font-medium text-gray-800 mb-2 flex items-center"> | |
| <i class="fas fa-file-alt text-indigo-500 mr-2"></i> Conclusión | |
| </h4> | |
| <div class="bg-blue-50 p-4 rounded-lg text-sm text-gray-700"> | |
| <p>Carlos es un candidato fuerte para el puesto de Desarrollador Frontend React. Su experiencia con las tecnologías clave y su capacidad para trabajar en equipo lo convierten en un buen ajuste. La principal área de mejora sería su experiencia con TypeScript, pero esto podría abordarse con capacitación interna. Recomendado para avanzar a la etapa de entrevista técnica.</p> | |
| </div> | |
| </div> | |
| <div class="flex justify-end space-x-3"> | |
| <button class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50"> | |
| <i class="fas fa-envelope mr-1"></i> Enviar email | |
| </button> | |
| <button class="px-4 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700"> | |
| <i class="fas fa-arrow-right mr-1"></i> Mover a siguiente etapa | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| </div> | |
| </div> | |
| <script> | |
| // DOM Elements | |
| const atsDashboard = document.getElementById('atsDashboard'); | |
| const createVacancyBtn = document.getElementById('createVacancyBtn'); | |
| const createVacancyForm = document.getElementById('createVacancyForm'); | |
| const closeFormBtn = document.getElementById('closeFormBtn'); | |
| const cancelFormBtn = document.getElementById('cancelFormBtn'); | |
| const vacancyForm = document.getElementById('vacancyForm'); | |
| const formOptions = document.getElementById('formOptions'); | |
| const finishBtn = document.getElementById('finishBtn'); | |
| const workflowView = document.getElementById('workflowView'); | |
| const viewWorkflowBtns = document.querySelectorAll('.view-workflow'); | |
| const candidateSummaryModal = document.getElementById('candidateSummaryModal'); | |
| const closeSummaryModal = document.getElementById('closeSummaryModal'); | |
| const viewSummaryBtns = document.querySelectorAll('.view-summary'); | |
| const generateDescriptionBtn = document.getElementById('generateDescriptionBtn'); | |
| const jobDescription = document.getElementById('jobDescription'); | |
| const desirableRequirements = document.getElementById('desirableRequirements'); | |
| const exclusiveRequirements = document.getElementById('exclusiveRequirements'); | |
| const jobTitle = document.getElementById('jobTitle'); | |
| const vacancyTabs = document.querySelectorAll('.vacancy-tab'); | |
| const dropdownMenus = document.querySelectorAll('.dropdown-menu'); | |
| const dropdownBtns = document.querySelectorAll('.dropdown button'); | |
| // Show create vacancy form | |
| createVacancyBtn.addEventListener('click', () => { | |
| atsDashboard.classList.add('hidden'); | |
| createVacancyForm.classList.remove('hidden'); | |
| }); | |
| // Close create vacancy form | |
| closeFormBtn.addEventListener('click', () => { | |
| createVacancyForm.classList.add('hidden'); | |
| atsDashboard.classList.remove('hidden'); | |
| }); | |
| // Cancel create vacancy form | |
| cancelFormBtn.addEventListener('click', () => { | |
| createVacancyForm.classList.add('hidden'); | |
| atsDashboard.classList.remove('hidden'); | |
| }); | |
| // Submit vacancy form | |
| vacancyForm.addEventListener('submit', (e) => { | |
| e.preventDefault(); | |
| createVacancyForm.classList.add('hidden'); | |
| formOptions.classList.remove('hidden'); | |
| }); | |
| // Finish form and show workflow | |
| finishBtn.addEventListener('click', () => { | |
| formOptions.classList.add('hidden'); | |
| workflowView.classList.remove('hidden'); | |
| }); | |
| // View workflow for a vacancy | |
| viewWorkflowBtns.forEach(btn => { | |
| btn.addEventListener('click', (e) => { | |
| e.preventDefault(); | |
| atsDashboard.classList.add('hidden'); | |
| workflowView.classList.remove('hidden'); | |
| }); | |
| }); | |
| // Show candidate summary modal | |
| viewSummaryBtns.forEach(btn => { | |
| btn.addEventListener('click', () => { | |
| candidateSummaryModal.classList.remove('hidden'); | |
| }); | |
| }); | |
| // Close candidate summary modal | |
| closeSummaryModal.addEventListener('click', () => { | |
| candidateSummaryModal.classList.add('hidden'); | |
| }); | |
| // Generate job description with AI | |
| generateDescriptionBtn.addEventListener('click', () => { | |
| if (jobTitle.value.trim() === '' || | |
| (desirableRequirements.value.trim() === '' && exclusiveRequirements.value.trim() === '')) { | |
| alert('Por favor completa al menos el título del puesto y algunos requisitos para generar la descripción.'); | |
| return; | |
| } | |
| // Simulate AI generation | |
| generateDescriptionBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-1"></i> Generando...'; | |
| setTimeout(() => { | |
| const title = jobTitle.value; | |
| const desirable = desirableRequirements.value; | |
| const exclusive = exclusiveRequirements.value; | |
| const generatedDescription = `Estamos buscando un ${title} para unirse a nuestro equipo. | |
| ${desirable ? `Requisitos deseables: | |
| ${desirable}` : ''} | |
| ${exclusive ? `Requisitos excluyentes: | |
| ${exclusive}` : ''} | |
| Ofrecemos un ambiente de trabajo dinámico, oportunidades de crecimiento y un excelente equipo. Si cumples con estos requisitos y estás buscando un nuevo desafío, ¡queremos conocerte!`; | |
| jobDescription.value = generatedDescription; | |
| generateDescriptionBtn.innerHTML = '<i class="fas fa-magic mr-1"></i> Generar descripción con IA'; | |
| }, 1500); | |
| }); | |
| // Vacancy tabs functionality | |
| vacancyTabs.forEach(tab => { | |
| tab.addEventListener('click', () => { | |
| vacancyTabs.forEach(t => t.classList.remove('active', 'text-indigo-600', 'border-indigo-600')); | |
| vacancyTabs.forEach(t => t.classList.add('text-gray-500', 'hover:text-gray-700')); | |
| tab.classList.add('active', 'text-indigo-600', 'border-indigo-600'); | |
| tab.classList.remove('text-gray-500', 'hover:text-gray-700'); | |
| // Here you would filter vacancies by status | |
| }); | |
| }); | |
| // Dropdown menus functionality | |
| dropdownBtns.forEach((btn, index) => { | |
| btn.addEventListener('click', () => { | |
| const menu = dropdownMenus[index]; | |
| menu.classList.toggle('hidden'); | |
| // Close other open menus | |
| dropdownMenus.forEach((m, i) => { | |
| if (i !== index) m.classList.add('hidden'); | |
| }); | |
| }); | |
| }); | |
| // Close dropdowns when clicking outside | |
| document.addEventListener('click', (e) => { | |
| if (!e.target.closest('.dropdown')) { | |
| dropdownMenus.forEach(menu => { | |
| menu.classList.add('hidden'); | |
| }); | |
| } | |
| }); | |
| // Drag and drop functionality for candidates | |
| const candidateCards = document.querySelectorAll('.candidate-card'); | |
| const workflowColumns = document.querySelectorAll('.workflow-column'); | |
| candidateCards.forEach(card => { | |
| card.addEventListener('dragstart', () => { | |
| card.classList.add('opacity-50', 'border-indigo-300'); | |
| }); | |
| card.addEventListener('dragend', () => { | |
| card.classList.remove('opacity-50', 'border-indigo-300'); | |
| }); | |
| }); | |
| workflowColumns.forEach(column => { | |
| column.addEventListener('dragover', (e) => { | |
| e.preventDefault(); | |
| column.classList.add('drag-over'); | |
| }); | |
| column.addEventListener('dragleave', () => { | |
| column.classList.remove('drag-over'); | |
| }); | |
| column.addEventListener('drop', (e) => { | |
| e.preventDefault(); | |
| column.classList.remove('drag-over'); | |
| const draggedCard = document.querySelector('.opacity-50'); | |
| if (draggedCard) { | |
| const candidateList = column.querySelector('.candidate-list'); | |
| candidateList.appendChild(draggedCard); | |
| // Here you would update the candidate's stage in your database | |
| const newStage = column.dataset.stage; | |
| console.log(`Candidate moved to ${newStage} stage`); | |
| } | |
| }); | |
| }); | |
| // Back to dashboard from workflow view | |
| document.addEventListener('keydown', (e) => { | |
| if (e.key === 'Escape') { | |
| if (!workflowView.classList.contains('hidden')) { | |
| workflowView.classList.add('hidden'); | |
| atsDashboard.classList.remove('hidden'); | |
| } | |
| if (!candidateSummaryModal.classList.contains('hidden')) { | |
| candidateSummaryModal.classList.add('hidden'); | |
| } | |
| } | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Nicolasvila/m" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |