Open In App

Tip Calculator using React

Last Updated : 22 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will create a Tip Calculator using ReactJS. This project basically implements functional components and manages the state accordingly using the useState and useEffect hook of ReactJS. The user enters the Bill Amount, Tip Percentage and the number of persons then the output will render dynamically which shows the tip amount per person and total amount(including bill amount) per person. There is also a RESET button that we can render back to the initial state.

Preview of Final Output:

Screenshot-2023-09-22-152056

Tip Calculator using React Preview Image

Prerequisites and Technologies:

  1. ReactJs
  2. CSS
  3. JSX
  4. useState and useEffect Hooks

 

 

Approach:

Tip Calculator component that calculates and displays tip amounts and totals per person based on user input for bill amount, tip percentage, and number of people. It includes interactive input fields, predefined tip percentage options, and a custom input option. The component updates tip calculations in real-time using the useEffect hook and allows users to reset the input fields to their default values with a reset button, providing a simple, interactive, fully responsive and practical tool for calculating tips in a user-friendly manner.

Steps to Create the Project:

Step 1: Set up React project using the command

npx create-react-app <<name of project>>

Step 2: Navigate to the project folder using

cd <<Name_of_project>>

Step 3: Create a folder “components” and add four new files in it and name them TipInput.js, TipResult.js, TipCalculator.js and TipCalculator.css.

Project Structure:

Screenshot-2023-09-20-133217

Project Structure

The updated dependencies in package.json will look like this:

{
"name": "tipcalculator",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
}

Example:

  • App.js: This file imports the TipCalculator components and exports it.
  • TipInput.js: Handles user input for bill amount, tip percentage, and number of people, providing a user-friendly interface for entering data.
  • TipResult.js: Calculates and displays the tip amount per person and the total amount per person based on user input, providing a clear presentation of the calculated results.
  • TipCalculator.js: Serves as the main container component, incorporating both the TipInput and TipResult components, along with a reset button to reset input fields, creating a complete and user-friendly tip calculator application.
  • TipCalculator.css: This file contains the design of the TipCalculator.js elements.

Javascript




// App.js
  
import './App.css';
import TipCalculator from './components/TipCalculator';
  
  
function App() {
  return (
    <div className="App">
      <TipCalculator/>
    </div>
  );
}
  
export default App;


Javascript




// TipCalculator.js
  
import React, { useState } from 'react';
import './TipCalculator.css';
import TipInput from './TipInput';
import TipResult from './TipResult';
  
export default function TipCalculator() {
    const [billAmount, setBillAmount] = useState('');
    const [tipPercent, setTipPercent] = useState('15');
    const [numberOfPerson, setNumberOfPerson] = useState('1');
  
    const handleReset = () => {
        setBillAmount('');
        setTipPercent('15');
        setNumberOfPerson('1');
    }
  
    return (
        <div className="container">
            <TipInput
                billAmount={billAmount}
                setBillAmount={setBillAmount}
                tipPercent={tipPercent}
                setTipPercent={setTipPercent}
                numberOfPerson={numberOfPerson}
                setNumberOfPerson={setNumberOfPerson}
            />
            <TipResult
                billAmount={billAmount}
                tipPercent={tipPercent}
                numberOfPerson={numberOfPerson}
                handleReset={handleReset}
            />
        </div>
    );
}


Javascript




// TipInput.js
  
import React from 'react';
  
export default function TipInput({
    billAmount,
    setBillAmount,
    tipPercent,
    setTipPercent,
    numberOfPerson,
    setNumberOfPerson,
}) {
    return (
        <div className="section1">
            <div className="row">
                <p>Bill Amount</p>
                <span>₹</span>
                <input
                    type='number'
                    value={billAmount}
                    onChange={(e) => { setBillAmount(e.target.value) }}
                />
            </div>
            <div className="row">
                <p>Select Tip</p>
                <ul>
                    <li onClick={(e) => {
                        setTipPercent('5');
                        document.querySelector(".select").classList.remove("select");
                        e.target.classList.add("select");
                    }}>5%</li>
                    <li onClick={(e) => {
                        setTipPercent('10');
                        document.querySelector(".select").classList.remove("select");
                        e.target.classList.add("select");
                    }}>10%</li>
                    <li className="select" onClick={(e) => {
                        setTipPercent('15');
                        document.querySelector(".select").classList.remove("select");
                        e.target.classList.add("select");
                    }}>15%</li>
                    <li onClick={(e) => {
                        setTipPercent('25');
                        document.querySelector(".select").classList.remove("select");
                        e.target.classList.add("select");
                    }}>25%</li>
                    <li onClick={(e) => {
                        setTipPercent('50');
                        document.querySelector(".select").classList.remove("select");
                        e.target.classList.add("select");
                    }}>50%</li>
                    <input
                        type='number'
                        value={tipPercent}
                        placeholder='Custom...'
                        onChange={(e) => setTipPercent(e.target.value)}
                    />
                </ul>
            </div>
            <div className="row">
                <p>Number of People</p>
                <input
                    type='number'
                    value={numberOfPerson}
                    onChange={(e) => setNumberOfPerson(e.target.value)}
                />
            </div>
        </div>
    );
}


