Update web/diagnosis.html
Browse files- web/diagnosis.html +103 -21
web/diagnosis.html
CHANGED
|
@@ -199,6 +199,69 @@
|
|
| 199 |
opacity: 0;
|
| 200 |
pointer-events: none;
|
| 201 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
</style>
|
| 203 |
</head>
|
| 204 |
<body class="vertical light">
|
|
@@ -1239,28 +1302,47 @@ if (false) { /* removed */ }
|
|
| 1239 |
}
|
| 1240 |
|
| 1241 |
function showAlert(type, message) {
|
| 1242 |
-
|
| 1243 |
-
|
| 1244 |
-
|
| 1245 |
-
|
| 1246 |
-
|
| 1247 |
-
|
| 1248 |
-
|
| 1249 |
-
const alertHtml = `
|
| 1250 |
-
<div class="alert ${alertClass} alert-dismissible fade show" role="alert">
|
| 1251 |
-
${(function(){var n=type==='error'?'x-circle':type==='success'?'check-circle':type==='warning'?'alert-triangle':'info';return typeof feather!=='undefined'?feather.icons[n].toSvg({'width':16,'height':16,'stroke-width':1.8,'style':'margin-right:6px;vertical-align:middle;'}):'';})()}
|
| 1252 |
-
${message}
|
| 1253 |
-
<button type="button" class="close" data-dismiss="alert">
|
| 1254 |
-
<span aria-hidden="true">×</span>
|
| 1255 |
-
</button>
|
| 1256 |
-
</div>
|
| 1257 |
-
`;
|
| 1258 |
-
|
| 1259 |
-
$('.container-fluid').prepend(alertHtml);
|
| 1260 |
|
| 1261 |
-
|
| 1262 |
-
|
| 1263 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1264 |
}
|
| 1265 |
|
| 1266 |
// === FUNCIONES GLOBALES ===
|
|
|
|
| 199 |
opacity: 0;
|
| 200 |
pointer-events: none;
|
| 201 |
}
|
| 202 |
+
|
| 203 |
+
/* ── TOAST NOTIFICATIONS ─────────────────────────── */
|
| 204 |
+
#toast-container {
|
| 205 |
+
position: fixed;
|
| 206 |
+
bottom: 1.5rem;
|
| 207 |
+
right: 1.5rem;
|
| 208 |
+
z-index: 99999;
|
| 209 |
+
display: flex;
|
| 210 |
+
flex-direction: column;
|
| 211 |
+
gap: 0.6rem;
|
| 212 |
+
pointer-events: none;
|
| 213 |
+
}
|
| 214 |
+
.toast-notify {
|
| 215 |
+
display: flex;
|
| 216 |
+
align-items: flex-start;
|
| 217 |
+
gap: 12px;
|
| 218 |
+
min-width: 300px;
|
| 219 |
+
max-width: 380px;
|
| 220 |
+
padding: 14px 16px;
|
| 221 |
+
border-radius: 10px;
|
| 222 |
+
box-shadow: 0 8px 24px rgba(0,0,0,0.15);
|
| 223 |
+
background: #fff;
|
| 224 |
+
border-left: 5px solid #ccc;
|
| 225 |
+
pointer-events: all;
|
| 226 |
+
opacity: 0;
|
| 227 |
+
transform: translateX(60px);
|
| 228 |
+
transition: opacity 0.3s ease, transform 0.3s ease;
|
| 229 |
+
position: relative;
|
| 230 |
+
overflow: hidden;
|
| 231 |
+
}
|
| 232 |
+
.toast-notify.show { opacity: 1; transform: translateX(0); }
|
| 233 |
+
.toast-notify.hide { opacity: 0; transform: translateX(60px); }
|
| 234 |
+
.toast-notify.toast-success { border-left-color: #28a745; }
|
| 235 |
+
.toast-notify.toast-error { border-left-color: #dc3545; }
|
| 236 |
+
.toast-notify.toast-warning { border-left-color: #ffc107; }
|
| 237 |
+
.toast-notify.toast-info { border-left-color: #17a2b8; }
|
| 238 |
+
.toast-icon { flex-shrink: 0; margin-top: 1px; }
|
| 239 |
+
.toast-success .toast-icon svg { stroke: #28a745; }
|
| 240 |
+
.toast-error .toast-icon svg { stroke: #dc3545; }
|
| 241 |
+
.toast-warning .toast-icon svg { stroke: #ffc107; }
|
| 242 |
+
.toast-info .toast-icon svg { stroke: #17a2b8; }
|
| 243 |
+
.toast-body { flex: 1; }
|
| 244 |
+
.toast-title { font-weight: 600; font-size: 0.875rem; margin-bottom: 2px; }
|
| 245 |
+
.toast-success .toast-title { color: #155724; }
|
| 246 |
+
.toast-error .toast-title { color: #721c24; }
|
| 247 |
+
.toast-warning .toast-title { color: #856404; }
|
| 248 |
+
.toast-info .toast-title { color: #0c5460; }
|
| 249 |
+
.toast-msg { font-size: 0.825rem; color: #555; line-height: 1.4; }
|
| 250 |
+
.toast-close {
|
| 251 |
+
background: none; border: none; font-size: 1rem;
|
| 252 |
+
line-height: 1; color: #aaa; cursor: pointer; padding: 0; flex-shrink: 0;
|
| 253 |
+
}
|
| 254 |
+
.toast-close:hover { color: #333; }
|
| 255 |
+
.toast-progress {
|
| 256 |
+
position: absolute;
|
| 257 |
+
bottom: 0; left: 0;
|
| 258 |
+
height: 3px;
|
| 259 |
+
border-radius: 0 0 0 10px;
|
| 260 |
+
}
|
| 261 |
+
.toast-success .toast-progress { background: #28a745; }
|
| 262 |
+
.toast-error .toast-progress { background: #dc3545; }
|
| 263 |
+
.toast-warning .toast-progress { background: #ffc107; }
|
| 264 |
+
.toast-info .toast-progress { background: #17a2b8; }
|
| 265 |
</style>
|
| 266 |
</head>
|
| 267 |
<body class="vertical light">
|
|
|
|
| 1302 |
}
|
| 1303 |
|
| 1304 |
function showAlert(type, message) {
|
| 1305 |
+
if (!document.getElementById('toast-container')) {
|
| 1306 |
+
const container = document.createElement('div');
|
| 1307 |
+
container.id = 'toast-container';
|
| 1308 |
+
document.body.appendChild(container);
|
| 1309 |
+
}
|
| 1310 |
+
const container = document.getElementById('toast-container');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1311 |
|
| 1312 |
+
const icons = {
|
| 1313 |
+
success: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>',
|
| 1314 |
+
error: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/></svg>',
|
| 1315 |
+
warning: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>',
|
| 1316 |
+
info: '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>'
|
| 1317 |
+
};
|
| 1318 |
+
const titles = { success: 'Éxito', error: 'Error', warning: 'Advertencia', info: 'Información' };
|
| 1319 |
+
const duration = type === 'error' ? 6000 : 4000;
|
| 1320 |
+
|
| 1321 |
+
const toast = document.createElement('div');
|
| 1322 |
+
toast.className = `toast-notify toast-${type}`;
|
| 1323 |
+
toast.innerHTML = `
|
| 1324 |
+
<div class="toast-icon">${icons[type] || icons.info}</div>
|
| 1325 |
+
<div class="toast-body">
|
| 1326 |
+
<div class="toast-title">${titles[type] || 'Aviso'}</div>
|
| 1327 |
+
<div class="toast-msg">${message}</div>
|
| 1328 |
+
</div>
|
| 1329 |
+
<button class="toast-close" onclick="this.closest('.toast-notify').remove()">×</button>
|
| 1330 |
+
<div class="toast-progress" style="width:100%;transition:width ${duration}ms linear;"></div>
|
| 1331 |
+
`;
|
| 1332 |
+
container.appendChild(toast);
|
| 1333 |
+
|
| 1334 |
+
requestAnimationFrame(() => requestAnimationFrame(() => {
|
| 1335 |
+
toast.classList.add('show');
|
| 1336 |
+
const bar = toast.querySelector('.toast-progress');
|
| 1337 |
+
if (bar) requestAnimationFrame(() => { bar.style.width = '0%'; });
|
| 1338 |
+
}));
|
| 1339 |
+
|
| 1340 |
+
const timer = setTimeout(() => {
|
| 1341 |
+
toast.classList.add('hide');
|
| 1342 |
+
toast.addEventListener('transitionend', () => toast.remove(), { once: true });
|
| 1343 |
+
}, duration);
|
| 1344 |
+
|
| 1345 |
+
toast.querySelector('.toast-close').addEventListener('click', () => clearTimeout(timer));
|
| 1346 |
}
|
| 1347 |
|
| 1348 |
// === FUNCIONES GLOBALES ===
|