<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Seguimiento Integral - Plan de Transformación</title>
<link href="https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.4.0/css/all.min.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
.section { display: none; }
.section.active { display: block; }
.nav-item.active { background-color: #3B82F6; color: white; }
.chart-container { height: 400px; }
.photo-comparison { max-height: 300px; }
</style>
</head>
<body class="bg-gray-100 font-sans">
<div class="min-h-screen">
<!-- Header -->
<header class="bg-blue-600 text-white p-4 shadow-lg">
<div class="container mx-auto flex justify-between items-center">
<h1 class="text-2xl font-bold"><i class="fas fa-heartbeat mr-2"></i>Plan de Transformación</h1>
<div class="flex items-center space-x-4">
<button onclick="exportData()" class="bg-blue-500 hover:bg-blue-700 px-3 py-2 rounded">
<i class="fas fa-download mr-1"></i>Exportar
</button>
<button onclick="importData()" class="bg-green-500 hover:bg-green-700 px-3 py-2 rounded">
<i class="fas fa-upload mr-1"></i>Importar
</button>
</div>
</div>
</header>
<!-- Navigation -->
<nav class="bg-white shadow-md p-2 overflow-x-auto">
<div class="container mx-auto">
<div class="flex space-x-2 min-w-max">
<button onclick="showSection('dashboard')" class="nav-item px-4 py-2 rounded hover:bg-gray-100 whitespace-nowrap active">
<i class="fas fa-tachometer-alt mr-2"></i>Dashboard
</button>
<button onclick="showSection('alimentacion')" class="nav-item px-4 py-2 rounded hover:bg-gray-100 whitespace-nowrap">
<i class="fas fa-utensils mr-2"></i>Alimentación
</button>
<button onclick="showSection('entrenamientos')" class="nav-item px-4 py-2 rounded hover:bg-gray-100 whitespace-nowrap">
<i class="fas fa-dumbbell mr-2"></i>Entrenamientos
</button>
<button onclick="showSection('sueno')" class="nav-item px-4 py-2 rounded hover:bg-gray-100 whitespace-nowrap">
<i class="fas fa-bed mr-2"></i>Sueño
</button>
<button onclick="showSection('medidas')" class="nav-item px-4 py-2 rounded hover:bg-gray-100 whitespace-nowrap">
<i class="fas fa-weight mr-2"></i>Medidas
</button>
<button onclick="showSection('fotos')" class="nav-item px-4 py-2 rounded hover:bg-gray-100 whitespace-nowrap">
<i class="fas fa-camera mr-2"></i>Fotos
</button>
<button onclick="showSection('suplementos')" class="nav-item px-4 py-2 rounded hover:bg-gray-100 whitespace-nowrap">
<i class="fas fa-pills mr-2"></i>Suplementos
</button>
<button onclick="showSection('sintomas')" class="nav-item px-4 py-2 rounded hover:bg-gray-100 whitespace-nowrap">
<i class="fas fa-thermometer-half mr-2"></i>Síntomas
</button>
<button onclick="showSection('objetivos')" class="nav-item px-4 py-2 rounded hover:bg-gray-100 whitespace-nowrap">
<i class="fas fa-target mr-2"></i>Objetivos
</button>
<button onclick="showSection('reportes')" class="nav-item px-4 py-2 rounded hover:bg-gray-100 whitespace-nowrap">
<i class="fas fa-chart-line mr-2"></i>Reportes
</button>
</div>
</div>
</nav>
<!-- Main Content -->
<main class="container mx-auto p-4">
<!-- Dashboard Section -->
<div id="dashboard" class="section active">
<h2 class="text-3xl font-bold mb-6 text-gray-800">Dashboard Principal</h2>
<!-- Resumen diario -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
<div class="bg-white p-6 rounded-lg shadow-md">
<div class="flex items-center justify-between">
<div>
<h3 class="text-lg font-semibold text-gray-700">Peso Actual</h3>
<p id="peso-actual" class="text-3xl font-bold text-blue-600">80.0 kg</p>
</div>
<i class="fas fa-weight text-4xl text-blue-500"></i>
</div>
</div>
<div class="bg-white p-6 rounded-lg shadow-md">
<div class="flex items-center justify-between">
<div>
<h3 class="text-lg font-semibold text-gray-700">Objetivo</h3>
<p class="text-3xl font-bold text-green-600">70.0 kg</p>
</div>
<i class="fas fa-target text-4xl text-green-500"></i>
</div>
</div>
<div class="bg-white p-6 rounded-lg shadow-md">
<div class="flex items-center justify-between">
<div>
<h3 class="text-lg font-semibold text-gray-700">Progreso</h3>
<p id="progreso-peso" class="text-3xl font-bold text-purple-600">0.0 kg</p>
</div>
<i class="fas fa-chart-line text-4xl text-purple-500"></i>
</div>
</div>
<div class="bg-white p-6 rounded-lg shadow-md">
<div class="flex items-center justify-between">
<div>
<h3 class="text-lg font-semibold text-gray-700">Sueño (anoche)</h3>
<p id="calidad-sueno" class="text-3xl font-bold text-indigo-600">- / 10</p>
</div>
<i class="fas fa-moon text-4xl text-indigo-500"></i>
</div>
</div>
</div>
<!-- Registro rápido -->
<div class="bg-white rounded-lg shadow-md p-6 mb-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Registro Rápido - Hoy</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Peso (kg)</label>
<input type="number" id="quick-weight" step="0.1" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Calidad del sueño (1-10)</label>
<input type="number" id="quick-sleep" min="1" max="10" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Energía (1-10)</label>
<input type="number" id="quick-energy" min="1" max="10" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
</div>
<button onclick="saveQuickData()" class="mt-4 bg-blue-500 hover:bg-blue-700 text-white px-6 py-2 rounded-md">
<i class="fas fa-save mr-2"></i>Guardar
</button>
</div>
<!-- Actividades de hoy -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Plan de Hoy</h3>
<div id="plan-hoy" class="space-y-2">
<!-- Se llena dinámicamente -->
</div>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Progreso Semanal</h3>
<div class="chart-container">
<canvas id="progress-chart"></canvas>
</div>
</div>
</div>
</div>
<!-- Alimentación Section -->
<div id="alimentacion" class="section">
<h2 class="text-3xl font-bold mb-6 text-gray-800">Alimentación Diaria</h2>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Registro de Hoy</h3>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Tipo de Día</label>
<select id="tipo-dia" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
<option value="keto">Keto Estricta (1350 kcal)</option>
<option value="fuerza">Día Fuerza (1600 kcal)</option>
<option value="refeed">Refeed (2100 kcal)</option>
<option value="libre">Libre Saludable (1800 kcal)</option>
</select>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Comida 1 (12:00)</label>
<textarea id="comida1" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500" rows="3" placeholder="Describe tu primera comida..."></textarea>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Cena (19:30)</label>
<textarea id="cena" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500" rows="3" placeholder="Describe tu cena..."></textarea>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Hora último líquido</label>
<input type="time" id="ultimo-liquido" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">¿Tomó vino?</label>
<select id="vino" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
<option value="no">No</option>
<option value="si">Sí</option>
</select>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Adherencia al plan (1-10)</label>
<input type="number" id="adherencia" min="1" max="10" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<button onclick="saveAlimentacion()" class="w-full bg-green-500 hover:bg-green-700 text-white py-2 rounded-md">
<i class="fas fa-save mr-2"></i>Guardar Alimentación
</button>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Historial Alimentación</h3>
<div id="historial-alimentacion" class="space-y-4 max-h-96 overflow-y-auto">
<!-- Se llena dinámicamente -->
</div>
</div>
</div>
</div>
<!-- Entrenamientos Section -->
<div id="entrenamientos" class="section">
<h2 class="text-3xl font-bold mb-6 text-gray-800">Entrenamientos</h2>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Registro de Entrenamiento</h3>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Tipo de Entrenamiento</label>
<select id="tipo-entrenamiento" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
<option value="fuerza1">Fuerza 1 - Tren Superior</option>
<option value="fuerza2">Fuerza 2 - Tren Inferior</option>
<option value="aerobico">Aeróbico Zona 2</option>
<option value="electro">Electroestimulación</option>
</select>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Duración (minutos)</label>
<input type="number" id="duracion" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Intensidad (1-10)</label>
<input type="number" id="intensidad" min="1" max="10" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Ejercicios realizados</label>
<textarea id="ejercicios" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500" rows="4" placeholder="Lista de ejercicios, series y repeticiones..."></textarea>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Sensación post-entreno (1-10)</label>
<input type="number" id="sensacion" min="1" max="10" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Notas</label>
<textarea id="notas-entrenamiento" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500" rows="2" placeholder="Observaciones, mejoras, dificultades..."></textarea>
</div>
<button onclick="saveEntrenamiento()" class="w-full bg-blue-500 hover:bg-blue-700 text-white py-2 rounded-md">
<i class="fas fa-save mr-2"></i>Guardar Entrenamiento
</button>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Historial Entrenamientos</h3>
<div id="historial-entrenamientos" class="space-y-4 max-h-96 overflow-y-auto">
<!-- Se llena dinámicamente -->
</div>
<div class="mt-6">
<h4 class="text-lg font-semibold mb-2">Progreso Fuerza</h4>
<div class="chart-container">
<canvas id="fuerza-chart"></canvas>
</div>
</div>
</div>
</div>
</div>
<!-- Sueño Section -->
<div id="sueno" class="section">
<h2 class="text-3xl font-bold mb-6 text-gray-800">Sueño y Descanso</h2>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Registro de Sueño</h3>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Fecha</label>
<input type="date" id="fecha-sueno" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Hora de acostarse</label>
<input type="time" id="hora-dormir" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Hora de levantarse</label>
<input type="time" id="hora-despertar" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Número de despertares</label>
<input type="number" id="despertares" min="0" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Causas de despertares</label>
<div class="space-y-2">
<label class="flex items-center">
<input type="checkbox" id="causa-bano" class="mr-2">
<span>Ir al baño</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="causa-perros" class="mr-2">
<span>Perros</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="causa-sofocos" class="mr-2">
<span>Sofocos</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="causa-ansiedad" class="mr-2">
<span>Ansiedad/Estrés</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="causa-otros" class="mr-2">
<span>Otros</span>
</label>
</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Calidad del sueño (1-10)</label>
<input type="number" id="calidad-sueno-input" min="1" max="10" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Energía al despertar (1-10)</label>
<input type="number" id="energia-despertar" min="1" max="10" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Notas</label>
<textarea id="notas-sueno" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500" rows="3" placeholder="Observaciones sobre el sueño..."></textarea>
</div>
<button onclick="saveSueno()" class="w-full bg-indigo-500 hover:bg-indigo-700 text-white py-2 rounded-md">
<i class="fas fa-save mr-2"></i>Guardar Sueño
</button>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Análisis del Sueño</h3>
<div class="chart-container mb-6">
<canvas id="sueno-chart"></canvas>
</div>
<div class="grid grid-cols-2 gap-4 text-center">
<div class="bg-blue-100 p-4 rounded-lg">
<h4 class="font-semibold text-blue-800">Promedio Semanal</h4>
<p id="promedio-sueno" class="text-2xl font-bold text-blue-600">-</p>
</div>
<div class="bg-green-100 p-4 rounded-lg">
<h4 class="font-semibold text-green-800">Horas Promedio</h4>
<p id="promedio-horas" class="text-2xl font-bold text-green-600">-</p>
</div>
</div>
</div>
</div>
</div>
<!-- Medidas Section -->
<div id="medidas" class="section">
<h2 class="text-3xl font-bold mb-6 text-gray-800">Medidas y Peso</h2>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Registro de Medidas</h3>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Fecha</label>
<input type="date" id="fecha-medidas" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Peso (kg)</label>
<input type="number" id="peso" step="0.1" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">IMC</label>
<input type="number" id="imc" step="0.1" readonly class="w-full p-2 border rounded-md bg-gray-100">
</div>
</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Cintura (cm)</label>
<input type="number" id="cintura" step="0.1" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Cadera (cm)</label>
<input type="number" id="cadera" step="0.1" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
</div>
<div class="grid grid-cols-2 gap-4 mb-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Muslo (cm)</label>
<input type="number" id="muslo" step="0.1" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Brazo (cm)</label>
<input type="number" id="brazo" step="0.1" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Notas</label>
<textarea id="notas-medidas" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500" rows="2" placeholder="Observaciones sobre las medidas..."></textarea>
</div>
<button onclick="saveMedidas()" class="w-full bg-purple-500 hover:bg-purple-700 text-white py-2 rounded-md">
<i class="fas fa-save mr-2"></i>Guardar Medidas
</button>
<div class="mt-4 p-4 bg-gray-100 rounded-lg">
<h4 class="font-semibold mb-2">Calculadoras</h4>
<div class="space-y-2">
<button onclick="calcularTMB()" class="bg-gray-500 hover:bg-gray-700 text-white px-3 py-1 rounded text-sm">
Calcular TMB
</button>
<button onclick="calcularTDEE()" class="bg-gray-500 hover:bg-gray-700 text-white px-3 py-1 rounded text-sm">
Calcular TDEE
</button>
</div>
<div id="calculadoras-result" class="mt-2 text-sm"></div>
</div>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Evolución del Peso</h3>
<div class="chart-container mb-4">
<canvas id="peso-chart"></canvas>
</div>
<h3 class="text-xl font-bold mb-4 text-gray-800">Evolución de Medidas</h3>
<div class="chart-container">
<canvas id="medidas-chart"></canvas>
</div>
</div>
</div>
</div>
<!-- Fotos Section -->
<div id="fotos" class="section">
<h2 class="text-3xl font-bold mb-6 text-gray-800">Fotos de Progreso</h2>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Subir Nueva Foto</h3>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Fecha</label>
<input type="date" id="fecha-foto" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Tipo de foto</label>
<select id="tipo-foto" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
<option value="frente">Frente</option>
<option value="perfil">Perfil</option>
<option value="espalda">Espalda</option>
</select>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Seleccionar foto</label>
<input type="file" id="foto-input" accept="image/*" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Notas</label>
<textarea id="notas-foto" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500" rows="2" placeholder="Observaciones sobre la foto..."></textarea>
</div>
<button onclick="saveFoto()" class="w-full bg-green-500 hover:bg-green-700 text-white py-2 rounded-md">
<i class="fas fa-camera mr-2"></i>Guardar Foto
</button>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Comparación de Progreso</h3>
<div class="mb-4">
<select id="comparacion-tipo" onchange="loadComparacion()" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
<option value="frente">Frente</option>
<option value="perfil">Perfil</option>
<option value="espalda">Espalda</option>
</select>
</div>
<div id="comparacion-fotos" class="grid grid-cols-2 gap-4">
<div class="text-center">
<h4 class="font-semibold mb-2">Primera foto</h4>
<div id="foto-inicial" class="bg-gray-200 h-64 rounded-lg flex items-center justify-center">
<span class="text-gray-500">Sin foto</span>
</div>
<p id="fecha-inicial" class="text-sm text-gray-600 mt-2">-</p>
</div>
<div class="text-center">
<h4 class="font-semibold mb-2">Última foto</h4>
<div id="foto-actual" class="bg-gray-200 h-64 rounded-lg flex items-center justify-center">
<span class="text-gray-500">Sin foto</span>
</div>
<p id="fecha-actual" class="text-sm text-gray-600 mt-2">-</p>
</div>
</div>
</div>
</div>
<div class="mt-6 bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Galería de Fotos</h3>
<div id="galeria-fotos" class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
<!-- Se llena dinámicamente -->
</div>
</div>
</div>
<!-- Suplementos Section -->
<div id="suplementos" class="section">
<h2 class="text-3xl font-bold mb-6 text-gray-800">Suplementos</h2>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Registro Diario</h3>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Fecha</label>
<input type="date" id="fecha-suplementos" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="space-y-3">
<h4 class="font-semibold text-gray-700">Mañana (7:00)</h4>
<div class="grid grid-cols-2 gap-2 text-sm">
<label class="flex items-center">
<input type="checkbox" id="vitamina-c" class="mr-2">
<span>Vitamina C (1g)</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="complejo-b" class="mr-2">
<span>Complejo B</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="rhodiola" class="mr-2">
<span>Rhodiola (opcional)</span>
</label>
</div>
<h4 class="font-semibold text-gray-700">Con primera comida (12:00)</h4>
<div class="grid grid-cols-2 gap-2 text-sm">
<label class="flex items-center">
<input type="checkbox" id="omega-3" class="mr-2">
<span>Omega-3 (2-3g)</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="vitamina-d" class="mr-2">
<span>Vitamina D3+K2</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="creatina-medio" class="mr-2">
<span>Creatina (días aeróbicos)</span>
</label>
</div>
<h4 class="font-semibold text-gray-700">Post-entreno</h4>
<div class="grid grid-cols-2 gap-2 text-sm">
<label class="flex items-center">
<input type="checkbox" id="creatina-post" class="mr-2">
<span>Creatina (días fuerza)</span>
</label>
</div>
<h4 class="font-semibold text-gray-700">Con cena (19:30)</h4>
<div class="grid grid-cols-2 gap-2 text-sm">
<label class="flex items-center">
<input type="checkbox" id="probiotico" class="mr-2">
<span>Probiótico</span>
</label>
</div>
<h4 class="font-semibold text-gray-700">Antes de dormir (22:00)</h4>
<div class="grid grid-cols-2 gap-2 text-sm">
<label class="flex items-center">
<input type="checkbox" id="magnesio" class="mr-2">
<span>Magnesio (300mg)</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="ashwagandha" class="mr-2">
<span>Ashwagandha (400mg)</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="zinc" class="mr-2">
<span>Zinc (10mg)</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="inositol" class="mr-2">
<span>Inositol (opcional)</span>
</label>
</div>
</div>
<div class="mt-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Notas</label>
<textarea id="notas-suplementos" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500" rows="2" placeholder="Observaciones sobre suplementos..."></textarea>
</div>
<button onclick="saveSupplementos()" class="mt-4 w-full bg-yellow-500 hover:bg-yellow-700 text-white py-2 rounded-md">
<i class="fas fa-save mr-2"></i>Guardar Suplementos
</button>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Adherencia Semanal</h3>
<div class="chart-container">
<canvas id="suplementos-chart"></canvas>
</div>
<div class="mt-4">
<h4 class="font-semibold mb-2">Resumen Actual</h4>
<div id="resumen-suplementos" class="space-y-2 text-sm">
<!-- Se llena dinámicamente -->
</div>
</div>
</div>
</div>
</div>
<!-- Síntomas Section -->
<div id="sintomas" class="section">
<h2 class="text-3xl font-bold mb-6 text-gray-800">Síntomas y Bienestar</h2>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Registro de Síntomas</h3>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Fecha</label>
<input type="date" id="fecha-sintomas" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="space-y-4">
<div>
<h4 class="font-semibold text-gray-700 mb-2">Síntomas Premenopáusicos</h4>
<div class="grid grid-cols-2 gap-2 text-sm">
<label class="flex items-center">
<input type="checkbox" id="sofocos" class="mr-2">
<span>Sofocos</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="sudores" class="mr-2">
<span>Sudores nocturnos</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="cambios-humor" class="mr-2">
<span>Cambios de humor</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="irritabilidad" class="mr-2">
<span>Irritabilidad</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="fatiga" class="mr-2">
<span>Fatiga</span>
</label>
<label class="flex items-center">
<input type="checkbox" id="dolores-articulares" class="mr-2">
<span>Dolores articulares</span>
</label>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Intensidad sofocos (0-10)</label>
<input type="number" id="intensidad-sofocos" min="0" max="10" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Estado de ánimo (1-10)</label>
<input type="number" id="estado-animo" min="1" max="10" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Nivel de estrés (1-10)</label>
<input type="number" id="nivel-estres" min="1" max="10" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Antojos alimentarios</label>
<select id="antojos" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
<option value="ninguno">Ninguno</option>
<option value="dulce">Dulce</option>
<option value="salado">Salado</option>
<option value="grasas">Grasas</option>
<option value="carbohidratos">Carbohidratos</option>
</select>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Notas adicionales</label>
<textarea id="notas-sintomas" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500" rows="3" placeholder="Describe otros síntomas o sensaciones..."></textarea>
</div>
</div>
<button onclick="saveSintomas()" class="mt-4 w-full bg-red-500 hover:bg-red-700 text-white py-2 rounded-md">
<i class="fas fa-save mr-2"></i>Guardar Síntomas
</button>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Tendencias de Bienestar</h3>
<div class="chart-container mb-4">
<canvas id="bienestar-chart"></canvas>
</div>
<div class="grid grid-cols-2 gap-4 text-center">
<div class="bg-blue-100 p-3 rounded-lg">
<h4 class="font-semibold text-blue-800">Estado Ánimo</h4>
<p id="promedio-animo" class="text-xl font-bold text-blue-600">-</p>
</div>
<div class="bg-orange-100 p-3 rounded-lg">
<h4 class="font-semibold text-orange-800">Nivel Estrés</h4>
<p id="promedio-estres" class="text-xl font-bold text-orange-600">-</p>
</div>
</div>
<div class="mt-4">
<h4 class="font-semibold mb-2">Síntomas Frecuentes</h4>
<div id="sintomas-frecuentes" class="text-sm space-y-1">
<!-- Se llena dinámicamente -->
</div>
</div>
</div>
</div>
</div>
<!-- Objetivos Section -->
<div id="objetivos" class="section">
<h2 class="text-3xl font-bold mb-6 text-gray-800">Configuración y Objetivos</h2>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Datos Personales</h3>
<div class="grid grid-cols-2 gap-4 mb-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Edad</label>
<input type="number" id="edad" value="49" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Altura (cm)</label>
<input type="number" id="altura" value="152" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Peso inicial (kg)</label>
<input type="number" id="peso-inicial" value="80" step="0.1" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Peso objetivo (kg)</label>
<input type="number" id="peso-objetivo" value="70" step="0.1" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Fecha inicio del plan</label>
<input type="date" id="fecha-inicio" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label class="block text-sm font-medium text-gray-700 mb-2">Objetivo de tiempo (meses)</label>
<input type="number" id="tiempo-objetivo" value="6" class="w-full p-2 border rounded-md focus:ring-2 focus:ring-blue-500">
</div>
<button onclick="saveObjetivos()" class="w-full bg-green-500 hover:bg-green-700 text-white py-2 rounded-md">
<i class="fas fa-save mr-2"></i>Guardar Configuración
</button>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Progreso hacia Objetivos</h3>
<div class="space-y-4">
<div>
<div class="flex justify-between items-center mb-2">
<span class="text-sm font-medium">Pérdida de Peso</span>
<span id="progreso-porcentaje" class="text-sm font-medium">0%</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-2">
<div id="progreso-barra" class="bg-blue-600 h-2 rounded-full" style="width: 0%"></div>
</div>
<p class="text-xs text-gray-500 mt-1">
<span id="peso-perdido">0</span> kg de <span id="peso-total-perder">10</span> kg perdidos
</p>
</div>
<div>
<h4 class="font-semibold mb-2">Tiempo transcurrido</h4>
<p id="tiempo-transcurrido" class="text-lg">-</p>
</div>
<div>
<h4 class="font-semibold mb-2">Tiempo restante estimado</h4>
<p id="tiempo-restante" class="text-lg">-</p>
</div>
<div>
<h4 class="font-semibold mb-2">Ritmo actual</h4>
<p id="ritmo-actual" class="text-lg">- kg/semana</p>
</div>
</div>
<div class="mt-6 p-4 bg-gray-100 rounded-lg">
<h4 class="font-semibold mb-2">Objetivos Secundarios</h4>
<div class="text-sm space-y-1">
<div class="flex justify-between">
<span>Mejora del sueño:</span>
<span id="objetivo-sueno" class="font-medium">En progreso</span>
</div>
<div class="flex justify-between">
<span>Reducir síntomas:</span>
<span id="objetivo-sintomas" class="font-medium">En progreso</span>
</div>
<div class="flex justify-between">
<span>Aumentar fuerza:</span>
<span id="objetivo-fuerza" class="font-medium">En progreso</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Reportes Section -->
<div id="reportes" class="section">
<h2 class="text-3xl font-bold mb-6 text-gray-800">Reportes y Análisis</h2>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Resumen General</h3>
<div class="space-y-4">
<div class="flex justify-between items-center p-3 bg-gray-50 rounded-lg">
<span>Días registrados:</span>
<span id="dias-registrados" class="font-bold">0</span>
</div>
<div class="flex justify-between items-center p-3 bg-gray-50 rounded-lg">
<span>Entrenamientos completados:</span>
<span id="entrenamientos-completados" class="font-bold">0</span>
</div>
<div class="flex justify-between items-center p-3 bg-gray-50 rounded-lg">
<span>Adherencia alimentaria promedio:</span>
<span id="adherencia-promedio" class="font-bold">-%</span>
</div>
<div class="flex justify-between items-center p-3 bg-gray-50 rounded-lg">
<span>Calidad del sueño promedio:</span>
<span id="sueno-promedio-reporte" class="font-bold">- / 10</span>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Tendencias</h3>
<div class="chart-container">
<canvas id="tendencias-chart"></canvas>
</div>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-lg font-bold mb-4 text-gray-800">Top Síntomas</h3>
<div id="top-sintomas" class="space-y-2">
<!-- Se llena dinámicamente -->
</div>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-lg font-bold mb-4 text-gray-800">Mejores Días</h3>
<div id="mejores-dias" class="space-y-2">
<!-- Se llena dinámicamente -->
</div>
</div>
<div class="bg-white rounded-lg shadow-md p-6">
<h3 class="text-lg font-bold mb-4 text-gray-800">Correlaciones</h3>
<div id="correlaciones" class="space-y-2 text-sm">
<!-- Se llena dinámicamente -->
</div>
</div>
</div>
<div class="mt-6 bg-white rounded-lg shadow-md p-6">
<h3 class="text-xl font-bold mb-4 text-gray-800">Exportar Reportes</h3>
<div class="flex space-x-4">
<button onclick="generarReporteSemanal()" class="bg-blue-500 hover:bg-blue-700 text-white px-4 py-2 rounded-md">
<i class="fas fa-file-pdf mr-2"></i>Reporte Semanal
</button>
<button onclick="generarReporteMensual()" class="bg-green-500 hover:bg-green-700 text-white px-4 py-2 rounded-md">
<i class="fas fa-calendar mr-2"></i>Reporte Mensual
</button>
<button onclick="exportarCSV()" class="bg-purple-500 hover:bg-purple-700 text-white px-4 py-2 rounded-md">
<i class="fas fa-table mr-2"></i>Exportar CSV
</button>
</div>
</div>
</div>
</main>
</div>
<!-- Import File Input (hidden) -->
<input type="file" id="import-file" accept=".json" style="display: none;">
<script>
// Variables globales
let currentSection = 'dashboard';
let charts = {};
// Inicialización
document.addEventListener('DOMContentLoaded', function() {
initializeApp();
updateDashboard();
loadAllCharts();
});
// Funciones de navegación
function showSection(sectionId) {
document.querySelectorAll('.section').forEach(section => {
section.classList.remove('active');
});
document.querySelectorAll('.nav-item').forEach(item => {
item.classList.remove('active');
});
document.getElementById(sectionId).classList.add('active');
event.target.classList.add('active');
currentSection = sectionId;
// Cargar datos específicos de la sección
switch(sectionId) {
case 'dashboard':
updateDashboard();
break;
case 'alimentacion':
loadHistorialAlimentacion();
break;
case 'entrenamientos':
loadHistorialEntrenamientos();
break;
case 'medidas':
loadMedidasChart();
break;
case 'fotos':
loadGaleriaFotos();
break;
case 'reportes':
updateReportes();
break;
}
}
// Inicialización de la app
function initializeApp() {
// Establecer fechas por defecto
const today = new Date().toISOString().split('T')[0];
document.getElementById('fecha-sueno').value = today;
document.getElementById('fecha-medidas').value = today;
document.getElementById('fecha-foto').value = today;
document.getElementById('fecha-suplementos').value = today;
document.getElementById('fecha-sintomas').value = today;
// Cargar configuración si existe
loadObjetivos();
// Calcular IMC en tiempo real
document.getElementById('peso').addEventListener('input', calcularIMC);
// Configurar plan del día según el día de la semana
updatePlanDelDia();
}
// Funciones de almacenamiento
function saveData(key, data) {
localStorage.setItem(key, JSON.stringify(data));
}
function loadData(key) {
const data = localStorage.getItem(key);
return data ? JSON.parse(data) : [];
}
function saveRecord(type, record) {
const records = loadData(type);
record.id = Date.now();
record.fecha = record.fecha || new Date().toISOString().split('T')[0];
records.push(record);
saveData(type, records);
}
// Dashboard functions
function updateDashboard() {
const medidas = loadData('medidas');
const suenos = loadData('suenos');
const objetivos = loadData('objetivos');
if (medidas.length > 0) {
const ultimoPeso = medidas[medidas.length - 1].peso;
document.getElementById('peso-actual').textContent = `${ultimoPeso} kg`;
if (objetivos.pesoInicial) {
const progreso = objetivos.pesoInicial - ultimoPeso;
document.getElementById('progreso-peso').textContent = `${progreso.toFixed(1)} kg`;
}
}
if (suenos.length > 0) {
const ultimoSueno = suenos[suenos.length - 1].calidad;
document.getElementById('calidad-sueno').textContent = `${ultimoSueno} / 10`;
}
updatePlanDelDia();
updateProgressChart();
}
function updatePlanDelDia() {
const planHoy = document.getElementById('plan-hoy');
const today = new Date();
const dayOfWeek = today.getDay(); // 0 = domingo, 1 = lunes, etc.
let plan = '';
switch(dayOfWeek) {
case 1: // Lunes
plan = '<div class="flex items-center p-2 bg-blue-100 rounded"><i class="fas fa-running mr-2 text-blue-600"></i>Aeróbico Zona 2 (45 min) - 7:00</div><div class="flex items-center p-2 bg-green-100 rounded mt-2"><i class="fas fa-utensils mr-2 text-green-600"></i>Keto Estricta (1350 kcal)</div>';
break;
case 2: // Martes
plan = '<div class="flex items-center p-2 bg-red-100 rounded"><i class="fas fa-dumbbell mr-2 text-red-600"></i>Fuerza 1 - Tren Superior (45 min) - 7:00</div><div class="flex items-center p-2 bg-yellow-100 rounded mt-2"><i class="fas fa-utensils mr-2 text-yellow-600"></i>Día Fuerza (1600 kcal)</div>';
break;
case 3: // Miércoles
plan = '<div class="flex items-center p-2 bg-blue-100 rounded"><i class="fas fa-running mr-2 text-blue-600"></i>Aeróbico Zona 2 (45 min) - 7:00</div><div class="flex items-center p-2 bg-green-100 rounded mt-2"><i class="fas fa-utensils mr-2 text-green-600"></i>Keto Estricta (1350 kcal)</div>';
break;
case 4: // Jueves
plan = '<div class="flex items-center p-2 bg-red-100 rounded"><i class="fas fa-dumbbell mr-2 text-red-600"></i>Fuerza 2 - Tren Inferior (40 min) - 7:00</div><div class="flex items-center p-2 bg-yellow-100 rounded mt-2"><i class="fas fa-utensils mr-2 text-yellow-600"></i>Día Fuerza (1600 kcal)</div>';
break;
case 5: // Viernes
plan = '<div class="flex items-center p-2 bg-blue-100 rounded"><i class="fas fa-running mr-2 text-blue-600"></i>Aeróbico Ligero (30 min) - 7:00</div><div class="flex items-center p-2 bg-green-100 rounded mt-2"><i class="fas fa-utensils mr-2 text-green-600"></i>Keto Estricta (1350 kcal)</div>';
break;
case 6: // Sábado
plan = '<div class="flex items-center p-2 bg-purple-100 rounded"><i class="fas fa-bolt mr-2 text-purple-600"></i>Electroestimulación (30 min) - 7:00</div><div class="flex items-center p-2 bg-orange-100 rounded mt-2"><i class="fas fa-utensils mr-2 text-orange-600"></i>Refeed (2100 kcal)</div>';
break;
case 0: // Domingo
plan = '<div class="flex items-center p-2 bg-gray-100 rounded"><i class="fas fa-bed mr-2 text-gray-600"></i>Descanso Activo (20-30 min opcional)</div><div class="flex items-center p-2 bg-indigo-100 rounded mt-2"><i class="fas fa-utensils mr-2 text-indigo-600"></i>Libre Saludable (1800 kcal)</div>';
break;
}
planHoy.innerHTML = plan;
}
function saveQuickData() {
const weight = document.getElementById('quick-weight').value;
const sleep = document.getElementById('quick-sleep').value;
const energy = document.getElementById('quick-energy').value;
if (weight) {
saveRecord('medidas', {
peso: parseFloat(weight),
fecha: new Date().toISOString().split('T')[0]
});
}
if (sleep || energy) {
saveRecord('quick-data', {
sleep: parseInt(sleep),
energy: parseInt(energy),
fecha: new Date().toISOString().split('T')[0]
});
}
// Limpiar campos
document.getElementById('quick-weight').value = '';
document.getElementById('quick-sleep').value = '';
document.getElementById('quick-energy').value = '';
alert('Datos guardados correctamente');
updateDashboard();
}
// Funciones de Alimentación
function saveAlimentacion() {
const record = {
tipoDia: document.getElementById('tipo-dia').value,
comida1: document.getElementById('comida1').value,
cena: document.getElementById('cena').value,
ultimoLiquido: document.getElementById('ultimo-liquido').value,
vino: document.getElementById('vino').value,
adherencia: parseInt(document.getElementById('adherencia').value)
};
saveRecord('alimentacion', record);
alert('Alimentación guardada correctamente');
loadHistorialAlimentacion();
// Limpiar formulario
document.getElementById('comida1').value = '';
document.getElementById('cena').value = '';
document.getElementById('ultimo-liquido').value = '';
document.getElementById('adherencia').value = '';
}
function loadHistorialAlimentacion() {
const historial = loadData('alimentacion').slice(-7); // Últimos 7 días
const container = document.getElementById('historial-alimentacion');
container.innerHTML = historial.map(record => `
<div class="border-l-4 border-blue-500 pl-4 py-2">
<div class="flex justify-between items-center">
<h4 class="font-semibold">${record.fecha}</h4>
<span class="text-sm px-2 py-1 rounded ${getTipoDiaClass(record.tipoDia)}">${getTipoDiaText(record.tipoDia)}</span>
</div>
<p class="text-sm text-gray-600 mt-1">Adherencia: ${record.adherencia}/10</p>
${record.vino === 'si' ? '<p class="text-sm text-orange-600">🍷 Vino</p>' : ''}
</div>
`).join('');
}
function getTipoDiaClass(tipo) {
const classes = {
'keto': 'bg-green-100 text-green-800',
'fuerza': 'bg-blue-100 text-blue-800',
'refeed': 'bg-orange-100 text-orange-800',
'libre': 'bg-purple-100 text-purple-800'
};
return classes[tipo] || 'bg-gray-100 text-gray-800';
}
function getTipoDiaText(tipo) {
const texts = {
'keto': 'Keto',
'fuerza': 'Fuerza',
'refeed': 'Refeed',
'libre': 'Libre'
};
return texts[tipo] || tipo;
}
// Funciones de Entrenamientos
function saveEntrenamiento() {
const record = {
tipo: document.getElementById('tipo-entrenamiento').value,
duracion: parseInt(document.getElementById('duracion').value),
intensidad: parseInt(document.getElementById('intensidad').value),
ejercicios: document.getElementById('ejercicios').value,
sensacion: parseInt(document.getElementById('sensacion').value),
notas: document.getElementById('notas-entrenamiento').value
};
saveRecord('entrenamientos', record);
alert('Entrenamiento guardado correctamente');
loadHistorialEntrenamientos();
// Limpiar formulario
document.getElementById('duracion').value = '';
document.getElementById('intensidad').value = '';
document.getElementById('ejercicios').value = '';
document.getElementById('sensacion').value = '';
document.getElementById('notas-entrenamiento').value = '';
}
function loadHistorialEntrenamientos() {
const historial = loadData('entrenamientos').slice(-10);
const container = document.getElementById('historial-entrenamientos');
container.innerHTML = historial.map(record => `
<div class="border rounded p-3">
<div class="flex justify-between items-center mb-2">
<h4 class="font-semibold">${record.fecha}</h4>
<span class="text-sm px-2 py-1 rounded ${getTipoEntrenamientoClass(record.tipo)}">${getTipoEntrenamientoText(record.tipo)}</span>
</div>
<div class="grid grid-cols-2 gap-2 text-sm text-gray-600">
<p>⏱️ ${record.duracion} min</p>
<p>💪 Intensidad: ${record.intensidad}/10</p>
<p>😊 Sensación: ${record.sensacion}/10</p>
</div>
${record.notas ? `<p class="text-sm mt-2">${record.notas}</p>` : ''}
</div>
`).join('');
}
function getTipoEntrenamientoClass(tipo) {
const classes = {
'fuerza1': 'bg-red-100 text-red-800',
'fuerza2': 'bg-red-100 text-red-800',
'aerobico': 'bg-blue-100 text-blue-800',
'electro': 'bg-purple-100 text-purple-800'
};
return classes[tipo] || 'bg-gray-100 text-gray-800';
}
function getTipoEntrenamientoText(tipo) {
const texts = {
'fuerza1': 'Fuerza Superior',
'fuerza2': 'Fuerza Inferior',
'aerobico': 'Aeróbico',
'electro': 'Electro'
};
return texts[tipo] || tipo;
}
// Funciones de Sueño
function saveSueno() {
const causas = [];
if (document.getElementById('causa-bano').checked) causas.push('baño');
if (document.getElementById('causa-perros').checked) causas.push('perros');
if (document.getElementById('causa-sofocos').checked) causas.push('sofocos');
if (document.getElementById('causa-ansiedad').checked) causas.push('ansiedad');
if (document.getElementById('causa-otros').checked) causas.push('otros');
const record = {
fecha: document.getElementById('fecha-sueno').value,
horaDormir: document.getElementById('hora-dormir').value,
horaDespertar: document.getElementById('hora-despertar').value,
despertares: parseInt(document.getElementById('despertares').value),
causas: causas,
calidad: parseInt(document.getElementById('calidad-sueno-input').value),
energia: parseInt(document.getElementById('energia-despertar').value),
notas: document.getElementById('notas-sueno').value
};
saveRecord('suenos', record);
alert('Registro de sueño guardado correctamente');
updateSuenoStats();
}
function updateSuenoStats() {
const suenos = loadData('suenos').slice(-7); // Última semana
if (suenos.length > 0) {
const promedio = suenos.reduce((sum, s) => sum + s.calidad, 0) / suenos.length;
document.getElementById('promedio-sueno').textContent = promedio.toFixed(1);
// Calcular horas promedio
const horasPromedio = suenos.map(s => {
if (s.horaDormir && s.horaDespertar) {
const dormir = new Date(`2000-01-01T${s.horaDormir}`);
const despertar = new Date(`2000-01-02T${s.horaDespertar}`);
return (despertar - dormir) / (1000 * 60 * 60);
}
return 0;
}).filter(h => h > 0);
if (horasPromedio.length > 0) {
const promHoras = horasPromedio.reduce((sum, h) => sum + h, 0) / horasPromedio.length;
document.getElementById('promedio-horas').textContent = `${promHoras.toFixed(1)}h`;
}
}
}
// Funciones de Medidas
function saveMedidas() {
const record = {
fecha: document.getElementById('fecha-medidas').value,
peso: parseFloat(document.getElementById('peso').value),
cintura: parseFloat(document.getElementById('cintura').value),
cadera: parseFloat(document.getElementById('cadera').value),
muslo: parseFloat(document.getElementById('muslo').value),
brazo: parseFloat(document.getElementById('brazo').value),
notas: document.getElementById('notas-medidas').value
};
record.imc = calcularIMCValue(record.peso, loadData('objetivos').altura || 152);
saveRecord('medidas', record);
alert('Medidas guardadas correctamente');
loadMedidasChart();
updateDashboard();
}
function calcularIMC() {
const peso = parseFloat(document.getElementById('peso').value);
const altura = loadData('objetivos').altura || 152;
if (peso && altura) {
const imc = calcularIMCValue(peso, altura);
document.getElementById('imc').value = imc;
}
}
function calcularIMCValue(peso, altura) {
return (peso / ((altura / 100) ** 2)).toFixed(1);
}
function calcularTMB() {
const objetivos = loadData('objetivos');
if (objetivos.edad && objetivos.altura) {
const medidas = loadData('medidas');
const peso = medidas.length > 0 ? medidas[medidas.length - 1].peso : objetivos.pesoInicial || 80;
// Fórmula Mifflin-St Jeor para mujeres
const tmb = (10 * peso) + (6.25 * objetivos.altura) - (5 * objetivos.edad) - 161;
document.getElementById('calculadoras-result').innerHTML = `<strong>TMB:</strong> ${tmb.toFixed(0)} kcal/día`;
}
}
function calcularTDEE() {
const objetivos = loadData('objetivos');
if (objetivos.edad && objetivos.altura) {
const medidas = loadData('medidas');
const peso = medidas.length > 0 ? medidas[medidas.length - 1].peso : objetivos.pesoInicial || 80;
const tmb = (10 * peso) + (6.25 * objetivos.altura) - (5 * objetivos.edad) - 161;
const tdeeDescanso = (tmb * 1.35).toFixed(0);
const tdeeElectro = (tmb * 1.45).toFixed(0);
const tdeeFuerza = (tmb * 1.55).toFixed(0);
document.getElementById('calculadoras-result').innerHTML = `
<div><strong>TDEE Descanso:</strong> ${tdeeDescanso} kcal</div>
<div><strong>TDEE Electro:</strong> ${tdeeElectro} kcal</div>
<div><strong>TDEE Fuerza:</strong> ${tdeeFuerza} kcal</div>
`;
}
}
// Funciones de Fotos
function saveFoto() {
const fileInput = document.getElementById('foto-input');
const file = fileInput.files[0];
if (!file) {
alert('Por favor selecciona una foto');
return;
}
const reader = new FileReader();
reader.onload = function(e) {
const record = {
fecha: document.getElementById('fecha-foto').value,
tipo: document.getElementById('tipo-foto').value,
imagen: e.target.result,
notas: document.getElementById('notas-foto').value
};
saveRecord('fotos', record);
alert('Foto guardada correctamente');
loadGaleriaFotos();
loadComparacion();
// Limpiar formulario
fileInput.value = '';
document.getElementById('notas-foto').value = '';
};
reader.readAsDataURL(file);
}
function loadGaleriaFotos() {
const fotos = loadData('fotos');
const galeria = document.getElementById('galeria-fotos');
galeria.innerHTML = fotos.slice(-12).map(foto => `
<div class="relative group">
<img src="${foto.imagen}" alt="${foto.tipo}" class="w-full h-32 object-cover rounded-lg cursor-pointer hover:opacity-75" onclick="viewFullPhoto('${foto.imagen}', '${foto.fecha}', '${foto.tipo}')">
<div class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-50 text-white p-2 text-xs rounded-b-lg">
<p>${foto.fecha}</p>
<p>${foto.tipo}</p>
</div>
</div>
`).join('');
}
function loadComparacion() {
const tipo = document.getElementById('comparacion-tipo').value;
const fotos = loadData('fotos').filter(f => f.tipo === tipo);
if (fotos.length >= 2) {
const primera = fotos[0];
const ultima = fotos[fotos.length - 1];
document.getElementById('foto-inicial').innerHTML = `<img src="${primera.imagen}" class="w-full h-full object-cover rounded-lg">`;
document.getElementById('foto-actual').innerHTML = `<img src="${ultima.imagen}" class="w-full h-full object-cover rounded-lg">`;
document.getElementById('fecha-inicial').textContent = primera.fecha;
document.getElementById('fecha-actual').textContent = ultima.fecha;
} else {
document.getElementById('foto-inicial').innerHTML = '<span class="text-gray-500">Sin foto</span>';
document.getElementById('foto-actual').innerHTML = '<span class="text-gray-500">Sin foto</span>';
}
}
function viewFullPhoto(src, fecha, tipo) {
// Crear modal para ver foto completa
const modal = document.createElement('div');
modal.className = 'fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50';
modal.onclick = () => modal.remove();
modal.innerHTML = `
<div class="max-w-4xl max-h-full p-4">
<img src="${src}" class="max-w-full max-h-full object-contain">
<div class="text-white text-center mt-2">
<p>${fecha} - ${tipo}</p>
</div>
</div>
`;
document.body.appendChild(modal);
}
// Funciones de Suplementos
function saveSupplementos() {
const record = {
fecha: document.getElementById('fecha-suplementos').value,
vitaminaC: document.getElementById('vitamina-c').checked,
complejoB: document.getElementById('complejo-b').checked,
rhodiola: document.getElementById('rhodiola').checked,
omega3: document.getElementById('omega-3').checked,
vitaminaD: document.getElementById('vitamina-d').checked,
creatinaMedio: document.getElementById('creatina-medio').checked,
creatinaPost: document.getElementById('creatina-post').checked,
probiotico: document.getElementById('probiotico').checked,
magnesio: document.getElementById('magnesio').checked,
ashwagandha: document.getElementById('ashwagandha').checked,
zinc: document.getElementById('zinc').checked,
inositol: document.getElementById('inositol').checked,
notas: document.getElementById('notas-suplementos').value
};
saveRecord('suplementos', record);
alert('Suplementos guardados correctamente');
updateResumenSupplementos();
}
function updateResumenSupplementos() {
const suplementos = loadData('suplementos').slice(-7); // Última semana
const resumen = document.getElementById('resumen-suplementos');
if (suplementos.length > 0) {
const adherencias = {
'Magnesio': suplementos.filter(s => s.magnesio).length,
'Ashwagandha': suplementos.filter(s => s.ashwagandha).length,
'Vitamina C': suplementos.filter(s => s.vitaminaC).length,
'Omega-3': suplementos.filter(s => s.omega3).length,
};
resumen.innerHTML = Object.entries(adherencias).map(([supl, count]) =>
`<div class="flex justify-between"><span>${supl}:</span><span>${count}/7 días</span></div>`
).join('');
}
}
// Funciones de Síntomas
function saveSintomas() {
const record = {
fecha: document.getElementById('fecha-sintomas').value,
sofocos: document.getElementById('sofocos').checked,
sudores: document.getElementById('sudores').checked,
cambiosHumor: document.getElementById('cambios-humor').checked,
irritabilidad: document.getElementById('irritabilidad').checked,
fatiga: document.getElementById('fatiga').checked,
doloresArticulares: document.getElementById('dolores-articulares').checked,
intensidadSofocos: parseInt(document.getElementById('intensidad-sofocos').value) || 0,
estadoAnimo: parseInt(document.getElementById('estado-animo').value),
nivelEstres: parseInt(document.getElementById('nivel-estres').value),
antojos: document.getElementById('antojos').value,
notas: document.getElementById('notas-sintomas').value
};
saveRecord('sintomas', record);
alert('Síntomas guardados correctamente');
updateBienestarStats();
}
function updateBienestarStats() {
const sintomas = loadData('sintomas').slice(-7); // Última semana
if (sintomas.length > 0) {
const promedioAnimo = sintomas.reduce((sum, s) => sum + (s.estadoAnimo || 5), 0) / sintomas.length;
const promedioEstres = sintomas.reduce((sum, s) => sum + (s.nivelEstres || 5), 0) / sintomas.length;
document.getElementById('promedio-animo').textContent = promedioAnimo.toFixed(1);
document.getElementById('promedio-estres').textContent = promedioEstres.toFixed(1);
// Síntomas más frecuentes
const sintomasFrecuentes = {
'Sofocos': sintomas.filter(s => s.sofocos).length,
'Sudores': sintomas.filter(s => s.sudores).length,
'Cambios humor': sintomas.filter(s => s.cambiosHumor).length,
'Irritabilidad': sintomas.filter(s => s.irritabilidad).length,
'Fatiga': sintomas.filter(s => s.fatiga).length
};
const sorted = Object.entries(sintomasFrecuentes)
.sort(([,a], [,b]) => b - a)
.slice(0, 3);
document.getElementById('sintomas-frecuentes').innerHTML = sorted
.map(([sintoma, count]) => `<div class="flex justify-between"><span>${sintoma}:</span><span>${count}/7 días</span></div>`)
.join('');
}
}
// Funciones de Objetivos
function saveObjetivos() {
const objetivos = {
edad: parseInt(document.getElementById('edad').value),
altura: parseInt(document.getElementById('altura').value),
pesoInicial: parseFloat(document.getElementById('peso-inicial').value),
pesoObjetivo: parseFloat(document.getElementById('peso-objetivo').value),
fechaInicio: document.getElementById('fecha-inicio').value,
tiempoObjetivo: parseInt(document.getElementById('tiempo-objetivo').value)
};
saveData('objetivos', objetivos);
alert('Configuración guardada correctamente');
updateObjetivosProgress();
}
function loadObjetivos() {
const objetivos = loadData('objetivos');
if (Object.keys(objetivos).length > 0) {
document.getElementById('edad').value = objetivos.edad || 49;
document.getElementById('altura').value = objetivos.altura || 152;
document.getElementById('peso-inicial').value = objetivos.pesoInicial || 80;
document.getElementById('peso-objetivo').value = objetivos.pesoObjetivo || 70;
document.getElementById('fecha-inicio').value = objetivos.fechaInicio || '';
document.getElementById('tiempo-objetivo').value = objetivos.tiempoObjetivo || 6;
updateObjetivosProgress();
}
}
function updateObjetivosProgress() {
const objetivos = loadData('objetivos');
const medidas = loadData('medidas');
if (Object.keys(objetivos).length > 0 && medidas.length > 0) {
const pesoActual = medidas[medidas.length - 1].peso;
const totalPerder = objetivos.pesoInicial - objetivos.pesoObjetivo;
const pesoPerdido = objetivos.pesoInicial - pesoActual;
const porcentaje = Math.max(0, Math.min(100, (pesoPerdido / totalPerder) * 100));
document.getElementById('peso-perdido').textContent = pesoPerdido.toFixed(1);
document.getElementById('peso-total-perder').textContent = totalPerder.toFixed(1);
document.getElementById('progreso-porcentaje').textContent = `${porcentaje.toFixed(1)}%`;
document.getElementById('progreso-barra').style.width = `${porcentaje}%`;
// Calcular tiempo transcurrido
if (objetivos.fechaInicio) {
const inicio = new Date(objetivos.fechaInicio);
const ahora = new Date();
const diasTranscurridos = Math.floor((ahora - inicio) / (1000 * 60 * 60 * 24));
document.getElementById('tiempo-transcurrido').textContent = `${Math.floor(diasTranscurridos / 30)} meses, ${diasTranscurridos % 30} días`;
// Calcular ritmo
if (diasTranscurridos > 0) {
const ritmoSemanal = (pesoPerdido / diasTranscurridos) * 7;
document.getElementById('ritmo-actual').textContent = `${ritmoSemanal.toFixed(2)} kg/semana`;
// Tiempo restante estimado
if (ritmoSemanal > 0) {
const pesoRestante = totalPerder - pesoPerdido;
const semanasRestantes = pesoRestante / ritmoSemanal;
const mesesRestantes = Math.ceil(semanasRestantes / 4);
document.getElementById('tiempo-restante').textContent = `${mesesRestantes} meses aprox.`;
}
}
}
}
}
// Funciones de Reportes
function updateReportes() {
const alimentacion = loadData('alimentacion');
const entrenamientos = loadData('entrenamientos');
const suenos = loadData('suenos');
const sintomas = loadData('sintomas');
document.getElementById('dias-registrados').textContent = Math.max(
alimentacion.length, entrenamientos.length, suenos.length, sintomas.length
);
document.getElementById('entrenamientos-completados').textContent = entrenamientos.length;
if (alimentacion.length > 0) {
const adherenciaPromedio = alimentacion.reduce((sum, a) => sum + (a.adherencia || 0), 0) / alimentacion.length;
document.getElementById('adherencia-promedio').textContent = `${adherenciaPromedio.toFixed(1)}%`;
}
if (suenos.length > 0) {
const suenoPromedio = suenos.reduce((sum, s) => sum + (s.calidad || 0), 0) / suenos.length;
document.getElementById('sueno-promedio-reporte').textContent = `${suenoPromedio.toFixed(1)} / 10`;
}
updateTopSintomas();
updateMejoresDias();
updateCorrelaciones();
}
function updateTopSintomas() {
const sintomas = loadData('sintomas');
const container = document.getElementById('top-sintomas');
if (sintomas.length > 0) {
const counts = {
'Sofocos': sintomas.filter(s => s.sofocos).length,
'Sudores': sintomas.filter(s => s.sudores).length,
'Fatiga': sintomas.filter(s => s.fatiga).length,
'Irritabilidad': sintomas.filter(s => s.irritabilidad).length,
'Dolores': sintomas.filter(s => s.doloresArticulares).length
};
const sorted = Object.entries(counts)
.sort(([,a], [,b]) => b - a)
.slice(0, 5);
container.innerHTML = sorted.map(([sintoma, count]) =>
`<div class="flex justify-between items-center p-2 bg-gray-50 rounded">
<span>${sintoma}</span>
<span class="font-bold">${count}</span>
</div>`
).join('');
}
}
function updateMejoresDias() {
const datos = loadData('quick-data').concat(loadData('suenos'));
const container = document.getElementById('mejores-dias');
// Implementar lógica para mejores días basado en energía y sueño
container.innerHTML = '<p class="text-sm text-gray-500">Análisis en desarrollo...</p>';
}
function updateCorrelaciones() {
const container = document.getElementById('correlaciones');
// Implementar análisis de correlaciones
container.innerHTML = '<p class="text-xs text-gray-500">Correlaciones automáticas en desarrollo...</p>';
}
// Funciones de gráficos
function updateProgressChart() {
const ctx = document.getElementById('progress-chart');
if (!ctx) return;
const medidas = loadData('medidas').slice(-30); // Último mes
if (charts.progressChart) {
charts.progressChart.destroy();
}
charts.progressChart = new Chart(ctx, {
type: 'line',
data: {
labels: medidas.map(m => m.fecha),
datasets: [{
label: 'Peso (kg)',
data: medidas.map(m => m.peso),
borderColor: 'rgb(59, 130, 246)',
backgroundColor: 'rgba(59, 130, 246, 0.1)',
tension: 0.1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: false
}
}
}
});
}
function loadMedidasChart() {
const medidas = loadData('medidas').slice(-20);
// Gráfico de peso
const pesoCtx = document.getElementById('peso-chart');
if (pesoCtx && medidas.length > 0) {
if (charts.pesoChart) charts.pesoChart.destroy();
charts.pesoChart = new Chart(pesoCtx, {
type: 'line',
data: {
labels: medidas.map(m => m.fecha),
datasets: [{
label: 'Peso (kg)',
data: medidas.map(m => m.peso),
borderColor: 'rgb(168, 85, 247)',
backgroundColor: 'rgba(168, 85, 247, 0.1)',
tension: 0.1
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
}
// Gráfico de medidas corporales
const medidasCtx = document.getElementById('medidas-chart');
if (medidasCtx && medidas.length > 0) {
if (charts.medidasChart) charts.medidasChart.destroy();
charts.medidasChart = new Chart(medidasCtx, {
type: 'line',
data: {
labels: medidas.map(m => m.fecha),
datasets: [{
label: 'Cintura (cm)',
data: medidas.map(m => m.cintura),
borderColor: 'rgb(34, 197, 94)',
tension: 0.1
}, {
label: 'Cadera (cm)',
data: medidas.map(m => m.cadera),
borderColor: 'rgb(239, 68, 68)',
tension: 0.1
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
}
}
function loadAllCharts() {
updateProgressChart();
loadMedidasChart();
// Cargar otros gráficos si están visibles
if (currentSection === 'entrenamientos') {
loadFuerzaChart();
}
if (currentSection === 'sueno') {
loadSuenoChart();
}
}
function loadFuerzaChart() {
const entrenamientos = loadData('entrenamientos')
.filter(e => e.tipo.includes('fuerza'))
.slice(-10);
const ctx = document.getElementById('fuerza-chart');
if (ctx && entrenamientos.length > 0) {
if (charts.fuerzaChart) charts.fuerzaChart.destroy();
charts.fuerzaChart = new Chart(ctx, {
type: 'bar',
data: {
labels: entrenamientos.map(e => e.fecha),
datasets: [{
label: 'Intensidad',
data: entrenamientos.map(e => e.intensidad),
backgroundColor: 'rgba(239, 68, 68, 0.5)',
borderColor: 'rgb(239, 68, 68)',
borderWidth: 1
}, {
label: 'Sensación',
data: entrenamientos.map(e => e.sensacion),
backgroundColor: 'rgba(34, 197, 94, 0.5)',
borderColor: 'rgb(34, 197, 94)',
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
max: 10
}
}
}
});
}
}
function loadSuenoChart() {
const suenos = loadData('suenos').slice(-14); // 2 semanas
const ctx = document.getElementById('sueno-chart');
if (ctx && suenos.length > 0) {
if (charts.suenoChart) charts.suenoChart.destroy();
charts.suenoChart = new Chart(ctx, {
type: 'line',
data: {
labels: suenos.map(s => s.fecha),
datasets: [{
label: 'Calidad sueño',
data: suenos.map(s => s.calidad),
borderColor: 'rgb(99, 102, 241)',
backgroundColor: 'rgba(99, 102, 241, 0.1)',
tension: 0.1
}, {
label: 'Energía al despertar',
data: suenos.map(s => s.energia),
borderColor: 'rgb(245, 158, 11)',
backgroundColor: 'rgba(245, 158, 11, 0.1)',
tension: 0.1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
max: 10
}
}
}
});
}
}
// Funciones de exportación/importación
function exportData() {
const data = {
alimentacion: loadData('alimentacion'),
entrenamientos: loadData('entrenamientos'),
suenos: loadData('suenos'),
medidas: loadData('medidas'),
fotos: loadData('fotos'),
suplementos: loadData('suplementos'),
sintomas: loadData('sintomas'),
objetivos: loadData('objetivos'),
quickData: loadData('quick-data')
};
const blob = new Blob([JSON.stringify(data, null, 2)], {type: 'application/json'});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `seguimiento_${new Date().toISOString().split('T')[0]}.json`;
a.click();
URL.revokeObjectURL(url);
}
function importData() {
document.getElementById('import-file').click();
}
document.getElementById('import-file').addEventListener('change', function(e) {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(e) {
try {
const data = JSON.parse(e.target.result);
// Importar todos los datos
Object.keys(data).forEach(key => {
if (data[key]) {
saveData(key, data[key]);
}
});
alert('Datos importados correctamente');
location.reload(); // Recargar para mostrar los nuevos datos
} catch (error) {
alert('Error al importar datos: ' + error.message);
}
};
reader.readAsText(file);
});
function exportarCSV() {
const medidas = loadData('medidas');
const suenos = loadData('suenos');
const sintomas = loadData('sintomas');
let csv = 'Fecha,Peso,Cintura,Cadera,Calidad_Sueno,Estado_Animo,Nivel_Estres\n';
// Combinar datos por fecha
const fechas = new Set([
...medidas.map(m => m.fecha),
...suenos.map(s => s.fecha),
...sintomas.map(s => s.fecha)
]);
fechas.forEach(fecha => {
const medida = medidas.find(m => m.fecha === fecha);
const sueno = suenos.find(s => s.fecha === fecha);
const sintoma = sintomas.find(s => s.fecha === fecha);
csv += `${fecha},${medida?.peso || ''},${medida?.cintura || ''},${medida?.cadera || ''},${sueno?.calidad || ''},${sintoma?.estadoAnimo || ''},${sintoma?.nivelEstres || ''}\n`;
});
const blob = new Blob([csv], {type: 'text/csv'});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `datos_${new Date().toISOString().split('T')[0]}.csv`;
a.click();
URL.revokeObjectURL(url);
}
function generarReporteSemanal() {
alert('Funcionalidad de reporte semanal en desarrollo');
}
function generarReporteMensual() {
alert('Funcionalidad de reporte mensual en desarrollo');
}
// Cargar datos al cambiar de sección
window.addEventListener('resize', function() {
// Redimensionar gráficos
Object.values(charts).forEach(chart => {
if (chart && typeof chart.resize === 'function') {
chart.resize();
}
});
});
</script>
</body>
</html>