Javascript




// TipResult.js
  
import React, { useEffect, useState } from 'react';
  
export default function TipResult({ billAmount, tipPercent, numberOfPerson, handleReset }) {
    const [tipAmountPerPerson, setTipAmountPerPerson] = useState('0.00');
    const [totalPerPerson, setTotalPerPerson] = useState('0.00');
  
    useEffect(() => {
        if (billAmount !== '' && tipPercent !== '' && numberOfPerson !== '') {
            const value1 = (tipPercent * billAmount) / (100 * numberOfPerson);
            setTipAmountPerPerson(value1.toFixed(2));
  
            const value2 = value1 + (billAmount / numberOfPerson);
            setTotalPerPerson(value2.toFixed(2));
        } else {
            setTipAmountPerPerson('0.00');
            setTotalPerPerson('0.00');
        }
    }, [billAmount, tipPercent, numberOfPerson]);
  
    return (
        <div className="section2">
            <div className="row">
                <div>
                    <p>Tip Amount</p>
                    <p>/ person</p>
                </div>
                <div>
                    {tipAmountPerPerson} ₹
                </div>
            </div>
            <div className="row">
                <div>
                    <p>Total</p>
                    <p>/ person</p>
                </div>
                <div>
                    {totalPerPerson} ₹
                </div>
            </div>
            <button className='reset' onClick={handleReset}>RESET</button>
        </div>
    );
}


CSS




/* TipCalculator.css */
body{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    display: flex;
    justify-content: center;
    align-items: center;
    background: rgba(240, 245, 240, 0.66);
    font-family: monospace;
}
  
#root{
    width: 100%;
    margin: 10px;
}
  
.container{
    max-width: 800px;
    margin: auto;
    margin-top: 50px;
    display: grid;
    background-color: #fff;
    grid-template-columns: 1fr 1fr;
    justify-content: center;
    align-items: center;
    padding: 20px;
    border: 1px solid #ccc;
    border-radius: 15px;
    box-shadow: 10px 10px 5px 0px rgba(109, 95, 95, 0.5);
}
  
.section1{
    margin-bottom: 15px;
}
  
.section1 .row{
    width: calc(100% - 50px);
    margin: auto;
}
  
.row p{
    margin: 5px;
    margin-top: 15px;
    text-align: left;
    position: relative;
    font-size: 14px;
}
  
.row span{
    position: absolute;
    padding: 10px 0px 0px 10px;
}
  
.row input{
    width: calc(100% - 25px);
    font-size: 1rem;
    padding: 6px 10px;
    font-weight: 400;
    line-height: 1.5;
    color: #495057;
    outline: none;
    background-color: #fff;
    background-clip: padding-box;
    border: 1px solid #ced4da;
    border-radius: 0.25rem;
    text-align: right;
}
  
.row ul{
    padding-inline-start: 0px;
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-gap: 5px;
    width: 100%;
    margin-top: 0;
}
  
.row ul li{
    list-style-type: none;
    border: 1px solid #ced4da;
    border-radius: 4px;
    padding: 10px;
    cursor: pointer;
    background-color: #1d9bf0;
    color: white;
    font-size: 15px;
    transition: 0.5s background-color ease-in-out;
}
  
.row ul .select{
    background-color: #0a9415;
}
  
.row ul li:hover{
    background-color: #068519;
}
  
.section2{
    margin-top: 10px;
    height: 250px;
    display: flex;
    flex-direction: column;
    border: 1px solid #ced4da;
    border-radius: 8px;
    padding: 20px;
    box-sizing: border-box;
    background-color: #2395e2;
    color: white;
}
  
.reset{
    position: relative;
    bottom: -40px;
    padding: 10px;
    outline: none;
    background-color: #fff;
    color:#1d9bf0;
    border: 2px solid #1d9bf0;
    border-radius: 5px;
    cursor: pointer;
    font-weight: bold;
    transition: 0.5s all;
}
  
.reset:hover{
    color: white;
    background-color: #1d9bf0;
    border-color: white;
    border-width: 2px;
}
  
.section2 .row{
    display: flex;
    justify-content: space-between;
    align-items: center;
}
  
.section2 .row div:last-child{
    font-size: 20px;
}
  
.section2 .row p:last-child{
    margin: 0px 0px 15px 5px;
    font-size: 12px;
}
  
.section2 .row p:first-child{
    font-size: 16px;
}
  
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
    -webkit-appearance: none;
    appearance: none;
    margin: 0; /* This is important for Firefox */
}
  
@media only screen and (max-width : 600px){
    .container{
        grid-template-columns : 1fr;
    }
}


Steps to run the application:

Step 1: Type the following command in terminal

npm start

Step 2: Open web-browser and type the following URL

http://localhost:3000/

Output:

Tip Calculator

Tip Calculator using React GIF



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads