Now add event listeners for the sort dropdowns and the clear/bulk-delete functions. Let me find the existing event listeners section:


No matches found


182:                <input type="text" id="contact-search" placeholder="Search contacts..." class="search-input">
195:                <button class="btn btn-small" onclick="loadContacts()">Refresh</button>


The search inputs don't have event listeners — they rely on the Refresh button or Apply button. Let me add the clear/bulk-delete functions and sort change handlers to the delete functions block I already added at the end of app.js:


  4028→            alert('Error: ' + (data.error || 'Delete failed'));
  4029→        }
  4030→    } catch(e) {
  4031→        alert('Error deleting thread: ' + e.message);
  4032→    }
  4033→}
  4034→
  4035→async function deleteThreadsByEmail(email, domain) {
  4036→    var target = email || ('@' + domain);
  4037→    if (!confirm('Delete ALL threads involving ' + target + '?\n\nThis removes all emails, analysis, and AI responses for those threads. Cannot be undone.')) return;
  4038→
  4039→    try {
  4040→        var body = {};
  4041→        if (email) body.email = email;
  4042→        if (domain) body.domain = domain;

            alert('Error: ' + (data.error || 'Delete failed'));
        }
    } catch(e) {
        alert('Error deleting thread: ' + e.message);
    }
}

async function deleteThreadsByEmail(email, domain) {
    var target = email || ('@' + domain);
    if (!confirm('Delete ALL threads involving ' + target + '?\n\nThis removes all emails, analysis, and AI responses for those threads. Cannot be undone.')) return;

    try {
        var body = {};
        if (email) body.email = email;
        if (domain) body.domain = domain;


  4052→            loadEmails(state.emails.page);
  4053→        } else {
  4054→            alert('Error: ' + (data.error || 'Delete failed'));
  4055→        }
  4056→    } catch(e) {
  4057→        alert('Error: ' + e.message);
  4058→    }
  4059→}
  4060→
  4061→

            loadEmails(state.emails.page);
        } else {
            alert('Error: ' + (data.error || 'Delete failed'));
        }
    } catch(e) {
        alert('Error: ' + e.message);
    }
}


Edit

    } catch(e) {
        alert('Error: ' + e.message);
    }
}

    } catch(e) {
        alert('Error: ' + e.message);
    }
}

function promptBulkDeleteByEmail() {
    var input = prompt('Enter email address (e.g. john@example.com) or domain (e.g. example.com) to delete all threads:');
    if (!input || !input.trim()) return;
    input = input.trim();
    if (input.indexOf('@') !== -1) {
        deleteThreadsByEmail(input, '');
    } else {
        deleteThreadsByEmail('', input);
    }
}

// ============================================
// FILTER FUNCTIONS
// ============================================
function clearContactFilters() {
    document.getElementById('contact-search').value = '';
    document.getElementById('contact-type-filter').value = '';
    document.getElementById('contact-date-from').value = '';
    document.getElementById('contact-date-to').value = '';
    document.getElementById('contact-sort').value = 'last_contact:DESC';
    loadContacts(1);
}

function clearThreadFilters() {
    document.getElementById('email-search').value = '';
    if (document.getElementById('thread-contact-filter')) document.getElementById('thread-contact-filter').value = '';
    document.getElementById('thread-date-from').value = '';
    document.getElementById('thread-date-to').value = '';
    if (document.getElementById('thread-status-filter')) document.getElementById('thread-status-filter').value = '';
    document.getElementById('thread-sort').value = 'last_date:DESC';
    loadEmails(1);
}

// Sort change listeners
document.addEventListener('DOMContentLoaded', function() {
    var contactSort = document.getElementById('contact-sort');
    if (contactSort) contactSort.addEventListener('change', function() { loadContacts(1); });
    var threadSort = document.getElementById('thread-sort');
    if (threadSort) threadSort.addEventListener('change', function() { loadEmails(1); });
});