dev1/src/components/LoanRepayment.js
2024-12-30 22:53:42 +00:00

197 lines
6.0 KiB
JavaScript

import React, { useState } from 'react';
function LoanRepayment({ schools, salaryData, earningHorizon }) {
const [tuitionType, setTuitionType] = useState('inState'); // 'inState' or 'outOfState'
const [interestRate, setInterestRate] = useState(5.5); // Default federal loan interest rate
const [loanTerm, setLoanTerm] = useState(10); // Default loan term (10 years)
const [extraPayment, setExtraPayment] = useState(0); // Extra monthly payment
const [currentSalary, setCurrentSalary] = useState(0); // Current salary input
const [results, setResults] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
// Validation function
const validateInputs = () => {
if (!schools || schools.length === 0) {
setError('School data is missing. Loan calculations cannot proceed.');
return false;
}
if (interestRate <= 0) {
setError('Interest rate must be greater than 0.');
return false;
}
if (loanTerm <= 0) {
setError('Loan term must be greater than 0.');
return false;
}
if (extraPayment < 0) {
setError('Extra monthly payment cannot be negative.');
return false;
}
if (currentSalary < 0) {
setError('Current salary cannot be negative.');
return false;
}
setError(null); // Clear errors if valid
return true;
};
// Loan calculation function for all schools
const calculateLoanDetails = () => {
if (!validateInputs()) return; // Validate inputs before calculation
const schoolResults = schools.map((school) => {
const tuition = tuitionType === 'inState' ? school.inState : school.outOfState;
const monthlyRate = interestRate / 12 / 100;
const loanTermMonths = loanTerm * 12;
// Calculate minimum monthly payment
const minimumMonthlyPayment = tuition * (monthlyRate * Math.pow(1 + monthlyRate, loanTermMonths)) /
(Math.pow(1 + monthlyRate, loanTermMonths) - 1);
// Total loan cost with extra payments
const extraMonthlyPayment = minimumMonthlyPayment + extraPayment;
let remainingBalance = tuition;
let monthsWithExtra = 0;
while (remainingBalance > 0) {
monthsWithExtra++;
const interest = remainingBalance * monthlyRate;
const principal = extraMonthlyPayment - interest;
remainingBalance -= principal;
}
const totalLoanCost = extraMonthlyPayment * monthsWithExtra;
// Handle missing salary data
let salary = salaryData && salaryData[0]?.value ? salaryData[0].value : null;
let netGain = 'N/A';
let monthlySalary = 'N/A';
if (salary) {
// Calculate net gain
const totalSalary = salary * earningHorizon;
const currentSalaryEarnings = currentSalary * earningHorizon * Math.pow(1.03, earningHorizon); // 3% growth
netGain = (totalSalary - totalLoanCost - currentSalaryEarnings).toFixed(2);
// Monthly salary
monthlySalary = (salary / 12).toFixed(2);
}
return {
...school,
tuition,
monthlyPayment: minimumMonthlyPayment.toFixed(2),
totalMonthlyPayment: extraMonthlyPayment.toFixed(2), // Add total payment including extra
totalLoanCost: totalLoanCost.toFixed(2),
netGain,
monthlySalary,
};
});
setResults(schoolResults);
};
return (
<div>
<h2>Loan Repayment and ROI Analysis</h2>
<div>
<label>
Tuition Type:
<select
value={tuitionType}
onChange={(e) => setTuitionType(e.target.value)}
>
<option value="inState">In-State</option>
<option value="outOfState">Out-of-State</option>
</select>
</label>
<label>
Interest Rate (%):
<input
type="number"
value={interestRate}
onChange={(e) => setInterestRate(Number(e.target.value))}
onFocus={(e) => e.target.select()}
min="0"
/>
</label>
<label>
Loan Term (Years):
<input
type="number"
value={loanTerm}
onChange={(e) => setLoanTerm(Number(e.target.value))}
onFocus={(e) => e.target.select()}
min="0"
/>
</label>
<label>
Extra Monthly Payment ($):
<input
type="number"
value={extraPayment}
onChange={(e) => setExtraPayment(Number(e.target.value))}
onFocus={(e) => e.target.select()}
min="0"
/>
</label>
<label>
Current Salary (Gross Annual $):
<input
type="number"
value={currentSalary}
onChange={(e) => setCurrentSalary(e.target.value)}
onFocus={(e) => e.target.select()}
min="0"
/>
</label>
<button onClick={calculateLoanDetails} disabled={loading}>
{loading ? 'Calculating...' : 'Calculate'}
</button>
</div>
{/* Error Message */}
{error && <p style={{ color: 'red' }}>{error}</p>}
{/* Results Display */}
{results.length > 0 && (
<div>
<h3>Comparison by School</h3>
{results.map((result, index) => (
<div key={index}>
<h4>{result.schoolName}</h4>
<p>Total Tuition: ${result.tuition}</p>
<p>Monthly Payment: ${result.monthlyPayment}</p>
<p>Total Monthly Payment (with extra): ${result.totalMonthlyPayment}</p>
<p>Total Loan Cost: ${result.totalLoanCost}</p>
<p>Net Gain: {result.netGain}</p>
<p>Monthly Salary (Gross): {result.monthlySalary}</p>
</div>
))}
</div>
)}
{/* Salary Warning */}
{!salaryData || salaryData.length === 0 ? (
<p style={{ color: 'red' }}>Salary data is not available for this profession. Loan calculations are limited.</p>
) : null}
</div>
);
}
export default LoanRepayment;