Skip to content

Commit 48f1944

Browse files
committed
more loan breakdowns
1 parent 7d4aee4 commit 48f1944

11 files changed

Lines changed: 195 additions & 91 deletions

File tree

trgmc/README.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,19 @@ Currently, two official plugins are available:
1818
# Todo
1919

2020
## Important
21-
- Show breakdown of total repayments
21+
-- Add a reset button
22+
-- Add a share button
23+
-- save it to cookie
24+
-- Add footer with ym name and link to git
25+
- tax should reduce if loan length decreases
26+
- show new finish date after events
27+
- double check maths against other sites
2228
- get a domain, make the site live
23-
- fix total repayment when overpayment & refinance added
24-
- show amount saved by doing overpayment
25-
- CLIO FEEDBACK
26-
-- show standard loan types and autofill length
27-
-- overpayment shows remaining balance reduction
28-
-- show “yearly”, “monthly”
29-
-- add comments section
30-
-- move export fn to common file to enable fast refresh
29+
-- google analytics
3130

3231

3332
## Later
33+
-- show standard loan types and autofill length
3434
- hover over explains how th eboxes were calculated
3535
- refinance has option to change loan length
3636
- Show loan length and new monthly payment
@@ -57,6 +57,15 @@ Currently, two official plugins are available:
5757

5858

5959
# Done
60+
- Show breakdown of total repayments
61+
-- fix total repayment when overpayment & refinance added
62+
-- show amount saved by doing overpayment
63+
-- overpayment shows remaining balance reduction
64+
65+
-- new monthly payment when re-cast is chosen
66+
-- show “yearly”, “monthly”
67+
-- move export fn to common file to enable fast refresh
68+
-- add comments section
6069
-- screen vertical too small
6170
-- note that monthly includes all
6271
-- refinance on same date crashes site
Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

trgmc/dist/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<link rel="icon" type="image/svg+xml" href="./vite.svg" />
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<title>Vite + React</title>
8-
<script type="module" crossorigin src="./assets/index-gJjfRCWf.js"></script>
9-
<link rel="stylesheet" crossorigin href="./assets/index-8iGur0UO.css">
8+
<script type="module" crossorigin src="./assets/index-BptAHnls.js"></script>
9+
<link rel="stylesheet" crossorigin href="./assets/index-CCIrZKUt.css">
1010
</head>
1111
<body>
1212
<div id="root"></div>

trgmc/src/App.jsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ function runCalculations(userInput, loanEvent, chosenInput, userSetDownPercent)
3030
: parseFloat(userInput["homeVal"]) - parseFloat(userInput["downPayCash"]);
3131
const downPay = userSetDownPercent ? parseFloat(userInput.downPayPercent) * 0.01 : parseFloat(userInput.downPayCash);
3232

