feat(ui): marketplace_external skeletons, empty states, toast notifications, Cmd+K
This commit is contained in:
@@ -105,7 +105,9 @@
|
|||||||
|
|
||||||
window.loadListings = async function() {
|
window.loadListings = async function() {
|
||||||
var container = document.getElementById('listingsContainer');
|
var container = document.getElementById('listingsContainer');
|
||||||
container.innerHTML = '<p>Cargando...</p>';
|
container.innerHTML = '<div class="meli-card"><div class="skeleton skeleton--text"></div><div class="skeleton skeleton--text-sm" style="width:70%;"></div></div>'
|
||||||
|
+ '<div class="meli-card"><div class="skeleton skeleton--text"></div><div class="skeleton skeleton--text-sm" style="width:60%;"></div></div>'
|
||||||
|
+ '<div class="meli-card"><div class="skeleton skeleton--text"></div><div class="skeleton skeleton--text-sm" style="width:80%;"></div></div>';
|
||||||
try {
|
try {
|
||||||
var res = await fetch(API + '/listings?page=1&per_page=50', { headers: headers() });
|
var res = await fetch(API + '/listings?page=1&per_page=50', { headers: headers() });
|
||||||
if (!res.ok) throw new Error('Failed to load listings');
|
if (!res.ok) throw new Error('Failed to load listings');
|
||||||
@@ -113,7 +115,11 @@
|
|||||||
listingsData = data.items || [];
|
listingsData = data.items || [];
|
||||||
renderListings();
|
renderListings();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
container.innerHTML = '<p style="color:var(--color-danger);">Error cargando publicaciones</p>';
|
container.innerHTML = renderEmptyState({
|
||||||
|
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><path d="M8 21h8M12 17v4"/></svg>',
|
||||||
|
title: 'Error cargando publicaciones',
|
||||||
|
subtitle: 'No se pudieron obtener las publicaciones de MercadoLibre. Intenta de nuevo.'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -129,7 +135,12 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!filtered.length) {
|
if (!filtered.length) {
|
||||||
container.innerHTML = '<p style="color:var(--color-text-muted);padding:var(--space-4);">No hay publicaciones. Ve a Inventario y publica un producto.</p>';
|
container.innerHTML = renderEmptyState({
|
||||||
|
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><path d="M8 21h8M12 17v4"/></svg>',
|
||||||
|
title: 'Sin publicaciones',
|
||||||
|
subtitle: 'Aún no hay publicaciones en MercadoLibre. Ve a Inventario y publica un producto.',
|
||||||
|
action: '<a href="/pos/inventory" class="btn btn--meli btn--sm">Ir a Inventario</a>'
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,13 +170,13 @@
|
|||||||
var res = await fetch(API + '/listings/' + id + '/sync', { method: 'POST', headers: headers() });
|
var res = await fetch(API + '/listings/' + id + '/sync', { method: 'POST', headers: headers() });
|
||||||
var data = await res.json();
|
var data = await res.json();
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
alert('Sincronizado: $' + data.price + ' · Stock: ' + data.stock);
|
showToast('Sincronizado: $' + data.price + ' · Stock: ' + data.stock, 'ok', { title: 'Publicación actualizada' });
|
||||||
loadListings();
|
loadListings();
|
||||||
} else {
|
} else {
|
||||||
alert('Error: ' + (data.error || 'Unknown'));
|
showToast(data.error || 'Error desconocido', 'error', { title: 'Error de sincronización' });
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert('Error: ' + e.message);
|
showToast(e.message, 'error', { title: 'Error de red' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -197,7 +208,7 @@
|
|||||||
|
|
||||||
window.loadOrders = async function() {
|
window.loadOrders = async function() {
|
||||||
var tbody = document.getElementById('ordersTableBody');
|
var tbody = document.getElementById('ordersTableBody');
|
||||||
tbody.innerHTML = '<tr><td colspan="6">Cargando...</td></tr>';
|
tbody.innerHTML = renderSkeletonRows(6, 5);
|
||||||
try {
|
try {
|
||||||
var res = await fetch(API + '/orders?page=1&per_page=50', { headers: headers() });
|
var res = await fetch(API + '/orders?page=1&per_page=50', { headers: headers() });
|
||||||
if (!res.ok) throw new Error('Failed to load orders');
|
if (!res.ok) throw new Error('Failed to load orders');
|
||||||
@@ -205,7 +216,11 @@
|
|||||||
ordersData = data.items || [];
|
ordersData = data.items || [];
|
||||||
renderOrders();
|
renderOrders();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
tbody.innerHTML = '<tr><td colspan="6" style="color:var(--color-danger)">Error cargando órdenes</td></tr>';
|
tbody.innerHTML = '<tr><td colspan="6">' + renderEmptyState({
|
||||||
|
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><path d="M8 21h8M12 17v4"/></svg>',
|
||||||
|
title: 'Error cargando órdenes',
|
||||||
|
subtitle: 'No se pudieron obtener las órdenes de MercadoLibre.'
|
||||||
|
}) + '</td></tr>';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -221,7 +236,11 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!filtered.length) {
|
if (!filtered.length) {
|
||||||
tbody.innerHTML = '<tr><td colspan="6" style="color:var(--color-text-muted)">No hay órdenes.</td></tr>';
|
tbody.innerHTML = '<tr><td colspan="6">' + renderEmptyState({
|
||||||
|
icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><path d="M8 21h8M12 17v4"/></svg>',
|
||||||
|
title: 'Sin órdenes',
|
||||||
|
subtitle: 'No hay órdenes de MercadoLibre en este momento.'
|
||||||
|
}) + '</td></tr>';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,13 +315,13 @@
|
|||||||
});
|
});
|
||||||
var data = await res.json();
|
var data = await res.json();
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
alert('Orden convertida a venta #' + data.sale_id);
|
showToast('Orden convertida a venta #' + data.sale_id, 'ok', { title: 'Venta creada' });
|
||||||
loadOrders();
|
loadOrders();
|
||||||
} else {
|
} else {
|
||||||
alert('Error: ' + (data.error || 'Unknown'));
|
showToast(data.error || 'Error desconocido', 'error', { title: 'Error al convertir' });
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert('Error: ' + e.message);
|
showToast(e.message, 'error', { title: 'Error de red' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -361,6 +380,13 @@
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Register Cmd+K items
|
||||||
|
if (typeof registerCmdKItem === 'function') {
|
||||||
|
registerCmdKItem({ group: 'MercadoLibre', label: 'Configuración ML', href: '/pos/marketplace-external', icon: '⚙️' });
|
||||||
|
registerCmdKItem({ group: 'MercadoLibre', label: 'Publicaciones ML', href: '/pos/marketplace-external#listings', icon: '📦' });
|
||||||
|
registerCmdKItem({ group: 'MercadoLibre', label: 'Órdenes ML', href: '/pos/marketplace-external#orders', icon: '🛒' });
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
loadConfig();
|
loadConfig();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -193,7 +193,7 @@
|
|||||||
<div class="meli-card" style="max-width:600px;">
|
<div class="meli-card" style="max-width:600px;">
|
||||||
<h3 style="margin:0 0 var(--space-4);font-family:var(--font-heading);">Conexión con MercadoLibre</h3>
|
<h3 style="margin:0 0 var(--space-4);font-family:var(--font-heading);">Conexión con MercadoLibre</h3>
|
||||||
<div id="configStatus">
|
<div id="configStatus">
|
||||||
<p>Cargando estado...</p>
|
<div class="skeleton skeleton--text" style="width:120px;"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="configForm" style="display:none;margin-top:var(--space-4);">
|
<div id="configForm" style="display:none;margin-top:var(--space-4);">
|
||||||
<p style="margin-bottom:var(--space-3);font-size:var(--text-body-sm);color:var(--color-text-secondary);">
|
<p style="margin-bottom:var(--space-3);font-size:var(--text-body-sm);color:var(--color-text-secondary);">
|
||||||
@@ -316,8 +316,9 @@
|
|||||||
|
|
||||||
<script src="/pos/static/js/i18n.js" defer></script>
|
<script src="/pos/static/js/i18n.js" defer></script>
|
||||||
<script src="/pos/static/js/app-init.js" defer></script>
|
<script src="/pos/static/js/app-init.js" defer></script>
|
||||||
|
<script src="/pos/static/js/pos-utils.js?v=2" defer></script>
|
||||||
<script src="/pos/static/js/sidebar.js" defer></script>
|
<script src="/pos/static/js/sidebar.js" defer></script>
|
||||||
<script src="/pos/static/js/marketplace_external.js?v=3" defer></script>
|
<script src="/pos/static/js/marketplace_external.js?v=4" defer></script>
|
||||||
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
<script>if('serviceWorker' in navigator){navigator.serviceWorker.register('/pos/sw.js',{scope:'/pos/'});}</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user