document.addEventListener("DOMContentLoaded", function () { console.log("Frontend.js loaded"); // Initialize charts on page load initializeCharts(); // Handle form submissions handleFormSubmissions(); // Add animations for results addResultAnimations(); }); function initializeCharts() { console.log("Initializing charts..."); // Mortgage Charts const mortgageCharts = document.querySelectorAll(".mortgage-chart"); mortgageCharts.forEach((canvas) => { console.log("Rendering mortgage chart for:", canvas); const principal = parseFloat(canvas.dataset.principal) || 200000; const totalInterest = parseFloat(canvas.dataset.interest) || 123312.18; renderMortgageChart(canvas, principal, totalInterest); }); // Data Center Charts const datacenterCharts = document.querySelectorAll(".datacenter-chart"); datacenterCharts.forEach((canvas) => { console.log("Rendering datacenter chart for:", canvas); const powerCost = parseFloat(canvas.dataset.power) || 730; const coolingCost = parseFloat(canvas.dataset.cooling) || 876; const rackCost = parseFloat(canvas.dataset.rack) || 500; renderDatacenterChart(canvas, powerCost, coolingCost, rackCost); }); // ROI Charts const roiCharts = document.querySelectorAll(".roi-chart"); roiCharts.forEach((canvas) => { console.log("Rendering ROI chart for:", canvas); const initialInvestment = parseFloat(canvas.dataset.investment) || 10000; const netProfit = parseFloat(canvas.dataset.profit) || 4025.52; renderRoiChart(canvas, initialInvestment, netProfit); }); } function handleFormSubmissions() { const calculatorForms = document.querySelectorAll(".maple-calc form"); calculatorForms.forEach((form) => { form.addEventListener("submit", function (e) { e.preventDefault(); console.log("Form submitted"); // Validate form inputs const inputs = form.querySelectorAll("input[required]"); let isValid = true; inputs.forEach((input) => { if (!input.value) { isValid = false; input.style.borderColor = "#ff0000"; } else { input.style.borderColor = "#ccc"; } }); if (!isValid) { alert("Please fill in all required fields."); return; } // Process form data const formData = new FormData(form); const formEntries = Object.fromEntries(formData.entries()); // Determine calculator type const calculatorType = form .closest(".maple-calc") .classList.contains("mortgage-calculator") ? "mortgage" : form .closest(".maple-calc") .classList.contains("datacenter-calculator") ? "datacenter" : "roi"; const resultsDiv = form.nextElementSibling; if (calculatorType === "mortgage") { const principal = parseFloat(formEntries.principal) || 200000; const interestRate = parseFloat(formEntries.interest_rate) || 3.5; const termYears = parseInt(formEntries.term_years) || 30; const monthlyPayment = calculateMonthlyPayment( principal, interestRate, termYears, ); const totalPayment = monthlyPayment * termYears * 12; const totalInterest = totalPayment - principal; updateMortgageResults( resultsDiv, monthlyPayment, totalPayment, totalInterest, ); renderMortgageChart( resultsDiv.querySelector(".mortgage-chart"), principal, totalInterest, ); } else if (calculatorType === "datacenter") { const powerKw = parseFloat(formEntries.power_kw) || 10; const costPerKwh = parseFloat(formEntries.cost_per_kwh) || 0.1; const rackSpace = parseInt(formEntries.rack_space) || 5; const coolingFactor = 1.2; const powerCostPerMonth = powerKw * costPerKwh * 24 * 30; const coolingCostPerMonth = powerCostPerMonth * coolingFactor; const rackCostPerMonth = rackSpace * 100; const totalMonthlyCost = powerCostPerMonth + coolingCostPerMonth + rackCostPerMonth; const totalAnnualCost = totalMonthlyCost * 12; updateDatacenterResults( resultsDiv, powerCostPerMonth, coolingCostPerMonth, rackCostPerMonth, totalMonthlyCost, totalAnnualCost, ); renderDatacenterChart( resultsDiv.querySelector(".datacenter-chart"), powerCostPerMonth, coolingCostPerMonth, rackCostPerMonth, ); } else if (calculatorType === "roi") { const initialInvestment = parseFloat(formEntries.initial_investment) || 10000; const annualReturnRate = parseFloat(formEntries.annual_return_rate) || 7; const timeYears = parseInt(formEntries.time_years) || 5; const finalValue = initialInvestment * Math.pow(1 + annualReturnRate / 100, timeYears); const netProfit = finalValue - initialInvestment; const roiPercentage = (netProfit / initialInvestment) * 100; updateRoiResults(resultsDiv, finalValue, netProfit, roiPercentage); renderRoiChart( resultsDiv.querySelector(".roi-chart"), initialInvestment, netProfit, ); } // Show results with animation resultsDiv.style.opacity = "0"; setTimeout(() => { resultsDiv.style.opacity = "1"; }, 100); }); }); } function calculateMonthlyPayment(principal, interestRate, termYears) { const monthlyInterestRate = interestRate / 100 / 12; const termMonths = termYears * 12; return ( (principal * (monthlyInterestRate * Math.pow(1 + monthlyInterestRate, termMonths))) / (Math.pow(1 + monthlyInterestRate, termMonths) - 1) ); } function updateMortgageResults( resultsDiv, monthlyPayment, totalPayment, totalInterest, ) { resultsDiv.querySelector("p:nth-child(2)").innerHTML = `Monthly Payment: $${monthlyPayment.toFixed(2)}`; resultsDiv.querySelector("p:nth-child(3)").innerHTML = `Total Payment: $${totalPayment.toFixed(2)}`; resultsDiv.querySelector("p:nth-child(4)").innerHTML = `Total Interest: $${totalInterest.toFixed(2)}`; } function updateDatacenterResults( resultsDiv, powerCost, coolingCost, rackCost, totalMonthlyCost, totalAnnualCost, ) { resultsDiv.querySelector("p:nth-child(2)").innerHTML = `Power Cost (Monthly): $${powerCost.toFixed(2)}`; resultsDiv.querySelector("p:nth-child(3)").innerHTML = `Cooling Cost (Monthly): $${coolingCost.toFixed(2)}`; resultsDiv.querySelector("p:nth-child(4)").innerHTML = `Rack Cost (Monthly): $${rackCost.toFixed(2)}`; resultsDiv.querySelector("p:nth-child(5)").innerHTML = `Total Monthly Cost: $${totalMonthlyCost.toFixed(2)}`; resultsDiv.querySelector("p:nth-child(6)").innerHTML = `Total Annual Cost: $${totalAnnualCost.toFixed(2)}`; } function updateRoiResults(resultsDiv, finalValue, netProfit, roiPercentage) { resultsDiv.querySelector("p:nth-child(2)").innerHTML = `Final Value: $${finalValue.toFixed(2)}`; resultsDiv.querySelector("p:nth-child(3)").innerHTML = `Net Profit: $${netProfit.toFixed(2)}`; resultsDiv.querySelector("p:nth-child(4)").innerHTML = `ROI (%): ${roiPercentage.toFixed(2)}%`; } function renderMortgageChart(canvas, principal, totalInterest) { if (!canvas) { console.error("Mortgage chart canvas not found"); return; } const ctx = canvas.getContext("2d"); new Chart(ctx, { type: "pie", data: { labels: ["Principal", "Total Interest"], datasets: [ { data: [principal, totalInterest], backgroundColor: ["#02066F", "#ff6384"], borderWidth: 1, }, ], }, options: { responsive: true, plugins: { legend: { position: "bottom", labels: { font: { size: 14, family: "Arial, sans-serif", }, color: "#222222", boxWidth: 20, padding: 20, usePointStyle: true, }, }, title: { display: false, }, }, }, }); } function renderDatacenterChart(canvas, powerCost, coolingCost, rackCost) { if (!canvas) { console.error("Datacenter chart canvas not found"); return; } const ctx = canvas.getContext("2d"); new Chart(ctx, { type: "pie", data: { labels: ["Power Cost", "Cooling Cost", "Rack Cost"], datasets: [ { data: [powerCost, coolingCost, rackCost], backgroundColor: ["#02066F", "#ff6384", "#36a2eb"], borderWidth: 1, }, ], }, options: { responsive: true, plugins: { legend: { position: "bottom", labels: { font: { size: 14, family: "Arial, sans-serif", }, color: "#222222", boxWidth: 20, padding: 20, usePointStyle: true, }, }, title: { display: false, }, }, }, }); } function renderRoiChart(canvas, initialInvestment, netProfit) { if (!canvas) { console.error("ROI chart canvas not found"); return; } const ctx = canvas.getContext("2d"); new Chart(ctx, { type: "pie", data: { labels: ["Initial Investment", "Net Profit"], datasets: [ { data: [initialInvestment, netProfit], backgroundColor: ["#02066F", "#36a2eb"], borderWidth: 1, }, ], }, options: { responsive: true, plugins: { legend: { position: "bottom", labels: { font: { size: 14, family: "Arial, sans-serif", }, color: "#222222", boxWidth: 20, padding: 20, usePointStyle: true, }, }, title: { display: false, }, }, }, }); } function addResultAnimations() { const resultsDivs = document.querySelectorAll(".results"); resultsDivs.forEach((div) => { div.style.transition = "opacity 0.5s ease-in-out"; }); }