├── .gitignore ├── App.js ├── Components ├── Component │ ├── BookingScreen │ │ ├── ScheduleDateCoursele.js │ │ ├── pendingBookingCoursele.js │ │ └── seats.js │ ├── HomeScreen │ │ ├── HomeButtonComponent.js │ │ └── HomeCarousel.js │ └── InputComponent.js ├── Containers │ ├── SimpleContainer.js │ └── loginContainer.js └── Modals │ ├── CityModal.js │ ├── ComplainModal.js │ ├── TicketPurchasedRefundModal.js │ ├── TicketPurchasingAccountModal.js │ └── TicketPurchasingDoneModal.js ├── Context ├── FireBaseContext.js └── LoginContext.js ├── Data ├── BusSchedule.json ├── Buses.json ├── Cities.json ├── Data.js └── PersonDetail.json ├── Firebase Database.json ├── Functions.js ├── Navigations └── Stacks │ ├── HomeStack.js │ └── LoginStack.js ├── README.md ├── Screen ├── Booking │ ├── BookingBuses.js │ ├── BookingDestination.js │ ├── BookingPending.js │ └── BookingSeats.js ├── Complain │ └── Complain.js ├── Home │ └── Home.js ├── Login │ ├── Login.js │ ├── LoginRegister.js │ ├── LoginRegisterVerify.js │ ├── LoginReset.js │ └── LoginResetNew.js ├── Ticket │ ├── TicketDetail.js │ ├── TicketPurchased.js │ └── TicketPurchasedRefund.js └── wait.js ├── ScreenShot ├── book seat.PNG ├── home.PNG ├── login.PNG └── select bus.PNG ├── Styles └── global.js ├── anchor-coursel ├── carousel.js └── index.js ├── app.json ├── assets ├── Images │ ├── BusLogo.png │ ├── BusLogo1.png │ ├── BusTicketLogo.png │ ├── Buses │ │ ├── Image1.jpg │ │ ├── Image2.jpg │ │ └── Image3.jpg │ ├── Calender.png │ ├── HomeLogo │ │ ├── cart.js │ │ ├── complaint.js │ │ ├── refund.js │ │ ├── safety-seat.js │ │ └── tickets.js │ ├── Icons │ │ ├── Arrival.js │ │ ├── Date.js │ │ ├── DropDown.js │ │ ├── Left.js │ │ ├── Right.js │ │ ├── bin.js │ │ ├── close.js │ │ ├── password.js │ │ ├── propfile.js │ │ └── search.js │ ├── background.jpg │ ├── clock.png │ ├── log.png │ ├── log.svg │ ├── profile.js │ └── seats.js └── fonts │ ├── RussoOne-Regular.ttf │ ├── Teko-Bold.ttf │ ├── Teko-Light.ttf │ ├── Teko-Medium.ttf │ ├── Teko-Regular.ttf │ └── Teko-SemiBold.ttf ├── babel.config.js ├── config.js ├── debug.log ├── package.json ├── react-native.config.js ├── yarn-error.log └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/**/* 2 | .expo/* 3 | npm-debug.* 4 | *.jks 5 | *.p8 6 | *.p12 7 | *.key 8 | *.mobileprovision 9 | *.orig.* 10 | web-build/ 11 | 12 | # macOS 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /App.js: -------------------------------------------------------------------------------- 1 | // React Native Imports 2 | import React, { useState,useEffect } from 'react'; 3 | import { Text,View,Button } from 'react-native'; 4 | // Navigation Related import 5 | import { NavigationContainer } from '@react-navigation/native'; 6 | import HomeStack from './Navigations/Stacks/HomeStack'; 7 | import LoginStack from './Navigations/Stacks/LoginStack'; 8 | // Context 9 | import LoginContextProvider from './Context/LoginContext'; 10 | // Firebase 11 | import firebase from 'firebase'; 12 | import {firebaseConfig} from './config'; 13 | 14 | 15 | if (!firebase.apps.length) { 16 | firebase.initializeApp(firebaseConfig); 17 | }else { 18 | firebase.app(); // if already initialized, use that one 19 | } 20 | 21 | export default function App() { 22 | 23 | /*===== Firebase ================================================= */ 24 | const rootReference=firebase.database().ref(); 25 | 26 | /*===== Firebase ================================================= */ 27 | 28 | 29 | /*===== Required Data ============================================= */ 30 | 31 | /*===================================== Require Data Ends Here===== */ 32 | 33 | 34 | 35 | 36 | 37 | 38 | /*===== State Data ================================================= */ 39 | let [isSignedIn, setSignedIn] = useState(false); 40 | /*=========================================State Data Ends Here===== */ 41 | 42 | 43 | 44 | 45 | 46 | /*===== Function Handlers ========================================== */ 47 | let [Loginperson, setLoginPerson] = useState({}); 48 | const LoginHandler = (person) => { 49 | if (person != "Logout") { 50 | setLoginPerson(person); 51 | setSignedIn(true); 52 | } 53 | else { 54 | setLoginPerson({}); 55 | setSignedIn(false); 56 | } 57 | } 58 | 59 | return ( 60 | 61 | 62 | {isSignedIn ? () : ()} 63 | 64 | 65 | ); 66 | } -------------------------------------------------------------------------------- /Components/Component/BookingScreen/ScheduleDateCoursele.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { View, StyleSheet, TouchableOpacity, Dimensions, Text } from 'react-native'; 3 | // Component 4 | import Carousel from '../../../anchor-coursel/index'; 5 | // Importing Styles 6 | import { GlobalBackgroundColors, GlobalBackgroundTextColors, globalShadowBox, primaryButton } from '../../../Styles/global'; 7 | // Icons 8 | import LeftIcon from '../../../assets/Images/Icons/Left'; 9 | import RightIcon from '../../../assets/Images/Icons/Right'; 10 | 11 | 12 | 13 | 14 | // Global Data 15 | const { width } = Dimensions.get('window'); 16 | var data = []; 17 | 18 | 19 | 20 | 21 | 22 | /*====== Slider Item goes here ================================================================================================== */ 23 | /** 24 | * 25 | * {*Day,*Date} props 26 | */ 27 | function Item(props) { 28 | return ( 29 | 30 | 31 | {props.Day} 32 | {props.Date} 33 | 34 | 35 | ); 36 | } 37 | /*===================================================================================================Slider Item goes here ===== */ 38 | 39 | 40 | 41 | 42 | /** 43 | * {*Date,*DateHandler} 44 | */ 45 | function ScheduleDate(props) { 46 | 47 | data=props.DateSchedule; 48 | 49 | 50 | var numberCarousel; 51 | var currentIndex; 52 | props.DateSchedule.map((item, index) => { 53 | if (item == props.Date) { 54 | currentIndex = index; 55 | } 56 | }) 57 | 58 | 59 | 60 | 61 | 62 | 63 | /*================== Render Item ===============================*/ 64 | var renderItem = ({ item, index }) => { 65 | return ( 66 | pressHandler(index, item)}> 70 | 71 | 72 | ); 73 | }; 74 | /*================== Render Item ================================ */ 75 | 76 | 77 | 78 | 79 | 80 | /*================== Bus Change Handler Item ===================== */ 81 | var pressHandler = (index, item) => { 82 | if (index != currentIndex) // Means you want to see the nex detail 83 | { 84 | currentIndex = index; 85 | numberCarousel.scrollToIndex(currentIndex); 86 | } 87 | else if (index == currentIndex && props.Date != item) // Means you need to change the date 88 | { 89 | props.DateHandler(item); 90 | console.log("You have been gone to the bext date"); 91 | } 92 | } 93 | var previousHandler = () => { 94 | if (currentIndex == 0) { 95 | currentIndex = data.length - 1; 96 | numberCarousel.scrollToIndex(currentIndex); 97 | } 98 | else { 99 | currentIndex--; 100 | numberCarousel.scrollToIndex(currentIndex); 101 | } 102 | } 103 | 104 | var NextHandler = () => { 105 | if (currentIndex == (data.length - 1)) { 106 | currentIndex = 0; 107 | numberCarousel.scrollToIndex(currentIndex); 108 | } 109 | else { 110 | currentIndex++; 111 | numberCarousel.scrollToIndex(currentIndex); 112 | } 113 | } 114 | /*================== Bus Change Handler Item ===================== */ 115 | 116 | 117 | 118 | 119 | 120 | 121 | return ( 122 | 123 | previousHandler()} activeOpacity={0.9}> 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | { 140 | if (c != null) { 141 | numberCarousel = c; 142 | c.scrollToIndex(currentIndex); 143 | } 144 | }} 145 | /> 146 | 147 | NextHandler()} activeOpacity={0.9}> 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | ); 156 | } 157 | const styles = StyleSheet.create({ 158 | carouselStyle: { 159 | } 160 | }) 161 | export default ScheduleDate; -------------------------------------------------------------------------------- /Components/Component/BookingScreen/pendingBookingCoursele.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {StyleSheet,Text,TouchableOpacity,Dimensions,View} from 'react-native'; 3 | import Carousel from '../../../anchor-coursel/index'; 4 | // Imporing Data 5 | // Importing Styles 6 | import { GlobalBackgroundColors, GlobalBackgroundTextColors, globalShadowBox, primaryButton } from '../../../Styles/global'; 7 | 8 | 9 | 10 | 11 | // Global Data 12 | const { width } = Dimensions.get('window'); 13 | var data = {}; 14 | 15 | 16 | 17 | 18 | 19 | 20 | /** 21 | * props(Departure,Arrival,onPress,Date) 22 | */ 23 | function PendingBookingContainer(props) { 24 | return ( 25 | 26 | {/* Departure/Arrival */} 27 | 28 | {props.Departure} 29 | To 30 | {props.Arrival} 31 | 32 | {/* Book Now */} 33 | 34 | {props.Date} 35 | Buy Ticket 36 | 37 | 38 | ); 39 | } 40 | 41 | 42 | 43 | 44 | 45 | /** 46 | * { PhoneNumber={person.PhoneNumber} navigation={navigation} onPress={navigation}} 47 | */ 48 | function ImageCarousel(props) { 49 | data = props.pendingBooking1; 50 | var renderItem = ({ item, index }) => { 51 | return ( 52 | { 56 | numberCarousel.scrollToIndex(index); 57 | }} 58 | > 59 | props.navigation.navigate("TicketDetailScreen", { Bus:item,person:props.person })} Date={item.Date} > 60 | 61 | ); 62 | }; 63 | var numberCarousel; 64 | return ( 65 | { 73 | numberCarousel = c; 74 | }} 75 | /> 76 | ); 77 | } 78 | const styles = StyleSheet.create({ 79 | carouselStyle:{ 80 | flex:1 81 | }, 82 | }) 83 | export default ImageCarousel; -------------------------------------------------------------------------------- /Components/Component/BookingScreen/seats.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MentorUsama/ReactNativeTicketBooking/fd205b22ac084077f8fe1a9a0869a59f3f04e034/Components/Component/BookingScreen/seats.js -------------------------------------------------------------------------------- /Components/Component/HomeScreen/HomeButtonComponent.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, StyleSheet, Text, TouchableOpacity } from 'react-native'; 3 | // Icon 4 | import Icon from 'react-native-vector-icons/Ionicons'; 5 | // Styles 6 | import { GlobalBackgroundColors, GlobalBackgroundTextColors, globalShadowBox } from '../../../Styles/global'; 7 | 8 | /** 9 | * 10 | * In Home screen we will use this as a link to another screen 11 | * {*iconName,*title,*onPress,buttonWidth,buttonHeight} 12 | */ 13 | function HomeButton(props) { 14 | var {buttonWidth=120,buttonHeight=90}=props; 15 | return ( 16 | 17 | 18 | 19 | {props.children} 20 | 21 | 22 | {props.title} 23 | 24 | 25 | 26 | ); 27 | } 28 | 29 | export default HomeButton; -------------------------------------------------------------------------------- /Components/Component/HomeScreen/HomeCarousel.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | StyleSheet, 4 | Text, 5 | TouchableOpacity, 6 | Dimensions, 7 | Image, 8 | View 9 | } from 'react-native'; 10 | import Carousel from '../../../anchor-coursel/index'; 11 | 12 | 13 | /** 14 | * {heightFlex,widthSubtract,carouselStyle 15 | * *data,*renderItem} 16 | */ 17 | const { width } = Dimensions.get('window'); 18 | 19 | 20 | 21 | const data = [ 22 | { url: require("../../../assets/Images/Buses/Image1.jpg") }, 23 | { url: require("../../../assets/Images/Buses/Image2.jpg") }, 24 | { url: require("../../../assets/Images/Buses/Image3.jpg") }, 25 | ]; 26 | function ImageCarousel() { 27 | 28 | var renderItem = ({ item, index }) => { 29 | const { url } = item; 30 | return ( 31 | { 35 | numberCarousel.scrollToIndex(index); 36 | }} 37 | > 38 | 39 | 40 | 41 | ); 42 | }; 43 | var numberCarousel; 44 | return ( 45 | { 54 | numberCarousel = c; 55 | }} 56 | /> 57 | ); 58 | } 59 | 60 | 61 | 62 | 63 | const styles = StyleSheet.create({ 64 | carouselStyle: { 65 | flex: 0.7 66 | }, 67 | item: { 68 | borderWidth: 2, 69 | backgroundColor: 'white', 70 | flex: 1, 71 | borderRadius: 5, 72 | borderColor: 'white', 73 | elevation: 3 74 | }, 75 | imageBackground: { 76 | flex: 2, 77 | backgroundColor: '#EBEBEB', 78 | borderWidth: 5, 79 | borderColor: 'white' 80 | }, 81 | rightTextContainer: { 82 | marginLeft: 'auto', 83 | marginRight: -2, 84 | backgroundColor: 'rgba(49, 49, 51,0.5)', 85 | padding: 3, 86 | marginTop: 3, 87 | borderTopLeftRadius: 5, 88 | borderBottomLeftRadius: 5 89 | }, 90 | rightText: { color: 'white' }, 91 | lowerContainer: { 92 | flex: 1, 93 | margin: 10 94 | }, 95 | titleText: { 96 | fontWeight: 'bold', 97 | fontSize: 18 98 | }, 99 | contentText: { 100 | fontSize: 12 101 | } 102 | }) 103 | export default ImageCarousel; -------------------------------------------------------------------------------- /Components/Component/InputComponent.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { View, TextInput, StyleSheet } from 'react-native'; 3 | 4 | import { GlobalBackgroundColors } from '../../Styles/global'; 5 | 6 | /** 7 | * This is the text input whihc required following things 8 | * {onchange,iconName,value,placeHolder,secure,fullWidth} 9 | */ 10 | var size = [200, 200] 11 | function InputComponent(props) { 12 | const [focusStyle, setFocusStyle] = useState({}); 13 | const { fullWidth = false } = props; 14 | if (fullWidth) 15 | size = ["100%", "90%"]; 16 | 17 | return ( 18 | 19 | 20 | {props.children} 21 | 22 | { props.onchange(text) }} 25 | value={props.value} 26 | placeholder={props.placeHolder} 27 | secureTextEntry={props.secure} 28 | onFocus={() => setFocusStyle({ outline: "none" }) 29 | } 30 | /> 31 | 32 | ) 33 | } 34 | 35 | const styles = StyleSheet.create({ 36 | textInputStyle: { 37 | width: size[1], 38 | height: 40, 39 | borderBottomColor: '#B7B7B7', 40 | borderBottomWidth: 1, 41 | paddingLeft: 30 42 | } 43 | }); 44 | export default InputComponent; 45 | -------------------------------------------------------------------------------- /Components/Containers/SimpleContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, StyleSheet, TouchableOpacity } from 'react-native'; 3 | // Styling 4 | import { GlobalBackgroundColors, GlobalBackgroundTextColors } from '../../Styles/global'; 5 | 6 | 7 | 8 | 9 | /** 10 | * Blue and white screen container 11 | * Props(*isBottomVisible,BottomLeftText,bottomRightLink,BottomRightText,headerContent,headerExtraStyle) 12 | * 13 | */ 14 | 15 | 16 | function SimpleContainer(props) { 17 | var {headerContent=}=props; 18 | var {headerExtraStyle={}}=props; 19 | var {headerFlexSize=35}=props; 20 | var secondFlex=100-headerFlexSize; 21 | return ( 22 | 23 | 24 | 25 | {/* Header Content */} 26 | 27 | {headerContent} 28 | 29 | 30 | 31 | {/* Main Content */} 32 | 33 | 34 | 35 | {/* Main Content */} 36 | 37 | {props.children} 38 | 39 | 40 | 41 | {/* Inner Links */} 42 | {props.isBottomVisible ? 43 | 44 | {props.BottomLeftText} 45 | {props.BottomRightText} 46 | 47 | : } 48 | {/* Inner Links Ends */} 49 | 50 | 51 | 52 | 53 | ); 54 | } 55 | 56 | 57 | const styles = StyleSheet.create({ 58 | userInfoContainer: 59 | { 60 | backgroundColor: GlobalBackgroundColors.ternaryColor, 61 | width: '80%', 62 | flexDirection: 'row', 63 | marginLeft: 'auto', 64 | marginRight: 'auto', 65 | marginTop: -60, 66 | paddingLeft: 10, 67 | borderBottomColor: GlobalBackgroundColors.primaryColor, 68 | borderBottomWidth: 5, 69 | borderTopLeftRadius: 30, 70 | borderTopEndRadius: 30 71 | }, 72 | menueContinerStyle: { 73 | flexDirection: 'row', 74 | justifyContent: 'space-around', 75 | marginTop: 15 76 | }, 77 | bottomLink: { 78 | color: GlobalBackgroundColors.secondaryColor, 79 | fontWeight: 'bold' 80 | } 81 | }) 82 | 83 | export default SimpleContainer; 84 | -------------------------------------------------------------------------------- /Components/Containers/loginContainer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, StyleSheet, Text, Image, TouchableOpacity, ScrollView } from 'react-native'; 3 | // Importing styles 4 | import { GlobalBackgroundColors, GlobalBackgroundTextColors, primaryButton, globalShadowBox, FontFamily } from '../../Styles/global'; 5 | 6 | 7 | 8 | /** 9 | * Container for our (Login,Register,ForgetPassword related all screens) 10 | * Props tha will be passed are {title,leftBottomText,rightBottomText,rightBottomLink,mainButtonText,mainButtonLink} 11 | */ 12 | function LoginContainer(props) { 13 | return ( 14 | 15 | // Overall container 16 | 17 | {/* */} 18 | {/* Header (Containing only title) */} 19 | 20 | {props.title} 21 | 22 | {/* Content Area Container */} 23 | 24 | {/* Everything that is passed as child */} 25 | 26 | 27 | 28 | 29 | 30 | {props.children} 31 | {props.mainButtonText} 32 | 33 | 34 | {/* Bottom Links container */} 35 | 36 | {props.leftBottomText} 37 | {props.rightBottomText} 38 | 39 | 40 | {/* */} 41 | 42 | ) 43 | } 44 | 45 | const styles = StyleSheet.create({ 46 | title: 47 | { 48 | textAlign: "center", 49 | marginTop: 'auto', 50 | marginBottom: 'auto', 51 | color: (GlobalBackgroundTextColors.primaryColor), 52 | 53 | }, 54 | linkBottom: { 55 | color: (GlobalBackgroundColors.secondaryColor), 56 | fontWeight: "bold" 57 | }, 58 | stretch: { 59 | minWidth: 90, 60 | minHeight: 80, 61 | marginBottom: 10 62 | }, 63 | contentArea: { 64 | backgroundColor: (GlobalBackgroundColors.ternaryColor), 65 | flex: 75, 66 | borderTopEndRadius: 100, 67 | paddingTop: 40, 68 | } 69 | }) 70 | export default LoginContainer; -------------------------------------------------------------------------------- /Components/Modals/CityModal.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, Modal, ScrollView, TouchableOpacity, StyleSheet } from 'react-native'; 3 | import SearchIcon from '../../assets/Images/Icons/search'; 4 | import CloseIcon from '../../assets/Images/Icons/close'; 5 | // TextInput 6 | import Input from '../Component/InputComponent'; 7 | import { GlobalBackgroundColors, GlobalBackgroundTextColors, globalShadowBox } from '../../Styles/global'; 8 | 9 | 10 | /** 11 | * 12 | * {searchValue,searchValueChange,modalVisible,modalVisibleChange,finalHandler} props 13 | */ 14 | function CityModal(props) { 15 | return ( 16 | 17 | 18 | 19 | props.modalVisibleChange(false)} style={{ marginTop: 4, marginLeft: 4, marginBottom: 20 }}> 20 | 21 | 22 | 23 | 24 | 25 | {props.data.map((item) => { 26 | if (props.searchValue == '') { 27 | return ( props.finalHandler(item)}>{item}) 28 | } 29 | else { 30 | if (item.includes(props.searchValue)) { 31 | return ( props.finalHandler(item)}>{item}) 32 | } 33 | } 34 | })} 35 | 36 | 37 | 38 | 39 | 40 | ); 41 | } 42 | 43 | const styles = StyleSheet.create({ 44 | City: 45 | { 46 | width: '90%', 47 | marginLeft: 'auto', 48 | marginRight: 'auto', 49 | marginTop: 30, 50 | paddingBottom: 10, 51 | paddingLeft: 5, 52 | borderBottomColor: GlobalBackgroundTextColors.textBoxColor, 53 | borderBottomWidth: 1 54 | } 55 | }) 56 | 57 | export default CityModal; -------------------------------------------------------------------------------- /Components/Modals/ComplainModal.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Button, Text, Modal } from 'react-native'; 3 | import { TouchableOpacity } from 'react-native-gesture-handler'; 4 | // importing syles 5 | import { globalShadowBox, GlobalBackgroundColors, GlobalBackgroundTextColors } from '../../Styles/global' 6 | 7 | function ComplainModal(props) { 8 | return ( 9 | 10 | 11 | 12 | 13 | Your suggestion/complaint has been submitted. We will try to act on it as soon as possible. 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | } 24 | export default ComplainModal; -------------------------------------------------------------------------------- /Components/Modals/TicketPurchasedRefundModal.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {View,Button,Text,Modal} from 'react-native'; 3 | 4 | function TicketPurchasedRefundModal(props) 5 | { 6 | return( 7 | 8 | 9 | Refund Complete "Amount has been transfered to your accounnt" 10 |