document.addEventListener('DOMContentLoaded', () => { // ... (theme switcher and other existing code) ... const apiRequest = async (url, options = {}) => { // ... (same as before) ... }; const loadDashboardStats = async () => { // ... (same as before) ... }; // ... (contact form code) ... // Deal Management const dealModal = document.getElementById('dealModal') ? new bootstrap.Modal(document.getElementById('dealModal')) : null; const dealForm = document.getElementById('dealForm'); const modalTitle = document.getElementById('dealModalLabel'); let dataTable = null; const fetchDealsAndInitTable = async (filters = {}) => { try { const queryParams = new URLSearchParams({ action: 'get_deals', ...filters }).toString(); const result = await apiRequest(`api.php?${queryParams}`); if (result && result.success) { if (dataTable) { dataTable.destroy(); } dataTable = new DataTable('#deals-table', { data: result.deals, columns: [ { data: 'name' }, { data: 'vendor' }, { data: 'category' }, { data: 'purchase_date' }, { data: 'price', render: (data, type, row) => `${row.currency} ${data}` }, { data: 'rating', render: (data, type, row) => `
${Array(5).fill(0).map((_, i) => ``).join('')}
` }, { data: 'website', render: (data, type, row) => `Visit` }, { data: 'files', render: (data, type, row) => { if (!data) return ''; const files = data.split(',').map(f => { const [id, name] = f.split(':'); return `
${name}
`; }); return files.join(''); } }, { data: 'id', render: (data, type, row) => ` `, orderable: false } ], responsive: true, }); } else if(result) { console.error('Failed to fetch deals:', result.error); } } catch (error) { console.error('Error fetching deals:', error); } }; const deleteDeal = async (id) => { // ... (same as before) ... }; const deleteDealFile = async (fileId) => { if (!confirm('Are you sure you want to delete this file?')) return; try { const result = await apiRequest('api.php?action=delete_deal_file', { method: 'POST', body: { id: fileId } }); if (result && result.success) { fetchDealsAndInitTable(); // Refresh table } else { alert('Error deleting file.'); } } catch (error) { alert('An error occurred while deleting the file.'); } }; const editDeal = (dealId) => { const dealData = dataTable.rows().data().toArray().find(d => d.id == dealId); if (dealData) { modalTitle.textContent = 'Edit Deal'; // Clear previous data and files dealForm.reset(); document.getElementById('deal-files-list').innerHTML = ''; // Populate form Object.keys(dealData).forEach(key => { const input = dealForm.querySelector(`[name="${key}"]`); if (input) { if (key === 'purchaseDate') { input.value = dealData.purchase_date; } else { input.value = dealData[key]; } } }); // Add hidden ID field let idInput = dealForm.querySelector('[name="id"]'); if (!idInput) { idInput = document.createElement('input'); idInput.type = 'hidden'; idInput.name = 'id'; dealForm.appendChild(idInput); } idInput.value = dealData.id; // Display existing files if (dealData.files) { const filesList = document.getElementById('deal-files-list'); dealData.files.split(',').forEach(f => { const [id, name] = f.split(':'); const fileEl = document.createElement('div'); fileEl.className = 'file-chip'; fileEl.innerHTML = `${name}`; filesList.appendChild(fileEl); }); } dealModal.show(); } }; // ... (loadCategoryFilter, loadTagsFilter) ... if (dealForm) { dealForm.addEventListener('submit', async (e) => { e.preventDefault(); const formData = new FormData(dealForm); const dealId = formData.get('id'); const action = dealId ? 'update_deal' : 'add_deal'; // Add action to formData formData.append('action', action); try { const response = await fetch(`api.php?action=${action}`, { method: 'POST', body: formData // FormData object // No 'Content-Type' header; browser sets it automatically }); const result = await response.json(); if (result.success) { dealModal.hide(); fetchDealsAndInitTable(); // Refresh table loadDashboardStats(); // Refresh stats loadCategoryChart(); } else { alert(`Error: ${result.error || 'Unknown error'}`); } } catch (error) { console.error('Form submission error:', error); alert('An error occurred while submitting the form.'); } }); } // ... (addDealBtn handler) ... if (dealsTable) { dealsTable.addEventListener('click', (e) => { if (e.target.classList.contains('delete-deal-btn')) { deleteDeal(e.target.dataset.id); } else if (e.target.classList.contains('edit-deal-btn')) { editDeal(e.target.dataset.id); } else if (e.target.classList.contains('delete-file-btn')) { deleteDealFile(e.target.dataset.fileId); } }); // ... (filters and initial load) ... } // ... (loadCategoryChart) ... });