diff --git a/src/background/service-worker.ts b/src/background/service-worker.ts
index 051ef53..811f05e 100644
--- a/src/background/service-worker.ts
+++ b/src/background/service-worker.ts
@@ -256,9 +256,12 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
sendResponse({ success: true, ...result });
})
.catch(error => {
+ // Include error code for 404 detection
+ const errorCode = (error as { statusCode?: number }).statusCode;
sendResponse({
success: false,
- error: error instanceof Error ? error.message : 'Failed to get status'
+ error: error instanceof Error ? error.message : 'Failed to get status',
+ errorCode
});
});
return true;
diff --git a/src/popup/popup.html b/src/popup/popup.html
index 7a3a72c..9f1ca5b 100644
--- a/src/popup/popup.html
+++ b/src/popup/popup.html
@@ -22,13 +22,6 @@
-
diff --git a/src/popup/popup.ts b/src/popup/popup.ts
index 18425a5..9e483cc 100644
--- a/src/popup/popup.ts
+++ b/src/popup/popup.ts
@@ -29,7 +29,6 @@ const logoutBtn = document.getElementById('logoutBtn')!;
const archiveToggleBtn = document.getElementById('archiveToggleBtn')!;
const archiveIcon = document.getElementById('archiveIcon')!;
const liveIcon = document.getElementById('liveIcon')!;
-const refreshBtn = document.getElementById('refreshBtn')!;
const helpBtn = document.getElementById('helpBtn')!;
const togglePasswordBtn = document.getElementById('togglePassword') as HTMLButtonElement;
const eyeIcon = document.getElementById('eyeIcon')!;
@@ -87,9 +86,16 @@ function setupEventListeners() {
loginForm.addEventListener('submit', handleLogin);
logoutBtn.addEventListener('click', handleLogout);
archiveToggleBtn.addEventListener('click', handleToggleArchiveView);
- refreshBtn.addEventListener('click', handleRefreshAll);
helpBtn.addEventListener('click', handleHelp);
- togglePasswordBtn.addEventListener('click', handleTogglePassword);
+
+ // Password toggle - ensure button exists and attach handler
+ if (togglePasswordBtn) {
+ togglePasswordBtn.addEventListener('click', (e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ handleTogglePassword();
+ });
+ }
}
/**
@@ -434,7 +440,7 @@ function renderPDFItem(pdf: DocumentProxy, section: 'pending' | 'basket' | 'prod
case 'basket':
actionsHtml = `
`;
@@ -539,7 +545,7 @@ function getStatusText(pdf: DocumentProxy): string {
case 'in_basket':
return pdf.binectStatusText || 'Ready to order';
case 'ordering':
- return 'Ordering...';
+ return 'Sending...';
case 'in_production':
return pdf.binectStatusText || 'In production';
case 'sent':
@@ -788,7 +794,7 @@ async function handleOrderPDF(id: string) {
pdf.binectStatusText = result.statusText;
renderPDFList();
- showStatus('Order placed! Document is in production.', 'success');
+ showStatus('Sent! Document is in production.', 'success');
// Start auto-refresh sequence
startAutoRefresh();
@@ -799,7 +805,7 @@ async function handleOrderPDF(id: string) {
}, 3000);
} catch (error) {
- const errorMessage = error instanceof Error ? error.message : 'Order failed';
+ const errorMessage = error instanceof Error ? error.message : 'Send failed';
// Revert to in_basket status
await chrome.runtime.sendMessage({
@@ -833,14 +839,10 @@ async function handleRefreshAll() {
);
if (uploadedDocs.length === 0) {
- showStatus('No documents to refresh', 'success');
- setTimeout(() => hideStatus(), 2000);
return;
}
- // Disable refresh button during refresh
- refreshBtn.classList.add('refreshing');
- showStatus(`Refreshing ${uploadedDocs.length} document${uploadedDocs.length > 1 ? 's' : ''}...`, 'uploading');
+ console.log(`[Popup] Refreshing ${uploadedDocs.length} document(s)...`);
let successCount = 0;
let errorCount = 0;
@@ -854,15 +856,9 @@ async function handleRefreshAll() {
}
}
- refreshBtn.classList.remove('refreshing');
-
- if (errorCount === 0) {
- showStatus(`Refreshed ${successCount} document${successCount > 1 ? 's' : ''}`, 'success');
- } else {
- showStatus(`Refreshed ${successCount}, ${errorCount} failed`, 'error');
+ if (errorCount > 0) {
+ console.log(`[Popup] Refresh complete: ${successCount} ok, ${errorCount} failed`);
}
-
- setTimeout(() => hideStatus(), 3000);
}
/**
@@ -884,6 +880,13 @@ async function handleRefreshStatus(id: string) {
});
if (!result.success) {
+ // Check if document was deleted on server (404)
+ if (result.errorCode === 404) {
+ console.log('[Popup] Document deleted on server, archiving:', id);
+ await handleArchivePDF(id);
+ showStatus('Document no longer exists on server', 'error');
+ return;
+ }
throw new Error(result.error || 'Failed to get status');
}
@@ -922,15 +925,9 @@ async function handleRefreshStatus(id: string) {
if (result.recipientAddress) pdf.recipientAddress = result.recipientAddress;
renderPDFList();
- showStatus(`Status: ${result.statusText}`, 'success');
-
- setTimeout(() => {
- hideStatus();
- }, 3000);
-
} catch (error) {
- const errorMessage = error instanceof Error ? error.message : 'Failed to refresh';
- showStatus(errorMessage, 'error');
+ console.error('[Popup] Refresh error:', error);
+ // Only show errors that aren't already handled (like 404)
}
}
diff --git a/src/utils/binect-api.ts b/src/utils/binect-api.ts
index cfcbb66..060c248 100644
--- a/src/utils/binect-api.ts
+++ b/src/utils/binect-api.ts
@@ -445,6 +445,10 @@ export async function getDocumentStatus(
}
if (error instanceof BinectApiError) {
+ // Check for 404 - document not found (deleted on server)
+ if (error.status === 404) {
+ throw new BinectAPIError('Document not found on server', 404);
+ }
throw BinectAPIError.fromBinectError(error);
}