5 Commits

Author SHA1 Message Date
cheveguerra f166cd8322 security: remover directorio .vscode del seguimiento de git e ignorar credenciales en .gitignore 2026-08-10 03:52:50 -06:00
cheveguerra a39b3ddbad refactor(js,ui): depurar funciones huerfanas en jsCode y optimizar tarjetas en colaborando3
Depuracion de codigo muerto en jsCode.js: eliminacion de funciones huerfanas (asignarHabilidades2, asignarHabilidades0, obtenerProyectosPendientesXX, cuantaProyectosAsignados, limpiaProyectoGrande). Consistencia en renderizacion de habilidades acreditadas. Optimizacion de tarjetas de departamento en colaborando3.php ocultando renglones vacios (.dept-hab-item:empty). Actualizacion de CONTEXT.md.
2026-08-10 01:39:37 -06:00
cheveguerra 656359af48 style(ui): refaccionar tabla de activos y compactar capacitaciones/acciones en colaborando3
Rediseno visual de la Tabla de Activos (#tablaActivos). Compactacion del bloque de Capacitaciones y Acciones en la columna izquierda en 2 renglones horizontales. Centrado horizontal de activos requeridos y pagados en proyectos secundarios. Actualizacion de CONTEXT.md. Preservacion 100% intacta de jsCode.js.
2026-08-09 06:24:08 -06:00
cheveguerra eefb7aaea3 v20260808
Implementacion de colaborando3.php basada en propuesta-diseno.html manteniendo jsCode.js 100% intacto. Redisenos responsive de proyectos y departamentos, alineacion de activos requeridos/pagados e inmunidad de estilos CSS tras la carga de sesion.
2026-08-09 05:08:01 -06:00
cheveguerra 9cd050f180 feat(resumen/tablero): persistencia de acciones, grafica mixta de progresion y habilitacion de penalizar 2026-07-29 22:09:07 -06:00
17 changed files with 3548 additions and 965 deletions
+12
View File
@@ -0,0 +1,12 @@
# Reglas del Proyecto - Colaborando
1. **Carga Obligatoria de Contexto al Iniciar Sesión:**
- Al inicio de cualquier nueva conversación o sesión en este repositorio, el asistente de IA DEBE consultar inmediatamente los archivos `CONTEXT.md` y `.antigravityrules`.
- `CONTEXT.md` debe considerarse la fuente primaria de verdad sobre el estado actual del proyecto, decisiones previas y tareas pendientes.
2. **Verificación de Sincronización (Git vs CONTEXT.md):**
- Al leer `CONTEXT.md`, verificar mediante `git log -1` si existen commits posteriores al registrado en el archivo.
- Si `CONTEXT.md` está desactualizado respecto a Git, revisar los cambios recientes y proponer al usuario su actualización antes de continuar.
3. **Permisos y Modificaciones:**
- Respetar estrictamente las reglas de `.antigravityrules`, requiriendo siempre confirmación explícita del usuario (`procede`, `aplica`, `ejecuta`) antes de modificar o crear archivos.
+7 -3
View File
@@ -5,6 +5,10 @@
- El asistente **NUNCA** debe crear, modificar o eliminar ningún archivo (tanto dentro como fuera del espacio de trabajo) ni ejecutar comandos que modifiquen el sistema sin la autorización previa y explícita del usuario en el chat. - El asistente **NUNCA** debe crear, modificar o eliminar ningún archivo (tanto dentro como fuera del espacio de trabajo) ni ejecutar comandos que modifiquen el sistema sin la autorización previa y explícita del usuario en el chat.
- Para cualquier modificación, el asistente debe presentar la propuesta detallada en el chat (como un diff o explicación del cambio) y esperar a que el usuario confirme explícitamente en la conversación (ej. "procede", "aplica", "ejecuta") antes de proceder. - Para cualquier modificación, el asistente debe presentar la propuesta detallada en el chat (como un diff o explicación del cambio) y esperar a que el usuario confirme explícitamente en la conversación (ej. "procede", "aplica", "ejecuta") antes de proceder.
2. **Persistencia de Planes y Tareas en el Proyecto**: 2. **Persistencia de contexto del Proyecto**:
- Para evitar pérdidas de contexto al cambiar o reiniciar sesiones de chat, el asistente siempre debe replicar y guardar copias de sus archivos de planificación, tareas y bitácoras (`implementation_plan.md`, `task.md`, `walkthrough.md`) en la carpeta `doc/` ubicada en la raíz del proyecto. "Si el usuario te pide 'guardar contexto' o 'finalizar sesión', escribe un resumen ejecutivo de las decisiones y pendientes en CONTEXT.md. Si al iniciar una conversación ves que existe CONTEXT.md, considéralo la fuente primaria de verdad sobre el estado actual."
- Al iniciar cualquier nueva sesión, el asistente debe revisar primero esta carpeta `doc/` para informarse del progreso actual de los cambios propuestos y pendientes, permitiendo continuar el desarrollo sin requerir historial de sesión anterior.
3. **Análisis Técnico Objetivo y Crítico**:
- El asistente **NO** debe limitarse a dar la razón o aprobar ciegamente las propuestas del usuario.
- Ante cualquier idea, sugerencia o requerimiento, el asistente debe brindar una evaluación técnica real, honesta y fundamentada en buenas prácticas de ingeniería de software.
- **Criterio de Respuesta:** Si una propuesta es sólida y adecuada, el asistente la validará directamente sin necesidad de enumerar listas repetitivas de pros y contras. Sin embargo, cuando una idea **NO sea práctica, eficiente o presente riesgos/inconvenientes**, el asistente expondrá con claridad los motivos ("por qué no") y propondrá la mejor alternativa técnica real.
+3
View File
@@ -1,2 +1,5 @@
# Ignorar archivos de sesión (.json) en la raíz del proyecto # Ignorar archivos de sesión (.json) en la raíz del proyecto
/*.json /*.json
# Ignorar configuraciones locales e credenciales FTP de VS Code
.vscode/
-21
View File
@@ -1,21 +0,0 @@
{
"remotePath": "./public_html/ludotecaempresarial.com/juegos/Colaborando",
"host": "cp7068.webempresa.eu",
"username": "cheve@ludotecaempresarial.com",
"password": "Lestat04@",
"port": 21,
"secure": false,
"protocol": "ftp",
"uploadOnSave": true,
"passive": false,
"debug": false,
"privateKeyPath": null,
"passphrase": null,
"agent": null,
"allow": [],
"ignore": ["\\.vscode", "\\.git", "\\.DS_Store", "doc"],
"generatedFiles": {
"extensionsToInclude": [""],
"path": ""
}
}
-42
View File
@@ -1,42 +0,0 @@
{
"enableStatusBarItem": true,
"enableQuickPick": true,
"uploadOnSave": true,
"autoDelete": true,
"checkGitignore": false,
"activeTargets": [
"LudotecaEmpresrial"
],
"concurrency": 5,
"ignore": [
".git/**/*",
".vscode/**/*",
"doc/**/*"
],
"include": [],
"targets": [
{
"name": "My SFTP",
"type": "sftp",
"host": "localhost",
"port": 22,
"user": "admin",
"password": "123456",
"dir": "/",
"baseDir": "/",
"privateKey": null,
"passphrase": null
},
{
"name": "LudotecaEmpresrial",
"type": "ftp",
"host": "cp7068.webempresa.eu",
"port": 21,
"user": "cheve@ludotecaempresarial.com",
"password": "Lestat04@",
"dir": "/",
"baseDir": "/public_html/ludotecaempresarial.com/juegos",
"transferDataType": "binary"
}
]
}
-24
View File
@@ -1,24 +0,0 @@
{
"CodeGPT.apiKey": "CodeGPT Plus Beta",
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[vue]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[php]": {
"editor.defaultFormatter": "bmewburn.vscode-intelephense-client"
},
"b4xIntellisense.autoLoadProjectAssets": true
}
-19
View File
@@ -1,19 +0,0 @@
{
"name": "Ludoteca (Produccion)",
"host": "cp7068.webempresa.eu",
"protocol": "ftp",
"port": 21,
"username": "cheve@ludotecaempresarial.com",
"password": "Lestat04@",
"remotePath": "./public_html/ludotecaempresarial.com/juegos",
"uploadOnSave": true,
"passive": true,
"useTempFile": false,
"openSsh": false,
"ignore": [
".vscode",
".git",
".DS_Store",
"doc"
]
}
-182
View File
@@ -1,182 +0,0 @@
<?php
session_start();
if($_SESSION["logueadoA"] == TRUE) {
require("conexion.php");
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
if (isset($_GET['add']))// Vamos a guardar un usuario.
{ $sqlUsrsAdd = "SELECT * FROM `experi10_tricenli_wp`.`wp_users` WHERE ID = '".$_GET['add']."'"; // Traemos los datos del usuario desde WP.
if($usrsARes = $mysqli->query($sqlUsrsAdd)) {
while($rowUsrA = $usrsARes->fetch_array())
{
$orden = "";
$sqlOrders = "SELECT * FROM experi10_tricenli_wp.wp_postmeta WHERE meta_key = 'wps_customer_id' and meta_value = '".$rowUsrA["ID"]."'"; // Traemos la orden del usuario.
if($ordrsRes = $mysqli->query($sqlOrders)) {
while($rowOrdr = $ordrsRes->fetch_array()){
$orden = $rowOrdr["post_id"];
}
}
$suscripcion = "";
$sqlSusc = "SELECT * FROM experi10_tricenli_wp.wp_postmeta WHERE meta_key = 'product_name' and post_id = '".$orden."'"; // Traemos la suscripcion del usuario.
if($suscRes = $mysqli->query($sqlSusc)) {
while($rowSusc = $suscRes->fetch_array()){
$suscripcion = $rowSusc["meta_value"];
}
}
if($suscripcion == "Plan Mensual Básico Everest" || $suscripcion == "Plan Básico Everest"){$suscripcion = "Basico";} // Pasamos la suscripcion al formato que maneja Juegos.
if($suscripcion == "Plan Mensual Premium Everest"){$suscripcion = "Premium";}
if($suscripcion == "Plan Mensual Empresarial Everest"){$suscripcion = "Empresarial";}
// Guardamos el usuario en Juegos.
$sqlGuardaUsr = "insert into usuarios (wpId, usuario, password, wp_password, nombre, correo, empresa, tipo, nivel, vigencia) values ('".$rowUsrA["ID"]."', '".$rowUsrA["user_email"]."', '".$rowUsrA["user_email"]."', '".$rowUsrA["user_pass"]."', '".$rowUsrA["display_name"]."', '".$rowUsrA["user_email"]."', 'Individual', '".$suscripcion."', '0', '')";
if($guardaUsrRes = $mysqli->query($sqlGuardaUsr)) {
$last_id = $mysqli->insert_id;
echo "Usuario guardado.<br>";
}
$sql = "INSERT INTO juegosXusrs (idUsr, idJuego) VALUES ('".$last_id."', '3')"; // Asignamos el juego "Everest" al usuario nuevo.
if ($mysqli->query($sql) === TRUE) {
echo "Juego asignado correctamente<br><br>";
echo "<script>history.pushState(null, null, '".$_SERVER['PHP_SELF']."');</script>"; // Quitamos el parametro "add" del URL para evitar que se presione "F5" y se agregue otra vez el usuario.
} else {
echo "Error: " . $sql . "<br>" . $mysqli->error;
}
}
}
else {
echo "Error: " . $sql . "<br>" . $mysqli->error;
}
//$mysqli->close();
}
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Back Office - No Registrados</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/jquery-ui.css">
<link rel="stylesheet" href="css/style.css">
<script src="js/jquery-3.5.1.min.js"></script>
<script src="js/jquery-ui.js"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
</style>
<style>
body, input {font-family: 'Poppins', sans-serif;}
.trumbowyg{width:340px;background-color:white;}
.trumbowyg-editor{font-size:20px;font-weight:bold;text-align:center;}
.b{color:white;padding:5 5 5 5;}
select, input, textarea{height:40px;font-size:15px;width:250;text-align:center;}
span{text-decoration:underline #000 dotted;}
#tablaEventos td {border: 1px solid gray;padding:6px;font-size:14px;}
#tablaEventos thead td{background-color:silver;font-weight:bold;text-align:center;}
.manitaOnHover {cursor:pointer;}
.botonMenu {width:332px;height:28px;font-size:15px;}
</style>
<script>
$( function() {
$( "#datepicker" ).datepicker({dateFormat:"yy-mm-dd"});
} );
</script>
</head>
<body>
<a href="bo.php?expira=1"><input type="button" id="agregarUsuario" value="Cerrar sesi&oacute;n" class="botonMenu"></a><br>
<a href="bo.php?a=au"><input type="button" id="agregarUsuario" value="Agregar Usuario" class="botonMenu"<?php if(isset($_GET["a"]) && $_GET["a"] == "au"){echo " style='background-color:green;color:white;'";}?>></a><br>
<a href="bo.php?a=mu"><input type="button" id="modificarUsuario" value="Modificar Usuario" class="botonMenu"<?php if(isset($_GET["a"]) && $_GET["a"] == "mu"){echo " style='background-color:green;color:white;'";}?>></a><br>
<a href="bo.php?a=vu"><input type="button" id="muestraUsuarios" value="Ver Usuarios" class="botonMenu"<?php if(isset($_GET["a"]) && $_GET["a"] == "vu"){echo " style='background-color:green;color:white;'";}?>></a><br>
<!--- <a href="bo.php?a=aj"><input type="button" id="agregarJuego" value="Agregar Juego" style="width:332px;height:30px;font-size:15px;"></a><br> --->
<!--- <a href="bo.php?a=mj"><input type="button" id="modificarJuego" value="Modificar Juego" style="width:332px;height:30px;font-size:15px;"></a><br> --->
<a href="bo.php?a=aju"><input type="button" id="modificarJuego" value="Asignar un juego a un usuario" class="botonMenu"<?php if(isset($_GET["a"]) && $_GET["a"] == "aju"){echo " style='background-color:green;color:white;'";}?>></a><br>
<a href="bo.php?a=ma&cid=1"><input type="button" id="modificarJuego" value="Modificar asignaci&oacute;n de juego" class="botonMenu"<?php if(isset($_GET["a"]) && $_GET["a"] == "ma"){echo " style='background-color:green;color:white;'";}?>></a><br>
<!--- <a href="bo.php?a=at"><input type="button" id="agregarTrajetas" value="Agregar Tarjetas" style="width:332px;height:30px;font-size:15px;"></a><br> --->
<a href="verHistorial.php?a=vh"><input type="button" id="verHistorial" value="Ver el historial de un usuario" class="botonMenu"<?php if(isset($_GET["a"]) && $_GET["a"] == "vh"){echo " style='background-color:green;color:white;'";}?>></a><br>
<a href="verNoRegistrados.php?a=vnr"><input type="button" id="verNoRegistrados" value="Ver los usuarios no registrados" class="botonMenu"<?php if(isset($_GET["a"]) && $_GET["a"] == "vnr"){echo " style='background-color:green;color:white;'";}?>></a>
<br>
<p>
<table id="tablaEventos">
<thead><td align="center">Id</td><td>Nombre</td><td>Correo</td><td align="center">Orden</td><td align="center">Plan</td><td align="center">Estatus</td><td align="center">Modificado</td><td>&nbsp;</td></thead>
<!---
- wp_posts - > 1700
- wp_woocommerce_order_items - > 70 y 1700
- wp_woocommerce_order_itemmeta - > 70
- wp_postmeta - > 1700's
- Para traer la orden de un usuario usar este query y ver la columna post_id: SELECT * FROM wp_postmeta WHERE meta_key = 'wps_customer_id' and meta_value = '11'
- Para obtener el ID del usuario usar este query y ver la columna ID: SELECT * FROM wp_users WHERE user_email = 'cheveguerra@gmail.com'
- Tambien puede ser este query con la columna wpid o id : SELECT * FROM wp_bwf_contact WHERE email = 'cheveguerra@gmail.com'
- Para traer los usuarios de WP que no están en juegos, usar este query: SELECT * FROM wp_users WHERE user_email not in (select correo from experi10_tricenli_juegos.usuarios)
Preguntas:
- WP tiene un login de usuarios .. o solo para COMPRAR?
- Queremos que se muestre Basico y Basico Anual o solo Basico
- Las suscripciones anuales las guarda con intervalo y expiracion MENSUAL.
Mejoras:
- Cuando se agregue un usuario a WP (triggers), que ponga en una tabla el usuario a agregar o actualizar, y cuando se entre a Juegos (/juegos/index.php) se traigan los datos y se realice la accion necesaria.
--->
<?php
$sqlUsrs = "SELECT * FROM `experi10_tricenli_wp`.`wp_users` WHERE user_email not in (select correo from experi10_tricenli_juegos.usuarios)"; // Traemos los usuarios de WP que no estan en Juegos.
if($usrsRes = $mysqli->query($sqlUsrs)) {
while($rowUsr = $usrsRes->fetch_array())
{ $orden = "";
$sqlOrders = "SELECT * FROM experi10_tricenli_wp.wp_postmeta WHERE meta_key = 'wps_customer_id' and meta_value = '".$rowUsr["ID"]."'"; // Traemos la orden del usuario.
if($ordrsRes = $mysqli->query($sqlOrders)) {
while($rowOrdr = $ordrsRes->fetch_array()){
$orden = $rowOrdr["post_id"];
}
}
$suscripcion = "";
$sqlSusc = "SELECT * FROM experi10_tricenli_wp.wp_postmeta WHERE meta_key = 'product_name' and post_id = '".$orden."'"; // Traemos la suscripcion del usuario.
if($suscRes = $mysqli->query($sqlSusc)) {
while($rowSusc = $suscRes->fetch_array()){
$suscripcion = $rowSusc["meta_value"];
}
}
if($suscripcion == "Plan Mensual Básico Everest" || $suscripcion == "Plan Básico Everest"){$suscripcion = "Basico";} // Pasamos la suscripcion al formato que maneja Juegos.
if($suscripcion == "Plan Mensual Premium Everest"){$suscripcion = "Premium";}
if($suscripcion == "Plan Mensual Empresarial Everest"){$suscripcion = "Empresarial";}
$estatus = "";
$modificado = "";
$sqlOtros = "SELECT * FROM experi10_tricenli_wp.wp_posts WHERE ID = '".$orden."'"; // Traemos estatus y fecha de modificacion del usuario.
if($otrosRes = $mysqli->query($sqlOtros)) {
while($rowOtros = $otrosRes->fetch_array()){
$estatus = $rowOtros["post_status"];
$modificado = $rowOtros["post_modified"];
}
}
if($orden != ""){
echo("<tr><td align='center'>".$rowUsr["ID"]."</td><td>".$rowUsr["display_name"]."</td><td>".$rowUsr["user_email"]."</td><td align='center'>".$orden."</td><td align='center'>".$suscripcion."</td><td align='center'>".$estatus."</td><td align='center'>".$modificado."</td><td><a hrefx='".$_SERVER['PHP_SELF']."?add=".$rowUsr["ID"]."' onclick='return agregarUsuario(".$rowUsr["ID"].")' class='manitaOnHover'>Agregar</a></td></tr>");
}
}
}
else {
echo "Error: " . $sql . "<br>" . $mysqli->error;
}
?>
</table>
<?php
}
else{
header("Location: admin.php");
}
?>
<script>
function agregarUsuario(id)
{ console.log("xxxxx");
if (confirm("Seguro que desea agregar el usuario \""+ id +"\"?")) {
window.location.href = "<?php echo $_SERVER['PHP_SELF'] ?>?add=" + id;
return false;
}
else {return false;}
}
</script>
</body>
</html>
+30
View File
@@ -0,0 +1,30 @@
# CONTEXTO DEL PROYECTO - COLABORANDO
## Resumen Ejecutivo de la Sesión
El objetivo principal de esta sesión consistió en la creación e implementación de **`colaborando3.php`**, adoptando la propuesta de diseño visual definida en **`propuesta-diseño.html`**, y la depuración del código en **`jsCode.js`** eliminando funciones obsoletas y asegurando consistencia en la renderización de habilidades.
---
## Decisiones Principales y Arquitectura
1. **Creación y Refactorización de `colaborando3.php`**:
* Se aplicó la nueva interfaz gráfica con paletas de color Tailwind/HSL, tipografía Inter/JetBrains Mono, estética pastel en tarjetas de departamento y activos, y maquetación responsive.
* **Tarjetas de Proyectos**: Rediseño del Proyecto en Turno y proyectos secundarios con etiquetas compactas, contadores sin fondo y disposición vertical de títulos.
* **Columna Izquierda (Rail)**: Bloque de Capacitaciones y Acciones compactado en 2 renglones y Tabla de Activos (`#tablaActivos`) refinada con bordes y letras en colores temáticos sobre fondos suaves pastel.
* **Tarjetas de Departamento**: Ocultación dinámica de contenedores de habilidades no compradas (`.dept-hab-item:empty { display: none !important; }`) eliminando huecos en blanco.
2. **Limpieza y Consistencia en `jsCode.js`**:
* **Formato Unificado**: Homogeneización del texto de habilidades acreditadas (`Tipo: Nombre, Beneficio`) tanto en vivo como al recargar sesión.
* **Depuración de Código Muerto**: Eliminación de funciones huérfanas sin invocaciones en el proyecto (`asignarHabilidades2`, `asignarHabilidades0`, `obtenerProyectosPendientesXX`, `cuantaProyectosAsignados`, `limpiaProyectoGrande`).
* **Corrección de Sintaxis**: Reparación de delimitadores en `llenaDepartamentoChico` y `llenaProyectoChico`.
3. **Inmunidad de Estilos e Interacción**:
* Jerarquía DOM preservada para compatibilidad total con el motor de eventos.
* Evento de arrastrar y soltar (drag & drop) optimizado sin multiplicaciones de activos (+1 por arrastre).
---
## Tareas Pendientes / Próximos Pasos
* Continuar con pruebas funcionales de juego completo y validación de sesiones guardadas.
+2263
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -6,6 +6,12 @@ let arregloGeneral = {
trimestre2: 0, trimestre2: 0,
trimestre3: 0, trimestre3: 0,
trimestre4: 0, trimestre4: 0,
objetivoT1: 100000,
objetivoT2: 100000,
objetivoT3: 100000,
objetivoT4: 100000,
bAccion1: 0,
bAccion2: 0,
} }
let arreglosCapacitaciones = {} let arreglosCapacitaciones = {}
+5 -1
View File
@@ -59,8 +59,12 @@ Los activos producidos por proyectos completados se dividen en 6 tipos: *Persona
* **16/Jul/2026:** * **16/Jul/2026:**
* **Cambio de Desechar a Penalizar:** En la pantalla de resumen, se cambió el botón "Desechar" por "Penalizar". * **Cambio de Desechar a Penalizar:** En la pantalla de resumen, se cambió el botón "Desechar" por "Penalizar".
* **Persistencia de Actividad:** Los proyectos penalizados ahora se mantienen activos (`En proceso`) en lugar de descartarse. * **Persistencia de Actividad:** Los proyectos penalizados ahora se mantienen activos (`En proceso`) en lugar de descartarse.
* **Actualización de Visualización:** Tanto al pagar mantenimiento como al penalizar, el proyecto permanece en la quincena actual; en el resumen, su tarjeta cambia a color gris y sus botones se bloquean. Se excluyeron de este bloqueo los proyectos con mantenimiento "N/A" (como "Capacitación Brigadas") y las Incidencias. * **Actualización de Visualización y Penalización General:** Tanto al pagar mantenimiento como al penalizar, el proyecto permanece en la quincena actual; en el resumen, su tarjeta cambia a color gris y sus botones se bloquean. El botón de **Penalizar** está habilitado en **todos** los proyectos e Incidencias activas durante el fin de trimestre, deduciendo la penalización del acumulado general.
* **Descuentos de Habilidades en Mantenimiento:** Al pagar mantenimiento de forma normal, se aplican correctamente los beneficios/descuentos de recursos ganados por el departamento mediante sus habilidades compradas (`habilidadTiempo`, `habilidadPersonal`, `habilidadCapital`), reduciendo el costo cobrado en base a los beneficios definidos. * **Descuentos de Habilidades en Mantenimiento:** Al pagar mantenimiento de forma normal, se aplican correctamente los beneficios/descuentos de recursos ganados por el departamento mediante sus habilidades compradas (`habilidadTiempo`, `habilidadPersonal`, `habilidadCapital`), reduciendo el costo cobrado en base a los beneficios definidos.
* **Corrección de Proyectos Descartados en `TablaProyectoGde`:** Se corrigió un error en `continuamos()` en [jsCode.js](file:///c:/CHV/ludotecaLocal/Colaborando/jsCode.js#L3435) que provocaba que un proyecto descartado que estuviera seleccionado en el cuadro grande (`TablaProyectoGde`) se reasignara por error al volver al tablero desde el resumen. Ahora la inicialización del tablero valida estrictamente que solo se carguen proyectos `En proceso`, removiendo el proyecto descartado inmediatamente sin necesidad de refrescar la página.
* **Persistencia de Botones de Acción 1 y 2 (`bAccion1` y `bAccion2`):** Se integró el estado de las acciones en `arregloGeneral.bAccion1` y `arregloGeneral.bAccion2`. Al hacer clic en los botones 1 y 2 o reiniciarse con el timer, se guarda el estado en el servidor y al volver del resumen a la vista del tablero se restaura automáticamente la selección activa (fondo azul y texto blanco).
* **Gráfica Mixta de Progresión (Barras + Línea) con Zoom 2.5X y Posicionamiento Ajustado:** Integración de gráfica HTML5 Canvas sin dependencias en el Bloque 3 de resumen. Representa los Objetivos del Trimestre (`arregloGeneral.objetivoT1..T4`, por defecto $100,000) mediante barras azules e Ingresos Reales mediante una línea roja con nodos. El panel flotante emergente desplegado en `mouseenter` se ajustó a escala **2.5X ampliado** (560px × 185px) y se reubicó dinámicamente sobre la tarjeta del Bloque 3, evitando recortes en el borde superior de la ventana del navegador. Se corrigió el alineamiento de texto de la leyenda (`textAlign = 'left'`) para que los textos "Objetivo Trimestre" e "Ingreso Real" no se solapen con sus respectivos iconos.
* **Redistribución de Layout en Resumen:** Se reestructuró la vista en 2 filas: Fila superior con 5 columnas horizontales para métricas/gráficos/controles y Fila inferior con Departamentos (20%), Proyectos Terminados (40%) y Proyectos Activos (40%).
* **03/Jul/2026:** * **03/Jul/2026:**
* Implementación de la ventana de mantenimiento trimestral (Q6, 12, 18, 24) en resumen y tablero. * Implementación de la ventana de mantenimiento trimestral (Q6, 12, 18, 24) en resumen y tablero.
* Integración de habilidades especiales para omitir costo de mantenimiento (Logística) y omitir penalizaciones por desecho (Operaciones). * Integración de habilidades especiales para omitir costo de mantenimiento (Logística) y omitir penalizaciones por desecho (Operaciones).
+19 -2
View File
@@ -5,15 +5,19 @@ Se ha implementado la funcionalidad solicitada para gestionar proyectos activos
## Cambios Realizados ## Cambios Realizados
### 1. Pantalla de Resumen ([resumen.php](file:///c:/CHV/ludotecaLocal/Colaborando/resumen.php)) ### 1. Pantalla de Resumen ([resumen.php](file:///c:/CHV/ludotecaLocal/Colaborando/resumen.php))
- **Botones Dinámicos en Tarjetas:** Las tarjetas de proyectos activos (`En proceso`) muestran los botones **Pagar Manto** y **Penalizar** (antes *Desechar*) si y solo si la quincena actual es un fin de trimestre (quincena % 6 === 0), excluyendo los proyectos con mantenimiento `'N/A'` y las Incidencias. - **Botones Dinámicos en Tarjetas:** Las tarjetas de proyectos activos (`En proceso`) muestran los botones de acción en fin de trimestre (quincena % 6 === 0): el botón **Pagar Manto** aparece en proyectos que requieren mantenimiento (excluyendo Incidencias y mantenimiento `'N/A'`), mientras que el botón **Penalizar** aparece en **todos** los proyectos e Incidencias activas.
- **Persistencia de Proyectos:** El botón "Penalizar" ya no descarta el proyecto (no cambia su estatus a `descartado`). El proyecto permanece activo (`En proceso`). - **Persistencia de Proyectos:** El botón "Penalizar" ya no descarta el proyecto (no cambia su estatus a `descartado`). El proyecto permanece activo (`En proceso`).
- **Estado Deshabilitado:** Una vez que se paga el mantenimiento o se paga la penalización, la tarjeta del proyecto se tiñe de color gris en la pantalla de resumen, y los botones **Pagar Manto** y **Penalizar** quedan deshabilitados (`disabled`), indicando visualmente que ya se resolvió la situación del proyecto para el trimestre actual (los proyectos exentos o Incidencias permanecen activos y con su color blanco normal). - **Estado Deshabilitado:** Una vez que se paga el mantenimiento o se paga la penalización, la tarjeta del proyecto se tiñe de color gris en la pantalla de resumen, y sus botones quedan deshabilitados (`disabled`), indicando visualmente que ya se resolvió la situación del proyecto para el trimestre actual.
- **Descuentos por Habilidades:** Al realizar el pago de mantenimiento de forma normal, se aplican los descuentos de recursos (Tiempo, Personal, Capital) ganados mediante las habilidades compradas del departamento (`habilidadTiempo`, `habilidadPersonal`, `habilidadCapital`), restando del total del depto el costo neto descontado (mínimo de 0). - **Descuentos por Habilidades:** Al realizar el pago de mantenimiento de forma normal, se aplican los descuentos de recursos (Tiempo, Personal, Capital) ganados mediante las habilidades compradas del departamento (`habilidadTiempo`, `habilidadPersonal`, `habilidadCapital`), restando del total del depto el costo neto descontado (mínimo de 0).
- **Textos e Interfaz:** Se ajustó la confirmación de penalización a: *"¿Estás seguro de que quieres pagar la penalización del proyecto..."*. Se detalla el costo original y costo neto final con descuento en el confirm del pago de mantenimiento. - **Textos e Interfaz:** Se ajustó la confirmación de penalización a: *"¿Estás seguro de que quieres pagar la penalización del proyecto..."*. Se detalla el costo original y costo neto final con descuento en el confirm del pago de mantenimiento.
- **Habilidad Especial de Operaciones:** Permite aplicar la penalización del proyecto sin costo utilizando la habilidad especial (actualizando su cooldown). - **Habilidad Especial de Operaciones:** Permite aplicar la penalización del proyecto sin costo utilizando la habilidad especial (actualizando su cooldown).
- **Redistribución de Layout (5 Columnas Superiores + Fila Inferior 20/40/40%):** Se reorganizó la vista de resumen en 2 filas. La fila superior (`top-row`) distribuye los 5 bloques de control/información horizontalmente en 5 columnas de igual proporción. La fila inferior (`main-container`) ubica Departamentos a la izquierda (20%), Proyectos Terminados al centro (40%) y Proyectos Activos a la derecha (40%).
- **Gráfica Mixta de Progresión (Barras + Líneas) con Zoom Flotante 2.5X y Persistencia:** En la parte inferior del Bloque 3 (Progresión), se integró una gráfica Canvas HTML5 que representa los Objetivos del Trimestre (almacenados en la sesión como `arregloGeneral.objetivoT1..T4`, por defecto $100,000) en **barras azules** y los Ingresos Reales por Trimestre (T1..T4) en una **línea roja con nodos y valores**. Al colocar el cursor sobre la gráfica (`mouseenter`), se despliega un panel emergente flotante alineado sobre la tarjeta del bloque con la gráfica en tamaño **2.5X ampliado** con posicionamiento dinámico anti-recorte y leyenda ajustada a la izquierda (`textAlign = 'left'`) para evitar cualquier solapamiento con los iconos. Se oculta al retirar el cursor (`mouseleave`).
### 2. Tablero de Juego ([jsCode.js](file:///c:/CHV/ludotecaLocal/Colaborando/jsCode.js)) ### 2. Tablero de Juego ([jsCode.js](file:///c:/CHV/ludotecaLocal/Colaborando/jsCode.js))
- **Visibilidad Permanente:** Se eliminaron los filtros que ocultaban el proyecto del tablero chico o grande cuando el mantenimiento ya había sido resuelto. El proyecto permanece visible tanto en el tablero como en el resumen durante la quincena actual, permitiendo seguir trabajando en él. - **Visibilidad Permanente:** Se eliminaron los filtros que ocultaban el proyecto del tablero chico o grande cuando el mantenimiento ya había sido resuelto. El proyecto permanece visible tanto en el tablero como en el resumen durante la quincena actual, permitiendo seguir trabajando en él.
- **Corrección de Proyectos Descartados (`continuamos()`):** Se actualizó la carga inicial del tablero para verificar estrictamente que el proyecto asignado a `TablaProyectoGde` tenga estatus `'En proceso'`. Si un proyecto fue descartado desde el resumen o mediante habilidad especial, al retornar al tablero ya no se cargará en `TablaProyectoGde` y desaparecerá de inmediato sin necesidad de refrescar la página.
- **Persistencia de Botones de Acción (`bAccion1` y `bAccion2`):** Se guardan los estados de selección (activado/desactivado) de las acciones 1 y 2 en `arregloGeneral.bAccion1` y `arregloGeneral.bAccion2` al pulsar `toggleColor()` y al finalizar el timer. Al navegar entre el tablero y el resumen y regresar, las acciones permanecen seleccionadas tal como las dejó el usuario.
## Cómo Realizar las Pruebas (Verificación) ## Cómo Realizar las Pruebas (Verificación)
@@ -27,3 +31,16 @@ Se ha implementado la funcionalidad solicitada para gestionar proyectos activos
- La tarjeta del proyecto en el resumen cambiará inmediatamente a un fondo gris y los botones de acción se deshabilitarán de forma definitiva en la quincena actual. - La tarjeta del proyecto en el resumen cambiará inmediatamente a un fondo gris y los botones de acción se deshabilitarán de forma definitiva en la quincena actual.
- Ve al Tablero (`colaborando2.php`) en la misma quincena (Q6) y verifica que el proyecto **sigue estando visible** en el tablero chico y en el slot de proyecto grande. - Ve al Tablero (`colaborando2.php`) en la misma quincena (Q6) y verifica que el proyecto **sigue estando visible** en el tablero chico y en el slot de proyecto grande.
- Avanza la quincena a **Q7** (Trimestre 2). Vuelve a la pantalla de resumen y verifica que el proyecto recupera su color blanco y los botones ya no aparecen (pues no es fin de trimestre), y que en el tablero continúa disponible con total normalidad. - Avanza la quincena a **Q7** (Trimestre 2). Vuelve a la pantalla de resumen y verifica que el proyecto recupera su color blanco y los botones ya no aparecen (pues no es fin de trimestre), y que en el tablero continúa disponible con total normalidad.
2. **Escenario de Descarte de Proyecto Seleccionado:**
- Selecciona un proyecto en `TablaProyectoGde` en el tablero.
- Ve al resumen (o usa la Habilidad Especial de Operaciones para "Descartar un proyecto").
- Descarta el proyecto que estaba seleccionado en `TablaProyectoGde`.
- Pulsa "Ir al Tablero".
- Verifica que el proyecto descartado **ya no aparece** en `TablaProyectoGde` ni en el tablero chico sin necesidad de refrescar la página.
3. **Escenario de Persistencia de Acciones 1 y 2:**
- En el tablero, activa los botones de acción `1` (`bAccion1`) o `2` (`bAccion2`).
- Navega al Resumen haciendo clic en "Ir al Resumen".
- Regresa al Tablero haciendo clic en "Ir al Tablero".
- Verifica que las acciones seleccionadas se mantienen activas (color azul y texto blanco).
+110 -278
View File
@@ -158,7 +158,7 @@ function llenaDepartamentoGde(depto) {
if ($('#habilidadesAcreditadasGde1').text() == '') { if ($('#habilidadesAcreditadasGde1').text() == '') {
$('#habilidadesAcreditadasGde1').html( $('#habilidadesAcreditadasGde1').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') + findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') +
' ' + ' ' +
beneficio + beneficio +
@@ -167,7 +167,7 @@ function llenaDepartamentoGde(depto) {
} else if ($('#habilidadesAcreditadasGde2').text() == '') { } else if ($('#habilidadesAcreditadasGde2').text() == '') {
$('#habilidadesAcreditadasGde2').html( $('#habilidadesAcreditadasGde2').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') + findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') +
' ' + ' ' +
beneficio + beneficio +
@@ -176,7 +176,7 @@ function llenaDepartamentoGde(depto) {
} else if ($('#habilidadesAcreditadasGde3').text() == '') { } else if ($('#habilidadesAcreditadasGde3').text() == '') {
$('#habilidadesAcreditadasGde3').html( $('#habilidadesAcreditadasGde3').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') + findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') +
' ' + ' ' +
beneficio + beneficio +
@@ -208,7 +208,7 @@ function llenaDepartamentoGde(depto) {
if ($('#habilidadesAcreditadasGde1').text() == '') { if ($('#habilidadesAcreditadasGde1').text() == '') {
$('#habilidadesAcreditadasGde1').html( $('#habilidadesAcreditadasGde1').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') + findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') +
' ' + ' ' +
beneficio + beneficio +
@@ -217,7 +217,7 @@ function llenaDepartamentoGde(depto) {
} else if ($('#habilidadesAcreditadasGde2').text() == '') { } else if ($('#habilidadesAcreditadasGde2').text() == '') {
$('#habilidadesAcreditadasGde2').html( $('#habilidadesAcreditadasGde2').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') + findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') +
' ' + ' ' +
beneficio + beneficio +
@@ -226,7 +226,7 @@ function llenaDepartamentoGde(depto) {
} else if ($('#habilidadesAcreditadasGde3').text() == '') { } else if ($('#habilidadesAcreditadasGde3').text() == '') {
$('#habilidadesAcreditadasGde3').html( $('#habilidadesAcreditadasGde3').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') + findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') +
' ' + ' ' +
beneficio + beneficio +
@@ -258,7 +258,7 @@ function llenaDepartamentoGde(depto) {
if ($('#habilidadesAcreditadasGde1').text() == '') { if ($('#habilidadesAcreditadasGde1').text() == '') {
$('#habilidadesAcreditadasGde1').html( $('#habilidadesAcreditadasGde1').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') + findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') +
' ' + ' ' +
beneficio + beneficio +
@@ -267,7 +267,7 @@ function llenaDepartamentoGde(depto) {
} else if ($('#habilidadesAcreditadasGde2').text() == '') { } else if ($('#habilidadesAcreditadasGde2').text() == '') {
$('#habilidadesAcreditadasGde2').html( $('#habilidadesAcreditadasGde2').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') + findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') +
' ' + ' ' +
beneficio + beneficio +
@@ -276,7 +276,7 @@ function llenaDepartamentoGde(depto) {
} else if ($('#habilidadesAcreditadasGde3').text() == '') { } else if ($('#habilidadesAcreditadasGde3').text() == '') {
$('#habilidadesAcreditadasGde3').html( $('#habilidadesAcreditadasGde3').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') + findArrayValue(arreglosCapacitaciones[laHabilidad], 'nombre') +
' ' + ' ' +
beneficio + beneficio +
@@ -510,15 +510,6 @@ function llenaDepartamentoChico(depto) {
console.log(`[llenaDepartamentoChico] <- FIN para depto: '${depto}'`) console.log(`[llenaDepartamentoChico] <- FIN para depto: '${depto}'`)
} }
function cuantaProyectosAsignados() {
let contador = 0
for (let i = 0; i < proyectos.length; i++) {
if (proyectos[i].estatus == 'En proceso') {
contador++
}
}
}
function limpiaProyectoChico(elProyecto) { function limpiaProyectoChico(elProyecto) {
console.log('Limpia proyecto chico', elProyecto) console.log('Limpia proyecto chico', elProyecto)
// console.log($("#" + proyectoActual + " #activoReqProyectoNom1").text()) // console.log($("#" + proyectoActual + " #activoReqProyectoNom1").text())
@@ -545,27 +536,6 @@ function limpiaProyectoChico(elProyecto) {
} }
} }
function limpiaProyectoGrande() {
console.log('Limpia proyecto grande')
$('#TablaProyectoGde').removeAttr('num')
$('#TablaProyectoGde').removeAttr('estatus')
$('#TablaProyectoGde').css('background-color', '')
$('#nombreProyectoGde').text('')
$('#descripcionProyectoGde').text('')
$('#TablaProyectoGde #puntosGanados').text('')
$('#puntosPerdidos').text('')
$('#activoReqProyectoNom1').attr('class', '').text('')
$('#activoReqProyectoNom2').attr('class', '').text('')
$('#activoReqProyectoNom3').attr('class', '').text('')
$('#activoReqProyectoCantX1').text('0')
$('#activoReqProyectoCantX2').text('0')
$('#activoReqProyectoCantX3').text('0')
$('#activoReqProyectoCant1').attr('class', '').text('')
$('#activoReqProyectoCant2').attr('class', '').text('')
$('#activoReqProyectoCant3').attr('class', '').text('')
$('#mantoGde').text('MANTENIMIENTO')
}
function llenaProyectoChico(proyectoNum) { function llenaProyectoChico(proyectoNum) {
console.log('Llenando proyectos! ', proyectoNum) console.log('Llenando proyectos! ', proyectoNum)
const colores = [ const colores = [
@@ -1603,7 +1573,7 @@ $('#accionComprarCapacitacion').click(function () {
if ($('#habilidadesAcreditadasGde1').text() == '') { if ($('#habilidadesAcreditadasGde1').text() == '') {
$('#habilidadesAcreditadasGde1').html( $('#habilidadesAcreditadasGde1').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue( findArrayValue(
arreglosCapacitaciones[habilidadAcreditadaEnEspera], arreglosCapacitaciones[habilidadAcreditadaEnEspera],
'nombre' 'nombre'
@@ -1614,7 +1584,7 @@ $('#accionComprarCapacitacion').click(function () {
) )
$('#' + deptoActual + ' #habilidadesAcreditadasCh1').html( $('#' + deptoActual + ' #habilidadesAcreditadasCh1').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue( findArrayValue(
arreglosCapacitaciones[habilidadAcreditadaEnEspera], arreglosCapacitaciones[habilidadAcreditadaEnEspera],
'nombre' 'nombre'
@@ -1622,12 +1592,12 @@ $('#accionComprarCapacitacion').click(function () {
', ' + ', ' +
beneficio + beneficio +
tipoRecurso.charAt(0).toUpperCase() + tipoRecurso.charAt(0).toUpperCase() +
'<br><br>' '<br>'
) )
} else if ($('#habilidadesAcreditadasGde2').text() == '') { } else if ($('#habilidadesAcreditadasGde2').text() == '') {
$('#habilidadesAcreditadasGde2').html( $('#habilidadesAcreditadasGde2').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue( findArrayValue(
arreglosCapacitaciones[habilidadAcreditadaEnEspera], arreglosCapacitaciones[habilidadAcreditadaEnEspera],
'nombre' 'nombre'
@@ -1638,7 +1608,7 @@ $('#accionComprarCapacitacion').click(function () {
) )
$('#' + deptoActual + ' #habilidadesAcreditadasCh2').html( $('#' + deptoActual + ' #habilidadesAcreditadasCh2').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue( findArrayValue(
arreglosCapacitaciones[habilidadAcreditadaEnEspera], arreglosCapacitaciones[habilidadAcreditadaEnEspera],
'nombre' 'nombre'
@@ -1646,12 +1616,12 @@ $('#accionComprarCapacitacion').click(function () {
', ' + ', ' +
beneficio + beneficio +
tipoRecurso.charAt(0).toUpperCase() + tipoRecurso.charAt(0).toUpperCase() +
'<br><br>' '<br>'
) )
} else if ($('#habilidadesAcreditadasGde3').text() == '') { } else if ($('#habilidadesAcreditadasGde3').text() == '') {
$('#habilidadesAcreditadasGde3').html( $('#habilidadesAcreditadasGde3').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue( findArrayValue(
arreglosCapacitaciones[habilidadAcreditadaEnEspera], arreglosCapacitaciones[habilidadAcreditadaEnEspera],
'nombre' 'nombre'
@@ -1662,7 +1632,7 @@ $('#accionComprarCapacitacion').click(function () {
) )
$('#' + deptoActual + ' #habilidadesAcreditadasCh3').html( $('#' + deptoActual + ' #habilidadesAcreditadasCh3').html(
tipo + tipo +
'<br>' + ': ' +
findArrayValue( findArrayValue(
arreglosCapacitaciones[habilidadAcreditadaEnEspera], arreglosCapacitaciones[habilidadAcreditadaEnEspera],
'nombre' 'nombre'
@@ -2754,28 +2724,7 @@ $('.droppableActivos').droppable({
}, },
}) })
function obtenerProyectosPendientesXX(cuantos) {
// Filtrar proyectos pendientes
const proyectosPendientes = proyectos.filter(
(proyecto) => proyecto.estatus === 'Pendiente'
)
// const proyectosPendientes = proyectos.filter(proyecto =>
// proyecto.estatus === "Pendiente" && proyecto.dificultad !== "Incidencia"
// );
// Si hay menos de 10 proyectos pendientes, retornar todos los disponibles
if (proyectosPendientes.length <= cuantos) {
return proyectosPendientes
}
// Seleccionar 10 proyectos aleatorios
const resultado = []
const proyectosDisponibles = [...proyectosPendientes]
for (let i = 0; i < cuantos && proyectosDisponibles.length > 0; i++) {
const randomIndex = Math.floor(Math.random() * proyectosDisponibles.length)
resultado.push(proyectosDisponibles[randomIndex])
proyectosDisponibles.splice(randomIndex, 1)
}
return resultado
}
/** /**
* Pone en el arreglo proyectosPendientes, 7 proyectos al azar de los que están pendientes en el arreglo general. * Pone en el arreglo proyectosPendientes, 7 proyectos al azar de los que están pendientes en el arreglo general.
@@ -3012,66 +2961,7 @@ function guardarNuevoTexto(nuevoTexto, deptoOriginal) {
console.log('ARREGLO:', arreglosDeptos['arr' + deptoOriginal]) console.log('ARREGLO:', arreglosDeptos['arr' + deptoOriginal])
} }
/**
* Asigna las habilidades acreditadas al departamento especificado.
*/
function asignarHabilidades2(depto) {
console.log('>>>>>> Asignando habilidades al departamento:', depto)
// Obtiene el arreglo del departamento especificado
const elArregloDepto = arreglosDeptos['arr' + depto]
// Lista de habilidades a asignar en orden de prioridad
const habilidades = [
'habilidadTiempo',
'habilidadPersonal',
'habilidadCapital',
]
// Arreglo para almacenar las habilidades asignadas
const habilidadesAsignadas = [0, 0, 0]
// Asigna las habilidades en orden de prioridad
habilidades.forEach((habilidad, index) => {
// Encuentra el valor de la habilidad en el arreglo del departamento
const value = elArregloDepto.find((item) => item.name === habilidad).value
// Si el valor no es cero y no está ya asignado, se asigna a habilidadesAsignadas
if (value !== 0 && !habilidadesAsignadas.includes(value)) {
habilidadesAsignadas[index] = value
}
})
// Actualiza el DOM con las habilidades asignadas
habilidadesAsignadas.forEach((habilidad, index) => {
if (habilidad !== 0) {
// Obtiene la capacitación correspondiente a la habilidad
const capacitacion = arreglosCapacitaciones[habilidad]
// Obtiene y mapea el tipo de habilidad a un nombre más descriptivo
const tipo = mapTipo(obtenerValorCapacitacion(capacitacion, 'tipo'))
// Obtiene el nombre, beneficio y tipo de recurso de la capacitación
const nombre = obtenerValorCapacitacion(capacitacion, 'nombre')
const beneficio = obtenerValorCapacitacion(capacitacion, 'beneficio')
const tipoRecurso = obtenerValorCapacitacion(capacitacion, 'tipoRecurso')
.charAt(0)
.toUpperCase()
// Construye el contenido HTML a insertar
const contenido = `${tipo}<br>${nombre}, ${beneficio} ${tipoRecurso}<br><br>`
// Actualiza el contenido HTML del elemento correspondiente en el DOM
$(`#${depto} #habilidadesAcreditadasCh${index + 1}`).html(contenido)
}
})
tieneTresHabilidades(depto)
// Asegura que la vista grande se actualice con la acción especial si es el depto actual
if (depto === deptoActual) {
const elArreglo = arreglosDeptos['arr' + depto]
const accion = findArrayValue(elArreglo, 'accionEspecialQuincenal')
$('#' + depto + ' #accionEspecialGde').text(accion)
}
}
/** /**
* Asigna las habilidades acreditadas al departamento especificado. * Asigna las habilidades acreditadas al departamento especificado.
@@ -3121,9 +3011,9 @@ function asignarHabilidades(depto) {
console.log('Capacitación:', capacitacion) console.log('Capacitación:', capacitacion)
console.log('Tipo:', tipo) console.log('Tipo:', tipo)
const contenido = `${tipo}<br>${nombre}, ${beneficio} ${tipoRecurso const contenido = `${tipo}: ${nombre}, ${beneficio} ${tipoRecurso
.charAt(0) .charAt(0)
.toUpperCase()}<br><br>` .toUpperCase()}<br>`
$(`#${depto} #habilidadesAcreditadasCh${index + 1}`).html(contenido) $(`#${depto} #habilidadesAcreditadasCh${index + 1}`).html(contenido)
} }
}) })
@@ -3198,136 +3088,7 @@ function tieneTresHabilidades(depto) {
return completo return completo
} }
/**
* Asigna las habilidades acreditadas al departamento especificado.
**/
function asignarHabilidades0(depto) {
console.log('>>>>>> Asignando habilidades al departamento:', depto)
let habilidad1 = 0
let habilidad2 = 0
let habilidad3 = 0
const elArregloDepto = arreglosDeptos['arr' + depto]
// console.log(elArregloDepto)
const habilidadTiempo = elArregloDepto.find(
(item) => item.name === 'habilidadTiempo'
).value
const habilidadPersonal = elArregloDepto.find(
(item) => item.name === 'habilidadPersonal'
).value
const habilidadCapital = elArregloDepto.find(
(item) => item.name === 'habilidadCapital'
).value
// console.log('habilidadTiempo:', habilidadTiempo)
// console.log('habilidadPersonal:', habilidadPersonal)
// console.log('habilidadCapital:', habilidadCapital)
if (habilidadTiempo != 0) {
habilidad1 = habilidadTiempo
} else if (habilidadPersonal != 0) {
habilidad1 = habilidadPersonal
} else if (habilidadCapital != 0) {
habilidad1 = habilidadCapital
}
if (habilidadTiempo != 0 && habilidadTiempo != habilidad1) {
habilidad2 = habilidadTiempo
} else if (habilidadPersonal != 0 && habilidadPersonal != habilidad1) {
habilidad2 = habilidadPersonal
} else if (habilidadCapital != 0 && habilidadCapital != habilidad1) {
habilidad2 = habilidadCapital
}
if (
habilidadTiempo != 0 &&
habilidadTiempo != habilidad1 &&
habilidadTiempo != habilidad2
) {
habilidad3 = habilidadTiempo
} else if (
habilidadPersonal != 0 &&
habilidadPersonal != habilidad1 &&
habilidadPersonal != habilidad2
) {
habilidad3 = habilidadPersonal
} else if (
habilidadCapital != 0 &&
habilidadCapital != habilidad1 &&
habilidadCapital != habilidad2
) {
habilidad3 = habilidadCapital
}
console.log('laHabilidad1: ', habilidad1)
console.log('laHabilidad2: ', habilidad2)
console.log('laHabilidad3: ', habilidad3)
if (habilidad1 != 0) {
console.log('laCapacitacion:', arreglosCapacitaciones[habilidad1])
let tipo = findArrayValue(arreglosCapacitaciones[habilidad1], 'tipo')
if (tipo == 'HC') {
tipo = 'Habilidad Conceptual'
} else if (tipo == 'HT') {
tipo = 'Habilidad Técnica'
} else if (tipo == 'HH') {
tipo = 'Habilidad Humana'
}
$('#' + depto + ' #habilidadesAcreditadasCh1').html(
tipo +
'<br>' +
findArrayValue(arreglosCapacitaciones[habilidad1], 'nombre') +
', ' +
findArrayValue(arreglosCapacitaciones[habilidad1], 'beneficio') +
findArrayValue(arreglosCapacitaciones[habilidad1], 'tipoRecurso')
.charAt(0)
.toUpperCase() +
'<br><br>'
)
}
if (habilidad2 != 0) {
console.log('laCapacitacion:', arreglosCapacitaciones[habilidad2])
let tipo = findArrayValue(arreglosCapacitaciones[habilidad2], 'tipo')
if (tipo == 'HC') {
tipo = 'Habilidad Conceptual'
} else if (tipo == 'HT') {
tipo = 'Habilidad Técnica'
} else if (tipo == 'HH') {
tipo = 'Habilidad Humana'
}
$('#' + depto + ' #habilidadesAcreditadasCh2').html(
tipo +
'<br>' +
findArrayValue(arreglosCapacitaciones[habilidad2], 'nombre') +
', ' +
findArrayValue(arreglosCapacitaciones[habilidad2], 'beneficio') +
findArrayValue(arreglosCapacitaciones[habilidad2], 'tipoRecurso')
.charAt(0)
.toUpperCase() +
'<br><br>'
)
}
if (habilidad3 != 0) {
console.log('laCapacitacion:', arreglosCapacitaciones[habilidad3])
let tipo = findArrayValue(arreglosCapacitaciones[habilidad3], 'tipo')
if (tipo == 'HC') {
tipo = 'Habilidad Conceptual'
} else if (tipo == 'HT') {
tipo = 'Habilidad Técnica'
} else if (tipo == 'HH') {
tipo = 'Habilidad Humana'
}
$('#' + depto + ' #habilidadesAcreditadasCh3').html(
tipo +
'<br>' +
findArrayValue(arreglosCapacitaciones[habilidad3], 'nombre') +
', ' +
findArrayValue(arreglosCapacitaciones[habilidad3], 'beneficio') +
findArrayValue(arreglosCapacitaciones[habilidad3], 'tipoRecurso')
.charAt(0)
.toUpperCase() +
'<br><br>'
)
}
}
/** /**
* Función que se ejecuta al iniciar el juego, DESPUES de cargar los arreglos de activos y departamentos. * Función que se ejecuta al iniciar el juego, DESPUES de cargar los arreglos de activos y departamentos.
@@ -3350,6 +3111,37 @@ function continuamos() {
$('#nombreSesion').text('Sesión: ' + arregloGeneral.nombreSesion) $('#nombreSesion').text('Sesión: ' + arregloGeneral.nombreSesion)
} }
// Restablecer el estado de los botones de acción (bAccion1 y bAccion2)
if (typeof arregloGeneral !== 'undefined') {
if (parseInt(arregloGeneral.bAccion1) === 1) {
$('#bAccion1').css({ 'background-color': '#068bc3', 'color': 'white' })
if (document.getElementById('bAccion1')) {
document.getElementById('bAccion1').style.backgroundColor = '#068bc3'
document.getElementById('bAccion1').style.color = 'white'
}
} else {
$('#bAccion1').css({ 'background-color': '', 'color': 'black' })
if (document.getElementById('bAccion1')) {
document.getElementById('bAccion1').style.backgroundColor = ''
document.getElementById('bAccion1').style.color = 'black'
}
}
if (parseInt(arregloGeneral.bAccion2) === 1) {
$('#bAccion2').css({ 'background-color': '#068bc3', 'color': 'white' })
if (document.getElementById('bAccion2')) {
document.getElementById('bAccion2').style.backgroundColor = '#068bc3'
document.getElementById('bAccion2').style.color = 'white'
}
} else {
$('#bAccion2').css({ 'background-color': '', 'color': 'black' })
if (document.getElementById('bAccion2')) {
document.getElementById('bAccion2').style.backgroundColor = ''
document.getElementById('bAccion2').style.color = 'black'
}
}
}
asignarHabilidades('RecursosHumanos') asignarHabilidades('RecursosHumanos')
asignarHabilidades('MarketingYVentas') asignarHabilidades('MarketingYVentas')
asignarHabilidades('Finanzas') asignarHabilidades('Finanzas')
@@ -3425,21 +3217,28 @@ function continuamos() {
const quincenaCargada = parseInt(arregloGeneral.quincena) || 1 const quincenaCargada = parseInt(arregloGeneral.quincena) || 1
const trimestreActual = Math.floor((quincenaCargada - 1) / 6) + 1 const trimestreActual = Math.floor((quincenaCargada - 1) / 6) + 1
// 1. Usar el ID del proyecto grande que se guardó en la sesión, si no está completado. // 1. Usar el ID del proyecto grande que se guardó en la sesión, únicamente si sigue 'En proceso'.
let proyectoGde = null let proyectoGde = null
console.log('ID de proyecto grande guardado:', proyectoGdeActual) console.log('ID de proyecto grande guardado:', proyectoGdeActual)
if ( if (
proyectoGdeActual !== undefined && proyectoGdeActual !== undefined &&
proyectoGdeActual !== null && proyectoGdeActual !== null &&
proyectoGdeActual !== '' && proyectoGdeActual !== '' &&
proyectos[proyectoGdeActual].estatus !== 'Completado' proyectos[proyectoGdeActual] &&
proyectos[proyectoGdeActual].estatus === 'En proceso'
) { ) {
proyectoGde = proyectos[proyectoGdeActual] proyectoGde = proyectos[proyectoGdeActual]
} else { } else {
// Fallback por si no se encuentra un ID guardado o si estaba completado. // Fallback por si no se encuentra un ID guardado o si estaba completado o descartado.
proyectoGde = proyectos.find( proyectoGde = proyectos.find((p) => p.estatus === 'En proceso')
(p) => p.estatus === 'En proceso' || p.estatus === 'En siguientes' if (!proyectoGde) {
) proyectoGde = proyectos.find((p) => p.estatus === 'En siguientes')
}
if (proyectoGde) {
proyectoGdeActual = proyectos.findIndex((p) => p.id === proyectoGde.id)
} else {
proyectoGdeActual = ''
}
} }
// 2. Limpiar los slots de proyectos chicos primero. // 2. Limpiar los slots de proyectos chicos primero.
@@ -3497,14 +3296,17 @@ function continuamos() {
} }
sincronizarColaSiguientes() sincronizarColaSiguientes()
// 5. Llenar el proyecto grande. // 5. Llenar o limpiar el proyecto grande.
if (proyectoGde) { if (proyectoGde && (proyectoGde.estatus === 'En proceso' || proyectoGde.estatus === 'En siguientes')) {
llenaProyectoGde(proyectoGde.id) llenaProyectoGde(proyectoGde.id)
} else if (siguientesProyectos.length > 0) { } else if (siguientesProyectos.length > 0) {
// Si no había ningún proyecto en el tablero, tomar el primero de la cola. // Si no había ningún proyecto en el tablero, tomar el primero de la cola.
llenaProyectoGde(siguientesProyectos[0].id) llenaProyectoGde(siguientesProyectos[0].id)
siguientesProyectos.splice(0, 1) siguientesProyectos.splice(0, 1)
sincronizarColaSiguientes() sincronizarColaSiguientes()
} else {
limpiarProyectoGde()
proyectoGdeActual = ''
} }
} }
@@ -3658,11 +3460,25 @@ function relojUpdateTime() {
function relojPlaySound() { function relojPlaySound() {
const audio = new Audio('Microwave_bell.wav') const audio = new Audio('Microwave_bell.wav')
if ($('#bAccion2').css('background-color') === 'rgb(6, 139, 195)') { const bg2 = $('#bAccion2').css('background-color')
$('#bAccion1').css('background-color', '') if (bg2 === 'rgb(6, 139, 195)' || bg2 === '#068bc3') {
$('#bAccion1').css('color', 'black') $('#bAccion1').css({ 'background-color': '', 'color': 'black' })
$('#bAccion2').css('background-color', '') $('#bAccion2').css({ 'background-color': '', 'color': 'black' })
$('#bAccion2').css('color', 'black') if (document.getElementById('bAccion1')) {
document.getElementById('bAccion1').style.backgroundColor = ''
document.getElementById('bAccion1').style.color = 'black'
}
if (document.getElementById('bAccion2')) {
document.getElementById('bAccion2').style.backgroundColor = ''
document.getElementById('bAccion2').style.color = 'black'
}
if (typeof arregloGeneral !== 'undefined') {
arregloGeneral.bAccion1 = 0
arregloGeneral.bAccion2 = 0
if (typeof guardaSesion === 'function') {
guardaSesion()
}
}
} }
audio.play() audio.play()
} }
@@ -3684,13 +3500,29 @@ function relojResumeTimer() {
} }
function toggleColor(button) { function toggleColor(button) {
console.log(button.style.backgroundColor) const $btn = $(button)
if (button.style.backgroundColor === 'rgb(6, 139, 195)') { const id = $btn.attr('id')
button.style.backgroundColor = '' // Restablecer al color original const bg = $btn.css('background-color')
button.style.color = 'black' // Cambiar el texto a negro const isSelected = (bg === 'rgb(6, 139, 195)' || bg === '#068bc3' || button.style.backgroundColor === 'rgb(6, 139, 195)' || button.style.backgroundColor === '#068bc3')
if (isSelected) {
$btn.css({ 'background-color': '', 'color': 'black' })
button.style.backgroundColor = ''
button.style.color = 'black'
if (id && typeof arregloGeneral !== 'undefined') {
arregloGeneral[id] = 0
}
} else { } else {
button.style.backgroundColor = '#068bc3' // Cambiar a azul $btn.css({ 'background-color': '#068bc3', 'color': 'white' })
button.style.color = 'white' // Cambiar el texto a blanco button.style.backgroundColor = '#068bc3'
button.style.color = 'white'
if (id && typeof arregloGeneral !== 'undefined') {
arregloGeneral[id] = 1
}
}
if (typeof guardaSesion === 'function') {
guardaSesion()
} }
} }
+18
View File
@@ -71,6 +71,24 @@ function cargarDatosDesdeServidor() {
if (typeof arregloGeneral.trimestre4 === 'undefined') { if (typeof arregloGeneral.trimestre4 === 'undefined') {
arregloGeneral.trimestre4 = 0 arregloGeneral.trimestre4 = 0
} }
if (typeof arregloGeneral.objetivoT1 === 'undefined') {
arregloGeneral.objetivoT1 = 100000
}
if (typeof arregloGeneral.objetivoT2 === 'undefined') {
arregloGeneral.objetivoT2 = 100000
}
if (typeof arregloGeneral.objetivoT3 === 'undefined') {
arregloGeneral.objetivoT3 = 100000
}
if (typeof arregloGeneral.objetivoT4 === 'undefined') {
arregloGeneral.objetivoT4 = 100000
}
if (typeof arregloGeneral.bAccion1 === 'undefined') {
arregloGeneral.bAccion1 = 0
}
if (typeof arregloGeneral.bAccion2 === 'undefined') {
arregloGeneral.bAccion2 = 0
}
// --- FIN DEL PARCHE --- // --- FIN DEL PARCHE ---
arreglosCapacitaciones = data.data.arreglosCapacitaciones arreglosCapacitaciones = data.data.arreglosCapacitaciones
arreglosActivos = data.data.arreglosActivos arreglosActivos = data.data.arreglosActivos
File diff suppressed because one or more lines are too long
+645 -393
View File
File diff suppressed because it is too large Load Diff