document.addEventListener('DOMContentLoaded', function() { initCharts(); // Initialize charts function initCharts() { // Revenue Line Chart const revenueCtx = document.getElementById('revenueChart'); if (revenueCtx) { new Chart(revenueCtx, { type: 'line', data: { labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct'], datasets: [{ label: 'Revenue', data: [12000, 19000, 15000, 18000, 21000, 25000, 22000, 28000, 26000, 30000], borderColor: '#6366f1', backgroundColor: 'rgba(99, 102, 241, 0.1)', borderWidth: 2, tension: 0.4, fill: true }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { display: false } }, scales: { y: { beginAtZero: true, grid: { display: true, color: 'rgba(0, 0, 0, 0.05)' } }, x: { grid: { display: false } } } } }); } // Expense Doughnut Chart const expenseCtx = document.getElementById('expenseChart'); if (expenseCtx) { new Chart(expenseCtx, { type: 'doughnut', data: { labels: ['Supplies', 'Software', 'Marketing', 'Salaries', 'Office'], datasets: [{ data: [12000, 8000, 5000, 30000, 7000], backgroundColor: [ '#6366f1', '#8b5cf6', '#ec4899', '#f97316', '#10b981' ], borderWidth: 0 }] }, options: { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: 'right' } }, cutout: '70%' } }); } } // Initialize tooltips const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); tooltipTriggerList.map(function (tooltipTriggerEl) { return new bootstrap.Tooltip(tooltipTriggerEl); }); // Dark mode toggle functionality const darkModeToggle = document.getElementById('darkModeToggle'); if (darkModeToggle) { darkModeToggle.addEventListener('click', function() { document.documentElement.classList.toggle('dark'); localStorage.setItem('darkMode', document.documentElement.classList.contains('dark')); }); } // Check for saved dark mode preference if (localStorage.getItem('darkMode') === 'true') { document.documentElement.classList.add('dark'); } // Invoice generation form handling const invoiceForm = document.getElementById('invoiceForm'); if (invoiceForm) { invoiceForm.addEventListener('submit', function(e) { e.preventDefault(); // Process form data and generate invoice console.log('Generating invoice...'); }); } // Responsive sidebar toggle document.addEventListener('click', function(e) { if (e.target.closest('#sidebarToggle')) { document.querySelector('custom-sidebar').classList.toggle('-translate-x-full'); } }); // Handle form submissions document.querySelectorAll('form').forEach(form => { form.addEventListener('submit', function(e) { e.preventDefault(); // Show loading state const submitBtn = form.querySelector('button[type="submit"]'); if (submitBtn) { const originalText = submitBtn.innerHTML; submitBtn.innerHTML = '
Processing...'; submitBtn.disabled = true; // Simulate API call setTimeout(() => { submitBtn.innerHTML = originalText; submitBtn.disabled = false; alert('Form submitted successfully!'); }, 1500); } }); }); }); // AI Processor functionality document.addEventListener('DOMContentLoaded', function() { const documentUpload = document.getElementById('documentUpload'); const uploadedDocuments = document.getElementById('uploadedDocuments'); const aiPreviewContainer = document.getElementById('aiPreviewContainer'); const processBtn = document.getElementById('processBtn'); // Handle document upload for AI processor if (documentUpload) { documentUpload.addEventListener('change', function(e) { const files = Array.from(e.target.files); if (files.length === 0) return; aiPreviewContainer.classList.remove('hidden'); uploadedDocuments.innerHTML = ''; files.forEach(file => { const fileContainer = document.createElement('div'); fileContainer.className = 'bg-gray-50 rounded-lg p-4 flex items-start'; const fileIcon = document.createElement('div'); fileIcon.className = 'w-10 h-10 bg-indigo-100 rounded-full flex items-center justify-center mr-3 flex-shrink-0'; let iconName = 'file'; if (file.type.match('image.*')) iconName = 'image'; else if (file.type === 'application/pdf') iconName = 'file-text'; else if (file.type.match('word')) iconName = 'file-text'; fileIcon.innerHTML = ``; const fileInfo = document.createElement('div'); fileInfo.className = 'flex-1 min-w-0'; const fileName = document.createElement('p'); fileName.className = 'text-sm font-medium text-gray-900 truncate'; fileName.textContent = file.name; const fileDetails = document.createElement('div'); fileDetails.className = 'flex items-center text-xs text-gray-500 mt-1'; fileDetails.innerHTML = ` ${(file.size / 1024).toFixed(2)} KB ${file.type} `; fileInfo.appendChild(fileName); fileInfo.appendChild(fileDetails); fileContainer.appendChild(fileIcon); fileContainer.appendChild(fileInfo); uploadedDocuments.appendChild(fileContainer); feather.replace(); }); }); } // Process button handler if (processBtn) { processBtn.addEventListener('click', async function() { const files = documentUpload.files; if (files.length === 0) { alert('Please upload documents first'); return; } processBtn.innerHTML = '
Processing...'; processBtn.disabled = true; // Simulate AI processing setTimeout(() => { processBtn.innerHTML = ' Processing Complete'; feather.replace(); alert('Documents processed successfully! Extracted data can now be reviewed.'); }, 3000); }); } }); // File upload and processing document.addEventListener('DOMContentLoaded', function() { const invoiceUpload = document.getElementById('invoiceUpload'); const uploadedFiles = document.getElementById('uploadedFiles'); const previewContainer = document.getElementById('previewContainer'); const scanBtn = document.getElementById('scanBtn'); // Handle file upload invoiceUpload.addEventListener('change', function(e) { const files = Array.from(e.target.files); if (files.length === 0) return; previewContainer.classList.remove('hidden'); uploadedFiles.innerHTML = ''; files.forEach(file => { const fileContainer = document.createElement('div'); fileContainer.className = 'bg-gray-50 rounded-lg p-3 flex items-center'; const fileIcon = document.createElement('div'); fileIcon.className = 'w-10 h-10 bg-indigo-100 rounded-full flex items-center justify-center mr-3'; fileIcon.innerHTML = ''; const fileInfo = document.createElement('div'); fileInfo.className = 'flex-1 min-w-0'; const fileName = document.createElement('p'); fileName.className = 'text-sm font-medium text-gray-900 truncate'; fileName.textContent = file.name; const fileSize = document.createElement('p'); fileSize.className = 'text-xs text-gray-500'; fileSize.textContent = `${(file.size / 1024).toFixed(2)} KB`; fileInfo.appendChild(fileName); fileInfo.appendChild(fileSize); fileContainer.appendChild(fileIcon); fileContainer.appendChild(fileInfo); uploadedFiles.appendChild(fileContainer); feather.replace(); // Process the file processUploadedFile(file); }); }); // Scan button handler scanBtn.addEventListener('click', function() { // This would trigger mobile device camera in production alert('Scanning feature would open device camera to capture invoice'); }); }); // Process uploaded file async function processUploadedFile(file) { const reader = new FileReader(); reader.onload = async function(e) { try { if (file.type === 'application/pdf') { // Process PDF const pdfBytes = new Uint8Array(e.target.result); const pdfDoc = await PDFLib.PDFDocument.load(pdfBytes); const textContent = await extractTextFromPDF(pdfDoc); extractLineItems(textContent); } else if (file.type.match('image.*')) { // Process image const imageText = await extractTextFromImage(e.target.result); extractLineItems(imageText); } } catch (error) { console.error('Error processing file:', error); } }; reader.readAsArrayBuffer(file); } // Extract text from PDF async function extractTextFromPDF(pdfDoc) { const pages = pdfDoc.getPages(); let textContent = ''; for (const page of pages) { const text = await page.getTextContent(); textContent += text.items.map(item => item.str).join(' '); } return textContent; } // Extract text from image using OCR async function extractTextFromImage(imageData) { const worker = Tesseract.createWorker(); await worker.load(); await worker.loadLanguage('eng'); await worker.initialize('eng'); const { data: { text } } = await worker.recognize(imageData); await worker.terminate(); return text; } // Extract line items from text function extractLineItems(text) { // This is a simplified example - in production you'd use more sophisticated NLP const lines = text.split('\n'); const items = []; let foundItems = false; lines.forEach(line => { // Simple pattern matching for line items const itemMatch = line.match(/(\d+)\s+([\w\s]+)\s+(\d+\.\d{2})/i); if (itemMatch) { items.push({ description: itemMatch[2].trim(), quantity: parseInt(itemMatch[1]), rate: parseFloat(itemMatch[3]), amount: parseInt(itemMatch[1]) * parseFloat(itemMatch[3]) }); foundItems = true; } // Look for totals const totalMatch = line.match(/total.*?(\d+\.\d{2})/i); if (totalMatch) { console.log('Found total:', totalMatch[1]); } }); if (foundItems) { populateInvoiceItems(items); } } // Populate invoice items table function populateInvoiceItems(items) { const tbody = document.querySelector('table tbody'); tbody.innerHTML = ''; items.forEach(item => { const row = document.createElement('tr'); row.innerHTML = ` ${item.amount.toFixed(2)} `; tbody.appendChild(row); }); feather.replace(); } // Enhanced AI processing with real API integration async function processInvoiceData(data) { try { // Using OpenAI API for enhanced processing const response = await fetch('https://api.openai.com/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${YOUR_OPENAI_KEY}` }, body: JSON.stringify({ model: "gpt-4", messages: [{ role: "system", content: "You are an expert invoice processing AI. Extract all relevant fields from this invoice data." }, { role: "user", content: JSON.stringify(data) }], temperature: 0.2 }) }); const result = await response.json(); return parseAIResponse(result.choices[0].message.content); } catch (error) { console.error('AI Processing Error:', error); return null; } } // New AI features function initAIFeatures() { // Smart suggestions document.querySelectorAll('input').forEach(input => { input.addEventListener('focus', async () => { const suggestions = await getAISuggestions(input.name); showAISuggestions(input, suggestions); }); }); // Auto-categorization document.querySelectorAll('.category-select').forEach(select => { select.addEventListener('change', async (e) => { if (e.target.value === 'auto') { const items = getLineItems(); const categories = await predictCategories(items); applyCategories(categories); } }); }); } // Initialize AI features when DOM loads document.addEventListener('DOMContentLoaded', initAIFeatures);