Skip to content
Merged
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
89 changes: 37 additions & 52 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useState } from "react";
import LoanForm from "./LoanForm.jsx";
import { loanMaths, isNumber } from "./loanMaths.js";
import ModeToggle from "./ModeToggle.jsx";
import LoanPlot from "./LoanPlot.jsx";
import LoanStats from "./LoanStats.jsx";
import EventsForm from "./EventsForm.jsx";
Expand Down Expand Up @@ -203,7 +204,7 @@ if (searchParams.has("downPayCash")) initialUserSetDownPercent = false;

function App() {
const [loanEvent, setLoanEvent] = useState(initialEvents);
const [chosenInput, setChosenInput] = useState("homeVal");
const [chosenInput, setChosenInput] = useState("monthlyPayment" in initialOverride ? "monthlyPayment" : "homeVal");
const [userSetDownPercent, setUserSetDownPercent] = useState(initialUserSetDownPercent);
const [showURLToast, setShowURLToast] = useState(gotStuffFromURL);
const [rentSim, setRentSim] = useState({ ...initialRentSimulation, ...overrideRentSimulation });
Expand Down Expand Up @@ -568,28 +569,18 @@ function App() {
</Modal>
</nav>
<div className="container-xxl py-3 rounded">
<div className="row">
<div className="col-12">
<div className="row shadow-sm border rounded mx-0 mb-3" style={{ backgroundColor: "white" }}>
<div className="col">
<p className="my-2">
An easy to use mortgage calculator to find out exactly how much it will cost to buy a house. Or, enter a monthly budget. How much can you
afford? This tool supports unlimited overpayment, re-finance and recast events. Also, try adding inflation.
</p>
</div>
</div>
</div>
</div>
<div className="row">
<div className="col-lg-7 col-12 mb-3">
<LoanForm displayState={displayState} valid={valid} flash={flash} updateUserInput={(f, v) => updateUserInput(f, v)} />
<ModeToggle chosenInput={chosenInput} displayState={displayState} valid={valid} flash={flash} userInput={userInput} updateUserInput={updateUserInput} />

<div className="row mx-0">
<div className="col-lg-7 col-12 mb-3 px-2 mx-0">
<LoanForm displayState={displayState} valid={valid} flash={flash} updateUserInput={(f, v) => updateUserInput(f, v)} chosenInput={chosenInput} />
</div>
<div className="col-lg-5 col-12">
<div className="row">
<div className="col-12 mb-3">
<div className="col-lg-5 col-12 px-0 mx-0">
<div className="row mx-0 px-0">
<div className="col-12 mb-3 px-2 mx-0">
<LoanStats loanRes={loanRes} userInput={userInput} />
</div>
<div className="col-12 mb-3">
<div className="col-12 mb-3 px-2 mx-0">
<EventsForm
loanMonths={loanRes["loanMonths"]}
loanEvent={loanEvent}
Expand All @@ -607,38 +598,32 @@ function App() {
</div>
</div>
</div>
<div className="row">
<div className="col-12">
<LoanPlot
maxMonthly={Math.max(loanRes["monthlyPayment"])}
loanRes={loanRes}
loanMonths={loanRes["loanMonths"]}
propertyTax={userInput["propertyTax"] * unitScaler(userInput["propertyTaxUnit"])}
hoa={userInput["hoa"] * unitScaler(userInput["hoaUnit"])}
pmi={userInput["pmi"] * unitScaler(userInput["pmiUnit"])}
utilities={userInput["utilities"] * unitScaler(userInput["utilitiesUnit"])}
maintenance={userInput["maintenance"] * unitScaler(userInput["maintenanceUnit"])}
insurance={userInput["insurance"] * unitScaler(userInput["insuranceUnit"])}
startDate={new Date(Number(userInput["startDate"]))}
inflation={loanRes["inflation"]}
/>
</div>
</div>
<div className="row shadow-sm border rounded mx-0 mt-5 mb-3" style={{ backgroundColor: "white" }}>
<div className="col-12 py-2">
<Rent
downPayment={displayState["downPayCash"]}
loanMonths={loanRes["loanMonths"]}
inflation={loanRes["inflation"]}
equity={loanRes["equity"]}
homeVal={loanRes["homeVal"]}
monthlyPayment={loanRes["monthlyPayment"]}
overPayments={loanRes["overPayments"]}
totalFees={loanRes["totalFees"]}
rentSim={rentSim}
setRentSim={(r) => setRentSim(r)}
/>
</div>
<LoanPlot
maxMonthly={Math.max(loanRes["monthlyPayment"])}
loanRes={loanRes}
loanMonths={loanRes["loanMonths"]}
propertyTax={userInput["propertyTax"] * unitScaler(userInput["propertyTaxUnit"])}
hoa={userInput["hoa"] * unitScaler(userInput["hoaUnit"])}
pmi={userInput["pmi"] * unitScaler(userInput["pmiUnit"])}
utilities={userInput["utilities"] * unitScaler(userInput["utilitiesUnit"])}
maintenance={userInput["maintenance"] * unitScaler(userInput["maintenanceUnit"])}
insurance={userInput["insurance"] * unitScaler(userInput["insuranceUnit"])}
startDate={new Date(Number(userInput["startDate"]))}
inflation={loanRes["inflation"]}
/>
<div className="row shadow-sm border rounded mx-2 mt-5 mb-3" style={{ backgroundColor: "white" }}>
<Rent
downPayment={displayState["downPayCash"]}
loanMonths={loanRes["loanMonths"]}
inflation={loanRes["inflation"]}
equity={loanRes["equity"]}
homeVal={loanRes["homeVal"]}
monthlyPayment={loanRes["monthlyPayment"]}
overPayments={loanRes["overPayments"]}
totalFees={loanRes["totalFees"]}
rentSim={rentSim}
setRentSim={(r) => setRentSim(r)}
/>
</div>
<div className="row shadow-sm border rounded mx-0" style={{ backgroundColor: "white" }}>
<div className="col-12">
Expand Down
44 changes: 0 additions & 44 deletions src/LoanForm.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,6 @@ function FbComp({ x }) {
function LoanForm({ displayState, flash, updateUserInput, valid }) {
const [show, setShow] = useState(false);
const feeOptions = ["$ / year", "$ / month", "% / year", "% / month"];
const additionalPayments =
Number(displayState["propertyTax"]) > 0 ||
Number(displayState["hoa"]) > 0 ||
Number(displayState["insurance"]) > 0 ||
Number(displayState["pmi"]) ||
Number(displayState["maintenance"]) > 0 ||
Number(displayState["utilities"]) > 0;

//builds class for each input based on flash (whether it changed and should flash) and valid (if user input is valid)
const startDateOptions = { month: "short", year: "numeric" };
Expand Down Expand Up @@ -97,43 +90,6 @@ function LoanForm({ displayState, flash, updateUserInput, valid }) {

return (
<div>
<div className="row shadow-sm border rounded mb-3 py-2 mx-0" style={{ backgroundColor: "white" }}>
<div className="col-5 pe-0">
<label>Home Value</label>
<input
// key={homeVal}
type="text"
inputMode="numeric"
className={inputClass["homeVal"]}
value={cashFormat(displayState["homeVal"])}
onChange={(e) => updateIfChanged(displayState["homeVal"], e.target.value, "homeVal")}
/>
<ValidFbComp x={valid["homeVal"]} />
{additionalPayments ? (
<label>
<small></small>
</label>
) : null}
</div>
<div className="col-2 text-center align-self-center">or</div>
<div className="col-5 ps-0">
<label>Monthly Payment</label>
<input
type="text"
inputMode="numeric"
className={inputClass["monthlyPayment"]}
onChange={(e) => updateIfChanged(displayState["monthlyPayment"], e.target.value, "monthlyPayment")}
value={cashFormat(displayState["monthlyPayment"])}
/>

<ValidFbComp x={valid["monthlyPayment"]} />
{additionalPayments ? (
<label>
<small>{cashFormat(displayState["monthlyPaymentToLoan"])} towards loan</small>
</label>
) : null}
</div>
</div>
<div className="row shadow-sm border rounded mb-3 py-2 mx-0" style={{ backgroundColor: "white" }}>
<div className="col-12">
<label>Down Payment</label>
Expand Down
23 changes: 8 additions & 15 deletions src/LoanPlot.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -249,23 +249,16 @@ function LoanPlot({ maxMonthly, loanRes, loanMonths, propertyTax, hoa, pmi, util
};

return (
<div className="row shadow-sm border rounded mb-3 py-1 mx-0 px-1" style={{ backgroundColor: "white" }}>
<div className="row shadow-sm border rounded mb-3 py-1 mx-2 px-1" style={{ backgroundColor: "white" }}>
<div className="col-12 px-0">
<div className="row mx-0">
<div className="col-12 px-0">
<div className="plotHeight">
<Chart type="bar" data={data} options={options} />
</div>
</div>
<div className="plotHeight">
<Chart type="bar" data={data} options={options} />
</div>

<div className="row mx-0">
<div className="col-1">
<span>Show: </span>
</div>
{["Monthly Breakdown", "Yearly Breakdown"].map((x) => (
<div className="col-xxl-2 col-md-4 col-sm-5 col-12" key={x}>
<div className="form-check form-check-inline">
<div className="col-12 ps-4">
{["Monthly Breakdown", "Yearly Breakdown"].map((x) => (
<div className="form-check form-check-inline" key={x}>
<input
className="form-check-input"
type="radio"
Expand All @@ -276,8 +269,8 @@ function LoanPlot({ maxMonthly, loanRes, loanMonths, propertyTax, hoa, pmi, util
/>
<label className="form-check-label">{x}</label>
</div>
</div>
))}
))}
</div>
</div>
</div>
</div>
Expand Down
Loading