diff --git a/MoneyMap/Pages/CategoryMappings.cshtml b/MoneyMap/Pages/CategoryMappings.cshtml index a975a1f..a6ba96c 100644 --- a/MoneyMap/Pages/CategoryMappings.cshtml +++ b/MoneyMap/Pages/CategoryMappings.cshtml @@ -304,73 +304,5 @@ else @section Scripts { - + } diff --git a/MoneyMap/Pages/EditTransaction.cshtml b/MoneyMap/Pages/EditTransaction.cshtml index dfdc8b9..defed2f 100644 --- a/MoneyMap/Pages/EditTransaction.cshtml +++ b/MoneyMap/Pages/EditTransaction.cshtml @@ -263,75 +263,11 @@ @section Scripts { + } - - - diff --git a/MoneyMap/Pages/Merchants.cshtml b/MoneyMap/Pages/Merchants.cshtml index 61b4eb5..513bb0c 100644 --- a/MoneyMap/Pages/Merchants.cshtml +++ b/MoneyMap/Pages/Merchants.cshtml @@ -152,35 +152,5 @@ else @section Scripts { - + } diff --git a/MoneyMap/Pages/Transactions.cshtml b/MoneyMap/Pages/Transactions.cshtml index 8deda2a..ba9d51c 100644 --- a/MoneyMap/Pages/Transactions.cshtml +++ b/MoneyMap/Pages/Transactions.cshtml @@ -304,47 +304,6 @@ else } @section Scripts { - + } diff --git a/MoneyMap/Pages/Upload.cshtml b/MoneyMap/Pages/Upload.cshtml index f517b99..aea6bed 100644 --- a/MoneyMap/Pages/Upload.cshtml +++ b/MoneyMap/Pages/Upload.cshtml @@ -235,116 +235,5 @@ else @section Scripts { - + } diff --git a/MoneyMap/wwwroot/js/category-mappings.js b/MoneyMap/wwwroot/js/category-mappings.js new file mode 100644 index 0000000..b240db4 --- /dev/null +++ b/MoneyMap/wwwroot/js/category-mappings.js @@ -0,0 +1,69 @@ +// Category Mappings Page JavaScript + +function openEditModal(id, category, pattern, priority, merchant) { + console.log('Opening modal for:', id, category, pattern, priority, merchant); + + document.getElementById('editId').value = id; + document.getElementById('editCategory').value = category; + document.getElementById('editPattern').value = pattern; + document.getElementById('editPriority').value = priority; + document.getElementById('editMerchant').value = merchant || ''; + + var modalElement = document.getElementById('editModal'); + if (modalElement && typeof bootstrap !== 'undefined') { + var modal = new bootstrap.Modal(modalElement); + modal.show(); + } else { + console.error('Bootstrap modal not available'); + alert('Error: Modal system not loaded. Please refresh the page.'); + } +} + +document.addEventListener('DOMContentLoaded', function() { + + // Debug: Log form values before submission + var addForm = document.querySelector('#addModal form'); + if (addForm) { + addForm.addEventListener('submit', function(e) { + var categoryInput = document.getElementById('addCategory'); + var patternInput = document.getElementById('addPattern'); + var priorityInput = document.getElementById('addPriority'); + + console.log('=== ADD FORM SUBMISSION ==='); + console.log('Category:', categoryInput.value, 'Name:', categoryInput.name); + console.log('Pattern:', patternInput.value, 'Name:', patternInput.name); + console.log('Priority:', priorityInput.value, 'Name:', priorityInput.name); + console.log('Form Data:'); + var formData = new FormData(addForm); + for (var pair of formData.entries()) { + console.log(' ' + pair[0] + ': ' + pair[1]); + } + }); + } + + var editForm = document.querySelector('#editModal form'); + if (editForm) { + editForm.addEventListener('submit', function(e) { + var id = document.getElementById('editId').value; + var category = document.getElementById('editCategory').value; + var pattern = document.getElementById('editPattern').value; + var priority = document.getElementById('editPriority').value; + console.log('Submitting Edit form:', { id, category, pattern, priority }); + console.log('Category input name:', document.getElementById('editCategory').name); + }); + } + + // Reopen modals if there are validation errors + var addCategoryInput = document.getElementById('addCategory'); + var editCategoryInput = document.getElementById('editCategory'); + + if (addCategoryInput && addCategoryInput.classList.contains('input-validation-error')) { + var addModal = new bootstrap.Modal(document.getElementById('addModal')); + addModal.show(); + } + + if (editCategoryInput && editCategoryInput.classList.contains('input-validation-error')) { + var editModal = new bootstrap.Modal(document.getElementById('editModal')); + editModal.show(); + } +}); diff --git a/MoneyMap/wwwroot/js/edit-transaction.js b/MoneyMap/wwwroot/js/edit-transaction.js new file mode 100644 index 0000000..d1b1eb5 --- /dev/null +++ b/MoneyMap/wwwroot/js/edit-transaction.js @@ -0,0 +1,73 @@ +// Edit Transaction Page JavaScript + +function handleCategoryChange() { + const select = document.getElementById('categorySelect'); + const customInputDiv = document.getElementById('customCategoryInput'); + const categoryInput = document.getElementById('categoryInput'); + + if (select.value === '__custom__') { + customInputDiv.style.display = 'block'; + categoryInput.value = ''; + categoryInput.focus(); + } else { + customInputDiv.style.display = 'none'; + categoryInput.value = select.value; + } +} + +function handleMerchantChange() { + const select = document.getElementById('merchantSelect'); + const customInput = document.getElementById('customMerchantInput'); + const hiddenInput = document.getElementById('merchantHidden'); + const merchantNameInput = document.querySelector('input[name="Transaction.MerchantName"]'); + + if (select.value === '__custom__') { + customInput.style.display = 'block'; + hiddenInput.value = ''; + merchantNameInput.value = ''; + merchantNameInput.focus(); + } else { + customInput.style.display = 'none'; + hiddenInput.value = select.value; + merchantNameInput.value = ''; + } +} + +function copyTransactionId(transactionId) { + if (navigator.clipboard && window.isSecureContext) { + navigator.clipboard.writeText(transactionId.toString()); + } else { + var ta = document.createElement('textarea'); + ta.value = transactionId; + document.body.appendChild(ta); + ta.select(); + document.execCommand('copy'); + document.body.removeChild(ta); + } + var btns = document.querySelectorAll('button[onclick*="copyTransactionId"]'); + btns.forEach(function(btn) { + var old = btn.textContent; + btn.textContent = 'Copied!'; + setTimeout(function() { + btn.textContent = old; + }, 1500); + }); +} + +// Update hidden field when custom input changes +document.addEventListener('DOMContentLoaded', function() { + const categoryInput = document.querySelector('input[name="Transaction.Category"]'); + const categorySelect = document.getElementById('categorySelect'); + + if (categoryInput) { + categoryInput.addEventListener('input', function() { + if (categorySelect.value === '__custom__') { + // Keep custom selected when typing + } + }); + } + + // Initialize on page load + handleCategoryChange(); + handleMerchantChange(); +}); diff --git a/MoneyMap/wwwroot/js/merchants.js b/MoneyMap/wwwroot/js/merchants.js new file mode 100644 index 0000000..a684a92 --- /dev/null +++ b/MoneyMap/wwwroot/js/merchants.js @@ -0,0 +1,31 @@ +// Merchants Page JavaScript + +function openEditModal(id, name) { + document.getElementById('editId').value = id; + document.getElementById('editName').value = name; + + var modalElement = document.getElementById('editModal'); + if (modalElement && typeof bootstrap !== 'undefined') { + var modal = new bootstrap.Modal(modalElement); + modal.show(); + } else { + console.error('Bootstrap modal not available'); + alert('Error: Modal system not loaded. Please refresh the page.'); + } +} + +document.addEventListener('DOMContentLoaded', function() { + // Reopen modals if there are validation errors + var addNameInput = document.getElementById('addName'); + var editNameInput = document.getElementById('editName'); + + if (addNameInput && addNameInput.classList.contains('input-validation-error')) { + var addModal = new bootstrap.Modal(document.getElementById('addModal')); + addModal.show(); + } + + if (editNameInput && editNameInput.classList.contains('input-validation-error')) { + var editModal = new bootstrap.Modal(document.getElementById('editModal')); + editModal.show(); + } +}); diff --git a/MoneyMap/wwwroot/js/transactions.js b/MoneyMap/wwwroot/js/transactions.js new file mode 100644 index 0000000..93e7c89 --- /dev/null +++ b/MoneyMap/wwwroot/js/transactions.js @@ -0,0 +1,44 @@ +// Transactions Page JavaScript + +// Initialize Bootstrap tooltips for notes badges +document.addEventListener('DOMContentLoaded', function() { + var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]')); + var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) { + return new bootstrap.Tooltip(tooltipTriggerEl); + }); +}); + +// Quick date range functions +function formatDate(date) { + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; +} + +function setDateRange(days) { + const endDate = new Date(); + const startDate = new Date(); + startDate.setDate(startDate.getDate() - days); + + document.getElementById('startDateInput').value = formatDate(startDate); + document.getElementById('endDateInput').value = formatDate(endDate); +} + +function setDateRangeThisMonth() { + const now = new Date(); + const startDate = new Date(now.getFullYear(), now.getMonth(), 1); + const endDate = new Date(now.getFullYear(), now.getMonth() + 1, 0); + + document.getElementById('startDateInput').value = formatDate(startDate); + document.getElementById('endDateInput').value = formatDate(endDate); +} + +function setDateRangeLastMonth() { + const now = new Date(); + const startDate = new Date(now.getFullYear(), now.getMonth() - 1, 1); + const endDate = new Date(now.getFullYear(), now.getMonth(), 0); + + document.getElementById('startDateInput').value = formatDate(startDate); + document.getElementById('endDateInput').value = formatDate(endDate); +} diff --git a/MoneyMap/wwwroot/js/upload.js b/MoneyMap/wwwroot/js/upload.js new file mode 100644 index 0000000..8604fa1 --- /dev/null +++ b/MoneyMap/wwwroot/js/upload.js @@ -0,0 +1,116 @@ +// Upload Page JavaScript +let currentPage = 0; +const pageSize = 100; +let totalRows = 0; + +function togglePaymentSelection() { + const mode = document.querySelector('input[name="PaymentMode"]:checked').value; + const cardRow = document.getElementById('cardSelectRow'); + const accountRow = document.getElementById('accountSelectRow'); + + cardRow.style.display = mode === 'Card' ? 'block' : 'none'; + accountRow.style.display = mode === 'Account' ? 'block' : 'none'; +} + +function toggleAllCheckboxes() { + const selectAll = document.getElementById('selectAll'); + const checkboxes = document.querySelectorAll('.transaction-checkbox'); + checkboxes.forEach(cb => cb.checked = selectAll.checked); + updateSelectedCount(); +} + +function updateSelectedCount() { + const checkboxes = document.querySelectorAll('.transaction-checkbox:checked'); + const count = checkboxes.length; + const selectedCountEl = document.getElementById('selectedCount'); + const selectedCountButtonEl = document.getElementById('selectedCountButton'); + if (selectedCountEl) selectedCountEl.textContent = count; + if (selectedCountButtonEl) selectedCountButtonEl.textContent = count; +} + +function updateAllTransactionAccounts() { + // Called when the global account dropdown changes + // No action needed - we'll read the global account on form submit +} + +function showPage(pageNum) { + const rows = document.querySelectorAll('.transaction-row'); + const start = pageNum * pageSize; + const end = start + pageSize; + + rows.forEach((row, index) => { + row.style.display = (index >= start && index < end) ? '' : 'none'; + }); + + // Update pagination display + const pageStartEl = document.getElementById('pageStart'); + const pageEndEl = document.getElementById('pageEnd'); + if (pageStartEl && pageEndEl) { + pageStartEl.textContent = start + 1; + pageEndEl.textContent = Math.min(end, totalRows); + } + + currentPage = pageNum; +} + +function nextPage() { + const maxPage = Math.ceil(totalRows / pageSize) - 1; + if (currentPage < maxPage) { + showPage(currentPage + 1); + } +} + +function previousPage() { + if (currentPage > 0) { + showPage(currentPage - 1); + } +} + +function prepareFormData() { + // Collect selected indices + const selectedIndices = []; + document.querySelectorAll('.transaction-checkbox:checked').forEach(cb => { + selectedIndices.push(cb.getAttribute('data-index')); + }); + document.getElementById('selectedIndices').value = selectedIndices.join(','); + + // Get the global account ID + const globalAccountId = document.getElementById('globalAccountId')?.value; + if (!globalAccountId) { + alert('Please select an account for all transactions'); + return false; + } + + // Collect payment data (account + optional card + category per transaction) + const paymentData = {}; + document.querySelectorAll('.card-select').forEach((select) => { + const index = select.getAttribute('data-index'); + const cardId = select.value ? parseInt(select.value) : null; + + // Get category for this transaction + const categoryInput = document.querySelector(`.category-input[data-index="${index}"]`); + const category = categoryInput ? categoryInput.value.trim() : ''; + + paymentData[index] = { + AccountId: parseInt(globalAccountId), + CardId: cardId, + Category: category + }; + }); + document.getElementById('paymentData').value = JSON.stringify(paymentData); + + return true; // Allow form submission +} + +// Initialize on page load +document.addEventListener('DOMContentLoaded', function() { + togglePaymentSelection(); + + // Get total rows from the preview transactions count + const previewCount = document.querySelectorAll('.transaction-row').length; + totalRows = previewCount; + + if (totalRows > pageSize) { + showPage(0); + } +});