feat: Enhance product management by adding WebSocket support for real-time updates, implement product loading in categories, and improve caching for category products.
This commit is contained in:
96
index.html
96
index.html
@@ -117,6 +117,21 @@
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
.category-products {
|
||||
margin-top: 0.5rem;
|
||||
padding-left: 4rem;
|
||||
font-size: 0.9rem;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.product-item {
|
||||
padding: 0.25rem 0;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.product-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -127,7 +142,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/socket.io/socket.io.js"></script>
|
||||
<script>
|
||||
const socket = io({
|
||||
transports: ['websocket']
|
||||
});
|
||||
|
||||
socket.on('connect', () => {
|
||||
console.log('🔌 Connected to server via WebSocket');
|
||||
});
|
||||
|
||||
socket.on('categoriesUpdated', () => {
|
||||
console.log('🔄 Categories updated, reloading tree...');
|
||||
loadCategories();
|
||||
});
|
||||
|
||||
socket.on('categoryProductsUpdated', ({ id }) => {
|
||||
console.log(`🔄 Products for category ${id} updated, reloading...`);
|
||||
// Find the specific category element and reload its products
|
||||
// Since we don't have easy access to instances, we could reload the whole tree
|
||||
// or dispatch a custom event. For simplicity, we'll reload the tree for now
|
||||
// but ideally we'd target the specific DOM element.
|
||||
|
||||
// Better approach: emit event that specific components can listen to
|
||||
document.dispatchEvent(new CustomEvent('productsUpdated', { detail: { id } }));
|
||||
});
|
||||
|
||||
async function loadCategories() {
|
||||
try {
|
||||
const response = await fetch('/api/categories');
|
||||
@@ -194,6 +234,62 @@
|
||||
|
||||
header.appendChild(info);
|
||||
div.appendChild(header);
|
||||
|
||||
// Products
|
||||
const productsDiv = document.createElement('div');
|
||||
productsDiv.className = 'category-products';
|
||||
productsDiv.innerHTML = '<small>Loading products...</small>';
|
||||
div.appendChild(productsDiv);
|
||||
|
||||
// Load products
|
||||
const loadProducts = () => {
|
||||
productsDiv.innerHTML = '<small>Loading products...</small>';
|
||||
productsDiv.style.display = 'block';
|
||||
|
||||
fetch(`/api/categories/${category.kKategorie}/products`)
|
||||
.then(res => res.ok ? res.json() : [])
|
||||
.then(products => {
|
||||
productsDiv.innerHTML = '';
|
||||
if (products.length === 0) {
|
||||
productsDiv.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
const ul = document.createElement('ul');
|
||||
ul.style.listStyle = 'none';
|
||||
|
||||
products.slice(0, 3).forEach(p => {
|
||||
const li = document.createElement('li');
|
||||
li.className = 'product-item';
|
||||
li.textContent = `📦 ${p.cName}`;
|
||||
ul.appendChild(li);
|
||||
});
|
||||
|
||||
if (products.length > 3) {
|
||||
const more = document.createElement('li');
|
||||
more.className = 'product-item';
|
||||
more.style.fontStyle = 'italic';
|
||||
more.textContent = `...and ${products.length - 3} more`;
|
||||
ul.appendChild(more);
|
||||
}
|
||||
|
||||
productsDiv.appendChild(ul);
|
||||
})
|
||||
.catch(() => {
|
||||
productsDiv.style.display = 'none';
|
||||
});
|
||||
};
|
||||
|
||||
loadProducts();
|
||||
|
||||
// Listen for updates
|
||||
const updateHandler = (e) => {
|
||||
if (e.detail.id === category.kKategorie) {
|
||||
console.log(`✨ refreshing products for category ${category.kKategorie}`);
|
||||
loadProducts();
|
||||
}
|
||||
};
|
||||
document.addEventListener('productsUpdated', updateHandler);
|
||||
|
||||
// Children
|
||||
if (category.children && category.children.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user