<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sawtech - Checker Pro</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
<style>
body { font-family: 'Inter', sans-serif; }
.glass { background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); }
.animate-fade-in { animation: fadeIn 0.3s ease-in-out; }
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
</style>
</head>
<body class="bg-slate-950 text-slate-100 min-h-screen flex items-center justify-center p-4">
<!-- SECCIÓN DE LOGIN / REGISTRO -->
<div id="login-screen" class="w-full max-w-md space-y-8 animate-fade-in">
<div class="text-center mb-8">
<h1 class="text-4xl font-bold text-white mb-2">SAWTECH</h1>
<p class="text-slate-400">Checker Profesional - Acceso Seguro</p>
</div>
<div class="glass p-8 rounded-2xl shadow-2xl space-y-6">
<div class="flex mb-6 bg-slate-800 p-1 rounded-lg">
<button onclick="switchTab('login')" id="tab-login" class="flex-1 py-2 rounded-md text-sm font-medium bg-blue-600 text-white transition-all">Login</button>
<button onclick="switchTab('register')" id="tab-register" class="flex-1 py-2 rounded-md text-sm font-medium text-slate-400 hover:text-white transition-all">Registro</button>
</div>
<!-- Formulario de Login -->
<div id="form-login" class="space-y-4">
<div>
<label class="block text-sm font-medium text-slate-300 mb-1">Usuario</label>
<input type="text" id="login-user" class="w-full p-3 rounded-lg bg-slate-800 border border-slate-700 text-white outline-none focus:ring-2 focus:ring-blue-500 transition-all" placeholder="Tu usuario">
</div>
<div>
<label class="block text-sm font-medium text-slate-300 mb-1">Contraseña</label>
<input type="password" id="login-pass" class="w-full p-3 rounded-lg bg-slate-800 border border-slate-700 text-white outline-none focus:ring-2 focus:ring-blue-500 transition-all" placeholder="••••••••">
</div>
<button onclick="handleLogin()" id="btn-login" class="w-full py-3 bg-blue-600 hover:bg-blue-500 text-white font-bold rounded-lg transition-all transform active:scale-95 shadow-lg">Ingresar</button>
</div>
<!-- Formulario de Registro -->
<div id="form-register" class="hidden space-y-4">
<div>
<label class="block text-sm font-medium text-slate-300 mb-1">Nombre de Usuario</label>
<input type="text" id="reg-user" class="w-full p-3 rounded-lg bg-slate-800 border border-slate-700 text-white outline-none" placeholder="Crea tu usuario">
</div>
<div>
<label class="block text-sm font-medium text-slate-300 mb-1">Nombre Completo</label>
<input type="text" id="reg-displayName" class="w-full p-3 rounded-lg bg-slate-800 border border-slate-700 text-white outline-none" placeholder="Ej: Juan Perez">
</div>
<div>
<label class="block text-sm font-medium text-slate-300 mb-1">Contraseña</label>
<input type="password" id="reg-pass" class="w-full p-3 rounded-lg bg-slate-800 border border-slate-700 text-white outline-none" placeholder="••••••••">
</div>
<button onclick="handleRegister()" id="btn-register" class="w-full py-3 bg-green-600 hover:bg-green-500 text-white font-bold rounded-lg transition-all transform active:scale-95 shadow-lg">Crear Cuenta</button>
</div>
<div class="relative flex py-3 items-center">
<div class="flex-grow border-t border-slate-700"></div>
<span class="flex-shrink mx-4 text-slate-500 text-xs uppercase">O usa</span>
<div class="flex-grow border-t border-slate-700"></div>
</div>
<!-- LOGIN CON WHATSAPP -->
<div class="space-y-4">
<div id="wa-input-group" class="flex gap-2">
<input type="text" id="wa-phone" class="flex-1 p-3 rounded-lg bg-slate-800 border border-slate-700 text-white outline-none" placeholder="Teléfono WhatsApp">
<button onclick="requestOTP()" id="btn-otp" class="px-4 py-3 bg-green-600 hover:bg-green-500 text-white font-bold rounded-lg transition-all">Enviar Código</button>
</div>
<div id="wa-verify-group" class="hidden flex gap-2">
<input type="text" id="wa-code" class="flex-1 p-3 rounded-lg bg-slate-800 border border-slate-700 text-white outline-none" placeholder="Código 6 dígitos">
<button onclick="verifyOTP()" id="btn-verify" class="px-4 py-3 bg-green-600 hover:bg-green-500 text-white font-bold rounded-lg transition-all">Verificar</button>
</div>
</div>
<p id="login-error" class="text-red-400 text-sm text-center mt-4 hidden"></p>
</div>
</div>
<!-- SECCIÓN DEL PANEL -->
<div id="main-panel" class="hidden w-full max-w-4xl space-y-8 animate-fade-in">
<div class="flex justify-between items-center mb-8">
<div class="flex items-center gap-4">
<div class="bg-blue-600 p-2 rounded-lg">🚀</div>
<div>
<h1 class="text-3xl font-bold text-white">Panel de Control</h1>
<p id="welcome-msg" class="text-slate-400">Bienvenido</p>
</div>
</div>
<div class="glass px-6 py-3 rounded-2xl text-right">
<p class="text-xs text-slate-400 uppercase font-semibold">Saldo Actual</p>
<p id="user-balance" class="text-2xl font-bold text-green-400">$0.00</p>
</div>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<div class="md:col-span-1 glass p-6 rounded-2xl space-y-4">
<h2 class="text-xl font-bold text-white mb-4">Servicios</h2>
<div id="services-list" class="space-y-3"></div>
</div>
<div class="md:col-span-2 glass p-8 rounded-2xl shadow-2xl space-y-6">
<div class="space-y-4">
<label class="block text-lg font-medium text-slate-200">Ingresa el IMEI:</label>
<div class="flex gap-2">
<input type="text" id="imei-input" class="flex-1 p-4 rounded-lg bg-slate-800 border border-slate-700 text-white text-xl font-mono outline-none" placeholder="000000000000000">
<button onclick="handleCheck()" id="btn-check" class="px-6 py-4 bg-blue-600 hover:bg-blue-500 text-white font-bold rounded-lg transition-all">Realizar Check</button>
</div>
</div>
<div id="result-area" class="hidden animate-fade-in">
<div id="result-card" class="p-6 rounded-xl border-l-8 bg-slate-800/50 transition-all">
<div class="flex justify-between items-start mb-4">
<h3 id="result-status" class="text-2xl font-bold">Cargando...</h3>
</div>
<div id="result-details" class="grid grid-cols-1 gap-2 text-sm"></div>
</div>
</div>
</div>
</div>
<button onclick="logout()" class="text-slate-500 hover:text-white text-sm transition-all underline">Cerrar Sesión</button>
</div>
<script>
const API_URL = 'https://checker-api.fastluigi.workers.dev';
let USER_TOKEN = localStorage.getItem('checker_token');
let SELECTED_SERVICE = null;
// --- NAVEGACIÓN ---
function switchTab(tab) {
const isLogin = tab === 'login';
document.getElementById('tab-login').className = isLogin ? 'flex-1 py-2 rounded-md text-sm font-medium bg-blue-600 text-white transition-all' : 'flex-1 py-2 rounded-md text-sm font-medium text-slate-400 hover:text-white transition-all';
document.getElementById('tab-register').className = !isLogin ? 'flex-1 py-2 rounded-md text-sm font-medium bg-blue-600 text-white transition-all' : 'flex-1 py-2 rounded-md text-sm font-medium text-slate-400 hover:text-white transition-all';
document.getElementById('form-login').classList.toggle('hidden', !isLogin);
document.getElementById('form-register').classList.toggle('hidden', isLogin);
}
function showScreen(screenId) {
document.getElementById('login-screen').classList.add('hidden');
document.getElementById('main-panel').classList.add('hidden');
document.getElementById(screenId).classList.remove('hidden');
}
// --- AUTENTICACIÓN ---
async function handleLogin() {
const user = document.getElementById('login-user').value;
const pass = document.getElementById('login-pass').value;
if(!user || !pass) return showError('Completa todos los campos');
try {
const res = await fetch(`${API_URL}/auth/login`, {
method: 'POST',
body: JSON.stringify({ user, pass })
});
const data = await res.json();
if(res.ok) {
USER_TOKEN = data.token;
localStorage.setItem('checker_token', USER_TOKEN);
initPanel(data);
} else {
showError(data.error || 'Error de acceso');
}
} catch(e) { showError('Error de conexión'); }
}
async function handleRegister() {
const user = document.getElementById('reg-user').value;
const name = document.getElementById('reg-displayName').value;
const pass = document.getElementById('reg-pass').value;
if(!user || !name || !pass) return showError('Completa todos los campos');
try {
const res = await fetch(`${API_URL}/auth/register`, {
method: 'POST',
body: JSON.stringify({ user, displayName: name, pass })
});
const data = await res.json();
if(res.ok) {
alert('Cuenta creada con éxito. Ahora puedes iniciar sesión.');
switchTab('login');
} else {
showError(data.error || 'Error al registrar');
}
} catch(e) { showError('Error de conexión'); }
}
async function requestOTP() {
const phone = document.getElementById('wa-phone').value;
if(!phone) return showError('Ingresa tu teléfono');
try {
const res = await fetch(`${API_URL}/auth/whatsapp-send`, {
method: 'POST',
body: JSON.stringify({ phone })
});
if(res.ok) {
document.getElementById('wa-input-group').classList.add('hidden');
document.getElementById('wa-verify-group').classList.remove('hidden');
} else {
const data = await res.json();
showError(data.error || 'Error enviando código');
}
} catch(e) { showError('Error de conexión'); }
}
async function verifyOTP() {
const phone = document.getElementById('wa-phone').value;
const code = document.getElementById('wa-code').value;
try {
const res = await fetch(`${API_URL}/auth/whatsapp-verify`, {
method: 'POST',
body: JSON.stringify({ phone, code })
});
const data = await res.json();
if(res.ok) {
USER_TOKEN = data.token;
localStorage.setItem('checker_token', USER_TOKEN);
initPanel(data);
} else {
showError(data.error || 'Código inválido');
}
} catch(e) { showError('Error de conexión'); }
}
function showError(msg) {
const err = document.getElementById('login-error');
err.textContent = msg;
err.classList.remove('hidden');
setTimeout(() => err.classList.add('hidden'), 5000);
}
// --- PANEL PRINCIPAL ---
async function initPanel(userData) {
showScreen('main-panel');
document.getElementById('welcome-msg').textContent = `Hola, ${userData.username || 'Usuario'}`;
document.getElementById('user-balance').textContent = `$${userData.balance || '0.00'}`;
loadServices();
}
async function loadServices() {
try {
const res = await fetch(`${API_URL}/services`, {
headers: { 'Authorization': `Bearer ${USER_TOKEN}` }
});
const services = await res.json();
const list = document.getElementById('services-list');
list.innerHTML = '';
services.forEach(s => {
const btn = document.createElement('button');
btn.className = 'w-full p-4 rounded-xl bg-slate-800 text-left hover:bg-blue-600 transition-all border border-slate-700 flex justify-between items-center group';
btn.innerHTML = `<div><p class="font-bold text-white">${s.sname}</p><p class="text-xs text-slate-400">$${s.sale}</p></div><span class="opacity-0 group-hover:opacity-100 transition-all">➔</span>`;
btn.onclick = () => {
SELECTED_SERVICE = s.sid;
document.querySelectorAll('#services-list button').forEach(b => b.classList.remove('bg-blue-600', 'ring-2', 'ring-white'));
btn.classList.add('bg-blue-600', 'ring-2', 'ring-white');
};
list.appendChild(btn);
});
} catch(e) { console.error('Error cargando servicios'); }
}
async function handleCheck() {
const imei = document.getElementById('imei-input').value;
if(!SELECTED_SERVICE) return alert('Selecciona un servicio primero');
if(!imei) return alert('Ingresa un IMEI');
const btn = document.getElementById('btn-check');
const resultArea = document.getElementById('result-area');
const resultCard = document.getElementById('result-card');
const resultStatus = document.getElementById('result-status');
const resultDetails = document.getElementById('result-details');
btn.disabled = true;
btn.textContent = 'Consultando...';
resultArea.classList.remove('hidden');
resultCard.className = 'p-6 rounded-xl border-l-8 bg-slate-800/50 border-blue-500';
resultStatus.textContent = 'Procesando IMEI...';
resultDetails.innerHTML = '';
try {
const res = await fetch(`${API_URL}/check`, {
method: 'POST',
body: JSON.stringify({ token: USER_TOKEN, imei, serviceId: SELECTED_SERVICE })
});
const data = await res.json();
if(res.ok) {
resultCard.className = 'p-6 rounded-xl border-l-8 bg-green-900/20 border-green-500';
resultStatus.textContent = '✅ Check Exitoso';
for(let key in data) {
resultDetails.innerHTML += `<div><p class="text-slate-400">${key}</p><p class="font-semibold text-white">${data[key]}</p></div>`;
}
} else {
resultCard.className = 'p-6 rounded-xl border-l-8 bg-red-900/20 border-red-500';
resultStatus.textContent = '❌ Error';
resultDetails.innerHTML = `<p class="text-red-300">${data.error || 'Ocurrió un error en la consulta'}</p>`;
}
} catch(e) {
resultCard.className = 'p-6 rounded-xl border-l-8 bg-red-900/20 border-red-500';
resultStatus.textContent = '❌ Error de Conexión';
resultDetails.innerHTML = `<p class="text-red-300">No se pudo conectar con el servidor</p>`;
} finally {
btn.disabled = false;
btn.textContent = 'Realizar Check';
}
}
function logout() {
localStorage.removeItem('checker_token');
location.reload();
}
// Auto-login si hay token
window.onload = () => {
if(USER_TOKEN) {
fetch(`${API_URL}/auth/me`, {
headers: { 'Authorization': `Bearer ${USER_TOKEN}` }
})
.then(res => res.json())
.then(data => initPanel(data))
.catch(() => { localStorage.removeItem('checker_token'); });
}
};
</script>
</body>
</html>