Skip to content
Open
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
51 changes: 23 additions & 28 deletions app/interactives/compounding-frequency-calculator/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ function formatCurrency(value: number): string {
}).format(value)
}

function formatNumber(value: number): string {
return Math.round(value).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
}

function calculateCompoundInterest(
principal: number,
rate: number,
Expand All @@ -46,19 +42,6 @@ function calculateCompoundInterest(
return { finalAmount, interestEarned, totalPeriods }
}

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} month${months !== 1 ? 's' : ''}`
if (months === 0) return `${years} year${years !== 1 ? 's' : ''}`

return `${years} year${years !== 1 ? 's' : ''} and ${months} month${months !== 1 ? 's' : ''}`
}

export default function CompoundInterestCalculator() {
const [initialAmount, setInitialAmount] = useState<string>("")
const [annualRate, setAnnualRate] = useState<string>("")
Expand All @@ -78,11 +61,6 @@ export default function CompoundInterestCalculator() {
return calculateCompoundInterest(principal, rate, totalPeriods, selectedOption.periodsPerYear)
}, [principal, rate, totalPeriods, selectedOption.periodsPerYear])

const formattedTimePeriod = useMemo(() =>
formatTimePeriod(totalPeriods, selectedOption.periodsPerYear),
[totalPeriods, selectedOption.periodsPerYear]
)

const comparisonResults = useMemo(() => {
const timeInYears = totalPeriods / selectedOption.periodsPerYear
return compoundingOptions.map((option) => {
Expand Down Expand Up @@ -152,9 +130,6 @@ export default function CompoundInterestCalculator() {
className="font-bold 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"
min="0"
/>
<p className="text-sm text-foreground mt-2">
{totalPeriods > 0 && `${formatNumber(totalPeriods)} ${selectedOption.label.toLowerCase()} periods = ${formattedTimePeriod}`}
</p>
</div>
</div>

Expand Down Expand Up @@ -185,9 +160,29 @@ export default function CompoundInterestCalculator() {
{/* Results Section */}
<Card className="w-full lg:w-1/2 bg-[var(--card-background)] rounded-3xl p-[32px]">
<CardContent className="p-0">
<p className="text-[20px] font-bold mb-1">Balance after {formattedTimePeriod}</p>
<p className="text-[20px] font-bold mb-1">Balance after {periods}
{
selectedCompounding === 'daily' ? ' days' :
selectedCompounding === 'weekly' ? ' weeks' :
selectedCompounding === 'biweekly' ? ' bi-weekly periods' :
selectedCompounding === 'monthly' ? ' months' :
selectedCompounding === 'quarterly' ? ' quarters' :
selectedCompounding === 'semi-annually' ? ' semi-annual periods' :
selectedCompounding === 'annually' ? ' years' :
selectedCompounding}
</p>
<p className="text-3xl font-bold text-lagunita mb-5">{formatCurrency(selectedResult.finalAmount)}</p>
<p className="text-[16px] font-semibold mb-1">Interest Earned over {formattedTimePeriod}</p>
<p className="text-[16px] font-semibold mb-1">Interest accrued over {periods}
{
selectedCompounding === 'daily' ? ' days' :
selectedCompounding === 'weekly' ? ' weeks' :
selectedCompounding === 'biweekly' ? ' bi-weekly periods' :
selectedCompounding === 'monthly' ? ' months' :
selectedCompounding === 'quarterly' ? ' quarters' :
selectedCompounding === 'semi-annually' ? ' semi-annual periods' :
selectedCompounding === 'annually' ? ' years' :
selectedCompounding}
</p>
<p className="text-3xl font-bold text-foreground">
{formatCurrency(selectedResult.interestEarned)}
</p>
Expand Down Expand Up @@ -228,7 +223,7 @@ export default function CompoundInterestCalculator() {
))}
</tbody>
</table>
<p className="pt-3 font-bold text-sm">Over the same time period, more frequent compounding generally results in more interest earned, assuming the annual interest rate stays the same.</p>
<p className="pt-3 font-bold text-sm">Over the same time period, more frequent compounding generally results in more interest accrued, assuming the annual interest rate stays the same.</p>
</div>
</section>

Expand Down