From ad7ef21029daf9668782f3dd5d65666d14ec064a Mon Sep 17 00:00:00 2001 From: Jen Breese-Kauth Date: Mon, 4 May 2026 13:54:38 -0700 Subject: [PATCH 1/4] IFDM-145: Initial commit --- .../present-value-calculator-v2/page.tsx | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/app/interactives/present-value-calculator-v2/page.tsx b/app/interactives/present-value-calculator-v2/page.tsx index c126665..2b7d3b0 100644 --- a/app/interactives/present-value-calculator-v2/page.tsx +++ b/app/interactives/present-value-calculator-v2/page.tsx @@ -96,8 +96,8 @@ export default function PresentValueCalculator() { - Single Amount - Payment Series + Single amount + Payment series {/* Single Amount Tab */} @@ -105,8 +105,9 @@ export default function PresentValueCalculator() {
{/* Future Value Input */} +

Enter a future value to calculate what it is worth today.

-
{/* Compounding Frequency */}
- + -
{/* Interest Rate Input */}
- - setInterestRate(e.target.value === "" ? 0 : Number(e.target.value))} - min={0} - max={100} - step={0.1} - className="bg-white border-1 w-full rounded-md shadow-sm py-2 px-3" - /> +
+ + setInterestRate(e.target.value === "" ? 0 : Number(e.target.value))} + min={0} + max={100} + step={0.1} + className="w-full pl-4 pr-16 py-3 border-2 border-gray-300 rounded-lg focus:border-blue-500 focus:ring-2 focus:ring-blue-200 outline-none transition [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" + /> + + % + +
{/* Time Period Input */} @@ -147,12 +185,14 @@ export default function PresentValueCalculator() { value={timePeriod === 0 ? "" : timePeriod} onChange={(e) => setTimePeriod(e.target.value === "" ? 0 : Number(e.target.value))} min={1} - max={100} + max={1000} step={1} - className="bg-white border-1 w-full rounded-md shadow-sm py-2 px-3" + className="bg-white border-1 w-full rounded-md shadow-sm py-2 px-3 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" />

- {totalPeriods > 0 && `${totalPeriods} ${frequencyMap[compoundingFrequency].label.toLowerCase()} periods = ${timePeriod} year${timePeriod === 1 ? '' : 's'}`} + + {timePeriod > 0 && `${formatNumber(timePeriod)} ${frequencyMap[compoundingFrequency].label.toLowerCase()} period${timePeriod !== 1 ? 's' : ''} = ${formatTimePeriod(timePeriod, frequencyMap[compoundingFrequency].periods)}`} +

@@ -179,11 +219,9 @@ export default function PresentValueCalculator() { {/* Results Section */}
-

Results

- {/* Main Present Value Display */} -

Present Value

-

+

Present value today

+

{formatCurrency(singleCalculations.presentValue)}

@@ -216,7 +254,7 @@ export default function PresentValueCalculator() {

- Compounded {frequencyMap[compoundingFrequency].label.toLowerCase()} over {timePeriod} years + {timePeriod} {frequencyMap[compoundingFrequency].label.toLowerCase()} periods = {formatTimePeriod(timePeriod, frequencyMap[compoundingFrequency].periods)}

@@ -228,18 +266,27 @@ export default function PresentValueCalculator() {
{/* Payment Amount Input */} -

Enter a payment amount and number of payments to calculate their value today.

+

Find what a series of payments is worth today. Enter a payment amount and number of payments to calculate the present value.

- setPaymentAmount(e.target.value === "" ? 0 : Number(e.target.value))} - className="bg-white border-1 w-full rounded-md shadow-sm py-2 px-3" - /> +
+ {paymentAmount > 0 && ( + + $ + + )} + setPaymentAmount(e.target.value === "" ? 0 : Number(e.target.value))} + className={`bg-white border-1 w-full rounded-md shadow-sm py-2 px-3 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none ${ + paymentAmount > 0 ? "pl-7" : "" + }`} + /> +
{/* Interest Rate Input */} @@ -247,16 +294,21 @@ export default function PresentValueCalculator() { - setPaymentInterestRate(e.target.value === "" ? 0 : Number(e.target.value))} - min={0} - max={100} - step={0.1} - className="bg-white border-1 w-full rounded-md shadow-sm py-2 px-3" - /> +
+ setPaymentInterestRate(e.target.value === "" ? 0 : Number(e.target.value))} + min={0} + max={100} + step={0.1} + className="bg-white border-1 w-full rounded-md shadow-sm py-2 px-3 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" + /> + + % + +
{/* Number of Payments Input */} @@ -272,7 +324,7 @@ export default function PresentValueCalculator() { min={1} max={1000} step={1} - className="bg-white border-1 w-full rounded-md shadow-sm py-2 px-3" + className="bg-white border-1 w-full rounded-md shadow-sm py-2 px-3 [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none" /> @@ -299,11 +351,8 @@ export default function PresentValueCalculator() { {/* Results Section */}
-

Results

- - {/* Main Present Value Display */} -

Present Value

-

+

Present value

+

{formatCurrency(paymentCalculations.presentValue)}

@@ -351,4 +400,4 @@ export default function PresentValueCalculator() {
) -} +} \ No newline at end of file From 2796f52ef833038b04a3ede14a25feca2950e007 Mon Sep 17 00:00:00 2001 From: Jen Breese-Kauth Date: Tue, 5 May 2026 08:45:56 -0700 Subject: [PATCH 4/4] IFDM-145: removing text per ticket --- .../present-value-calculator-v2/page.tsx | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/app/interactives/present-value-calculator-v2/page.tsx b/app/interactives/present-value-calculator-v2/page.tsx index c95bdc2..e039927 100644 --- a/app/interactives/present-value-calculator-v2/page.tsx +++ b/app/interactives/present-value-calculator-v2/page.tsx @@ -14,13 +14,15 @@ import { } from "@/app/ui/components/select" import ThemeToggle from "@/app/lib/theme-toggle" -type CompoundingFrequency = "annually" | "semi-annually" | "quarterly" | "monthly" | "daily" +type CompoundingFrequency = "annually" | "semi-annually" | "quarterly" | "monthly" | "biweekly" | "weekly" | "daily" const frequencyMap: Record = { annually: { periods: 1, label: "Annually" }, "semi-annually": { periods: 2, label: "Semi-annually" }, quarterly: { periods: 4, label: "Quarterly" }, monthly: { periods: 12, label: "Monthly" }, + biweekly: { periods: 26, label: "Biweekly" }, + weekly: { periods: 52, label: "Weekly" }, daily: { periods: 365, label: "Daily" }, } @@ -220,7 +222,7 @@ export default function PresentValueCalculator() { {/* Results Section */}
{/* Main Present Value Display */} -

Present value today

+

Present value

{formatCurrency(singleCalculations.presentValue)}

@@ -252,10 +254,6 @@ export default function PresentValueCalculator() {
- -

- {timePeriod} {frequencyMap[compoundingFrequency].label.toLowerCase()} periods = {formatTimePeriod(timePeriod, frequencyMap[compoundingFrequency].periods)} -

@@ -389,9 +387,6 @@ export default function PresentValueCalculator() { -

- {numberOfPayments} payments made {frequencyMap[paymentFrequency].label.toLowerCase()} -