// HBU Asset Recovery Command Center - Main JavaScript // Initialize app document.addEventListener('DOMContentLoaded', function() { feather.replace(); initializeApp(); }); // App initialization function initializeApp() { // Set initial section showSection('dashboard'); // Start periodic updates setInterval(updateStats, 30000); // Update stats every 30 seconds setInterval(checkNewNotifications, 10000); // Check notifications every 10 seconds // Initialize tooltips initializeTooltips(); // Add keyboard shortcuts initializeKeyboardShortcuts(); } // Section management function showSection(sectionId) { // Hide all sections const sections = document.querySelectorAll('.section'); sections.forEach(section => { section.classList.add('hidden'); }); // Show selected section const targetSection = document.getElementById(sectionId); if (targetSection) { targetSection.classList.remove('hidden'); } // Update nav items const navItems = document.querySelectorAll('.nav-item'); navItems.forEach(item => { item.classList.remove('text-primary-700', 'bg-primary-50'); item.classList.add('text-gray-700'); }); // Highlight active nav item const activeNavItem = document.querySelector(`[onclick="showSection('${sectionId}')"]`); if (activeNavItem) { activeNavItem.classList.remove('text-gray-700'); activeNavItem.classList.add('text-primary-700', 'bg-primary-50'); } // Re-render feather icons feather.replace(); } // Toggle notifications panel function toggleNotifications() { const panel = document.getElementById('notificationsPanel'); if (panel) { panel.classList.toggle('translate-x-full'); } } // Modal management function openNewLeadModal() { const modal = document.getElementById('newLeadModal'); if (modal) { modal.classList.remove('hidden'); document.body.style.overflow = 'hidden'; } } function closeNewLeadModal() { const modal = document.getElementById('newLeadModal'); if (modal) { modal.classList.add('hidden'); document.body.style.overflow = 'auto'; } } // Add new lead function addNewLead(event) { event.preventDefault(); // Show loading state const submitButton = event.target.querySelector('button[type="submit"]'); const originalText = submitButton.innerHTML; submitButton.innerHTML = '
Adding...'; submitButton.disabled = true; // Simulate API call setTimeout(() => { // Reset form event.target.reset(); // Close modal closeNewLeadModal(); // Show success notification showNotification('Lead added successfully!', 'success'); // Reset button submitButton.innerHTML = originalText; submitButton.disabled = false; // Update lead count updateLeadCount(); }, 1500); } // Skip trace functionality function performSkipTrace(event) { event.preventDefault(); const formData = { firstName: document.getElementById('firstName').value, lastName: document.getElementById('lastName').value, phoneNumber: document.getElementById('phoneNumber').value, address: document.getElementById('address').value }; // Show loading state const submitButton = event.target.querySelector('button[type="submit"]'); const originalText = submitButton.innerHTML; submitButton.innerHTML = '
Searching...'; submitButton.disabled = true; // Simulate API call setTimeout(() => { // Simulate found results const results = { status: 'found', phone: '(405) 555-' + Math.floor(Math.random() * 9000 + 1000), email: formData.firstName.toLowerCase() + '.' + formData.lastName.toLowerCase() + '@email.com', address: formData.address || Math.floor(Math.random() * 9000 + 1000) + ' Main St, Oklahoma City, OK 73102', relatives: ['John Doe', 'Jane Smith'] }; // Show results showSkipTraceResults(formData, results); // Reset button submitButton.innerHTML = originalText; submitButton.disabled = false; // Show notification showNotification('Skip trace completed successfully!', 'success'); }, 2000); } function showSkipTraceResults(searchData, results) { // This would normally update the UI with results console.log('Skip trace results:', results); // Add to recent results section const resultsContainer = document.querySelector('#skiptrace .bg-white.rounded-xl:last-child .space-y-4'); if (resultsContainer) { const resultHtml = `

${searchData.firstName} ${searchData.lastName}

