Fix coin tracker data persistence issue

- Updated API URLs from localhost:3000 to localhost:3001 in script.js
- Added CORS headers to server.js to enable cross-origin requests
- Changed server port from 3000 to 3001 to avoid port conflicts
- Updated CSP in index.html to allow connections to localhost:3001
- Coin tracker entries now persist across page refreshes
This commit is contained in:
root
2025-09-19 13:29:59 +02:00
parent c0bf7413de
commit 4803ae2d18
3 changed files with 79 additions and 49 deletions

View File

@@ -8,7 +8,7 @@
script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net;
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
connect-src 'self' http://localhost:3000;
connect-src 'self' http://localhost:3001;
">
<title>Rechner</title>

View File

@@ -1,4 +1,4 @@
"use strict";
"use strict";
(() => {
// Helper functions
const $ = id => {
@@ -32,7 +32,7 @@
const updateCoinTrackersToBackend = (trackers) => {
console.log("Saving trackers to backend:", trackers);
fetch('/api/coinTrackers', {
fetch('http://localhost:3001/api/coinTrackers', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -1182,7 +1182,7 @@
const loadCoinTrackers = () => {
console.log("Loading trackers from backend...");
fetch('/api/coinTrackers')
fetch('http://localhost:3001/api/coinTrackers')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
@@ -1507,57 +1507,79 @@
console.log("updateAnalysisTable called");
console.trace("Call stack for updateAnalysisTable");
// Get reinvestment rate from the dedicated analysis input - NOT the main calculator
// FIXED: Use main calculator inputs first, fallback to analysis settings if needed
const mainInitialPrincipal = parseFloat($('initialPrincipal')?.value) || 0;
const mainDailyRate = parseFloat($('dailyRate')?.value) || 0;
const mainTermDays = parseInt($('termDays')?.value) || 0;
const mainReinvestRate = parseFloat($('reinvestRate')?.value) || 0;
// Get analysis settings as fallback/override
const reinvestRateElement = document.getElementById('analysisReinvestRate');
const analysisDaysElement = document.getElementById('analysisDays');
console.log("Elements found:", !!reinvestRateElement, !!analysisDaysElement);
console.log("Elements:", reinvestRateElement, analysisDaysElement);
if (reinvestRateElement) {
console.log("Reinvest rate value:", reinvestRateElement.value);
console.log("Reinvest rate attribute:", reinvestRateElement.getAttribute('value'));
console.log("Reinvest rate type:", typeof reinvestRateElement.value);
}
if (analysisDaysElement) {
console.log("Days value:", analysisDaysElement.value);
console.log("Days attribute:", analysisDaysElement.getAttribute('value'));
console.log("Days type:", typeof analysisDaysElement.value);
}
console.log("Main calculator values:", {mainInitialPrincipal, mainDailyRate, mainTermDays, mainReinvestRate});
const reinvestRate = reinvestRateElement ? parseFloat(reinvestRateElement.value) || 0 : 0;
const days = analysisDaysElement ? parseInt(analysisDaysElement.value) || 30 : 30;
// Use main calculator values, but allow analysis settings to override if they have non-zero values
let reinvestRate = mainReinvestRate;
let days = mainTermDays;
let initialPrincipal = mainInitialPrincipal;
let dailyRate = mainDailyRate;
// Override with analysis settings ONLY if they have meaningful values different from defaults
if (reinvestRateElement && reinvestRateElement.value !== "" && reinvestRateElement.value !== "0") {
const analysisReinvestRate = parseFloat(reinvestRateElement.value);
if (analysisReinvestRate > 0) {
reinvestRate = analysisReinvestRate;
}
}
if (analysisDaysElement && analysisDaysElement.value !== "" && analysisDaysElement.value !== "30") {
const analysisDays = parseInt(analysisDaysElement.value);
if (analysisDays > 0 && analysisDays !== 30) {
days = analysisDays;
}
}
console.log("Parsed values - Reinvest Rate:", reinvestRate, "Days:", days);
console.log("Using values - Initial Principal:", initialPrincipal, "Daily Rate:", dailyRate);
// Get data from active coin trackers
const container = $('coinTrackerContainer');
const trackerDivs = container.getElementsByClassName("coin-tracker");
// If we have main calculator values, use those for initial investment and yield
// Otherwise fall back to coin tracker data
let totalInvestment = initialPrincipal;
let weightedAverageDailyYield = dailyRate;
// Initialize total investment and weighted yield
let totalInvestment = 0;
let weightedYieldSum = 0;
// Only use coin tracker data if main calculator has no values
if (totalInvestment === 0 || weightedAverageDailyYield === 0) {
// Get data from active coin trackers
const container = $('coinTrackerContainer');
const trackerDivs = container.getElementsByClassName("coin-tracker");
// Initialize total investment and weighted yield
totalInvestment = 0;
let weightedYieldSum = 0;
// Calculate total investment and weighted yield
Array.from(trackerDivs).forEach(div => {
if (div.dataset.active === "false") return;
const table = div.querySelector("table.coin-table");
if (!table) return;
// Calculate total investment and weighted yield
Array.from(trackerDivs).forEach(div => {
if (div.dataset.active === "false") return;
const table = div.querySelector("table.coin-table");
if (!table) return;
const rows = table.querySelector("tbody").rows;
if (rows.length > 0) {
const lastRow = rows[rows.length - 1];
const inputCurrent = lastRow.cells[2].querySelector("input");
const currentVal = parseFloat(inputCurrent.value || "0") || 0;
const yieldInput = lastRow.cells[5].querySelector("input");
const dailyYieldPercent = parseFloat(yieldInput.value || "0") || 0;
totalInvestment += currentVal;
weightedYieldSum += (currentVal * dailyYieldPercent);
}
});
// Calculate weighted average daily yield
const weightedAverageDailyYield = totalInvestment > 0 ? (weightedYieldSum / totalInvestment) : 0;
const rows = table.querySelector("tbody").rows;
if (rows.length > 0) {
const lastRow = rows[rows.length - 1];
const inputCurrent = lastRow.cells[2].querySelector("input");
const currentVal = parseFloat(inputCurrent.value || "0") || 0;
const yieldInput = lastRow.cells[5].querySelector("input");
const dailyYieldPercent = parseFloat(yieldInput.value || "0") || 0;
totalInvestment += currentVal;
weightedYieldSum += (currentVal * dailyYieldPercent);
}
});
// Calculate weighted average daily yield
weightedAverageDailyYield = totalInvestment > 0 ? (weightedYieldSum / totalInvestment) : 0;
}
console.log("Analysis values - Reinvest Rate:", reinvestRate, "Days:", days);
console.log("Total Investment:", totalInvestment, "Weighted Yield:", weightedAverageDailyYield);
@@ -1617,7 +1639,7 @@
document.getElementById('createBackupBtn').textContent = 'Creating backup...';
// Make request to API
fetch(`/api/backup/create${backupName ? `?name=${encodeURIComponent(backupName)}` : ''}`)
fetch(`http://localhost:3001/api/backup/create${backupName ? `?name=${encodeURIComponent(backupName)}` : ''}`)
.then(response => {
if (!response.ok) {
throw new Error(`Network error: ${response.status}`);
@@ -1648,7 +1670,7 @@
// Function to load the list of available backups
const loadBackupList = () => {
fetch('/api/backup/list')
fetch('http://localhost:3001/api/backup/list')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
@@ -1773,7 +1795,7 @@
return;
}
fetch(`/api/backup/restore/${filename}`)
fetch(`http://localhost:3001/api/backup/restore/${filename}`)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');

View File

@@ -5,12 +5,20 @@ const fs = require('fs');
const path = require('path');
const cron = require('node-cron');
const app = express();
const port = 3000;
const port = 3001;
// Serve static files from the current directory
app.use(express.static(__dirname));
app.use(bodyParser.json());
// Add CORS middleware
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
// Create backups directory if it doesn't exist
const backupDir = path.join(__dirname, 'backups');
if (!fs.existsSync(backupDir)) {