Files
web/test.html
2026-02-07 15:53:39 +00:00

186 lines
6.3 KiB
HTML

<!doctype html>
<html lang="es">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>IntegraRepara — Test API</title>
<style>
body { font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif; margin: 24px; }
.row { display: flex; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
button { padding: 10px 14px; border: 0; border-radius: 10px; cursor: pointer; }
button.primary { background: #111; color: #fff; }
button.gray { background: #eee; }
input, textarea { width: 100%; padding: 10px; border-radius: 10px; border: 1px solid #ddd; }
.card { border: 1px solid #eee; border-radius: 14px; padding: 14px; margin-top: 14px; }
pre { background: #0b0b0b; color: #eaeaea; padding: 12px; border-radius: 12px; overflow: auto; }
.muted { color: #666; font-size: 14px; }
label { display: block; font-size: 13px; margin: 8px 0 6px; color: #444; }
.list { margin-top: 12px; display: grid; gap: 10px; }
.item { border: 1px solid #eee; border-radius: 12px; padding: 12px; }
.item h3 { margin: 0 0 6px; font-size: 16px; }
.meta { display:flex; gap: 10px; flex-wrap: wrap; color:#555; font-size: 13px; }
.pill { background:#f3f3f3; padding: 4px 8px; border-radius: 999px; }
.error { color:#b00020; font-weight:600; }
</style>
</head>
<body>
<h1>IntegraRepara — Test API</h1>
<p class="muted">Esto es para probar tu API desde el navegador, sin Postman.</p>
<div class="card">
<label>Base URL de tu API</label>
<input id="baseUrl" value="https://integrarepara-api.integrarepara.es" />
<div class="row" style="margin-top:12px;">
<button class="primary" id="btnRoot">GET /</button>
<button class="primary" id="btnHealth">GET /health</button>
<button class="gray" id="btnClear">Limpiar consola</button>
</div>
<pre id="out">{ "ready": true }</pre>
</div>
<div class="card">
<h2 style="margin-top:0;">Crear servicio</h2>
<p class="muted">POST /services y GET /services (en memoria por ahora).</p>
<label>Título / Descripción *</label>
<input id="sTitle" placeholder="Ej: Fuga en cocina / Enchufe no funciona" value="sin luz" />
<label>Cliente *</label>
<input id="sClient" placeholder="Ej: Juan Pérez" value="juan perez" />
<label>Teléfono</label>
<input id="sPhone" placeholder="Ej: 600123123" value="666777888" />
<label>Dirección</label>
<input id="sAddress" placeholder="Ej: Calle X, 12, Algeciras" value="calle" />
<label>Notas</label>
<textarea id="sNotes" rows="3" placeholder="Ej: Llamar antes, perro suelto (pero majo)">ejemplo</textarea>
<div class="row" style="margin-top:12px;">
<button class="primary" id="btnCreate">POST /services</button>
<button class="primary" id="btnList">GET /services</button>
</div>
<div id="list" class="list"></div>
</div>
<script>
const out = document.getElementById("out");
const listEl = document.getElementById("list");
function log(obj) {
out.textContent = (typeof obj === "string") ? obj : JSON.stringify(obj, null, 2);
}
function base() {
return document.getElementById("baseUrl").value.replace(/\/$/, "");
}
async function req(path, options = {}) {
const url = base() + path;
const res = await fetch(url, {
...options,
headers: {
"Content-Type": "application/json",
...(options.headers || {})
}
});
const text = await res.text();
let data;
try { data = JSON.parse(text); } catch { data = text; }
if (!res.ok) {
const msg = (data && data.error) ? data.error : "Request failed";
throw { status: res.status, message: msg, data };
}
return data;
}
function esc(s) {
return String(s ?? "").replace(/[&<>"']/g, m => ({
"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"
}[m]));
}
function renderList(payload) {
const services = payload?.services || [];
if (!services.length) {
listEl.innerHTML = `<div class="muted">No hay servicios todavía. Crea uno y saldrá aquí.</div>`;
return;
}
listEl.innerHTML = services.map(s => `
<div class="item">
<h3>#${esc(s.id)}${esc(s.title)}</h3>
<div class="meta">
<span class="pill">👤 ${esc(s.client)}</span>
${s.phone ? `<span class="pill">📞 ${esc(s.phone)}</span>` : ``}
${s.address ? `<span class="pill">📍 ${esc(s.address)}</span>` : ``}
<span class="pill">🕒 ${esc(s.createdAt)}</span>
</div>
${s.notes ? `<div class="muted" style="margin-top:8px;">📝 ${esc(s.notes)}</div>` : ``}
</div>
`).join("");
}
async function refreshServices() {
const data = await req("/services");
renderList(data);
return data;
}
document.getElementById("btnRoot").onclick = async () => {
try { log(await req("/")); }
catch (e) { log({ error: true, ...e }); }
};
document.getElementById("btnHealth").onclick = async () => {
try { log(await req("/health")); }
catch (e) { log({ error: true, ...e }); }
};
document.getElementById("btnClear").onclick = () => {
log({ cleared: true });
};
document.getElementById("btnCreate").onclick = async () => {
const payload = {
title: document.getElementById("sTitle").value.trim(),
client: document.getElementById("sClient").value.trim(), // <-- clave: client (no clientName)
phone: document.getElementById("sPhone").value.trim(),
address: document.getElementById("sAddress").value.trim(),
notes: document.getElementById("sNotes").value.trim()
};
try {
const created = await req("/services", { method: "POST", body: JSON.stringify(payload) });
log(created);
await refreshServices();
} catch (e) {
log({ error: true, ...e });
listEl.innerHTML = `<div class="error">❌ Error: ${esc(e.message || "No se pudo crear")}</div>`;
}
};
document.getElementById("btnList").onclick = async () => {
try {
const data = await refreshServices();
log(data);
} catch (e) {
log({ error: true, ...e });
listEl.innerHTML = `<div class="error">❌ Error: ${esc(e.message || "No se pudo listar")}</div>`;
}
};
// Carga inicial
(async () => {
try { await refreshServices(); }
catch { /* si aún no está arriba la API, no pasa nada */ }
})();
</script>
</body>
</html>