Found: Just now

Complete

๐Ÿ“ž ${results.phone}

๐Ÿ“ง ${results.email}

๐Ÿ“ ${results.address}

`; resultsContainer.insertAdjacentHTML('afterbegin', resultHtml); } } // Communication functions function makeAICall() { const phoneNumber = prompt('Enter phone number to call:'); if (phoneNumber) { showNotification(`Initiating AI call to ${phoneNumber}...`, 'info'); // Simulate call initiation setTimeout(() => { showNotification('AI call initiated successfully!', 'success'); updateCallStats(); }, 1000); } } function sendSMS() { const phoneNumber = prompt('Enter phone number for SMS:'); const message = prompt('Enter message:'); if (phoneNumber && message) { showNotification(`Sending SMS to ${phoneNumber}...`, 'info'); setTimeout(() => { showNotification('SMS sent successfully!', 'success'); }, 1000); } } function sendEmail() { const email = prompt('Enter email address:'); const subject = prompt('Enter subject:'); const message = prompt('Enter message:'); if (email && subject && message) { showNotification(`Sending email to ${email}...`, 'info'); setTimeout(() => { showNotification('Email sent successfully!', 'success'); }, 1500); } } // AI Assistant chat function sendAIMessage(event) { event.preventDefault(); const input = document.getElementById('aiInput'); const message = input.value.trim(); if (!message) return; // Add user message to chat addChatMessage(message, 'user'); // Clear input input.value = ''; // Show typing indicator showTypingIndicator(); // Simulate AI response setTimeout(() => { removeTypingIndicator(); const response = generateAIResponse(message); addChatMessage(response, 'assistant'); }, 1500); } function addChatMessage(message, sender) { const chatContainer = document.getElementById('chatMessages'); if (!chatContainer) return; const messageHtml = sender === 'user' ? `

${message}

User
` : `

${message}

