@ -41,21 +41,37 @@ function extractInvoiceDataFromSearchResults() {
const resultsDiv = document . getElementById ( 'invoice-search-results' ) ;
const invoiceCards = resultsDiv . querySelectorAll ( '.invoice-card' ) ;
lastSearchResults = [ ] ;
// Store new search results separately
const newSearchResults = [ ] ;
invoiceCards . forEach ( card => {
const invoiceData = extractInvoiceDataFromCard ( card ) ;
if ( invoiceData ) {
last SearchResults. push ( invoiceData ) ;
new SearchResults. push ( invoiceData ) ;
console . log ( 'Extracted invoice data:' , invoiceData ) ;
}
} ) ;
console . log ( ` Captured ${ lastSearchResults . length } invoices from search results ` ) ;
console . log ( ` Captured ${ newSearchResults . length } new invoices from search results ` ) ;
// Add new results to existing results (avoid duplicates)
newSearchResults . forEach ( newInvoice => {
const exists = lastSearchResults . some ( existing =>
existing . id === newInvoice . id ||
existing . invoiceNumber === newInvoice . invoiceNumber
) ;
// If we're currently in board view, update it immediately
if ( ! exists ) {
lastSearchResults . push ( newInvoice ) ;
console . log ( ` Added new invoice to collection: ${ newInvoice . id } ` ) ;
} else {
console . log ( ` Invoice already exists in collection: ${ newInvoice . id } ` ) ;
}
} ) ;
// If we're currently in board view, add the new invoices to the board
if ( currentView === 'board' ) {
populateBoardWithSearchResults ( ) ;
addNewInvoicesToBoard ( newSearchResults ) ;
}
}
@ -160,13 +176,11 @@ function clearSearch() {
< / d i v >
` ;
// Clear board if currently in board view
if ( currentView === 'board' ) {
clearBoard ( ) ;
}
// Don't clear board when clearing search - let users keep their board intact
console . log ( 'Search cleared, but board preserved' ) ;
}
// View switching functionality
// View switching functionality (modified to preserve board)
function switchView ( viewName ) {
const searchView = document . getElementById ( 'search-view' ) ;
const boardView = document . getElementById ( 'board-view' ) ;
@ -183,10 +197,13 @@ function switchView(viewName) {
currentView = viewName ;
// If switching to board view, populate it with search results
// If switching to board view, only populate if board is empty
if ( viewName === 'board' ) {
if ( lastSearchResults . length > 0 ) {
const existingCards = document . querySelectorAll ( '.board-invoice-card' ) ;
if ( existingCards . length === 0 && lastSearchResults . length > 0 ) {
populateBoardWithSearchResults ( ) ;
} else if ( existingCards . length > 0 ) {
console . log ( ` Board already has ${ existingCards . length } invoices, keeping them ` ) ;
} else {
checkBoardState ( ) ;
}
@ -195,6 +212,24 @@ function switchView(viewName) {
console . log ( ` Switched to ${ viewName } view ` ) ;
}
// Populate board with search results (modified to be explicit about clearing)
function populateBoardWithSearchResults ( ) {
console . log ( ` Populating board with ${ lastSearchResults . length } search results ` ) ;
// Clear existing board content
clearBoard ( ) ;
// Add each search result to the board
lastSearchResults . forEach ( invoiceData => {
addInvoiceToBoard ( invoiceData ) ;
} ) ;
// Debug the board state after population
debugBoardState ( ) ;
showMessage ( ` Added ${ lastSearchResults . length } invoices to board ` , 'success' ) ;
}
// Clear all invoices from the board
function clearBoard ( ) {
document . querySelectorAll ( '.invoice-drop-zone' ) . forEach ( zone => {
@ -214,24 +249,8 @@ function clearBoard() {
// Update counts
updateColumnCounts ( ) ;
}
// Populate board with search results
function populateBoardWithSearchResults ( ) {
console . log ( ` Populating board with ${ lastSearchResults . length } search results ` ) ;
// Clear existing board content
clearBoard ( ) ;
// Add each search result to the board
lastSearchResults . forEach ( invoiceData => {
addInvoiceToBoard ( invoiceData ) ;
} ) ;
// Debug the board state after population
debugBoardState ( ) ;
showMessage ( ` Added ${ lastSearchResults . length } invoices to board ` , 'success ') ;
console . log ( 'Board cleared' ) ;
}
// Board functionality
@ -263,7 +282,7 @@ function loadRecentInvoices() {
// For now, show a helpful message
setTimeout ( ( ) => {
showBoardLoading ( false ) ;
showMessage ( 'Search for invoices in the Search View to populate the boar d' , 'info' ) ;
showMessage ( 'Sorry, this feature is not yet implemente d' , 'info' ) ;
} , 1000 ) ;
}
@ -630,18 +649,111 @@ function createBoardCardHTML(invoice) {
< div class = "board-card-footer" >
< div class = "status-indicator status-${invoice.status}" > $ { invoice . status } < / d i v >
< button class = "card-details-btn" onclick = "showInvoiceDetails('${invoice.id}')" title = "View Details" >
👁 ️
🔍
< / b u t t o n >
< / d i v >
< / d i v >
` ;
}
// Invoice details modal (placeholder)
// Invoice details modal
function showInvoiceDetails ( invoiceId ) {
console . log ( ` Showing details for invoice ${ invoiceId } ` ) ;
// TODO: Implement invoice details modal
showMessage ( ` Details for invoice ${ invoiceId } ` , 'info' ) ;
// Find the invoice data in our stored data
let invoiceData = boardInvoices . get ( invoiceId ) ;
// If not found in board, try searching in lastSearchResults
if ( ! invoiceData ) {
invoiceData = lastSearchResults . find ( inv =>
inv . id === invoiceId || inv . id === invoiceId . toString ( ) ||
inv . invoiceNumber === invoiceId
) ;
}
if ( ! invoiceData ) {
showMessage ( 'Invoice details not found' , 'error' ) ;
return ;
}
// Create and show modal
const modal = createInvoiceDetailsModal ( invoiceData ) ;
document . body . appendChild ( modal ) ;
// Show modal with animation
setTimeout ( ( ) => modal . classList . add ( 'show' ) , 10 ) ;
// Close modal when clicking outside or on close button
modal . addEventListener ( 'click' , function ( e ) {
if ( e . target === modal || e . target . classList . contains ( 'modal-close' ) ) {
closeInvoiceDetailsModal ( modal ) ;
}
} ) ;
}
function createInvoiceDetailsModal ( invoiceData ) {
const modal = document . createElement ( 'div' ) ;
modal . className = 'invoice-details-modal' ;
modal . innerHTML = `
< div class = "modal-content" >
< div class = "modal-header" >
< h3 > Invoice Details < / h 3 >
< button class = "modal-close" type = "button" > ✕ < / b u t t o n >
< / d i v >
< div class = "modal-body" >
< div class = "invoice-detail-grid" >
< div class = "detail-row" >
< span class = "detail-label" > Invoice # : < / s p a n >
< span class = "detail-value" > $ { invoiceData . invoiceNumber || 'N/A' } < / s p a n >
< / d i v >
< div class = "detail-row" >
< span class = "detail-label" > Invoice ID : < / s p a n >
< span class = "detail-value" > $ { invoiceData . id || 'N/A' } < / s p a n >
< / d i v >
< div class = "detail-row" >
< span class = "detail-label" > Status : < / s p a n >
< span class = "detail-value" >
< span class = "status-badge status-${invoiceData.status}" > $ { invoiceData . status } < / s p a n >
< / s p a n >
< / d i v >
< div class = "detail-row" >
< span class = "detail-label" > Customer : < / s p a n >
< span class = "detail-value" > $ { invoiceData . customer ? invoiceData . customer . name : 'N/A' } < / s p a n >
< / d i v >
< div class = "detail-row" >
< span class = "detail-label" > Job : < / s p a n >
< span class = "detail-value" > $ { invoiceData . job ? invoiceData . job . name : 'N/A' } < / s p a n >
< / d i v >
< div class = "detail-row" >
< span class = "detail-label" > Total Price : < / s p a n >
< span class = "detail-value total-amount" > $$ { invoiceData . totalPrice || '0.00' } < / s p a n >
< / d i v >
< / d i v >
< / d i v >
< div class = "modal-footer" >
< button class = "btn-secondary modal-close" type = "button" > Close < / b u t t o n >
< / d i v >
< / d i v >
` ;
return modal ;
}
function closeInvoiceDetailsModal ( modal ) {
modal . classList . remove ( 'show' ) ;
setTimeout ( ( ) => {
if ( document . body . contains ( modal ) ) {
document . body . removeChild ( modal ) ;
}
} , 300 ) ;
}
// Utility function for showing messages
@ -713,4 +825,44 @@ function debugBoardState() {
}
// Make debug function globally accessible for browser console
window . debugBoardState = debugBoardState ;
window . debugBoardState = debugBoardState ;
// Add new invoices to board without clearing existing ones
function addNewInvoicesToBoard ( newInvoices ) {
console . log ( ` Adding ${ newInvoices . length } new invoices to existing board ` ) ;
let addedCount = 0 ;
newInvoices . forEach ( invoiceData => {
// Check if invoice is already on the board
const existingCard = document . getElementById ( ` board-invoice- ${ invoiceData . id } ` ) ;
if ( ! existingCard ) {
addInvoiceToBoard ( invoiceData ) ;
addedCount ++ ;
} else {
console . log ( ` Invoice ${ invoiceData . id } already on board, skipping ` ) ;
}
} ) ;
if ( addedCount > 0 ) {
showMessage ( ` Added ${ addedCount } new invoices to board ` , 'success' ) ;
} else if ( newInvoices . length > 0 ) {
showMessage ( ` All ${ newInvoices . length } invoices already on board ` , 'info' ) ;
}
}
// Clear board with confirmation
function clearBoardAndConfirm ( ) {
const existingCards = document . querySelectorAll ( '.board-invoice-card' ) ;
if ( existingCards . length === 0 ) {
showMessage ( 'Board is already empty' , 'info' ) ;
return ;
}
const confirmed = confirm ( ` Are you sure you want to clear all ${ existingCards . length } invoices from the board? This will not affect the invoices themselves, only remove them from the board view. ` ) ;
if ( confirmed ) {
clearBoard ( ) ;
showMessage ( 'Board cleared successfully' , 'success' ) ;
}
}