The Loan Calculator allows users to determine loan amount, interest rate, and tenure, calculate monthly mortgage payments, total loan payments over tenure, and total interest payable. In this article, we will walk you through the process of building a Loan Calculator using Next.js.
Let’s take a look at how our completed project will look:
Technologies Used/Prerequisites
- Introduction to Next
- Next Component
- React Hooks
- NPM or NPX
Approach
It is important to import essential dependencies including React’s useState, useRef, and useEffect hooks, as well as CSS styles from a module. The core functionality of this calculator allows users to input specific details regarding their loan such as the loan amount, interest rate, and loan tenure.
As users interact with the app or make changes to their inputs, the application will automatically recalculate key figures such as the Equated Monthly Installment (EMI), total interest payable, and total amount to be repaid. To achieve this dynamic updating of values, state management techniques utilizing useState are employed. Additionally, input references are handled using useRef.
Steps to create the NextJS Application
Step 1: Create a new Next.js project using the following command
npx create-next-app loanCalculator
Step 2: Change to the project directory:
cd loanCalculator
Project Structure
Example: In this example, we will see the Loan Calculator App using Next.js
- index.js
Javascript
// Filename: index.js import { useState, useRef, useEffect } from "react" ; import styles from "../styles/Home.module.css" ; export default function Home() { const [loanAmount, setLoanAmount] = useState(100000); const [interestRate, setInterestRate] = useState(9); // Default value of 12 months const [loanTenure, setLoanTenure] = useState(12); const [loanEMI, setLoanEMI] = useState(0); const [totalInterest, setTotalInterest] = useState(0); const [totalAmount, setTotalAmount] = useState(0); const inputRefs = { loanAmount: useRef(), interestRate: useRef(), loanTenure: useRef(), }; useEffect(() => { calculateEMI(); }, []); const handleInputChange = (e) => { const { name, value } = e.target; if ( name === "loanAmount" || name === "loanTenure" || name === "interestRate" ) { if (name === "loanTenure" ) { setLoanTenure(parseInt(value) || 0); } else if (name === "loanAmount" ) { setLoanAmount(parseFloat(value) || 0); } else if (name === "interestRate" ) { setInterestRate(parseFloat(value) || 0); } } }; const calculateEMI = () => { const emi = loanAmount * (interestRate / 12 / 100) * (Math.pow( 1 + interestRate / 12 / 100, loanTenure ) / (Math.pow( 1 + interestRate / 12 / 100, loanTenure ) - 1)); setLoanEMI(emi); setTotalAmount(Math.round(loanTenure * emi)); setTotalInterest( Math.round(loanTenure * emi) - loanAmount ); updateData(); }; const updateData = () => { Object.keys(inputRefs).forEach((key) => { inputRefs[key].current.value = parseFloat( inputRefs[key].current.value || 0 ).toFixed(2); }); inputRefs.loanAmount.current.value = loanAmount.toFixed(2); inputRefs.interestRate.current.value = interestRate.toFixed(2); inputRefs.loanTenure.current.value = loanTenure; }; const handleCalculate = () => { calculateEMI(); }; return ( <div className={styles.loanCalculator}> <div className={styles.top}> <h1 className={styles.heading}> Geeksforneveropen </h1> <h3>Loan Calculator</h3> <form action= "#" > {Object.entries(inputRefs).map( ([key, ref]) => ( <div key={key} className={ styles.subContainer } > <div className={styles.title} > {key.replace( /^\w/, (c) => c.toUpperCase() )} </div> <input type= "text" name={key} defaultValue={ key === "interestRate" ? interestRate : key === "loanTenure" ? loanTenure : loanAmount } className={styles[key]} ref={ref} onChange={ handleInputChange } /> </div> ) )} </form> <button className={styles.btn} onClick={handleCalculate} > Calculate </button> </div> <div className={styles.finalResult}> <div className={styles.left}> <div className={styles.loanEMI}> <h3>Loan EMI</h3> <div className={styles.value}> {Math.round(loanEMI)} </div> </div> <div className={styles.totalInterest}> <h3>Total Interest Payable</h3> <div className={styles.value}> {totalInterest} </div> </div> <div className={styles.totalAmount}> <h3>Total Amount</h3> <div className={styles.value}> {totalAmount} </div> </div> </div> </div> </div> ); } |
For styling open Home.module.css file then paste the following code
CSS
/* styles/Home.module.css */ .loanCalculator { font-family : "Roboto" , sans-serif ; width : 80% ; margin : 0 auto ; background : #f0f0f0 ; box-shadow: 15px 15px 30px 15px rgba( 0 , 0 , 0 , 0.1 ); border-radius: 10px ; color : #333 ; overflow : hidden ; margin-top : 5 rem; } .heading { color : #1d8a34 ; font-size : 32px ; margin : 0 ; padding : 24px ; text-align : center ; background : #fff ; } . top { background : #fff ; padding : 24px ; text-align : center ; } . top h 3 { font-size : 24px ; margin : 0 ; } .subContainer { margin-bottom : 16px ; text-align : left ; } .subContainer .title { font-size : 18px ; margin-bottom : 8px ; color : #333 ; } .loanAmount, .interestRate, .loanTenure { font-size : 18px ; padding : 10px ; border-radius: 8px ; width : 100% ; border : 4px solid #ccc ; outline : none ; } .loanAmount:focus, .interestRate:focus, .loanTenure:focus { border-color : #1d8a34 ; } .finalResult { background : #fff ; padding : 24px ; text-align : center ; } .finalResult .value::before { content : "₹" ; font-size : 24px ; font-weight : 400 ; margin-right : 6px ; opacity: 1 ; } .finalResult . left { display : flex; justify- content : space-around; } . left h 3 { font-size : 20px ; margin : 0 ; color : #1d8a34 ; padding : 10px ; } .value { font-size : 32px ; font-weight : 700 ; padding : 12px 24px ; border-radius: 8px ; background : #1d8a34 ; color : #fff ; min-width : 120px ; } .btn { background : #1d8a34 ; color : #fff ; border : none ; padding : 15px 20px ; border-radius: 8px ; font-size : 18px ; font-weight : 700 ; cursor : pointer ; margin : 20px 0 ; transition: background 0.3 s; } .btn:hover { background : #155d27 ; } |
Step 3: To run the next.js application use the following command and then go to this URL http://localhost:3000
npm run dev
Output: