Open In App

Create a Tip Calculator using React-Native

Last Updated : 06 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

A Tip Calculator proves to be a convenient tool for effortlessly calculating tips and dividing bills among friends at restaurants. The app enables users to input the bill amount, select their desired tip perce­ntage, specify the numbe­r of people sharing the bill, and promptly obtain calculate­d values for both the tip and total amounts

Preview of final output: Let us have a look at how the final output will look like.

Create-a-Tip-Calculator-using-React-Native

Prerequisites:

Steps to Create React Native Application:

Step 1: Create a react native application by using this command

npx create-react-native-app TipCalculator

Step 2: After creating your project folder, i.e. TipCalculator, use the following command to navigate to it:

cd TipCalculator

Approach :

  • We are using the useState hook to manage the state of various input fields and calculated values.
  • Functions such as handleBillAmountChange­, handleCustomTipChange, handleNumbe­rOfPeopleChange, and handle­TipButtonClick were create­d to effectively manage­ input changes and update rele­vant state variables
  • The calculate­Bill function performs the computation of the tip amount, total bill, and individual share­s based on the provided input value­s.
  • The UI layout in this conte­xt is constructed by utilizing a ScrollView alongside various Vie­w components. Label display and input fields are­ facilitated through the utilization of Text and Te­xtInput components.

Project Structure:

Screenshot-(196)

Project Structure

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

"dependencies": {
"react-native-paper": "4.9.2",
"@expo/vector-icons": "^13.0.0"
}

Example: In this example, we’ll use react native to to build a Tip calculator.

Javascript




// App.js
  
import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, ScrollView } from 'react-native';
import { styles } from "./styles";
  
export default function BillSplitter() {
  const [billAmount, setBillAmount] = useState('');
  const [customTip, setCustomTip] = useState('');
  const [numberOfPeople, setNumberOfPeople] = useState('');
  const [tipPercentage, setTipPercentage] = useState(0);
  const [tipAmount, setTipAmount] = useState('');
  const [totalBill, setTotalBill] = useState('');
  const [eachPersonBill, setEachPersonBill] = useState('');
  
  const handleBillAmountChange = (value) => {
    const amount = parseFloat(value);
  
    if (!isNaN(amount) && amount >= 0) {
      setBillAmount(amount.toFixed(2));
      setCustomTip('');
      setTipPercentage(0);
      setTipAmount('');
      setTotalBill('');
      setEachPersonBill('');
    } else {
      // Handle negative or invalid input
      setBillAmount('');
    }
  };
  
  const handleCustomTipChange = (value) => {
    const custom = parseFloat(value);
  
    if (!isNaN(custom) && custom >= 0) {
      setCustomTip(custom.toString());
      setTipPercentage(custom);
      setTipAmount('');
      setTotalBill('');
      setEachPersonBill('');
    } else {
      // Handle negative or invalid input
      setCustomTip('');
    }
  };
  
  const handleNumberOfPeopleChange = (value) => {
    const people = parseInt(value);
  
    if (!isNaN(people) && people >= 0) {
      setNumberOfPeople(people);
    } else {
      // Handle negative or invalid input
      setNumberOfPeople('');
    }
  };
  
  const handleTipButtonClick = (percentage) => {
    setTipPercentage(percentage);
    setCustomTip(percentage.toString()); // Set the custom tip input to the selected percentage
  };
  
  const calculateBill = () => {
    const bill = parseFloat(billAmount);
    const tip = (bill * tipPercentage) / 100;
    const total = bill + tip;
    const eachPerson = total / parseFloat(numberOfPeople);
  
    setTipAmount(`₹${tip.toFixed(2)}`);
    setTotalBill(`₹${total.toFixed(2)}`);
    setEachPersonBill(`₹${eachPerson.toFixed(2)}`);
  };
  
  return (
    <ScrollView contentContainerStyle={styles.container}>
      <View style={styles.billInput}>
        <Text style={styles.text} >Bill</Text>
        <View style={styles.inputContainer}>
          <Text >₹</Text>
          <TextInput
            style={styles.input}
            keyboardType="numeric"
            value={billAmount}
            onChangeText={handleBillAmountChange}
          />
        </View>
        <Text  style={styles.text} >Select Tip</Text>
        <View style={styles.tipContainer}>
          <TouchableOpacity
            style={[styles.tip, tipPercentage === 5 ? styles.selected : null]}
            onPress={() => handleTipButtonClick(5)}
          >
            <Text style={styles.tipText} >5%</Text>
          </TouchableOpacity>
          <TouchableOpacity
            style={[styles.tip, tipPercentage === 10 ? styles.selected : null]}
            onPress={() => handleTipButtonClick(10)}
          >
            <Text  style={styles.tipText}>10%</Text>
          </TouchableOpacity>
          <TouchableOpacity
            style={[styles.tip, tipPercentage === 15 ? styles.selected : null]}
            onPress={() => handleTipButtonClick(15)}
          >
            <Text  style={styles.tipText}>15%</Text>
          </TouchableOpacity>
          <TouchableOpacity
            style={[styles.tip, tipPercentage === 25 ? styles.selected : null]}
            onPress={() => handleTipButtonClick(25)}
          >
            <Text  style={styles.tipText}>25%</Text>
          </TouchableOpacity>
          <TouchableOpacity
            style={[styles.tip, tipPercentage === 50 ? styles.selected : null]}
            onPress={() => handleTipButtonClick(50)}
          >
            <Text  style={styles.tipText}>50%</Text>
          </TouchableOpacity>
          <TouchableOpacity
            style={[styles.tip, tipPercentage === 75 ? styles.selected : null]}
            onPress={() => handleTipButtonClick(75)}
          >
            <Text  style={styles.tipText}>75%</Text>
          </TouchableOpacity>
        </View>
        <TextInput
          style={styles.customTip}
          placeholder="Custom Tip in Percentage"
          keyboardType="numeric"
          value={customTip}
          onChangeText={handleCustomTipChange}
        />
        <Text  style={styles.text} >Number of People</Text>
        <TextInput
          style={styles.numberOfPeople}
          placeholder="Number of people"
          keyboardType="numeric"
          value={numberOfPeople}
          onChangeText={handleNumberOfPeopleChange}
        />
        <TouchableOpacity
          style={styles.generateBillBtn}
          onPress={calculateBill}
          disabled={!billAmount || !numberOfPeople || !tipPercentage}
        >
          <Text style={styles.generateBillBtnText}>Generate Bill</Text>
        </TouchableOpacity>
      </View>
      <View style={styles.billOutput}>
        <Text style={styles.tipAmount}>
          Tip amount <Text style={styles.value}>{tipAmount}</Text>
        </Text>
        <Text style={styles.total}>
          Total <Text style={styles.value}>{totalBill}</Text>
        </Text>
        <Text style={styles.eachPersonBill}>
          Each Person Bill <Text style={styles.value}>{eachPersonBill}</Text>
        </Text>
        <TouchableOpacity
          style={styles.resetBtn}
          onPress={() => handleBillAmountChange('')}
          disabled={!billAmount}
        >
          <Text style={styles.resetBtnText}>Reset</Text>
        </TouchableOpacity>
      </View>
    </ScrollView>
  );
}


