Actualizar test.html
This commit is contained in:
100
test.html
100
test.html
@@ -15,6 +15,12 @@
|
|||||||
pre { background: #0b0b0b; color: #eaeaea; padding: 12px; border-radius: 12px; overflow: auto; }
|
pre { background: #0b0b0b; color: #eaeaea; padding: 12px; border-radius: 12px; overflow: auto; }
|
||||||
.muted { color: #666; font-size: 14px; }
|
.muted { color: #666; font-size: 14px; }
|
||||||
label { display: block; font-size: 13px; margin: 8px 0 6px; color: #444; }
|
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>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -35,32 +41,35 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h2 style="margin-top:0;">Crear servicio (cuando exista POST /services)</h2>
|
<h2 style="margin-top:0;">Crear servicio</h2>
|
||||||
<p class="muted">Ahora mismo tu API no tiene este endpoint, pero el formulario ya queda listo.</p>
|
<p class="muted">POST /services y GET /services (en memoria por ahora).</p>
|
||||||
|
|
||||||
<label>Título / Descripción</label>
|
<label>Título / Descripción *</label>
|
||||||
<input id="sTitle" placeholder="Ej: Fuga en cocina / Enchufe no funciona" />
|
<input id="sTitle" placeholder="Ej: Fuga en cocina / Enchufe no funciona" value="sin luz" />
|
||||||
|
|
||||||
<label>Cliente</label>
|
<label>Cliente *</label>
|
||||||
<input id="sClient" placeholder="Ej: Juan Pérez" />
|
<input id="sClient" placeholder="Ej: Juan Pérez" value="juan perez" />
|
||||||
|
|
||||||
<label>Teléfono</label>
|
<label>Teléfono</label>
|
||||||
<input id="sPhone" placeholder="Ej: 600123123" />
|
<input id="sPhone" placeholder="Ej: 600123123" value="666777888" />
|
||||||
|
|
||||||
<label>Dirección</label>
|
<label>Dirección</label>
|
||||||
<input id="sAddress" placeholder="Ej: Calle X, 12, Algeciras" />
|
<input id="sAddress" placeholder="Ej: Calle X, 12, Algeciras" value="calle" />
|
||||||
|
|
||||||
<label>Notas</label>
|
<label>Notas</label>
|
||||||
<textarea id="sNotes" rows="3" placeholder="Ej: Llamar antes, perro suelto (pero majo)"></textarea>
|
<textarea id="sNotes" rows="3" placeholder="Ej: Llamar antes, perro suelto (pero majo)">ejemplo</textarea>
|
||||||
|
|
||||||
<div class="row" style="margin-top:12px;">
|
<div class="row" style="margin-top:12px;">
|
||||||
<button class="primary" id="btnCreate">POST /services</button>
|
<button class="primary" id="btnCreate">POST /services</button>
|
||||||
<button class="primary" id="btnList">GET /services</button>
|
<button class="primary" id="btnList">GET /services</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="list" class="list"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const out = document.getElementById("out");
|
const out = document.getElementById("out");
|
||||||
|
const listEl = document.getElementById("list");
|
||||||
|
|
||||||
function log(obj) {
|
function log(obj) {
|
||||||
out.textContent = (typeof obj === "string") ? obj : JSON.stringify(obj, null, 2);
|
out.textContent = (typeof obj === "string") ? obj : JSON.stringify(obj, null, 2);
|
||||||
@@ -85,11 +94,45 @@
|
|||||||
try { data = JSON.parse(text); } catch { data = text; }
|
try { data = JSON.parse(text); } catch { data = text; }
|
||||||
|
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
throw { status: res.status, data };
|
const msg = (data && data.error) ? data.error : "Request failed";
|
||||||
|
throw { status: res.status, message: msg, data };
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function esc(s) {
|
||||||
|
return String(s ?? "").replace(/[&<>"']/g, m => ({
|
||||||
|
"&":"&","<":"<",">":">",'"':""","'":"'"
|
||||||
|
}[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 () => {
|
document.getElementById("btnRoot").onclick = async () => {
|
||||||
try { log(await req("/")); }
|
try { log(await req("/")); }
|
||||||
catch (e) { log({ error: true, ...e }); }
|
catch (e) { log({ error: true, ...e }); }
|
||||||
@@ -106,35 +149,38 @@
|
|||||||
|
|
||||||
document.getElementById("btnCreate").onclick = async () => {
|
document.getElementById("btnCreate").onclick = async () => {
|
||||||
const payload = {
|
const payload = {
|
||||||
title: document.getElementById("sTitle").value,
|
title: document.getElementById("sTitle").value.trim(),
|
||||||
clientName: document.getElementById("sClient").value,
|
client: document.getElementById("sClient").value.trim(), // <-- clave: client (no clientName)
|
||||||
phone: document.getElementById("sPhone").value,
|
phone: document.getElementById("sPhone").value.trim(),
|
||||||
address: document.getElementById("sAddress").value,
|
address: document.getElementById("sAddress").value.trim(),
|
||||||
notes: document.getElementById("sNotes").value
|
notes: document.getElementById("sNotes").value.trim()
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
log(await req("/services", { method: "POST", body: JSON.stringify(payload) }));
|
const created = await req("/services", { method: "POST", body: JSON.stringify(payload) });
|
||||||
|
log(created);
|
||||||
|
await refreshServices();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log({
|
log({ error: true, ...e });
|
||||||
hint: "Si esto falla con 404, es normal: aún no hemos creado POST /services.",
|
listEl.innerHTML = `<div class="error">❌ Error: ${esc(e.message || "No se pudo crear")}</div>`;
|
||||||
error: true,
|
|
||||||
...e
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
document.getElementById("btnList").onclick = async () => {
|
document.getElementById("btnList").onclick = async () => {
|
||||||
try {
|
try {
|
||||||
log(await req("/services"));
|
const data = await refreshServices();
|
||||||
|
log(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log({
|
log({ error: true, ...e });
|
||||||
hint: "Si esto falla con 404, es normal: aún no hemos creado GET /services.",
|
listEl.innerHTML = `<div class="error">❌ Error: ${esc(e.message || "No se pudo listar")}</div>`;
|
||||||
error: true,
|
|
||||||
...e
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Carga inicial
|
||||||
|
(async () => {
|
||||||
|
try { await refreshServices(); }
|
||||||
|
catch { /* si aún no está arriba la API, no pasa nada */ }
|
||||||
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user