diff --git a/app/interactives/present-value-calculator-v2/page.tsx b/app/interactives/present-value-calculator-v2/page.tsx index c126665..e039927 100644 --- a/app/interactives/present-value-calculator-v2/page.tsx +++ b/app/interactives/present-value-calculator-v2/page.tsx @@ -14,27 +14,52 @@ 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" }, } +function formatTimePeriod(totalPeriods: number, periodsPerYear: number): string { + const totalYears = totalPeriods / periodsPerYear + const years = Math.floor(totalYears) + const remainingPeriods = totalPeriods - (years * periodsPerYear) + const months = Math.round((remainingPeriods / periodsPerYear) * 12) + + if (years === 0 && months === 0) return "0 months" + if (years === 0) { + return months === 1 ? "1 month" : `${months} months` + } + if (months === 0) { + return years === 1 ? "1 year" : `${years} years` + } + + const yearText = years === 1 ? "1 year" : `${years} years` + const monthText = months === 1 ? "1 month" : `${months} months` + return `${yearText} and ${monthText}` +} + +function formatNumber(value: number): string { + return Math.round(value).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") +} + export default function PresentValueCalculator() { const [activeTab, setActiveTab] = useState("single") // Single Amount State - const [futureValue, setFutureValue] = useState(10000) + const [futureValue, setFutureValue] = useState(0) const [interestRate, setInterestRate] = useState(5) const [timePeriod, setTimePeriod] = useState(10) const [compoundingFrequency, setCompoundingFrequency] = useState("annually") // Payment Series State - const [paymentAmount, setPaymentAmount] = useState(1000) + const [paymentAmount, setPaymentAmount] = useState(0) const [paymentInterestRate, setPaymentInterestRate] = useState(5) const [numberOfPayments, setNumberOfPayments] = useState(10) const [paymentFrequency, setPaymentFrequency] = useState("annually") @@ -42,10 +67,10 @@ export default function PresentValueCalculator() { const singleCalculations = useMemo(() => { const rate = interestRate / 100 const n = frequencyMap[compoundingFrequency].periods - const totalPeriods = n * timePeriod + const totalPeriods = timePeriod // CHANGED: use input directly as total periods const periodRate = rate / n const presentValue = futureValue / Math.pow(1 + periodRate, totalPeriods) - const discountAmount = futureValue - presentValue + const discountAmount = futureValue - presentValue return { presentValue, @@ -68,7 +93,7 @@ export default function PresentValueCalculator() { } const totalPayments = paymentAmount * numberOfPayments - const discountAmount = totalPayments -presentValue + const discountAmount = totalPayments - presentValue return { presentValue, @@ -96,49 +121,65 @@ export default function PresentValueCalculator() { - Single Amount - Payment Series + Single amount + Payment series {/* Single Amount Tab */}
+ {/* Future Value Input */} +

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

{/* Future Value Input */}
-
{/* 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 */}
-
{/* Compounding Frequency */}
- + 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 */}
-
{/* Number of Payments Input */}
-
{/* Payment Frequency */}
- +