Javascript




// index.js
  
import { StyleSheet } from 'react-native';
  
const styles = StyleSheet.create({
  
 container: {
    flex: 1,
    padding: 20,
    backgroundColor: '#fff',
  },
  billInput: {
    marginBottom: 20,
  },
  text:{
    fontSize: 16,
    fontWeight: 'bold',
    paddingLeft:10,
  },
  inputContainer: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  input: {
    flex: 1,
    borderColor: '#ccc',
    borderWidth: 1,
    padding: 10,
    borderRadius: 4,
    fontSize: 20,
    marginVertical: 10,
  },
  tipContainer: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'space-between',
    marginBottom: 12,
  },
  tip: {
    width: '30%',
    backgroundColor: '#2395e2',
    borderRadius: 5,
    textAlign: 'center',
    padding: 10,
    marginVertical: 5,
  },
  selected: {
    backgroundColor: 'green',
  },
  customTip: {
    borderColor: '#ccc',
    borderWidth: 1,
    padding: 10,
    borderRadius: 4,
    fontSize: 16,
    marginVertical: 10,
  },
  numberOfPeople: {
    borderColor: '#ccc',
    borderWidth: 1,
    padding: 10,
    borderRadius: 4,
    fontSize: 16,
    marginVertical: 10,
  },
  generateBillBtn: {
    width: '100%',
    height: 40,
    backgroundColor: '#2395e2',
    borderRadius: 7,
    alignItems: 'center',
    justifyContent: 'center',
    marginVertical: 16,
  },
  generateBillBtnText: {
    color: 'white',
    fontSize: 16,
    fontWeight: 'bold',
  },
  billOutput: {
    marginVertical: 15,
    padding: 20,
    backgroundColor: '#2395e2',
    borderRadius: 8,
    color: 'white',
  },
  tipAmount: {
    marginBottom: 10,
    color:"white",
    fontWeight:"bold",
  },
  tipText:{
    color:"white",
    fontWeight:"bold",
  },
  total: {
    marginBottom: 10,
    color:"white",
    fontWeight:"bold",
  },
  value:{
    color:"white",
    fontWeight:"bold",
    paddingLeft:10,
    fontSize: 19,
  },
  eachPersonBill:{
    color:"white",
    fontWeight:"bold",
  },
  resetBtn: {
    padding: 12,
    borderRadius: 5,
    backgroundColor: 'red',
    alignItems: 'center',
    justifyContent: 'center',
    marginTop: 10,
  },
  resetBtnText: {
    color: 'white',
    fontSize: 16,
    fontWeight: 'bold',
  },
     
});
  
export { styles }


Steps to Run the application:

Step 1:To run react native application use the following command:

npx expo start

Step 2: Depending on your Operating System type the following command.

  • To run on Android:
npx react-native run-android
  • To run on iOS:
npx react-native run-ios

Output:

Create-a-Tip-Calculator-using-React-Native



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads