From d373cb0ec38ef5aafa92f29867e90798678f4969 Mon Sep 17 00:00:00 2001 From: Jen Breese-Kauth Date: Fri, 27 Mar 2026 11:49:54 -0700 Subject: [PATCH 1/3] IFDM-127: Fixes to the interest calculation --- app/interactives/interest-calculator/page.tsx | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/app/interactives/interest-calculator/page.tsx b/app/interactives/interest-calculator/page.tsx index 5a7ee22..af51ea6 100644 --- a/app/interactives/interest-calculator/page.tsx +++ b/app/interactives/interest-calculator/page.tsx @@ -10,36 +10,36 @@ const InterestRateVisual = () => { const [mode, setMode] = useState("saving"); // 'saving' or 'borrowing' const [amount, setAmount] = useState(100); const [interestRate, setInterestRate] = useState(5); - const [years, setYears] = useState(10); + const [periods, setPeriods] = useState(10); const [compounding, setCompounding] = useState("annually"); const [interestAmount, setInterestAmount] = useState(0); const [totalAmount, setTotalAmount] = useState(0); - const MAX_YEARS = 240; + const MAX_PERIODS = 960; // 240 years * 4 quarters (reasonable max) // Calculate the interest and total amount useEffect(() => { - let periods = 1; + let periodsPerYear = 1; switch (compounding) { case "monthly": - periods = 12; + periodsPerYear = 12; break; case "quarterly": - periods = 4; + periodsPerYear = 4; break; case "semi-annually": - periods = 2; + periodsPerYear = 2; break; default: - periods = 1; + periodsPerYear = 1; } - // Compound interest formula: A = P(1 + r/n)^(nt) + // Compound interest formula: A = P(1 + r/n)^(t) + // where t is the number of compounding periods const rate = interestRate / 100; - const periodicRate = rate / periods; - const totalPeriods = periods * years; + const periodicRate = rate / periodsPerYear; - const calculatedTotal = amount * Math.pow(1 + periodicRate, totalPeriods); + const calculatedTotal = amount * Math.pow(1 + periodicRate, periods); const calculatedInterest = calculatedTotal - amount; setInterestAmount( @@ -48,7 +48,7 @@ const InterestRateVisual = () => { setTotalAmount( mode === "saving" ? calculatedTotal : amount + calculatedInterest ); - }, [amount, interestRate, years, compounding, mode]); + }, [amount, interestRate, periods, compounding, mode]); return (
@@ -218,12 +218,12 @@ const InterestRateVisual = () => { - setYears( - Math.min(MAX_YEARS, Math.max(0, parseInt(e.target.value) || 0)) + setPeriods( + Math.min(MAX_PERIODS, Math.max(0, parseInt(e.target.value) || 0)) ) } className="block w-full rounded-md shadow-sm py-2 px-3 border pr-10 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" @@ -232,11 +232,11 @@ const InterestRateVisual = () => {
- + {/* Example section */}
@@ -353,4 +353,4 @@ const InterestRateVisual = () => { ); }; -export default InterestRateVisual; +export default InterestRateVisual; \ No newline at end of file From 7723acf280685e0a3b80eeec08221e9c9d74691e Mon Sep 17 00:00:00 2001 From: Jen Breese-Kauth Date: Tue, 31 Mar 2026 15:01:29 -0700 Subject: [PATCH 2/3] Removed the max persiod --- app/interactives/interest-calculator/page.tsx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/app/interactives/interest-calculator/page.tsx b/app/interactives/interest-calculator/page.tsx index af51ea6..bcb9e92 100644 --- a/app/interactives/interest-calculator/page.tsx +++ b/app/interactives/interest-calculator/page.tsx @@ -15,7 +15,6 @@ const InterestRateVisual = () => { const [interestAmount, setInterestAmount] = useState(0); const [totalAmount, setTotalAmount] = useState(0); - const MAX_PERIODS = 960; // 240 years * 4 quarters (reasonable max) // Calculate the interest and total amount useEffect(() => { @@ -218,12 +217,11 @@ const InterestRateVisual = () => { setPeriods( - Math.min(MAX_PERIODS, Math.max(0, parseInt(e.target.value) || 0)) + Math.max(0, parseInt(e.target.value) || 0) ) } className="block w-full rounded-md shadow-sm py-2 px-3 border pr-10 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" @@ -233,11 +231,8 @@ const InterestRateVisual = () => { type="button" tabIndex={-1} aria-label="Increase periods" - onClick={() => setPeriods((prev) => Math.min(MAX_PERIODS, prev + 1))} - disabled={periods >= MAX_PERIODS} - className={`mb-[-5px] hover:text-grey-med-dark focus:outline-none ${ - periods >= MAX_PERIODS ? 'opacity-30 cursor-not-allowed' : '' - }`} + onClick={() => setPeriods((prev) => Math.min(prev + 1))} + className="mb-[-5px] hover:text-grey-med-dark focus:outline-none" > From 51ce92e9ca6812d2fe032765066fe7fe0007f0fd Mon Sep 17 00:00:00 2001 From: Ian Monroe Date: Thu, 2 Apr 2026 15:04:57 +0000 Subject: [PATCH 3/3] Math.min no longer needed --- app/interactives/interest-calculator/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/interactives/interest-calculator/page.tsx b/app/interactives/interest-calculator/page.tsx index ea47021..706bc6a 100644 --- a/app/interactives/interest-calculator/page.tsx +++ b/app/interactives/interest-calculator/page.tsx @@ -240,7 +240,7 @@ const InterestRateVisual = () => { type="button" tabIndex={-1} aria-label="Increase periods" - onClick={() => setPeriods((prev) => Math.min(prev + 1))} + onClick={() => setPeriods((prev) => prev + 1)} className="mb-[-5px] hover:text-grey-med-dark focus:outline-none" >