Fixed Expected Salary input fields and Calculation

This commit is contained in:
Josh 2025-03-04 13:36:37 +00:00
parent 5f4992d4d3
commit 62175b5823
2 changed files with 126 additions and 54 deletions

View File

@ -1,9 +1,65 @@
.loan-repayment-container { .loan-repayment-container {
padding: 20px; width: 100%;
background-color: #fafafa; max-width: 500px; /* Adjust as needed */
border-radius: 8px; margin: auto;
} padding: 20px;
}
.loan-repayment-container form {
display: flex;
flex-direction: column;
gap: 10px;
align-items: start;
}
.loan-repayment-container .input-group {
display: flex;
align-items: center; /* Ensures labels and inputs are aligned */
justify-content: space-between;
width: 100%;
}
.loan-repayment-container label {
font-weight: bold;
width: 40%; /* Consistent width for labels */
text-align: left;
}
.loan-repayment-container input,
.loan-repayment-container select {
width: 58%; /* Consistent width for inputs */
padding: 8px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-bottom: 10px;
}
.loan-repayment-container .calculate-button-container {
display: flex;
justify-content: center;
width: 100%;
margin-top: 10px;
}
.loan-repayment-container button {
width: 100%;
max-width: 300px;
padding: 10px;
background-color: green;
color: white;
border: none;
cursor: pointer;
border-radius: 4px;
font-size: 16px;
text-align: center;
}
.loan-repayment-container button:hover {
background-color: green;
}
.loan-repayment-fields label { .loan-repayment-fields label {
display: block; display: block;
margin-bottom: 10px; margin-bottom: 10px;
@ -131,4 +187,8 @@
font-weight: bold; font-weight: bold;
margin-top: 15px; margin-top: 15px;
} }
.error {
color: red;
margin-top: 10px;
}

View File

@ -46,32 +46,42 @@ function LoanRepayment({
setLoading(true); setLoading(true);
const schoolResults = schools.map((school) => { const schoolResults = schools.map((school) => {
const tuition = tuitionType === 'inState' ? school.inState : school.outOfState; const tuition = tuitionType === 'inState' ? school.inState : school.outOfState;
const monthlyRate = interestRate / 12 / 100; const monthlyRate = Number(interestRate) / 12 / 100;
const loanTermMonths = loanTerm * 12; const loanTermMonths = Number(loanTerm) * 12;
const minimumMonthlyPayment = tuition * (monthlyRate * Math.pow(1 + monthlyRate, loanTermMonths)) / const minimumMonthlyPayment = tuition * (monthlyRate * Math.pow(1 + monthlyRate, loanTermMonths)) /
(Math.pow(1 + monthlyRate, loanTermMonths) - 1); (Math.pow(1 + monthlyRate, loanTermMonths) - 1);
const extraMonthlyPayment = minimumMonthlyPayment + extraPayment; const extraMonthlyPayment = Number(minimumMonthlyPayment) + Number(extraPayment);
let remainingBalance = tuition; let remainingBalance = tuition;
let monthsWithExtra = 0; let monthsWithExtra = 0;
while (remainingBalance > 0) { while (remainingBalance > 0) {
monthsWithExtra++; monthsWithExtra++;
const interest = remainingBalance * monthlyRate;
const principal = extraMonthlyPayment - interest; // Calculate interest for this month
remainingBalance -= principal; const interest = remainingBalance * monthlyRate;
}
// Ensure principal payment never goes negative
const principal = Math.max(extraMonthlyPayment - interest, 0);
// Reduce balance
remainingBalance -= principal;
// Prevent infinite loop in case of incorrect values
if (monthsWithExtra > loanTermMonths * 2) break;
}
const totalLoanCost = extraMonthlyPayment * monthsWithExtra; const totalLoanCost = extraMonthlyPayment * monthsWithExtra;
let salary = salaryData.find((point) => point.percentile === selectedSalary)?.value || 0; let salary = Number(salaryData.find((point) => point.percentile === selectedSalary)?.value || 0);
let netGain = 'N/A'; let netGain = 'N/A';
let monthlySalary = 'N/A'; let monthlySalary = 'N/A';
if (salary > 0) { if (salary > 0) {
const totalSalary = salary * loanTerm; const totalSalary = salary * loanTerm;
const currentSalaryEarnings = currentSalary * loanTerm * Math.pow(1.03, loanTerm); const currentSalaryEarnings = Number(currentSalary) * loanTerm * Math.pow(1.03, loanTerm);
netGain = (totalSalary - totalLoanCost - currentSalaryEarnings).toFixed(2); netGain = (totalSalary - totalLoanCost - currentSalaryEarnings).toFixed(2);
monthlySalary = (salary / 12).toFixed(2); monthlySalary = (salary / 12).toFixed(2);
} }
@ -94,41 +104,43 @@ function LoanRepayment({
return ( return (
<div className="loan-repayment-container"> <div className="loan-repayment-container">
<form onSubmit={(e) => { e.preventDefault(); calculateLoanDetails(); }}> <form onSubmit={(e) => { e.preventDefault(); calculateLoanDetails(); }}>
<div> <div className="input-group">
<label>Tuition Type:</label> <label>Tuition Type:</label>
<select value={tuitionType} onChange={(e) => setTuitionType(e.target.value)}> <select value={tuitionType} onChange={(e) => setTuitionType(e.target.value)}>
<option value="inState">In-State</option> <option value="inState">In-State</option>
<option value="outOfState">Out-of-State</option> <option value="outOfState">Out-of-State</option>
</select> </select>
</div>
<div>
<label>Interest Rate:</label>
<input type="number" value={interestRate} onChange={(e) => setInterestRate(e.target.value)} />
</div>
<div>
<label>Loan Term (years):</label>
<input type="number" value={loanTerm} onChange={(e) => setLoanTerm(e.target.value)} />
</div>
<div>
<label>Extra Monthly Payment:</label>
<input type="number" value={extraPayment} onChange={(e) => setExtraPayment(e.target.value)} />
</div>
<div>
<label>Current Salary:</label>
<input type="number" value={currentSalary} onChange={(e) => setCurrentSalary(e.target.value)} />
</div>
<div>
<label>Expected Salary:</label>
<select value={selectedSalary} onChange={(e) => setSelectedSalary(e.target.value)}>
{salaryData.map((point, index) => (
<option key={index} value={point.percentile}>{point.percentile}</option>
))}
</select>
</div>
<button type="submit">Calculate</button>
</form>
{error && <div className="error">{error}</div>}
</div> </div>
<div className="input-group">
<label>Interest Rate:</label>
<input type="number" value={interestRate} onChange={(e) => setInterestRate(e.target.value)} />
</div>
<div className="input-group">
<label>Loan Term (years):</label>
<input type="number" value={loanTerm} onChange={(e) => setLoanTerm(e.target.value)} />
</div>
<div className="input-group">
<label>Extra Monthly Payment:</label>
<input type="number" value={extraPayment} onChange={(e) => setExtraPayment(e.target.value)} />
</div>
<div className="input-group">
<label>Current Salary:</label>
<input type="number" value={currentSalary} onChange={(e) => setCurrentSalary(e.target.value)} />
</div>
<div className="input-group">
<label>Expected Salary:</label>
<select value={selectedSalary} onChange={(e) => setSelectedSalary(e.target.value)}>
{salaryData.map((point, index) => (
<option key={index} value={point.percentile}>{point.percentile}</option>
))}
</select>
</div>
<div className="calculate-button-container">
<button type="submit">Calculate</button>
</div>
</form>
{error && <div className="error">{error}</div>}
</div>
); );
} }