34695-vm/assets/js/main.js
Flatlogic Bot 90597ae75f draftv1
2025-10-05 16:43:57 +00:00

198 lines
7.8 KiB
JavaScript

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) => `<div class="text-nowrap">${Array(5).fill(0).map((_, i) => `<i class="bi bi-star-fill ${i < data ? 'text-warning' : 'text-secondary'}"></i>`).join('')}</div>`
},
{
data: 'website',
render: (data, type, row) => `<a href="${data}" target="_blank" class="btn btn-sm btn-outline-primary">Visit</a>`
},
{
data: 'files',
render: (data, type, row) => {
if (!data) return '';
const files = data.split(',').map(f => {
const [id, name] = f.split(':');
return `<div class="file-chip"><a href="uploads/${name}" target="_blank">${name}</a><button class="btn-close btn-close-sm delete-file-btn" data-file-id="${id}"></button></div>`;
});
return files.join('');
}
},
{
data: 'id',
render: (data, type, row) =>
`<button class="btn btn-sm btn-outline-secondary edit-deal-btn" data-id="${data}">Edit</button>
<button class="btn btn-sm btn-outline-danger delete-deal-btn" data-id="${data}">Delete</button>`,
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 = `<span>${name}</span><button type="button" class="btn-close btn-close-sm delete-file-btn" data-file-id="${id}"></button>`;
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) ...
});