`; chatContainer.insertAdjacentHTML('beforeend', messageHtml); chatContainer.scrollTop = chatContainer.scrollHeight; feather.replace(); } function showTypingIndicator() { const chatContainer = document.getElementById('chatMessages'); if (!chatContainer) return; const typingHtml = `
`; chatContainer.insertAdjacentHTML('beforeend', typingHtml); chatContainer.scrollTop = chatContainer.scrollHeight; feather.replace(); } function removeTypingIndicator() { const indicator = document.getElementById('typingIndicator'); if (indicator) { indicator.remove(); } } function generateAIResponse(message) { const responses = { 'skip trace': 'I can help you skip trace individuals. Please provide the person\'s name, and any known phone numbers or addresses. I\'ll search through multiple databases to locate current contact information.', 'legal': 'Oklahoma unclaimed property is governed by 12 O.S. ยง 772. The Unclaimed Property Act requires holders to report and remit unclaimed property to the State Treasurer after a specified dormancy period.', 'call script': 'Here\'s a professional opening script: "Hello, my name is [Your Name] from HBU Asset Recovery. I\'m calling because we\'ve located potential unclaimed funds that may belong to you. Would you have a moment to discuss this opportunity?"', 'default': 'I understand you\'re looking for help with asset recovery. I can assist with skip tracing, legal research, document analysis, and generating outreach materials. What specific task would you like help with?' }; const lowerMessage = message.toLowerCase(); for (const [key, response] of Object.entries(responses)) { if (lowerMessage.includes(key)) { return response; } } return responses.default; } // Notification system function showNotification(message, type = 'info') { const notification = document.createElement('div'); const colors = { success: 'bg-green-500', error: 'bg-red-500', info: 'bg-blue-500', warning: 'bg-yellow-500' }; notification.className = `fixed top-20 right-4 ${colors[type]} text-white px-6 py-3 rounded-lg shadow-lg z-50 transform translate-x-full transition-transform`; notification.textContent = message; document.body.appendChild(notification); // Animate in setTimeout(() => { notification.classList.remove('translate-x-full'); }, 100); // Remove after 3 seconds setTimeout(() => { notification.classList.add('translate-x-full'); setTimeout(() => { notification.remove(); }, 300); }, 3000); } function checkNewNotifications() { // This would normally check for new notifications from the server // Simulate random notifications if (Math.random() > 0.9) { const notifications = [ 'New lead has been assigned to you', 'AI call completed with positive outcome', 'Document review required', 'Skip trace results available' ]; const randomNotification = notifications[Math.floor(Math.random() * notifications.length)]; showNotification(randomNotification, 'info'); } } // Stats updates function updateStats() { // Update dashboard stats with simulated data const stats = { leads: 247 + Math.floor(Math.random() * 10 - 5), calls: 42 + Math.floor(Math.random() * 10), traces: 18 + Math.floor(Math.random() * 5), recovered: 84500 + Math.floor(Math.random() * 5000) }; // Update stat displays const statElements = document.querySelectorAll('.text-2xl'); if (statElements.length >= 4) { statElements[0].textContent = stats.leads; statElements[1].textContent = stats.calls; statElements[2].textContent = stats.traces; statElements[3].textContent = '$' + (stats.recovered / 1000).toFixed(1) + 'K'; } } function updateLeadCount() { const leadCountElement = document.querySelector('[onclick="showSection(\'leads\')"] span'); if (leadCountElement) { const currentCount = parseInt(leadCountElement.textContent); leadCountElement.textContent = currentCount + 1; leadCountElement.classList.add('notification-badge'); setTimeout(() => { leadCountElement.classList.remove('notification-badge'); }, 500); } } function updateCallStats() { const callsElement = document.querySelectorAll('.text-2xl')[1]; if (callsElement) { const currentCalls = parseInt(callsElement.textContent); callsElement.textContent = currentCalls + 1; callsElement.parentElement.classList.add('success-animation'); } } // Utility functions function initializeTooltips() { const elements = document.querySelectorAll('[data-tooltip]'); elements.forEach(element => { element.classList.add('tooltip'); }); } function initializeKeyboardShortcuts() { document.addEventListener('keydown', function(event) { // Ctrl/Cmd + K for quick search if ((event.ctrlKey || event.metaKey) && event.key === 'k') { event.preventDefault(); const searchInput = document.querySelector('input[placeholder="Search leads..."]'); if (searchInput) { searchInput.focus(); } } // Escape to close modals if (event.key === 'Escape') { closeNewLeadModal(); const notificationsPanel = document.getElementById('notificationsPanel'); if (notificationsPanel && !notificationsPanel.classList.contains('translate-x-full')) { toggleNotifications(); } } // Number keys for navigation if (event.altKey && event.key >= '1' && event.key <= '8') { const sections = ['dashboard', 'leads', 'skiptrace', 'communications', 'tasks', 'documents', 'ai-assistant', 'settings']; const sectionIndex = parseInt(event.key) - 1; if (sections[sectionIndex]) { showSection(sections[sectionIndex]); } } }); } // Utility functions for API calls (would be implemented with actual endpoints) async function apiCall(endpoint, method = 'GET', data = null) { try { const options = { method, headers: { 'Content-Type': 'application/json', } }; if (data) { options.body = JSON.stringify(data); } const response = await fetch(`/api/${endpoint}`, options); return await response.json(); } catch (error) { console.error('API call failed:', error); showNotification('An error occurred. Please try again.', 'error'); return null; } } // Export functions for global access window.showSection = showSection; window.toggleNotifications = toggleNotifications; window.openNewLeadModal = openNewLeadModal; window.closeNewLeadModal = closeNewLeadModal; window.addNewLead = addNewLead; window.performSkipTrace = performSkipTrace; window.makeAICall = makeAICall; window.sendSMS = sendSMS; window.sendEmail = sendEmail; window.sendAIMessage = sendAIMessage;