// Direct conversion handler script document.addEventListener("DOMContentLoaded", function() { console.log("Direct conversion handler loaded"); // Initialize conversion history table on page load initializeConversionHistory(); // Give the main script time to load, then add our direct handler setTimeout(function() { // Get the conversion button const button = document.getElementById('executeConversion'); if (!button) { console.error("Could not find conversion button"); return; } // Replace the button with a clone to remove any existing event listeners const newButton = button.cloneNode(true); button.parentNode.replaceChild(newButton, button); // Add our direct event handler newButton.addEventListener('click', function(event) { console.log("Direct handler: Convert button clicked"); // Get form values const fromAsset = document.getElementById('fromAsset').value; const toAsset = document.getElementById('toAsset').value; const dollarAmountInput = document.getElementById('conversionAmount'); const dollarAmount = parseFloat(dollarAmountInput ? dollarAmountInput.value : '0') || 0; const transferType = document.getElementById('conversionType').value; console.log("Form values:", {fromAsset, toAsset, dollarAmount, transferType}); // Validate inputs if (!fromAsset || !toAsset || dollarAmount <= 0) { alert("Please fill in all fields with valid values."); console.warn("Invalid form values:", {fromAsset, toAsset, dollarAmount}); return; } try { // Get the tracker elements directly const fromTracker = document.getElementById(fromAsset); const toTracker = document.getElementById(toAsset); if (!fromTracker || !toTracker) { console.error("Could not find tracker elements:", {fromTracker, toTracker}); alert("Error: Could not find one or both asset trackers."); return; } // Get coin names for logging const fromName = fromTracker.querySelector(".coin-tracker-header input.coin-name-input").value; const toName = toTracker.querySelector(".coin-tracker-header input.coin-name-input").value; // Get table elements const sourceTable = fromTracker.querySelector("table.coin-table"); const destTable = toTracker.querySelector("table.coin-table"); if (!sourceTable || !destTable) { console.error("Could not find tables:", {sourceTable, destTable}); alert("Error: Could not find tracker tables."); return; } // Get tbody elements const sourceTbody = sourceTable.querySelector("tbody"); const destTbody = destTable.querySelector("tbody"); if (!sourceTbody || !destTbody) { console.error("Could not find tbody elements:", {sourceTbody, destTbody}); alert("Error: Could not find tracker table bodies."); return; } // Get current date and time const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD const options = { hour: '2-digit', minute: '2-digit', hour12: false, timeZone: 'Europe/Berlin' }; const currentTime = new Date().toLocaleTimeString('en-GB', options); // Process the transfer based on type if (transferType === 'income') { // For income transfer, we don't subtract from the current value (principal) // Instead, we record it as income in the source tracker addTableRow(sourceTbody, { date: today, time: currentTime, currentValue: 0, // Don't change principal income: -dollarAmount, // Negative income (transferred out) compound: 0, dailyYield: 0, notes: `Transferred income: $${dollarAmount.toFixed(2)} to ${toName}` }); console.log("Added source row for income transfer"); } else { // Regular principal transfer - subtract from current value of source addTableRow(sourceTbody, { date: today, time: currentTime, currentValue: -dollarAmount, // Reduce current value by transfer amount income: 0, compound: 0, dailyYield: 0, notes: `Moved $${dollarAmount.toFixed(2)} to ${toName}` }); console.log("Added source row for principal transfer"); } // Get the last current value from the destination tracker // This is key to the fix: instead of just transferring the amount as a standalone value, // we add it to the last known value of the destination asset let lastDestValue = 0; const destRows = Array.from(destTbody.rows); if (destRows.length > 0) { // Check rows in reverse order to find the last non-zero current value // This ensures we get the most recent valid amount from the destination tracker for (const row of destRows.reverse()) { const currentVal = parseFloat(row.cells[2].querySelector("input").value) || 0; if (currentVal > 0) { lastDestValue = currentVal; break; } } } // Add row to destination tracker (add to the last current value) const newDestValue = lastDestValue + dollarAmount; addTableRow(destTbody, { date: today, time: currentTime, currentValue: newDestValue, // Add to the last destination value income: 0, compound: 0, dailyYield: 0, notes: transferType === 'income' ? `Received income: $${dollarAmount.toFixed(2)} from ${fromName} (prev: $${lastDestValue.toFixed(2)})` : `Received $${dollarAmount.toFixed(2)} from ${fromName} (prev: $${lastDestValue.toFixed(2)})` }); console.log("Added destination row with accumulated value:", { lastDestValue, dollarAmount, newDestValue }); // Log the transfer to conversion history logConversion({ date: today, time: currentTime, fromName: fromName, toName: toName, dollarAmount: dollarAmount, transferType: transferType, destPreviousValue: lastDestValue, // Store the previous value for reference destNewValue: newDestValue // Store the new combined value }); // Update the tracker summaries if (typeof updateCoinTrackerSummary === 'function') { updateCoinTrackerSummary(fromAsset); updateCoinTrackerSummary(toAsset); // Update the header display values directly const fromTracker = document.getElementById(fromAsset); const toTracker = document.getElementById(toAsset); if (fromTracker) { const fromValueSpan = fromTracker.querySelector(".last-value"); if (fromValueSpan) { // Find the last non-zero current value from the source tracker let lastSourceValue = 0; const sourceRows = Array.from(sourceTbody.rows).reverse(); for (const row of sourceRows) { const currentVal = parseFloat(row.cells[2].querySelector("input").value) || 0; if (currentVal > 0) { lastSourceValue = currentVal; break; } } fromValueSpan.textContent = `Current Value: $${lastSourceValue.toFixed(2)}`; } } if (toTracker) { const toValueSpan = toTracker.querySelector(".last-value"); if (toValueSpan) { toValueSpan.textContent = `Current Value: $${newDestValue.toFixed(2)}`; } } } // Save tracker changes if (typeof saveCoinTrackers === 'function') { saveCoinTrackers(); } // Update conversion statistics if (typeof updateConversionStats === 'function') { updateConversionStats(); } // Update total investment display if (typeof updateTotalInvested === 'function') { updateTotalInvested(); } // Clear the amount input field if (dollarAmountInput) { dollarAmountInput.value = ''; } // Show success message alert(`Transferred $${dollarAmount.toFixed(2)} from ${fromName} to ${toName}`); } catch (error) { console.error("Error during asset transfer:", error); alert("Error during transfer: " + error.message); } }); console.log("Direct conversion handler added successfully"); }, 1000); // Wait 1 second for the page to fully load }); // Function to add a row to a tracker table function addTableRow(tbody, data) { if (!tbody) { console.error("Could not find tbody to add row"); return; } const tr = document.createElement("tr"); tr.dataset.created = Date.now(); // Date cell const tdDate = document.createElement("td"); const inputDate = document.createElement("input"); inputDate.type = "date"; inputDate.value = data.date || ""; tdDate.appendChild(inputDate); tr.appendChild(tdDate); // Time cell const tdTime = document.createElement("td"); const inputTime = document.createElement("input"); inputTime.type = "time"; inputTime.value = data.time || ""; tdTime.appendChild(inputTime); tr.appendChild(tdTime); // Current Value cell const tdCurrent = document.createElement("td"); tdCurrent.innerHTML = "$"; const inputCurrent = document.createElement("input"); inputCurrent.type = "number"; inputCurrent.step = "0.01"; inputCurrent.value = parseFloat(data.currentValue).toFixed(2) || "0.00"; tdCurrent.appendChild(inputCurrent); tr.appendChild(tdCurrent); // Income cell const tdIncome = document.createElement("td"); const inputIncome = document.createElement("input"); inputIncome.type = "number"; inputIncome.step = "0.01"; inputIncome.value = data.income || ""; tdIncome.appendChild(inputIncome); tr.appendChild(tdIncome); // Compound cell const tdCompound = document.createElement("td"); const inputCompound = document.createElement("input"); inputCompound.type = "number"; inputCompound.step = "0.01"; inputCompound.value = data.compound || ""; tdCompound.appendChild(inputCompound); tr.appendChild(tdCompound); // Daily Yield cell const tdYield = document.createElement("td"); const inputYield = document.createElement("input"); inputYield.type = "number"; inputYield.step = "0.01"; inputYield.value = data.dailyYield || ""; tdYield.appendChild(inputYield); tr.appendChild(tdYield); // Actions cell const tdActions = document.createElement("td"); const delBtn = document.createElement("button"); delBtn.textContent = "Delete"; delBtn.className = "deleteRowBtn"; delBtn.addEventListener("click", () => { tr.remove(); if (typeof saveCoinTrackers === 'function') { saveCoinTrackers(); } }); tdActions.appendChild(delBtn); tr.appendChild(tdActions); // Notes cell const tdNotes = document.createElement("td"); const notesInput = document.createElement("input"); notesInput.type = "text"; notesInput.value = data.notes || ""; notesInput.placeholder = "Transaction notes"; notesInput.style.width = "100%"; tdNotes.appendChild(notesInput); tr.appendChild(tdNotes); // Add row to table tbody.appendChild(tr); } // Function to log conversions to history function logConversion(conversionData) { // Get existing history let conversionHistory = JSON.parse(localStorage.getItem("conversionHistory") || "[]"); // Add new conversion with timestamp conversionData.timestamp = Date.now(); conversionHistory.push(conversionData); // Save back to localStorage localStorage.setItem("conversionHistory", JSON.stringify(conversionHistory)); // Simply reinitialize the entire conversion history table initializeConversionHistory(); } conversionHistory.forEach((conversion, index) => { const row = document.createElement("tr"); row.dataset.index = index; // Store the index for easy deletion const dateCell = document.createElement("td"); dateCell.textContent = `${conversion.date} ${conversion.time}`; row.appendChild(dateCell); const fromCell = document.createElement("td"); fromCell.textContent = conversion.fromName; row.appendChild(fromCell); const amountCell = document.createElement("td"); // For backward compatibility with existing data const dollarAmount = conversion.dollarAmount || conversion.sentAmount || 0; // If this is an income transfer, show that in the cell if (conversion.transferType === 'income') { amountCell.textContent = `$${dollarAmount.toFixed(2)} (Income)`; amountCell.style.color = '#4CAF50'; // Green for income transfers } else { amountCell.textContent = `$${dollarAmount.toFixed(2)}`; } row.appendChild(amountCell); const toCell = document.createElement("td"); toCell.textContent = conversion.toName; row.appendChild(toCell); const receivedCell = document.createElement("td"); // If we have previous and new values for the destination, show that info if (conversion.destPreviousValue !== undefined && conversion.destNewValue !== undefined) { receivedCell.textContent = `$${dollarAmount.toFixed(2)} → $${conversion.destNewValue.toFixed(2)}`; receivedCell.title = `Previous value: $${conversion.destPreviousValue.toFixed(2)}, Added: $${dollarAmount.toFixed(2)}, New value: $${conversion.destNewValue.toFixed(2)}`; } else { // Backward compatibility with existing data receivedCell.textContent = `$${dollarAmount.toFixed(2)}`; } row.appendChild(receivedCell); // Add delete button const actionsCell = document.createElement("td"); const deleteBtn = document.createElement("button"); deleteBtn.textContent = "Delete"; deleteBtn.style.padding = "3px 8px"; deleteBtn.style.background = "#ff4444"; deleteBtn.style.color = "white"; deleteBtn.style.border = "none"; deleteBtn.style.borderRadius = "3px"; deleteBtn.style.cursor = "pointer"; deleteBtn.addEventListener("click", function() { if (confirm("Are you sure you want to delete this conversion record?")) { // Remove from the array conversionHistory.splice(index, 1); // Save back to local storage localStorage.setItem("conversionHistory", JSON.stringify(conversionHistory)); // Remove the row from the table row.remove(); // Update conversion stats if (typeof updateConversionStats === 'function') { updateConversionStats(); } } }); actionsCell.appendChild(deleteBtn); row.appendChild(actionsCell); tableBody.appendChild(row); }); } catch (error) { console.error("Error updating conversion history table:", error); } } // Function to initialize the conversion history table on page load function initializeConversionHistory() { try { // Get existing history from localStorage let conversionHistory = JSON.parse(localStorage.getItem("conversionHistory") || "[]"); // If there's no history, create an empty table if (conversionHistory.length === 0) { console.log("No conversion history found in localStorage"); // Still clear the table if it exists to ensure old data is removed const tableBody = document.querySelector("#conversionHistoryTable tbody"); if (tableBody) { tableBody.innerHTML = ""; } return; } console.log("Initializing conversion history from localStorage:", conversionHistory.length, "entries"); // Sort by date, newest first conversionHistory.sort((a, b) => { // First try to use timestamp if (a.timestamp && b.timestamp) { return b.timestamp - a.timestamp; } // Fall back to date comparison return new Date(`${b.date} ${b.time || "00:00"}`) - new Date(`${a.date} ${a.time || "00:00"}`); }); // Get the table body const tableBody = document.querySelector("#conversionHistoryTable tbody"); if (!tableBody) { console.warn("Conversion history table not found in DOM"); return; } // Clear existing rows tableBody.innerHTML = ""; // Add rows for each conversion (reusing code from logConversion) conversionHistory.forEach((conversion, index) => { const row = document.createElement("tr"); row.dataset.index = index; const dateCell = document.createElement("td"); dateCell.textContent = `${conversion.date} ${conversion.time || ""}`; row.appendChild(dateCell); const fromCell = document.createElement("td"); fromCell.textContent = conversion.fromName; row.appendChild(fromCell); const amountCell = document.createElement("td"); const dollarAmount = conversion.dollarAmount || conversion.sentAmount || 0; if (conversion.transferType === 'income') { amountCell.textContent = `$${dollarAmount.toFixed(2)} (Income)`; amountCell.style.color = '#4CAF50'; } else { amountCell.textContent = `$${dollarAmount.toFixed(2)}`; } row.appendChild(amountCell); const toCell = document.createElement("td"); toCell.textContent = conversion.toName; row.appendChild(toCell); const receivedCell = document.createElement("td"); if (conversion.destPreviousValue !== undefined && conversion.destNewValue !== undefined) { receivedCell.textContent = `$${dollarAmount.toFixed(2)} → $${conversion.destNewValue.toFixed(2)}`; receivedCell.title = `Previous value: $${conversion.destPreviousValue.toFixed(2)}, Added: $${dollarAmount.toFixed(2)}, New value: $${conversion.destNewValue.toFixed(2)}`; } else { receivedCell.textContent = `$${dollarAmount.toFixed(2)}`; } row.appendChild(receivedCell); // Add delete button const actionsCell = document.createElement("td"); const deleteBtn = document.createElement("button"); deleteBtn.textContent = "Delete"; deleteBtn.style.padding = "3px 8px"; deleteBtn.style.background = "#ff4444"; deleteBtn.style.color = "white"; deleteBtn.style.border = "none"; deleteBtn.style.borderRadius = "3px"; deleteBtn.style.cursor = "pointer"; deleteBtn.addEventListener("click", function() { if (confirm("Are you sure you want to delete this conversion record?")) { // Remove from the array conversionHistory.splice(index, 1); // Save back to local storage localStorage.setItem("conversionHistory", JSON.stringify(conversionHistory)); // Remove the row from the table row.remove(); // Update conversion stats if (typeof updateConversionStats === 'function') { updateConversionStats(); } } }); actionsCell.appendChild(deleteBtn); row.appendChild(actionsCell); tableBody.appendChild(row); }); console.log("Conversion history table initialized successfully"); // Update conversion statistics if the function exists if (typeof updateConversionStats === 'function') { updateConversionStats(); } } catch (error) { console.error("Error initializing conversion history table:", error); } }