- Fase A: license templates, search history, cost estimator - Fase B: import URL, bulk ZIP, batch download - Fase C: comparison mode, mesh validation, measurement tool - Fase D: cross-section clipping, overhang heatmap, layer animation - Refactor Pydantic/SQLAlchemy warnings - 24 tests pytest - README actualizado - WebP thumbnails, lazy loading, cache headers
60 lines
1.5 KiB
JavaScript
60 lines
1.5 KiB
JavaScript
const API_BASE = '/api';
|
|
|
|
function showToast(message, type = 'info') {
|
|
const container = document.getElementById('toast-container');
|
|
if (!container) return;
|
|
const toast = document.createElement('div');
|
|
toast.className = `toast ${type}`;
|
|
toast.textContent = message;
|
|
container.appendChild(toast);
|
|
setTimeout(() => {
|
|
toast.style.opacity = '0';
|
|
toast.style.transform = 'translateX(20px)';
|
|
toast.style.transition = 'all 0.3s ease';
|
|
setTimeout(() => toast.remove(), 300);
|
|
}, 4000);
|
|
}
|
|
|
|
async function apiGet(path) {
|
|
const res = await fetch(API_BASE + path);
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(text || `HTTP ${res.status}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
async function apiDelete(path) {
|
|
const res = await fetch(API_BASE + path, { method: 'DELETE' });
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(text || `HTTP ${res.status}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
async function apiPostForm(path, formData) {
|
|
const res = await fetch(API_BASE + path, {
|
|
method: 'POST',
|
|
body: formData,
|
|
});
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(text || `HTTP ${res.status}`);
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
async function apiPut(path, data) {
|
|
const res = await fetch(API_BASE + path, {
|
|
method: 'PUT',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(data),
|
|
});
|
|
if (!res.ok) {
|
|
const text = await res.text();
|
|
throw new Error(text || `HTTP ${res.status}`);
|
|
}
|
|
return res.json();
|
|
}
|