238 lines
8.3 KiB
JavaScript

// API base URL
const API_BASE_URL = '/api';
// Selected orders for actions
let selectedOrders = new Set();
// Show toast notification
function showToast(message, type = 'success') {
const toast = document.createElement('div');
toast.className = `fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-lg text-white ${
type === 'success' ? 'bg-green-600' : 'bg-red-600'
} transform translate-y-0 opacity-100 transition-all duration-300`;
toast.textContent = message;
document.body.appendChild(toast);
setTimeout(() => {
toast.style.transform = 'translateY(100%)';
toast.style.opacity = '0';
setTimeout(() => toast.remove(), 300);
}, 3000);
}
// Show loading state
function setLoading(isLoading) {
const buttons = document.querySelectorAll('button');
buttons.forEach(button => {
if (isLoading) {
button.disabled = true;
button.classList.add('opacity-50', 'cursor-not-allowed');
} else {
button.disabled = false;
button.classList.remove('opacity-50', 'cursor-not-allowed');
}
});
}
// Fetch orders from the API
async function fetchOrders() {
try {
setLoading(true);
const searchRange = document.getElementById('searchRange').value;
const openOnly = document.getElementById('openOnly').checked;
const response = await fetch(`${API_BASE_URL}/orders?search_range=${searchRange}&open_only=${openOnly}`);
if (!response.ok) {
throw new Error('Failed to fetch orders');
}
const orders = await response.json();
displayOrders(orders);
showToast('Orders loaded successfully');
} catch (error) {
showToast('Error fetching orders: ' + error.message, 'error');
} finally {
setLoading(false);
}
}
// Display orders in the UI
function displayOrders(orders) {
const ordersList = document.getElementById('ordersList');
ordersList.innerHTML = '';
if (!orders || orders.length === 0) {
ordersList.innerHTML = '<div class="col-span-full text-center text-gray-400 py-4">No orders found</div>';
return;
}
orders.forEach(order => {
const orderCard = document.createElement('div');
orderCard.className = `bg-gray-700 rounded-lg shadow-sm p-4 border border-gray-600 hover:shadow-md transition-shadow cursor-pointer ${
selectedOrders.has(order.orderNumber) ? 'ring-2 ring-blue-500' : ''
}`;
orderCard.dataset.orderId = order.orderNumber;
orderCard.innerHTML = `
<div class="flex flex-col h-full">
<div class="flex justify-between items-start mb-3">
<div class="flex-1 min-w-0">
<h3 class="text-lg font-bold text-blue-400 truncate">#${order.orderNumber || 'N/A'}</h3>
<p class="text-sm text-gray-400">${order.buyerName || 'N/A'}</p>
</div>
<span class="px-2 py-1 text-xs rounded-full ${
order.orderStatus === 'Open' ? 'bg-green-900/50 text-green-300' : 'bg-gray-600/50 text-gray-300'
}">${order.orderStatus || 'Unknown'}</span>
</div>
<div class="mt-auto">
<div class="flex justify-between items-center">
<p class="text-sm text-gray-400">${order.orderDate ? new Date(order.orderDate).toLocaleString() : 'N/A'}</p>
<p class="text-lg font-bold text-white">$${order.totalAmount ? order.totalAmount.toFixed(2) : '0.00'}</p>
</div>
</div>
</div>
`;
ordersList.appendChild(orderCard);
// Add click event listener to the order card
orderCard.addEventListener('click', () => {
const orderId = orderCard.dataset.orderId;
if (selectedOrders.has(orderId)) {
selectedOrders.delete(orderId);
orderCard.classList.remove('ring-2', 'ring-blue-500');
} else {
selectedOrders.add(orderId);
orderCard.classList.add('ring-2', 'ring-blue-500');
}
});
});
}
// Select all orders on the page
function selectAllOrders() {
const orderCards = document.querySelectorAll('[data-order-id]');
const allSelected = orderCards.length > 0 && Array.from(orderCards).every(card => selectedOrders.has(card.dataset.orderId));
orderCards.forEach(card => {
const orderId = card.dataset.orderId;
if (allSelected) {
selectedOrders.delete(orderId);
card.classList.remove('ring-2', 'ring-blue-500');
} else {
selectedOrders.add(orderId);
card.classList.add('ring-2', 'ring-blue-500');
}
});
showToast(allSelected ? 'All orders deselected' : 'All orders selected');
}
// Generate pull sheets
async function generatePullSheets() {
try {
const orderIds = Array.from(selectedOrders);
if (orderIds.length === 0) {
showToast('Please select at least one order', 'error');
return;
}
setLoading(true);
const response = await fetch(`${API_BASE_URL}/orders/generate-pull-sheets`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
order_ids: orderIds
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.detail || 'Failed to generate pull sheets');
}
showToast('Pull sheets generated successfully');
} catch (error) {
showToast('Error generating pull sheets: ' + error.message, 'error');
} finally {
setLoading(false);
}
}
// Generate packing slips
async function generatePackingSlips() {
try {
const orderIds = Array.from(selectedOrders);
if (orderIds.length === 0) {
showToast('Please select at least one order', 'error');
return;
}
setLoading(true);
const response = await fetch(`${API_BASE_URL}/orders/generate-packing-slips`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
order_ids: orderIds
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.detail || 'Failed to generate packing slips');
}
showToast('Packing slips generated successfully');
} catch (error) {
showToast('Error generating packing slips: ' + error.message, 'error');
} finally {
setLoading(false);
}
}
// Generate address labels
async function generateAddressLabels() {
try {
const orderIds = Array.from(selectedOrders);
if (orderIds.length === 0) {
showToast('Please select at least one order', 'error');
return;
}
const labelType = document.getElementById('labelType').value;
setLoading(true);
const response = await fetch(`${API_BASE_URL}/orders/generate-address-labels`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
order_ids: orderIds,
label_type: labelType
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.detail || 'Failed to generate address labels');
}
showToast('Address labels generated successfully');
} catch (error) {
showToast('Error generating address labels: ' + error.message, 'error');
} finally {
setLoading(false);
}
}
// Load orders when page loads
document.addEventListener('DOMContentLoaded', () => {
fetchOrders();
// Add event listeners for search range and open only checkbox
document.getElementById('searchRange').addEventListener('change', fetchOrders);
document.getElementById('openOnly').addEventListener('change', fetchOrders);
});