treepod-web-app.html•16.6 kB
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🏕️ TreePod Financial - Agente Financiero</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
overflow: hidden;
}
.header {
background: linear-gradient(135deg, #2d5016 0%, #3e6b1f 100%);
color: white;
padding: 30px;
text-align: center;
}
.header h1 {
font-size: 2.5em;
margin-bottom: 10px;
}
.header p {
font-size: 1.2em;
opacity: 0.9;
}
.tools-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
padding: 30px;
}
.tool-card {
background: #f8f9fa;
border-radius: 15px;
padding: 25px;
border: 2px solid #e9ecef;
transition: all 0.3s ease;
cursor: pointer;
}
.tool-card:hover {
border-color: #667eea;
transform: translateY(-5px);
box-shadow: 0 10px 25px rgba(0,0,0,0.1);
}
.tool-card h3 {
color: #2d5016;
margin-bottom: 15px;
font-size: 1.3em;
}
.tool-card p {
color: #6c757d;
margin-bottom: 20px;
line-height: 1.6;
}
.tool-form {
display: none;
margin-top: 20px;
}
.tool-form.active {
display: block;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 600;
color: #495057;
}
.form-group select,
.form-group input {
width: 100%;
padding: 10px;
border: 2px solid #e9ecef;
border-radius: 8px;
font-size: 14px;
transition: border-color 0.3s ease;
}
.form-group select:focus,
.form-group input:focus {
outline: none;
border-color: #667eea;
}
.btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 24px;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
width: 100%;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}
.btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.result {
margin-top: 20px;
padding: 20px;
background: #f8f9fa;
border-radius: 10px;
border-left: 4px solid #28a745;
display: none;
}
.result.show {
display: block;
}
.result pre {
white-space: pre-wrap;
font-family: inherit;
margin: 0;
color: #495057;
line-height: 1.6;
}
.loading {
display: none;
text-align: center;
padding: 20px;
}
.loading.show {
display: block;
}
.spinner {
border: 3px solid #f3f3f3;
border-top: 3px solid #667eea;
border-radius: 50%;
width: 30px;
height: 30px;
animation: spin 1s linear infinite;
margin: 0 auto 10px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.status {
background: #d4edda;
color: #155724;
padding: 15px;
margin: 20px;
border-radius: 10px;
text-align: center;
font-weight: 600;
}
.error {
background: #f8d7da;
color: #721c24;
padding: 15px;
margin: 20px;
border-radius: 10px;
text-align: center;
font-weight: 600;
display: none;
}
.error.show {
display: block;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🏕️ TreePod Financial</h1>
<p>Agente Financiero Inteligente para TreePod Glamping</p>
</div>
<div class="status">
✅ Servidor TreePod Financial activo y funcionando
</div>
<div class="error" id="errorMessage">
❌ Error de conexión con el servidor
</div>
<div class="tools-grid">
<!-- Test Connection -->
<div class="tool-card" onclick="toggleTool('test')">
<h3>🔗 Test de Conexión</h3>
<p>Prueba la conexión con el servidor TreePod Financial y verifica que todas las funciones estén operativas.</p>
<div class="tool-form" id="test-form">
<div class="form-group">
<label for="test-message">Mensaje de prueba:</label>
<input type="text" id="test-message" value="Hello TreePod!" placeholder="Ingresa un mensaje">
</div>
<button class="btn" onclick="runTool('test_connection')">🚀 Probar Conexión</button>
<div class="loading" id="test-loading">
<div class="spinner"></div>
<p>Probando conexión...</p>
</div>
<div class="result" id="test-result">
<pre id="test-output"></pre>
</div>
</div>
</div>
<!-- Analyze Finances -->
<div class="tool-card" onclick="toggleTool('finances')">
<h3>📊 Análisis Financiero</h3>
<p>Analiza las finanzas actuales del negocio TreePod Glamping con proyecciones y métricas clave.</p>
<div class="tool-form" id="finances-form">
<div class="form-group">
<label for="finances-period">Período de análisis:</label>
<select id="finances-period">
<option value="monthly">Mensual</option>
<option value="quarterly">Trimestral</option>
<option value="yearly">Anual</option>
</select>
</div>
<div class="form-group">
<label>
<input type="checkbox" id="finances-projections" checked>
Incluir proyecciones futuras
</label>
</div>
<button class="btn" onclick="runTool('analyze_finances')">📈 Analizar Finanzas</button>
<div class="loading" id="finances-loading">
<div class="spinner"></div>
<p>Analizando finanzas...</p>
</div>
<div class="result" id="finances-result">
<pre id="finances-output"></pre>
</div>
</div>
</div>
<!-- Calculate Rates -->
<div class="tool-card" onclick="toggleTool('rates')">
<h3>💰 Calculadora de Tarifas</h3>
<p>Calcula tarifas óptimas para TreePod según temporada, tipo de pod y duración de estadía.</p>
<div class="tool-form" id="rates-form">
<div class="form-group">
<label for="rates-season">Temporada:</label>
<select id="rates-season">
<option value="high">Alta</option>
<option value="medium" selected>Media</option>
<option value="low">Baja</option>
</select>
</div>
<div class="form-group">
<label for="rates-type">Tipo de TreePod:</label>
<select id="rates-type">
<option value="standard" selected>Standard</option>
<option value="premium">Premium</option>
<option value="luxury">Luxury</option>
</select>
</div>
<div class="form-group">
<label for="rates-nights">Número de noches:</label>
<input type="number" id="rates-nights" value="1" min="1" max="30">
</div>
<button class="btn" onclick="runTool('calculate_rates')">💵 Calcular Tarifas</button>
<div class="loading" id="rates-loading">
<div class="spinner"></div>
<p>Calculando tarifas...</p>
</div>
<div class="result" id="rates-result">
<pre id="rates-output"></pre>
</div>
</div>
</div>
<!-- Check Occupancy -->
<div class="tool-card" onclick="toggleTool('occupancy')">
<h3>🏕️ Estado de Ocupación</h3>
<p>Verifica el estado actual de ocupación de los TreePods y obtén métricas de disponibilidad.</p>
<div class="tool-form" id="occupancy-form">
<div class="form-group">
<label for="occupancy-range">Rango de fechas:</label>
<select id="occupancy-range">
<option value="today" selected>Hoy</option>
<option value="week">Esta semana</option>
<option value="month">Este mes</option>
</select>
</div>
<button class="btn" onclick="runTool('check_occupancy')">🏕️ Verificar Ocupación</button>
<div class="loading" id="occupancy-loading">
<div class="spinner"></div>
<p>Verificando ocupación...</p>
</div>
<div class="result" id="occupancy-result">
<pre id="occupancy-output"></pre>
</div>
</div>
</div>
</div>
</div>
<script>
// URL del servidor TreePod Financial
const SERVER_URL = 'http://localhost:3001';
// Función para alternar la visibilidad de las herramientas
function toggleTool(toolName) {
const form = document.getElementById(toolName + '-form');
const isActive = form.classList.contains('active');
// Cerrar todos los formularios
document.querySelectorAll('.tool-form').forEach(f => f.classList.remove('active'));
// Abrir el formulario seleccionado si no estaba activo
if (!isActive) {
form.classList.add('active');
}
}
// Función para ejecutar herramientas
async function runTool(toolName) {
const loadingId = getToolPrefix(toolName) + '-loading';
const resultId = getToolPrefix(toolName) + '-result';
const outputId = getToolPrefix(toolName) + '-output';
const errorElement = document.getElementById('errorMessage');
// Mostrar loading
document.getElementById(loadingId).classList.add('show');
document.getElementById(resultId).classList.remove('show');
errorElement.classList.remove('show');
try {
// Preparar argumentos según la herramienta
let args = {};
switch(toolName) {
case 'test_connection':
args.message = document.getElementById('test-message').value;
break;
case 'analyze_finances':
args.period = document.getElementById('finances-period').value;
args.include_projections = document.getElementById('finances-projections').checked;
break;
case 'calculate_rates':
args.season = document.getElementById('rates-season').value;
args.pod_type = document.getElementById('rates-type').value;
args.nights = parseInt(document.getElementById('rates-nights').value);
break;
case 'check_occupancy':
args.date_range = document.getElementById('occupancy-range').value;
break;
}
// Hacer solicitud al servidor
const response = await fetch(SERVER_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
jsonrpc: "2.0",
method: "tools/call",
params: {
name: toolName,
arguments: args
},
id: Date.now()
})
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
if (data.error) {
throw new Error(data.error.message);
}
// Mostrar resultado
const content = data.result.content[0].text;
document.getElementById(outputId).textContent = content;
document.getElementById(resultId).classList.add('show');
} catch (error) {
console.error('Error:', error);
errorElement.textContent = `❌ Error: ${error.message}`;
errorElement.classList.add('show');
} finally {
// Ocultar loading
document.getElementById(loadingId).classList.remove('show');
}
}
// Función auxiliar para obtener el prefijo de la herramienta
function getToolPrefix(toolName) {
const prefixes = {
'test_connection': 'test',
'analyze_finances': 'finances',
'calculate_rates': 'rates',
'check_occupancy': 'occupancy'
};
return prefixes[toolName];
}
// Verificar conexión al cargar la página
window.addEventListener('load', async () => {
try {
const response = await fetch(SERVER_URL + '/health');
if (!response.ok) {
throw new Error('Servidor no disponible');
}
console.log('✅ Conexión con servidor TreePod Financial establecida');
} catch (error) {
console.error('❌ Error de conexión:', error);
document.getElementById('errorMessage').textContent =
'❌ No se puede conectar al servidor. Asegúrate de que el servidor TreePod Financial esté ejecutándose en ' + SERVER_URL;
document.getElementById('errorMessage').classList.add('show');
}
});
</script>
</body>
</html>