Create a Tip Calculator using React-Native
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 percentage, specify the number of people sharing the bill, and promptly obtain calculated 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.
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, handleNumberOfPeopleChange, and handleTipButtonClick were created to effectively manage input changes and update relevant state variables
- The calculateBill function performs the computation of the tip amount, total bill, and individual shares based on the provided input values.
- The UI layout in this context is constructed by utilizing a ScrollView alongside various View components. Label display and input fields are facilitated through the utilization of Text and TextInput components.
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: