Compare commits
2 Commits
8b321f47d7
...
e80bfbcd77
Author | SHA1 | Date |
---|---|---|
|
e80bfbcd77 | |
|
f00c01838e |
|
@ -0,0 +1,44 @@
|
|||
/* editorPiscina.css */
|
||||
#canvasFormacion {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
background-color: #e3f4ff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 0 8px rgba(0,0,0,0.1);
|
||||
position: relative;
|
||||
margin-bottom: 20px;
|
||||
border: 2px solid #007bff;
|
||||
background-image: linear-gradient(to right, transparent 49%, #999 50%, transparent 51%);
|
||||
background-size: 100% 100%;
|
||||
}
|
||||
|
||||
.atleta-icono {
|
||||
position: absolute;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border-radius: 50%;
|
||||
font-size: 12px;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.3);
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.atleta-volador { background-color: #a259ff; }
|
||||
.atleta-pilar { background-color: #007bff; }
|
||||
.atleta-grupoA { border: 2px solid #28a745; }
|
||||
.atleta-grupoB { border: 2px solid #ffc107; }
|
||||
|
||||
.flecha-mirada {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 6px solid transparent;
|
||||
border-right: 6px solid transparent;
|
||||
border-bottom: 10px solid #444;
|
||||
position: absolute;
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
#poolCanvas {
|
||||
background-color: #cceeff;
|
||||
border: 2px solid #007bff;
|
||||
border-radius: 6px;
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.info {
|
||||
font-weight: bold;
|
||||
margin-top: 1rem;
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
const canvas = document.getElementById("poolCanvas");
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
let currentAtleta = null;
|
||||
let rutinaId = new URLSearchParams(window.location.search).get("routineId");
|
||||
let atletas = [];
|
||||
let colocados = [];
|
||||
|
||||
function drawPool() {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillStyle = "#cceeff";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(canvas.width / 2, 0);
|
||||
ctx.lineTo(canvas.width / 2, canvas.height);
|
||||
ctx.strokeStyle = "#555";
|
||||
ctx.setLineDash([6, 4]);
|
||||
ctx.stroke();
|
||||
ctx.setLineDash([]);
|
||||
|
||||
colocados.forEach(({ x, y, atleta }) => drawAthlete(x, y, atleta));
|
||||
}
|
||||
|
||||
function drawAthlete(x, y, atleta) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, 14, 0, Math.PI * 2);
|
||||
ctx.fillStyle = "#ff4444";
|
||||
ctx.fill();
|
||||
ctx.lineWidth = 2;
|
||||
ctx.strokeStyle = "#fff";
|
||||
ctx.stroke();
|
||||
|
||||
ctx.fillStyle = "#fff";
|
||||
ctx.font = "bold 12px sans-serif";
|
||||
ctx.textAlign = "center";
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.fillText(atleta.idPersonalizado, x, y);
|
||||
}
|
||||
|
||||
canvas.addEventListener("click", (e) => {
|
||||
if (!currentAtleta) return;
|
||||
|
||||
const rect = canvas.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
const y = e.clientY - rect.top;
|
||||
|
||||
if (x < 0 || y < 0 || x > canvas.width || y > canvas.height) return;
|
||||
|
||||
if (colocados.find(a => a.atleta.idPersonalizado === currentAtleta.idPersonalizado)) {
|
||||
alert("Este atleta ya fue colocado.");
|
||||
return;
|
||||
}
|
||||
|
||||
colocados.push({ x, y, atleta: currentAtleta });
|
||||
updateLegend(currentAtleta);
|
||||
drawPool();
|
||||
currentAtleta = null;
|
||||
});
|
||||
|
||||
function updateLegend(atleta) {
|
||||
const li = document.createElement("li");
|
||||
li.textContent = `${atleta.idPersonalizado}: ${atleta.atletaId?.name || 'Desconocido'} (${atleta.rol})`;
|
||||
document.getElementById("legend").appendChild(li);
|
||||
}
|
||||
|
||||
function enablePlacement() {
|
||||
const index = document.getElementById("athleteSelect").value;
|
||||
if (index >= 0) {
|
||||
currentAtleta = atletas[index];
|
||||
}
|
||||
}
|
||||
|
||||
async function loadRoutine() {
|
||||
try {
|
||||
const res = await fetch(`/routines/${rutinaId}`);
|
||||
const data = await res.json();
|
||||
|
||||
document.getElementById("routineTitle").textContent = data.nombreCompetencia;
|
||||
document.getElementById("routineType").textContent = data.tipoCompetencia;
|
||||
document.getElementById("routineMode").textContent = data.modalidad;
|
||||
|
||||
atletas = data.participantes;
|
||||
const select = document.getElementById("athleteSelect");
|
||||
|
||||
if (!atletas || atletas.length === 0) {
|
||||
select.innerHTML = `<option disabled>No hay atletas</option>`;
|
||||
return;
|
||||
}
|
||||
|
||||
atletas.forEach((a, i) => {
|
||||
const opt = document.createElement("option");
|
||||
opt.value = i;
|
||||
opt.textContent = `${a.idPersonalizado} - ${a.atletaId?.name || 'Desconocido'} (${a.rol})`;
|
||||
select.appendChild(opt);
|
||||
});
|
||||
|
||||
drawPool();
|
||||
} catch (err) {
|
||||
console.error("Error cargando rutina:", err);
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("DOMContentLoaded", loadRoutine);
|
|
@ -1,6 +1,67 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="es">
|
||||
<head>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Editor de Formación</title>
|
||||
<link rel="stylesheet" href="css/editorPiscina.css">
|
||||
<link rel="stylesheet" href="css/piscina.css">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
|
||||
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary fixed-top">
|
||||
<div class="container-fluid">
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav ms-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="coach.html">Inicializar Rutina</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="equipoDisponibles.html">Equipos Disponibles</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#otroLink2">Catalogo de formaciones</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="container mt-5 pt-5">
|
||||
<h2 id="routineTitle">Cargando nombre...</h2>
|
||||
<p><strong>Tipo:</strong> <span id="routineType">Cargando...</span></p>
|
||||
<p><strong>Modalidad:</strong> <span id="routineMode">Cargando...</span></p>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="athleteSelect" class="form-label">Selecciona atleta:</label>
|
||||
<select id="athleteSelect" class="form-select"></select>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-success mb-3" onclick="enablePlacement()">Añadir atleta a la formación</button>
|
||||
<canvas id="poolCanvas" width="1000" height="300"></canvas>
|
||||
|
||||
<button class="btn btn-primary mt-3">Guardar Formación</button>
|
||||
|
||||
<div class="info">
|
||||
<ul id="legend" class="mt-3"></ul>
|
||||
</div>
|
||||
|
||||
<h5 class="mt-4">Simbología</h5>
|
||||
<ul>
|
||||
<li><strong>1</strong>: Axel</li>
|
||||
<li><strong>axel, =</strong>: Pilar</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<script src="js/piscina.js"></script>
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Detalles de la Rutina</title>
|
||||
|
|
|
@ -71,3 +71,16 @@ router.post('/', async (req, res) => {
|
|||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
// Ruta para obtener una rutina específica por ID
|
||||
router.get('/:id', async (req, res) => {
|
||||
try {
|
||||
const routine = await Routine.findById(req.params.id)
|
||||
.populate('participantes.atletaId', 'name'); // para obtener nombres
|
||||
res.json(routine);
|
||||
} catch (error) {
|
||||
console.error('❌ Error al obtener rutina por ID:', error);
|
||||
res.status(500).json({ error: 'Error cargando rutina' });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue