Appointment Booking App using React Native – Part 1

Appointment booking in an important feature, if you want to create an app for listing professionals like hairdresser, dentist, doctors, lawyer, etc.   In this article we will add appointment booking feature to a boiler plate membership app. This boiler plate app is built with React Native and Firebase and has the following features :

  1. Login
  2. Registration
  3. Email verification
  4. User Listing
  5. User’s Profile
  6. In App Messaging
  7. Skill based filter
  8. Distance based filter ( similar to tinder)

You can check the demo of this app here. You can check the features of this app here and if you want, you can get it from here.

So first we will add a ‘Book an appointment’ button to the profile page and link it to the calendar screen. Below is the code for calendar screen :

import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  StatusBar
} from 'react-native';
import Commonstyle from '../../components/commonstyle'
import {Calendar} from 'react-native-calendars';

export default class Calc extends Component {
  constructor(props) {
    super(props);
    this.state = {};
    this.onDayPress = this.onDayPress.bind(this);
  }
  onDayPress(day) {
    this.setState({
      selected: day.dateString
    });
    this.props.navigation.navigate('Slot', { bookingDate : day })
  }
  _onPressBack(){
    const {goBack} = this.props.navigation
      goBack()
  }
  render() {
    return (
      <View style={styles.container}>
      <StatusBar barStyle="light-content"/>
      <View style={Commonstyle.toolbar}>
        <TouchableOpacity onPress={() => this._onPressBack() }><Text style={Commonstyle.toolbarButton}>Back</Text></TouchableOpacity>
                    <Text style={Commonstyle.toolbarTitle}></Text>
                    <Text style={Commonstyle.toolbarButton}></Text>
      </View>
        <Calendar
          onDayPress={this.onDayPress}
          style={styles.calendar}
          hideExtraDays
          markedDates={{[this.state.selected]: {selected: true}}}
          theme={{
            selectedDayBackgroundColor: 'green',
            todayTextColor: 'green',
            arrowColor: 'green',
          }}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1
  },
  calendar: {
    borderTopWidth: 1,
    paddingTop: 5,
    borderBottomWidth: 1,
    borderColor: '#eee',
    height: 350
  }
});

In the above code, we have  created a calendar. On tapping on any of the date of calendar user gets navigated to booking screen and the date which was tapped is passed as parameter.

Below is the code for slot booking screen :

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  StatusBar
} from 'react-native';
import * as firebase from 'firebase'
import Animbutton from '../../components/animbutton'
import Commonstyle from '../../components/commonstyle'
const jsonData = { "slots" : {
    "slot1": "9:00am to 9:30am",
    "slot2": "9:30am to 10:00am",
    "slot3": "10:00am to 10:30am",
    "slot4": "10:30am to 11:00am",
    "slot5": "11:00am to 11:30am",
    "slot6": "11:30am to 12:00pm"
 }
}
export default class Slot extends Component {
  constructor(props) {
     super(props);
     this.state ={
       bookingDate: this.props.navigation.state.params.bookingDate
     }

   }
  _onPressBack(){
    const {goBack} = this.props.navigation
    goBack()
  }
  _bookSlot(status,key,value){
    const month = this.state.bookingDate.month
    const date = this.state.bookingDate.day
    const user = firebase.auth().currentUser
    const uid = user.uid
    let userDataJson = {}
    if(status)
    userDataJson[key] = uid
    else
    userDataJson[key] = null

    firebase.database().ref('users').child(uid).child("appointments").child(month).child(date).update(userDataJson)
  }
  render() {
    let _this = this
    const slots = jsonData.slots
    const slotsarr = Object.keys(slots).map( function(k) {
      return (  <View key={k} style={{margin:5}}>
                  <Animbutton countCheck={0} onColor={"green"} effect={"pulse"} _onPress={(status) => _this._bookSlot(status,k,slots[k]) } text={slots[k]} />
                </View>)
    });
    return (
      <View style={styles.container}>
      <StatusBar barStyle="light-content"/>
      <View style={Commonstyle.toolbar}>
        <TouchableOpacity onPress={() => this._onPressBack() }><Text style={Commonstyle.toolbarButton}>Back</Text></TouchableOpacity>
                    <Text style={Commonstyle.toolbarTitle}></Text>
                    <Text style={Commonstyle.toolbarButton}></Text>
      </View>
      { slotsarr }
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1
  }
});

In the above code, we have saved the booking slots in ‘jsonData’, a json constant . To keep things dynamic you can save the slots in DB.  For booking slots we are using animated toggle button(that we create in our previous tutorial).  When user makes a booking, tapping the animated button, we save the booking status in database. Also, if user taps booked slot we delete the booking from database and booking toggle button slot is unmarked.