33+
// console.log("loanAmount_1", loanAmount)
34+
3335
var loanRes = loanMaths(
3436
parseFloat(loanAmount),
3537
parseFloat(userInput["loanLength"]),
@@ -52,6 +54,7 @@ function runCalculations(userInput, loanEvent, chosenInput, userSetDownPercent)
5254
displayState["monthlyPayment"] = parseFloat(loanRes["monthlyPayment"][0]);
5355
}
5456
displayState["monthlyPaymentToLoan"] = parseFloat(loanRes["monthlyInterest"][0]) + parseFloat(loanRes["monthlyPrincipal"][0]);
57+
// console.log("homeVal",homeVal)
5558
if (userSetDownPercent) {
5659
displayState["downPayPercent"] = userInput["downPayPercent"];
5760
displayState["downPayCash"] = homeVal * parseFloat(userInput["downPayPercent"]) * 0.01;
@@ -68,6 +71,7 @@ function runCalculations(userInput, loanEvent, chosenInput, userSetDownPercent)
6871
displayState["interestRate"] = userInput["interestRate"];
6972
displayState["loanLength"] = userInput["loanLength"];
7073
displayState["loanAmount"] = loanRes["loanAmount"];
74+
// console.log("loanAmount_2", loanRes["loanAmount"])
7175

7276
displayState["propertyTax"] = userInput["propertyTax"];
7377
displayState["hoa"] = userInput["hoa"];
@@ -100,10 +104,11 @@ function loanEventDecoder(e) {
100104
}
101105

102106
var accurateDate = new Date();
103-
const dateLu = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"];
104-
var dStr = `${accurateDate.getFullYear()}-${dateLu[accurateDate.getMonth()]}-01`;
107+
// const dateLu = ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"];
108+
// var dStr = `${accurateDate.getFullYear()}-${dateLu[accurateDate.getMonth()]}-05`;
109+
var dStr = `${accurateDate.getFullYear()}-01-05`; //Always defaultstarting at month 01 so graph looks symetrical
105110
var coarseDate = Date.parse(dStr); //only care about month - don't want minor date changes going in URL
106-
console.log("coarseDate", dStr, coarseDate);
111+
// console.log("coarseDate", dStr, coarseDate);
107112
const initialState = {
108113
homeVal: "500000",
109114
monthlyPayment: "0",
@@ -198,7 +203,6 @@ function App() {
198203
var newValid = { ...valid };
199204
var newUserSetDownPercent = userSetDownPercent;
200205
var newDisplayState = { ...displayState };
201-
console.log("bp2");
202206

203207
// if (userSetDownPercent) {
204208
// var downPayCash = (loanRes["loanAmount"] * userInput["downPayPercent"]) / 100;
@@ -244,16 +248,22 @@ function App() {
244248
// newFlash["loanAmount"] = !flash["loanAmount"];
245249
} else if (field == "insurance") {
246250
newUserInput.insurance = value;
251+
if (newChosenInput == "homeVal") newFlash["loanAmount"] = !newFlash["loanAmount"];
247252
} else if (field == "insuranceUnit") {
248253
newUserInput.insuranceUnit = value;
254+
if (newChosenInput == "homeVal") newFlash["loanAmount"] = !newFlash["loanAmount"];
249255
} else if (field == "hoa") {
250256
newUserInput.hoa = value;
257+
if (newChosenInput == "homeVal") newFlash["loanAmount"] = !newFlash["loanAmount"];
251258
} else if (field == "hoaUnit") {
252259
newUserInput.hoaUnit = value;
260+
if (newChosenInput == "homeVal") newFlash["loanAmount"] = !newFlash["loanAmount"];
253261
} else if (field == "propertyTax") {
254262
newUserInput.propertyTax = value;
263+
if (newChosenInput == "homeVal") newFlash["loanAmount"] = !newFlash["loanAmount"];
255264
} else if (field == "propertyTaxUnit") {
256265
newUserInput.propertyTaxUnit = value;
266+
if (newChosenInput == "homeVal") newFlash["loanAmount"] = !newFlash["loanAmount"];
257267
} else if (field == "startDate") {
258268
newUserInput.startDate = value;
259269
}
@@ -359,7 +369,7 @@ function App() {
359369
<nav className="navbar bg-body-tertiary mb-2">
360370
<div className="container-xxl">
361371
<a className="navbar-brand" href="#">
362-
<b>t</b>he <b>R</b>eally <b>G</b>ood <b>M</b>ortgage <b>C</b>alculator
372+
the <b>R</b>eally <b>G</b>ood <b>M</b>ortgage <b>C</b>alculator <small>.net</small>
363373
</a>
364374
</div>
365375
</nav>
@@ -380,7 +390,7 @@ function App() {
380390
monthlyPaymentPerEvent={loanRes["monthlyPaymentPerEvent"]}
381391
/>
382392

383-
<LoanStats loanRes={loanRes} loanEvent={loanEvent} />
393+
<LoanStats loanRes={loanRes} loanEvent={loanEvent} userInput={userInput} />
384394
</div>
385395
<div className="col-md-7 col-12">
386396
<LoanPlot
@@ -390,11 +400,12 @@ function App() {
390400
propertyTax={userInput["propertyTax"] * unitScaler(userInput["propertyTaxUnit"])}
391401
hoa={userInput["hoa"] * unitScaler(userInput["hoaUnit"])}
392402
insurance={userInput["insurance"] * unitScaler(userInput["insuranceUnit"])}
403+
startDate={new Date(Number(userInput["startDate"]))}
393404
/>
394405
</div>
395406
</div>
396407
<div className="row">
397-
<p>Leave some feedback!</p>
408+
<p>It would be great to hear your feedback!</p>
398409
</div>
399410
<div className="row">
400411
<Comments website-id={11189} page-id="" />

trgmc/src/EventsForm.jsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ function EventsForm({ loanMonths, loanEvent, setLoanEvent, monthlyPaymentPerEven
1111
const [newChange, setNewChange] = useState(1000);
1212
const [chosenDate, setChosenDate] = useState(loanMonths[1]);
1313
const [newLength, setNewLength] = useState(0);
14-
const [cost, setCost] = useState(100);
14+
const [cost, setCost] = useState(0);
1515

1616
//prevent hanging when url params set up illegal state
1717
if (loanMonths.length < 2) return null;
@@ -279,7 +279,7 @@ function EventsForm({ loanMonths, loanEvent, setLoanEvent, monthlyPaymentPerEven
279279
maximumFractionDigits: 0,
280280
}).format(x["cost"])}
281281
</td>
282-
<td>{`${x["change"]}${x["event"] == "Refinance" ? "%" : ""}`}</td>
282+
<td>{x["event"] == "Refinance" ? `${x["change"]}%` : x["event"] == "Over-payment" ? cashFormat(x["change"]) : x["change"]}</td>
283283
<td key="pen">
284284
<span
285285
style={{ cursor: "pointer" }}
@@ -316,16 +316,16 @@ function EventsForm({ loanMonths, loanEvent, setLoanEvent, monthlyPaymentPerEven
316316
</td>
317317
</tr>
318318
{x["event"] == "Refinance" ? (
319-
<>
320-
<tr key={"refi1"}>
321-
<td></td>
322-
<td colSpan={5}>New loan length: {x["newLength"] == "" ? <em>unchanged</em> : `${x["newLength"]}yr`}</td>
323-
</tr>
324-
<tr key={"refi2"}>
325-
<td></td>
326-
<td colSpan={5}>New monthly payment: {cashFormat(monthlyPaymentPerEvent[i + 1])}</td>
327-
</tr>
328-
</>
319+
<tr key={"refi1"}>
320+
<td></td>
321+
<td colSpan={5}>New loan length: {x["newLength"] == "" ? <em>unchanged</em> : `${x["newLength"]}yr`}</td>
322+
</tr>
323+
) : null}
324+
{x["event"] == "Refinance" || x["event"] == "Recast" ? (
325+
<tr key={"refi2"}>
326+
<td></td>
327+
<td colSpan={5}>New monthly payment: {cashFormat(monthlyPaymentPerEvent[i + 1])}</td>
328+
</tr>
329329
) : null}
330330
</tbody>
331331
))}

trgmc/src/LoanForm.jsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ function ValidFbComp({ x }) {
2929
function LoanForm({ displayState, flash, updateUserInput, valid }) {
3030
const [show, setShow] = useState(false);
3131
const feeOptions = ["$ / year", "$ / month", "% / year", "% / month"];
32-
// const loanAmount = displayState["loanAmount"];
3332

3433
// var validClass = {};
3534
// for (const i in valid) validClass[i] = valid[i] === null ? null : "is-invalid";

trgmc/src/LoanPlot.jsx

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +15,59 @@ import { useState } from "react";
1515
// BarController
1616
// );
1717

18-
function LoanPlot({ maxMonthly, loanRes, loanMonths, propertyTax, hoa, insurance }) {
19-
const [monthsPerYearToPlot, setMonthsPerYearToPlot] = useState(1);
20-
const indexPlot = 12 / monthsPerYearToPlot;
18+
function LoanPlot({ maxMonthly, loanRes, loanMonths, propertyTax, hoa, insurance, startDate }) {
19+
const [monthsPerYearToPlot, setMonthsPerYearToPlot] = useState("yearly payments");
20+
const indexPlot = monthsPerYearToPlot == "monthly payments" ? 1 : 12;
21+
const yTitle = monthsPerYearToPlot == "monthly payments" ? "Monthly Payments" : "Yearly Payments";
22+
const startMonth = startDate.getMonth();
23+
// console.log(startDate, startMonth)
2124

2225
// console.log('rem',loanRes["remaining"])
26+
var monthlyPrincipalFiltered;
27+
var monthlyInterestFiltered;
28+
var loanMonthsFiltered;
29+
var remainingFiltered;
2330

24-
var loanMonthsFiltered = loanMonths.filter(function (element, index) {
25-
return index % indexPlot === 0;
26-
});
27-
var monthlyPrincipalFiltered = loanRes["monthlyPrincipal"].filter(function (element, index) {
28-
return index % indexPlot === 0;
29-
});
30-
var monthlyInterestFiltered = loanRes["monthlyInterest"].filter(function (element, index) {
31-
return index % indexPlot === 0;
32-
});
33-
// var monthlyTaxFiltered = loanRes["monthlyTax"].filter(function (element, index, array) {
34-
// return index % indexPlot === 0;
35-
// });
36-
var remainingFiltered = loanRes["remaining"].filter(function (element, index) {
37-
return index % indexPlot === 0;
38-
});
31+
if (monthsPerYearToPlot == "monthly payments") {
32+
loanMonthsFiltered = loanMonths;
33+
monthlyPrincipalFiltered = loanRes["monthlyPrincipal"];
34+
monthlyInterestFiltered = loanRes["monthlyInterest"];
35+
remainingFiltered = loanRes["remaining"];
36+
} else {
37+
// var loanMonthsFiltered = [0]
38+
monthlyPrincipalFiltered = [0];
39+
monthlyInterestFiltered = [0];
40+
// var remainingFiltered = [0]
41+
42+
var loanMonthsFiltered_full = loanMonths.filter(function (element, index) {
43+
return index % 12 === 0;
44+
});
45+
loanMonthsFiltered = loanMonthsFiltered_full.map((d) => d.substring(4, 8));
46+
remainingFiltered = loanRes["remaining"].filter(function (element, index) {
47+
return index % indexPlot === 0;
48+
});
49+
50+
for (var i = 0; i < loanMonths.length; i++) {
51+
var yearIndex = Math.floor((startMonth + i) / 12);
52+
// console.log(yearIndex)
53+
// if ((yearIndex==0) || (i==0)) {
54+
// monthlyPrincipalFiltered.push(0);// = 0
55+
// monthlyInterestFiltered[yearIndex] = 0
56+
// }
57+
if (yearIndex >= monthlyPrincipalFiltered.length) monthlyPrincipalFiltered.push(0);
58+
if (yearIndex >= monthlyInterestFiltered.length) monthlyInterestFiltered.push(0);
59+
monthlyPrincipalFiltered[yearIndex] = monthlyPrincipalFiltered[yearIndex] + loanRes["monthlyPrincipal"][i];
60+
monthlyInterestFiltered[yearIndex] = monthlyInterestFiltered[yearIndex] + loanRes["monthlyInterest"][i];
61+
}
62+
// console.log(yearIndex, loanRes["monthlyPrincipal"], loanRes["monthlyInterest"])
63+
64+
// var monthlyPrincipalFiltered = loanRes["monthlyPrincipal"].filter(function (element, index) {
65+
// return index % indexPlot === 0;
66+
// });
67+
// var monthlyInterestFiltered = loanRes["monthlyInterest"].filter(function (element, index) {
68+
// return index % indexPlot === 0;
69+
// });
70+
}
3971

4072
const DEFAULT_PLOTLY_COLORS = [
4173
"rgba(31, 119, 180, 0.6)",
@@ -126,7 +158,7 @@ function LoanPlot({ maxMonthly, loanRes, loanMonths, propertyTax, hoa, insurance
126158
// return '$' + value;
127159
},
128160
},
129-
title: { text: "Monthly Payments", display: true },
161+
title: { text: yTitle, display: true },
130162
},
131163
x1: {
132164
ticks: {
@@ -192,7 +224,7 @@ function LoanPlot({ maxMonthly, loanRes, loanMonths, propertyTax, hoa, insurance
192224
<div className="col-12 px-0">
193225
<div className="input-group ">
194226
<span className="pe-3">Show: </span>
195-
{[1, 2, 12].map((x) => (
227+
{["monthly payments", "yearly payments"].map((x) => (
196228
<div className="form-check form-check-inline" key={x}>
197229
<input
198230
className="form-check-input"
@@ -202,9 +234,7 @@ function LoanPlot({ maxMonthly, loanRes, loanMonths, propertyTax, hoa, insurance
202234
value={x}
203235
onChange={() => setMonthsPerYearToPlot(x)}
204236
/>
205-
<label className="form-check-label">
206-
{x} month{x > 1 ? "s" : null} per year
207-
</label>
237+
<label className="form-check-label">{x}</label>
208238
</div>
209239
))}
210240
</div>

0 commit comments

Comments
 (0)