Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 45 additions & 22 deletions app/interactives/mortgage-refinancing-calculator/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default function MortgageCalculator() {
const [refCurrentBalance, setRefCurrentBalance] = useState("")
const [refCurrentMonthlyPayment, setRefCurrentMonthlyPayment] = useState("")
const [refCurrentMonths, setRefCurrentMonths] = useState("")
const [refCurrentRate, setRefCurrentRate] = useState("") // Added missing state for refinance current rate
const [refCurrentRate, setRefCurrentRate] = useState("")
const [refNewLoanAmount, setRefNewLoanAmount] = useState("")
const [refNewRate, setRefNewRate] = useState("")
const [refNewMonths, setRefNewMonths] = useState("")
Expand All @@ -40,6 +40,10 @@ export default function MortgageCalculator() {
breakEvenMonths: number
breakEvenMessage: string
} | null>(null)
const [frozenMonthsRemaining, setFrozenMonthsRemaining] = useState("")
const [frozenAnnualRate, setFrozenAnnualRate] = useState("")
const [frozenBalance, setFrozenBalance] = useState("")
const [frozenMonthlyPayment, setFrozenMonthlyPayment] = useState("")

const calculateBalance = () => {
const months = Number.parseFloat(monthsRemaining)
Expand All @@ -60,23 +64,33 @@ export default function MortgageCalculator() {
}

setCurrentBalance(balance)
// Freeze the values for use in Refinance tab
setFrozenMonthsRemaining(monthsRemaining)
setFrozenAnnualRate(annualRate)
setFrozenBalance(balance.toFixed(2))
setFrozenMonthlyPayment(monthlyPayment)

// Prefill the Refinance tab with frozen values
setRefCurrentBalance(balance.toFixed(2))
setRefCurrentMonths(monthsRemaining)
setRefCurrentRate(annualRate)
setRefCurrentMonthlyPayment(monthlyPayment)
}

const calculateRefinance = () => {
const currentBal = Number.parseFloat(refCurrentBalance)
const currentR = Number.parseFloat(refCurrentRate) / 100 / 12 // Fixed: Use refCurrentRate instead of refCurrentMonthlyPayment
const currentR = Number.parseFloat(refCurrentRate) / 100 / 12
const currentM = Number.parseFloat(refCurrentMonths)
const newR = Number.parseFloat(refNewRate) / 100 / 12
const newM = Number.parseFloat(refNewMonths)
const closingCosts = Number.parseFloat(refClosingCosts)
const closingCosts = Number.parseFloat(refClosingCosts) || 0

if (
isNaN(currentBal) ||
isNaN(currentR) ||
isNaN(currentM) ||
isNaN(newR) ||
isNaN(newM) ||
isNaN(closingCosts) ||
currentBal <= 0 ||
currentR < 0 ||
currentM <= 0 ||
Expand All @@ -100,19 +114,18 @@ export default function MortgageCalculator() {
// Calculate new monthly payment
const newLoanAmount = Number.parseFloat(refNewLoanAmount)

// Validate newLoanAmount in your validation section
// Validate newLoanAmount
if (
isNaN(currentBal) ||
isNaN(currentR) ||
isNaN(currentM) ||
isNaN(newLoanAmount) || // ✅ Add this
isNaN(newLoanAmount) ||
isNaN(newR) ||
isNaN(newM) ||
isNaN(closingCosts) ||
currentBal <= 0 ||
currentR < 0 ||
currentM <= 0 ||
newLoanAmount <= 0 || // ✅ Add this
newLoanAmount <= 0 ||
newR < 0 ||
newM <= 0 ||
closingCosts < 0
Expand All @@ -121,12 +134,11 @@ export default function MortgageCalculator() {
return
}

// Calculate new monthly payment
let newMonthlyPayment: number
if (newR === 0) {
newMonthlyPayment = newLoanAmount / newM // ✅ Use newLoanAmount
newMonthlyPayment = newLoanAmount / newM
} else {
newMonthlyPayment = (newLoanAmount * (newR * Math.pow(1 + newR, newM))) / (Math.pow(1 + newR, newM) - 1) // ✅ Use newLoanAmount
newMonthlyPayment = (newLoanAmount * (newR * Math.pow(1 + newR, newM))) / (Math.pow(1 + newR, newM) - 1)
}

const monthlySavings = currentMonthlyPayment - newMonthlyPayment
Expand All @@ -139,14 +151,17 @@ export default function MortgageCalculator() {

if (monthlySavings > 0) {
// Case 1: Lower monthly payment
breakEvenMonths = closingCosts / monthlySavings
breakEvenMessage = `You'll recover closing costs in ${breakEvenMonths.toFixed(1)} months`
breakEvenMonths = closingCosts > 0 ? closingCosts / monthlySavings : 0
breakEvenMessage = closingCosts > 0
? `You'll recover closing costs in ${breakEvenMonths.toFixed(1)} months`
: "No closing costs to recover - immediate savings!"
} else if (monthlySavings < 0) {
// Case 2: Higher monthly payment
// Only makes sense if total savings over loan term is positive
if (totalSavings > 0) {
breakEvenMonths = closingCosts / (-monthlySavings)
breakEvenMessage = `Despite higher monthly payments, you'll save overall if you stay ${breakEvenMonths.toFixed(1)}+ months`
breakEvenMonths = closingCosts > 0 ? closingCosts / (-monthlySavings) : 0
breakEvenMessage = closingCosts > 0
? `Despite higher monthly payments, you'll save overall if you stay ${breakEvenMonths.toFixed(1)}+ months`
: "Despite higher monthly payments, you save overall on total interest"
} else {
breakEvenMonths = Infinity
breakEvenMessage = "This refinance costs more overall - not recommended"
Expand All @@ -167,7 +182,7 @@ export default function MortgageCalculator() {
totalNewCost,
totalSavings,
breakEvenMonths,
breakEvenMessage, // Add this to state type
breakEvenMessage,
})
}

Expand Down Expand Up @@ -329,7 +344,17 @@ export default function MortgageCalculator() {
)}
<Button
className={`h-18 whitespace-normal bg-navy border-2 border-navy cursor-pointer hover:bg-white hover:border-2 hover:border-lagunita hover:text-lagunita text-white w-full md:w-auto`}
onClick={currentBalance !== null ? () => { setCurrentBalance(null); setMonthsRemaining(""); setAnnualRate(""); setMonthlyPayment(""); } : calculateBalance}
onClick={currentBalance !== null ? () => {
setCurrentBalance(null);
setMonthsRemaining("");
setAnnualRate("");
setMonthlyPayment("");
// Clear frozen values
setFrozenMonthsRemaining("");
setFrozenAnnualRate("");
setFrozenBalance("");
setFrozenMonthlyPayment("");
} : calculateBalance}
>
{currentBalance !== null ? "Reset" : "Calculate Current Balance"}
</Button>
Expand Down Expand Up @@ -734,7 +759,7 @@ export default function MortgageCalculator() {
<p className={`text-2xl p-4 border-1 rounded-lg font-bold ${
refinanceResults.monthlySavings >= 0
? "bg-lagunita-lighter text-black border-1 border-lagunita"
: "bg-berry-light border-berry text-black"
: "bg-sky border-sky-dark text-black"
}`}>
${formatCurrency(Math.abs(refinanceResults.monthlySavings))}
</p>
Expand All @@ -744,9 +769,7 @@ export default function MortgageCalculator() {
<p className="text-md font-bold mt-4 mb-2">
{refinanceResults.totalSavings >= 0 ? "Refinancing saves you" : "Refinancing costs you"}
</p>
<p className={`text-4xl font-bold ${
refinanceResults.totalSavings >= 0 ? "text-lagunita" : "text-berry"
}`}>
<p className="text-4xl font-bold text-lagunita">
${formatCurrency(Math.abs(refinanceResults.totalSavings))}
</p>
</div>
Expand Down
2 changes: 2 additions & 0 deletions app/ui/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
--radius-xl: calc(var(--radius) + 4px);

--font-poppins: Poppins, sans-serif;
--color-sky: rgba(206, 232, 255, 1);
--color-sky-dark: rgba(14, 59, 79, 1);
--color-berry: rgba(195, 31, 112, 1);
--color-berry-light: rgba(255, 237, 246, 1);
--color-palo-verde: rgba(39, 153, 137, 1);
Expand Down