198 lines
7.8 KiB
JavaScript
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) ...
|
|
});
|