├── src
├── screens
│ ├── home
│ │ ├── style.js
│ │ └── index.js
│ ├── profile
│ │ ├── style.js
│ │ └── index.js
│ ├── setting
│ │ ├── style.js
│ │ └── index.js
│ ├── car
│ │ ├── listYourCar
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── pastBookingScreen
│ │ │ └── index.js
│ │ ├── reserveCar
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ ├── drivingScreen
│ │ │ ├── styles.js
│ │ │ └── index.js
│ │ └── index.js
│ └── index.js
├── utilities
│ ├── Consants
│ │ ├── Strings.js
│ │ ├── Colors.js
│ │ └── apiKey.js
│ ├── Constants.js
│ ├── AppStatusBar.js
│ ├── ImagePicker.js
│ ├── DatePicker.js
│ ├── dummyData
│ │ └── index.js
│ └── AppUtils.js
├── actions
│ ├── types.js
│ ├── reservedCar.js
│ ├── returnedCar.js
│ └── rentCarList.js
├── reducers
│ ├── index.js
│ ├── reservedCar.js
│ ├── returnedCar.js
│ └── myCarList.js
├── customHooks
│ └── useForm.js
├── Main.js
├── components
│ ├── carListWrapper
│ │ ├── styles.js
│ │ └── index.js
│ ├── pastBookingItem
│ │ ├── index.js
│ │ └── styles.js
│ ├── carItem
│ │ ├── styles.js
│ │ └── index.js
│ └── activeCar
│ │ ├── styles.js
│ │ └── index.js
├── store.js
└── styles
│ └── global.js
├── assets
├── car.png
├── end.png
├── icon.png
├── lock.png
├── time.png
├── favicon.png
├── splash.png
├── car_image.png
├── lock_open.png
├── reserved.png
└── adaptive-icon.png
├── babel.config.js
├── .expo-shared
└── assets.json
├── .gitignore
├── App.js
├── app.json
├── README.md
└── package.json
/src/screens/home/style.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/screens/profile/style.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/screens/setting/style.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/utilities/Consants/Strings.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/car.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hamzaahmed95/car_rental_app_react_native/HEAD/assets/car.png
--------------------------------------------------------------------------------
/assets/end.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hamzaahmed95/car_rental_app_react_native/HEAD/assets/end.png
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hamzaahmed95/car_rental_app_react_native/HEAD/assets/icon.png
--------------------------------------------------------------------------------
/assets/lock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hamzaahmed95/car_rental_app_react_native/HEAD/assets/lock.png
--------------------------------------------------------------------------------
/assets/time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hamzaahmed95/car_rental_app_react_native/HEAD/assets/time.png
--------------------------------------------------------------------------------
/src/utilities/Constants.js:
--------------------------------------------------------------------------------
1 | export const name = "hamza";
2 | export const statusBarColor = "#56CCF2";
3 |
--------------------------------------------------------------------------------
/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hamzaahmed95/car_rental_app_react_native/HEAD/assets/favicon.png
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hamzaahmed95/car_rental_app_react_native/HEAD/assets/splash.png
--------------------------------------------------------------------------------
/assets/car_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hamzaahmed95/car_rental_app_react_native/HEAD/assets/car_image.png
--------------------------------------------------------------------------------
/assets/lock_open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hamzaahmed95/car_rental_app_react_native/HEAD/assets/lock_open.png
--------------------------------------------------------------------------------
/assets/reserved.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hamzaahmed95/car_rental_app_react_native/HEAD/assets/reserved.png
--------------------------------------------------------------------------------
/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Hamzaahmed95/car_rental_app_react_native/HEAD/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | };
6 | };
7 |
--------------------------------------------------------------------------------
/.expo-shared/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
3 | "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
4 | }
5 |
--------------------------------------------------------------------------------
/.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 |
--------------------------------------------------------------------------------
/src/actions/types.js:
--------------------------------------------------------------------------------
1 | export const GET_ALL_CARS = "GET_ALL_CARS";
2 | export const CREATE_A_CAR = "CREATE_A_CAR";
3 | export const RESERVE_CAR = "RESERVE_CAR";
4 | export const RETURN_CAR = "RETURN_CAR";
5 | export const GET_MY_PAST_BOOKINGS = "GET_MY_PAST_BOOKINGS";
6 |
--------------------------------------------------------------------------------
/src/reducers/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from "redux";
2 | import my_car from "./myCarList";
3 | import reserve_car from "./reservedCar";
4 | import returned_car from "./returnedCar";
5 |
6 | export default combineReducers({
7 | my_car,
8 | reserve_car,
9 | returned_car
10 | });
11 |
--------------------------------------------------------------------------------
/src/utilities/Consants/Colors.js:
--------------------------------------------------------------------------------
1 | export const appBackgrounColor = "#ffffff";
2 | export const appColor = "#56CCF2";
3 | export const btnFontColor = "#ffffff";
4 | export const appFontColor = "#000000";
5 | export const appDisableColor = "rgba(0, 0, 0, 0.6)";
6 | export const appDecisionMakingBtnColor = "#2F80ED";
7 |
--------------------------------------------------------------------------------
/src/customHooks/useForm.js:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | export const useForm = initialValues => {
3 | const [values, setValues] = useState(initialValues);
4 |
5 | return [
6 | values,
7 | (name, value) => {
8 | setValues({
9 | ...values,
10 | [name]: value
11 | });
12 | }
13 | ];
14 | };
15 |
--------------------------------------------------------------------------------
/src/reducers/reservedCar.js:
--------------------------------------------------------------------------------
1 | const initialState = {
2 | isDataLoaded: false
3 | };
4 |
5 | export default function (state = initialState, action) {
6 | switch (action.type) {
7 | case "RESERVE_CAR":
8 | return {
9 | ...state,
10 | isDataLoaded: action.payload
11 | };
12 | default:
13 | return state;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/reducers/returnedCar.js:
--------------------------------------------------------------------------------
1 | const initialState = {
2 | pastCar: [],
3 | status: false
4 | };
5 |
6 | export default function (state = initialState, action) {
7 | switch (action.type) {
8 | case "PAST":
9 | return {
10 | ...state,
11 | pastCar: action.payload
12 | };
13 | default:
14 | return state;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Main.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Text, View } from "react-native";
3 | import Screens from "./screens";
4 | import store from "./store";
5 | import { Provider } from "react-redux";
6 |
7 | const Main = () => {
8 | return (
9 |
10 |
11 |
12 | );
13 | };
14 |
15 | export default Main;
16 |
--------------------------------------------------------------------------------
/src/components/carListWrapper/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet, StatusBar } from "react-native";
2 |
3 | export const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | marginTop: StatusBar.currentHeight || 0
7 | },
8 | item: {
9 | padding: 20,
10 | marginVertical: 8,
11 | marginHorizontal: 16,
12 | color: "black"
13 | },
14 | title: {
15 | fontSize: 32
16 | }
17 | });
18 |
--------------------------------------------------------------------------------
/src/store.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware } from "redux";
2 | import { composeWithDevTools } from "redux-devtools-extension";
3 | import thunk from "redux-thunk";
4 | import rootReducer from "./reducers";
5 |
6 | const initialState = {};
7 |
8 | const middleware = [thunk];
9 |
10 | const store = createStore(
11 | rootReducer,
12 | initialState,
13 | composeWithDevTools(applyMiddleware(...middleware))
14 | );
15 |
16 | export default store;
17 |
--------------------------------------------------------------------------------
/src/utilities/Consants/apiKey.js:
--------------------------------------------------------------------------------
1 | export const firebaseConfig = {
2 | apiKey: "AIzaSyDEJMBlridzimKpNKvpYbM1iedg7RCnKdM",
3 | authDomain: "socar-3b084.firebaseapp.com",
4 | databaseURL: "https://socar-3b084-default-rtdb.firebaseio.com",
5 | projectId: "socar-3b084",
6 | storageBucket: "socar-3b084.appspot.com",
7 | messagingSenderId: "168562982707",
8 | appId: "1:168562982707:web:02680135d0325d3a228846",
9 | measurementId: "G-N3EWN5ZDH6"
10 | };
11 |
--------------------------------------------------------------------------------
/src/reducers/myCarList.js:
--------------------------------------------------------------------------------
1 | const initialState = {
2 | myCar: [],
3 | status: false
4 | };
5 |
6 | export default function (state = initialState, action) {
7 | switch (action.type) {
8 | case "GET_ALL_CARS":
9 | return {
10 | ...state,
11 | myCar: action.payload
12 | };
13 | case "CREATE_A_CAR":
14 | return {
15 | ...state,
16 | status: action.payload
17 | };
18 | default:
19 | return state;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/screens/home/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View } from "react-native";
3 | import AppStatusBar from "../../utilities/AppStatusBar";
4 | import { commonNavigation } from "../../utilities/AppUtils";
5 |
6 | const Home = props => {
7 | return (
8 |
9 |
10 |
11 | );
12 | };
13 | Home.navigationOptions = commonNavigation("Home");
14 |
15 | export default Home;
16 |
--------------------------------------------------------------------------------
/src/screens/profile/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Text, View } from "react-native";
3 | import AppStatusBar from "../../utilities/AppStatusBar";
4 | import { commonNavigation } from "../../utilities/AppUtils";
5 |
6 | const Profile = props => {
7 | return (
8 |
9 |
10 |
11 | {Profile}
12 |
13 | );
14 | };
15 | Profile.navigationOptions = commonNavigation("Profile");
16 |
17 | export default Profile;
18 |
--------------------------------------------------------------------------------
/src/screens/setting/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Text, View } from "react-native";
3 | import AppStatusBar from "../../utilities/AppStatusBar";
4 | import { commonNavigation } from "../../utilities/AppUtils";
5 |
6 | const Setting = props => {
7 | return (
8 |
9 |
10 |
11 | {Setting}
12 |
13 | );
14 | };
15 | Setting.navigationOptions = commonNavigation("Setting");
16 |
17 | export default Setting;
18 |
--------------------------------------------------------------------------------
/src/utilities/AppStatusBar.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { StyleSheet, StatusBar, View } from "react-native";
3 | import { statusBarColor } from "../utilities/Constants";
4 |
5 | const AppStatusBar = ({ backgroundColor, ...props }) => {
6 | return (
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | const BAR_HEIGHT = StatusBar.currentHeight;
14 |
15 | const styles = StyleSheet.create({
16 | statusBar: {
17 | height: BAR_HEIGHT
18 | }
19 | });
20 |
21 | export default AppStatusBar;
22 |
--------------------------------------------------------------------------------
/App.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from "react";
2 | import MainApp from "./src/Main";
3 | import Toast from "react-native-toast-message";
4 |
5 | import { firebaseConfig } from "./src/utilities/Consants/apiKey";
6 | import firebase from "firebase/app";
7 |
8 | export default class App extends Component {
9 | constructor(props) {
10 | super(props);
11 | if (!firebase.apps.length) {
12 | firebase.initializeApp(firebaseConfig);
13 | } else {
14 | firebase.app(); // if already initialized, use that one
15 | }
16 | }
17 | render() {
18 | return (
19 | <>
20 |
21 | Toast.setRef(ref)} />
22 | >
23 | );
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/components/carListWrapper/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import CarItem from "../carItem/index";
3 | import { SafeAreaView, FlatList, StatusBar } from "react-native";
4 |
5 | //lit of rent a car
6 | const CarList = props => {
7 | return (
8 |
14 | (
17 |
23 | )}
24 | />
25 |
26 | );
27 | };
28 |
29 | export default CarList;
30 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "socar",
4 | "slug": "socar",
5 | "version": "1.0.0",
6 | "platforms": ["ios", "android"],
7 | "orientation": "portrait",
8 | "icon": "./assets/icon.png",
9 | "splash": {
10 | "image": "./assets/splash.png",
11 | "resizeMode": "contain",
12 | "backgroundColor": "#ffffff"
13 | },
14 | "updates": {
15 | "fallbackToCacheTimeout": 1500
16 | },
17 | "assetBundlePatterns": ["**/*"],
18 | "ios": {
19 | "supportsTablet": true
20 | },
21 | "android": {
22 | "adaptiveIcon": {
23 | "foregroundImage": "./assets/adaptive-icon.png",
24 | "backgroundColor": "#FFFFFF"
25 | }
26 | },
27 | "web": {
28 | "favicon": "./assets/favicon.png"
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CAR RENTAL APP
2 |
3 | A cross platform car rental app built on react native
4 |
5 |
6 |
7 | ## Features
8 |
9 | 1. Users can list their cars on rent
10 | 2. Users can book for cars per hours
11 | 3. Users can view previous bookings
12 |
13 | ## Development Environment /Tools/Languages
14 | 1. ReactNative v0.63
15 | 2. Material Ui v4.11.2
16 | 3. React hooks
17 | 4. Redux v^7.2.2
18 | 5. Firebase v^8.2.2
19 | 6. Moment v^2.29.1
20 | 7. ReactNavigationStack v^2.10.1
21 | 8. ReduxThunk v^2.3.0
22 |
23 | ## Getting Started
24 | ```bash
25 | git clone
26 | cd
27 | yarn install //install all the dependencies using yarn
28 | npm start //run your react native app
29 | ```
30 |
--------------------------------------------------------------------------------
/src/actions/reservedCar.js:
--------------------------------------------------------------------------------
1 | import firebase from "firebase";
2 | import { RESERVE_CAR } from "./types";
3 |
4 | import Toast from "react-native-toast-message";
5 |
6 | export const reserve_car = (registeredCar, props) => dispatch => {
7 | let registeredCarRef = firebase.database().ref("registeredCar");
8 | let newCarRegisteredRef = registeredCarRef.push();
9 | newCarRegisteredRef
10 | .set(registeredCar)
11 | .then(() => {
12 | dispatch({
13 | type: RESERVE_CAR,
14 | payload: true
15 | });
16 | setTimeout(() => {
17 | props.navigation.goBack();
18 | Toast.show({
19 | text1: "Congrats",
20 | text2: "Car has been registered 👋"
21 | });
22 | }, 2000);
23 | })
24 | .catch(err =>
25 | dispatch({
26 | type: RESERVE_CAR,
27 | payload: false
28 | })
29 | );
30 | };
31 |
--------------------------------------------------------------------------------
/src/utilities/ImagePicker.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import {
3 | Button,
4 | Image,
5 | View,
6 | TouchableOpacity,
7 | Platform,
8 | Text
9 | } from "react-native";
10 |
11 | import { globalStyles } from "../styles/global";
12 | import Constants from "expo-constants";
13 | import { MaterialCommunityIcons } from "@expo/vector-icons";
14 |
15 | const ImagePickerComp = props => {
16 | return (
17 |
18 | {!props.image ? (
19 |
20 | Upload car images
21 |
22 |
23 | ) : (
24 |
25 | )}
26 |
27 | );
28 | };
29 | export default ImagePickerComp;
30 |
--------------------------------------------------------------------------------
/src/screens/car/listYourCar/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from "react-native";
2 | export const styles = StyleSheet.create({
3 | container: {
4 | flex: 1,
5 | justifyContent: "flex-start"
6 | },
7 | container1: {
8 | flex: 1,
9 | justifyContent: "space-between",
10 | flexDirection: "row"
11 | },
12 | containerSub: {
13 | flexDirection: "row",
14 | alignItems: "baseline"
15 | },
16 | input: {
17 | width: "50%",
18 | borderWidth: 1,
19 | borderColor: "#ddd",
20 | padding: 10,
21 | margin: 2,
22 | fontSize: 18,
23 | borderRadius: 6
24 | },
25 | inputs: {
26 | flexBasis: "48%",
27 | marginBottom: 10,
28 | marginTop: 10,
29 | borderWidth: 1,
30 | paddingLeft: 10,
31 | borderColor: "#3B5998",
32 | fontSize: 18,
33 | borderRadius: 6
34 | },
35 | animatedCircular: {
36 | flex: 1,
37 | justifyContent: "center",
38 | alignItems: "center"
39 | }
40 | });
41 |
--------------------------------------------------------------------------------
/src/utilities/DatePicker.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { StyleSheet, View, Text } from "react-native";
3 | import moment from "moment";
4 | import DateRangePicker from "react-native-daterange-picker";
5 |
6 | export default class DatePicker extends React.Component {
7 | constructor(props) {
8 | super(props);
9 | this.state = {
10 | startDate: null,
11 | endDate: null,
12 | displayedDate: moment()
13 | };
14 | }
15 |
16 | setDates = dates => {
17 | this.setState({
18 | ...dates
19 | });
20 | };
21 |
22 | render() {
23 | const { startDate, endDate, displayedDate } = this.state;
24 | return (
25 |
26 |
33 | Click me!
34 |
35 |
36 | );
37 | }
38 | }
39 |
40 | const styles = StyleSheet.create({
41 | container: {
42 | backgroundColor: "#fff"
43 | }
44 | });
45 |
--------------------------------------------------------------------------------
/src/screens/car/pastBookingScreen/index.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import { Text, View } from "react-native";
3 | import { SafeAreaView, FlatList } from "react-native";
4 | import PastBookingItem from "../../../components/pastBookingItem/index";
5 | import { getMyPastBooking } from "../../../actions/returnedCar";
6 | import { connect } from "react-redux";
7 |
8 | const PastBookingScreen = props => {
9 | useEffect(() => {
10 | props.getMyPastBooking();
11 | }, []);
12 | return (
13 |
14 |
15 | (
18 |
25 | )}
26 | />
27 |
28 |
29 | );
30 | };
31 |
32 | const mapStateToProps = state => ({
33 | past_car: state.returned_car.pastCar
34 | });
35 |
36 | export default connect(mapStateToProps, { getMyPastBooking })(
37 | PastBookingScreen
38 | );
39 |
--------------------------------------------------------------------------------
/src/components/pastBookingItem/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { View, Text, Image, TouchableOpacity } from "react-native";
3 | import { styles } from "./styles";
4 |
5 | const PastBookingItem = props => {
6 | return (
7 |
8 |
9 |
13 |
14 | {props.name}
15 | {props.color}
16 | Available
17 |
18 |
19 |
26 |
27 | MYR 20.00 / HR
28 |
29 | console.log("clicked!")}>
30 | Check Details
31 |
32 |
33 |
34 | );
35 | };
36 |
37 | export default PastBookingItem;
38 |
--------------------------------------------------------------------------------
/src/actions/returnedCar.js:
--------------------------------------------------------------------------------
1 | import firebase from "firebase";
2 | import { RETURN_CAR } from "./types";
3 |
4 | import Toast from "react-native-toast-message";
5 |
6 | export const returned_car = (pastBooking, props) => dispatch => {
7 | let pastBookingRef = firebase.database().ref("pastBooking");
8 | let newPastBookingRef = pastBookingRef.push();
9 | newPastBookingRef
10 | .set(pastBooking)
11 | .then(() => {
12 | dispatch({
13 | type: RETURN_CAR,
14 | payload: true
15 | });
16 | setTimeout(() => {
17 | props.navigation.goBack();
18 | Toast.show({
19 | text1: "Congrats",
20 | text2: "Car has been safely returned 👋"
21 | });
22 | }, 2000);
23 | })
24 | .catch(err =>
25 | dispatch({
26 | type: RETURN_CAR,
27 | payload: false
28 | })
29 | );
30 | };
31 |
32 | export const getMyPastBooking = () => dispatch => {
33 | firebase
34 | .database()
35 | .ref("pastBooking")
36 | .orderByChild("name")
37 | .on("value", snapshot => {
38 | let dataList = [];
39 | snapshot.forEach(child => {
40 | dataList.push(child.val());
41 | });
42 | dispatch({
43 | type: "PAST",
44 | payload: dataList
45 | });
46 | });
47 | };
48 |
--------------------------------------------------------------------------------
/src/screens/car/reserveCar/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from "react-native";
2 |
3 | export const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | backgroundColor: "#fff",
7 | flexDirection: "column"
8 | },
9 | subcontainer: {
10 | backgroundColor: "#56CCF2",
11 | alignItems: "center",
12 | width: "100%"
13 | },
14 | tinyLogo: {
15 | width: 20.61,
16 | marginRight: 10,
17 | height: 20
18 | },
19 | content: {
20 | fontSize: 14,
21 | marginTop: 30,
22 | color: "black",
23 | fontWeight: "bold",
24 | fontFamily: "Roboto"
25 | },
26 | buttonContent: {
27 | fontFamily: "Roboto",
28 | fontSize: 16,
29 | color: "black"
30 | },
31 | buttonContainer: {
32 | backgroundColor: "#ffffff",
33 | marginTop: 15,
34 | paddingLeft: 15,
35 | flexDirection: "row",
36 | marginBottom: 15,
37 | alignItems: "center",
38 | justifyContent: "flex-start",
39 | width: 328,
40 | height: 46
41 | },
42 | buttonBottomContainer: {
43 | backgroundColor: "#56CCF2",
44 | marginTop: 10,
45 | alignItems: "center",
46 | justifyContent: "center",
47 | width: 143,
48 | height: 36
49 | },
50 | bottomContainer: {
51 | paddingBottom: 50,
52 | position: "absolute",
53 | alignItems: "center",
54 | bottom: 0
55 | }
56 | });
57 |
--------------------------------------------------------------------------------
/src/components/carItem/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from "react-native";
2 |
3 | export const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | backgroundColor: "#fff",
7 | marginTop: 15,
8 | marginBottom: 0,
9 | marginLeft: 15,
10 | marginRight: 15,
11 | padding: 15,
12 | borderWidth: 1,
13 | borderColor: "#ddd"
14 | },
15 | carrateContainer: {
16 | flex: 1,
17 | flexDirection: "row",
18 | paddingTop: 10,
19 | paddingLeft: 10,
20 | paddingRight: 10,
21 | justifyContent: "space-between",
22 | color: "#828282",
23 | fontSize: 12
24 | },
25 | carratefont: {
26 | color: "#828282",
27 | fontSize: 12
28 | },
29 | carratefontB: {
30 | color: "#56CCF2",
31 | fontSize: 12
32 | },
33 |
34 | subcontainers: {
35 | flex: 1,
36 | alignItems: "center",
37 | flexDirection: "row"
38 | },
39 | carname: {
40 | fontSize: 16
41 | },
42 | cardetail: {
43 | fontSize: 12
44 | },
45 | subcontainer: {
46 | paddingLeft: 20,
47 | flexDirection: "column",
48 | alignItems: "flex-start"
49 | },
50 | tinyLogo: {
51 | width: 78,
52 | height: 59
53 | },
54 | input: {
55 | width: "50%",
56 | borderWidth: 1,
57 | borderColor: "#ddd",
58 | padding: 10,
59 | margin: 2,
60 | fontSize: 18,
61 | borderRadius: 6
62 | }
63 | });
64 |
--------------------------------------------------------------------------------
/src/components/pastBookingItem/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from "react-native";
2 |
3 | export const styles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | backgroundColor: "#fff",
7 | marginTop: 15,
8 | marginBottom: 0,
9 | marginLeft: 15,
10 | marginRight: 15,
11 | padding: 15,
12 | borderWidth: 1,
13 | borderColor: "#ddd"
14 | },
15 | carrateContainer: {
16 | flex: 1,
17 | flexDirection: "row",
18 | paddingTop: 10,
19 | paddingLeft: 10,
20 | paddingRight: 10,
21 | justifyContent: "space-between",
22 | color: "#828282",
23 | fontSize: 12
24 | },
25 | carratefont: {
26 | color: "#828282",
27 | fontSize: 12
28 | },
29 | carratefontB: {
30 | color: "#56CCF2",
31 | fontSize: 12
32 | },
33 |
34 | subcontainers: {
35 | flex: 1,
36 | alignItems: "center",
37 | flexDirection: "row"
38 | },
39 | carname: {
40 | fontSize: 16
41 | },
42 | cardetail: {
43 | fontSize: 12
44 | },
45 | subcontainer: {
46 | paddingLeft: 20,
47 | flexDirection: "column",
48 | alignItems: "flex-start"
49 | },
50 | tinyLogo: {
51 | width: 78,
52 | height: 59
53 | },
54 | input: {
55 | width: "50%",
56 | borderWidth: 1,
57 | borderColor: "#ddd",
58 | padding: 10,
59 | margin: 2,
60 | fontSize: 18,
61 | borderRadius: 6
62 | }
63 | });
64 |
--------------------------------------------------------------------------------
/src/screens/car/drivingScreen/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from "react-native";
2 | import {
3 | appBackgrounColor,
4 | appColor,
5 | btnFontColor
6 | } from "../../../utilities/Consants/Colors";
7 |
8 | export const styles = StyleSheet.create({
9 | container: {
10 | flex: 1,
11 | flexDirection: "column",
12 | backgroundColor: appBackgrounColor
13 | },
14 | containersub: {
15 | flex: 1,
16 | justifyContent: "flex-start",
17 | alignItems: "center",
18 | flexDirection: "column"
19 | },
20 | tinyLogo: {
21 | width: 286,
22 | height: 211
23 | },
24 | content: {
25 | fontSize: 14,
26 | marginTop: 30,
27 | color: "black",
28 | fontWeight: "bold",
29 | fontFamily: "Roboto"
30 | },
31 | buttonContent: {
32 | fontFamily: "Roboto",
33 | fontSize: 14,
34 | color: btnFontColor
35 | },
36 | buttonContainer: {
37 | backgroundColor: appColor,
38 | marginTop: 10,
39 | alignItems: "center",
40 | justifyContent: "center",
41 | width: 196,
42 | height: 36
43 | },
44 | buttonBottomContainer: {
45 | backgroundColor: appColor,
46 | marginTop: 10,
47 | alignItems: "center",
48 | justifyContent: "center",
49 | width: 143,
50 | height: 36
51 | },
52 | bottomContainer: {
53 | paddingBottom: 50,
54 | position: "absolute",
55 | alignItems: "center",
56 | bottom: 0
57 | }
58 | });
59 |
--------------------------------------------------------------------------------
/src/screens/car/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { createAppContainer } from "react-navigation";
4 | import { createMaterialTopTabNavigator } from "react-navigation-tabs";
5 | import { createStackNavigator } from "react-navigation-stack";
6 |
7 | import DrivingScreen from "./drivingScreen/index";
8 | import PastBookingScreen from "./pastBookingScreen/index";
9 |
10 | const DrivingStack = createStackNavigator(
11 | {
12 | Driving: DrivingScreen
13 | },
14 | {
15 | defaultNavigationOptions: {
16 | header: null
17 | }
18 | }
19 | );
20 |
21 | const PastBookStack = createStackNavigator(
22 | {
23 | PastBook: PastBookingScreen
24 | },
25 | {
26 | defaultNavigationOptions: {
27 | header: null
28 | }
29 | }
30 | );
31 |
32 | const TabNavigator = createMaterialTopTabNavigator({
33 | DriveScreen: {
34 | screen: DrivingStack,
35 | navigationOptions: {
36 | tabBarLabel: "DRIVING NOW",
37 | tabBarOptions: {
38 | style: {
39 | backgroundColor: "#56CCF2" //color you want to change
40 | }
41 | }
42 | }
43 | },
44 | PastBookingScreen: {
45 | screen: PastBookStack,
46 | navigationOptions: {
47 | tabBarLabel: "PAST BOOKINGS",
48 | tabBarOptions: {
49 | style: {
50 | backgroundColor: "#56CCF2" //color you want to change
51 | }
52 | }
53 | }
54 | }
55 | });
56 |
57 | export default createAppContainer(TabNavigator);
58 |
--------------------------------------------------------------------------------
/src/styles/global.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from "react-native";
2 |
3 | export const globalStyles = StyleSheet.create({
4 | container: {
5 | flex: 1,
6 | padding: 20,
7 | backgroundColor: "#fff"
8 | },
9 | titleText: {
10 | fontFamily: "nunito-bold",
11 | fontSize: 18,
12 | color: "#333"
13 | },
14 | paragraph: {
15 | marginVertical: 8,
16 | lineHeight: 20
17 | },
18 | input: {
19 | borderWidth: 1,
20 | borderColor: "#003e59",
21 | padding: 13,
22 | marginTop: 10,
23 | marginBottom: 10,
24 | fontSize: 18,
25 | borderRadius: 6
26 | },
27 | heading: {
28 | fontSize: 24,
29 | fontFamily: "sans-serif",
30 | fontWeight: "bold",
31 | color: "#003e59"
32 | },
33 | appButtonContainer: {
34 | elevation: 8,
35 | backgroundColor: "#56CCF2",
36 | borderRadius: 10,
37 | paddingVertical: 10,
38 | paddingHorizontal: 12
39 | },
40 | appButtonText: {
41 | fontSize: 18,
42 | color: "#fff",
43 | fontWeight: "bold",
44 | alignSelf: "center",
45 | textTransform: "uppercase"
46 | },
47 |
48 | upload: {
49 | alignItems: "flex-start",
50 | justifyContent: "center",
51 | flexDirection: "row",
52 | padding: 10,
53 | marginBottom: 10,
54 | borderWidth: 1,
55 | borderColor: "#003e59"
56 | },
57 | imageUpload: {
58 | alignItems: "flex-start",
59 | justifyContent: "center",
60 | width: 200,
61 | height: 200,
62 | borderWidth: 1,
63 | padding: 10,
64 | marginBottom: 10,
65 | borderColor: "#003e59"
66 | }
67 | });
68 |
--------------------------------------------------------------------------------
/src/utilities/dummyData/index.js:
--------------------------------------------------------------------------------
1 | export const carData = [
2 | {
3 | id: "1",
4 | address: "Titiwangsa",
5 | color: "Black",
6 | fuel: "Diesel",
7 | image:
8 | "file:/data/user/0/host.exp.exponent/cache/ExperienceData/%2540bidcholhamzaahmed%252Fsocar/ImagePicker/c274c84d-e4f2-4b41-a547-203a54edb56e.jpg",
9 | name: "Civic",
10 | rate: 57,
11 | seating: "4",
12 | transmission: "Manual",
13 | type: "COUPE"
14 | },
15 | {
16 | id: "2",
17 | address: "Titiwangsa",
18 | color: "White",
19 | fuel: "Diesel",
20 | image:
21 | "file:/data/user/0/host.exp.exponent/cache/ExperienceData/%2540bidcholhamzaahmed%252Fsocar/ImagePicker/c274c84d-e4f2-4b41-a547-203a54edb56e.jpg",
22 | name: "HRV",
23 | rate: 57,
24 | seating: "4",
25 | transmission: "Manual",
26 | type: "COUPE"
27 | },
28 | {
29 | id: "3",
30 | address: "Titiwangsa",
31 | color: "Brown",
32 | fuel: "Diesel",
33 | image:
34 | "file:/data/user/0/host.exp.exponent/cache/ExperienceData/%2540bidcholhamzaahmed%252Fsocar/ImagePicker/c274c84d-e4f2-4b41-a547-203a54edb56e.jpg",
35 | name: "City",
36 | rate: 57,
37 | seating: "4",
38 | transmission: "Manual",
39 | type: "COUPE"
40 | },
41 | {
42 | id: "4",
43 | address: "Titiwangsa",
44 | color: "Grey",
45 | fuel: "Diesel",
46 | image:
47 | "file:/data/user/0/host.exp.exponent/cache/ExperienceData/%2540bidcholhamzaahmed%252Fsocar/ImagePicker/c274c84d-e4f2-4b41-a547-203a54edb56e.jpg",
48 | name: "Myvi",
49 | rate: 57,
50 | seating: "4",
51 | transmission: "Manual",
52 | type: "COUPE"
53 | }
54 | ];
55 |
--------------------------------------------------------------------------------
/src/components/carItem/index.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { View, Text, Image, TouchableOpacity } from "react-native";
3 | import { styles } from "./styles";
4 | import { connect } from "react-redux";
5 | import { reserve_car } from "../../actions/reservedCar";
6 |
7 | const CarItem = props => {
8 | const handleSubmit = item => {
9 | const registeredCar = {
10 | car: item,
11 | isRegistered: true,
12 | registeredBy: "Hamza",
13 | isDriving: false
14 | };
15 | props.reserve_car(registeredCar, props);
16 | };
17 | console.log("=>" + props.flag);
18 |
19 | return (
20 |
21 |
22 |
26 |
27 | {props.name}
28 | {props.color}
29 | Available
30 |
31 |
32 |
39 |
40 | MYR 20.00 / HR
41 | handleSubmit(props.name)}>
42 | BOOK NOW
43 |
44 |
45 |
46 | );
47 | };
48 | const mapStateToProps = state => ({
49 | isDataLoaded: state.reserve_car.isDataLoaded
50 | });
51 |
52 | export default connect(mapStateToProps, { reserve_car })(CarItem);
53 |
--------------------------------------------------------------------------------
/src/screens/car/reserveCar/index.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { Text, View, Image, TouchableOpacity } from "react-native";
3 | import { commonNavigation } from "../../../utilities/AppUtils";
4 | import CarListWrapper from "../../../components/carListWrapper";
5 | import { styles } from "./styles";
6 | import { getAllCar } from "../../../actions/rentCarList";
7 | import { connect } from "react-redux";
8 |
9 | const ReserveCarScreen = props => {
10 | useEffect(() => {
11 | props.getAllCar();
12 | }, []);
13 | return (
14 |
15 |
16 | {
19 | props.navigation.navigate("Reservation");
20 | }}
21 | >
22 |
26 | 00:30 AM - Wed, 28/09/2020
27 |
28 | {
31 | props.navigation.navigate("Reservation");
32 | }}
33 | >
34 |
38 | 00:30 AM - Wed, 28/09/2020
39 |
40 |
41 |
46 |
47 | );
48 | };
49 |
50 | ReserveCarScreen.navigationOptions = commonNavigation("Make a Reservation");
51 |
52 | const mapStateToProps = state => ({
53 | mycar: state.my_car.myCar
54 | });
55 |
56 | export default connect(mapStateToProps, { getAllCar })(ReserveCarScreen);
57 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "main": "node_modules/expo/AppEntry.js",
3 | "scripts": {
4 | "start": "expo start",
5 | "android": "expo start --android",
6 | "ios": "expo start --ios",
7 | "web": "expo start --web",
8 | "eject": "expo eject"
9 | },
10 | "dependencies": {
11 | "@react-native-community/masked-view": "0.1.10",
12 | "@react-native-community/slider": "^3.0.3",
13 | "@react-navigation/material-top-tabs": "^5.3.10",
14 | "date-fns": "^2.16.1",
15 | "expo": "~39.0.2",
16 | "expo-constants": "^9.2.0",
17 | "expo-image-picker": "~9.2.0",
18 | "expo-secure-store": "^9.2.0",
19 | "expo-status-bar": "~1.0.2",
20 | "firebase": "^8.2.2",
21 | "moment": "^2.29.1",
22 | "react": "16.13.1",
23 | "react-dom": "16.13.1",
24 | "react-native": "https://github.com/expo/react-native/archive/sdk-39.0.4.tar.gz",
25 | "react-native-circular-progress": "^1.3.6",
26 | "react-native-daterange-picker": "^1.5.1",
27 | "react-native-gesture-handler": "~1.7.0",
28 | "react-native-markdown-renderer": "^3.2.8",
29 | "react-native-material-dropdown": "git+https://github.com/noway/react-native-material-dropdown.git",
30 | "react-native-reanimated": "~1.13.0",
31 | "react-native-safe-area-context": "3.1.4",
32 | "react-native-screens": "~2.10.1",
33 | "react-native-slider-picker": "^1.1.3",
34 | "react-native-svg": "^12.1.0",
35 | "react-native-tab-view": "2.14.2",
36 | "react-native-toast-message": "^1.4.2",
37 | "react-native-web": "~0.13.12",
38 | "react-navigation": "^4.4.3",
39 | "react-navigation-stack": "^2.10.1",
40 | "react-navigation-tabs": "^2.10.1",
41 | "react-redux": "^7.2.2",
42 | "redux": "^4.0.5",
43 | "redux-devtools-extension": "^2.13.8",
44 | "redux-thunk": "^2.3.0"
45 | },
46 | "devDependencies": {
47 | "@babel/core": "~7.9.0",
48 | "babel-preset-expo": "^8.3.0",
49 | "eslint": "^7.13.0",
50 | "eslint-config-prettier": "^6.15.0",
51 | "eslint-plugin-react-native": "^3.10.0",
52 | "prettier": "^2.1.2"
53 | },
54 | "private": true
55 | }
56 |
--------------------------------------------------------------------------------
/src/components/activeCar/styles.js:
--------------------------------------------------------------------------------
1 | import { StyleSheet } from "react-native";
2 | import { appDisableColor } from "../../utilities/Consants/Colors";
3 | export const styles = StyleSheet.create({
4 | container: {
5 | backgroundColor: "#fff",
6 | marginTop: 15,
7 | marginBottom: 0,
8 | marginLeft: 15,
9 | marginRight: 15,
10 | padding: 15,
11 | borderWidth: 1,
12 | borderColor: "#ddd"
13 | },
14 | subContainer: {
15 | alignItems: "center"
16 | },
17 | statusContent: {
18 | alignItems: "center",
19 | paddingTop: 30
20 | },
21 | tinyLogo: {
22 | width: 254,
23 | height: 163
24 | },
25 | lock: {
26 | width: 16,
27 | margin: 10,
28 | height: 21
29 | },
30 | subContent: {
31 | flexDirection: "row",
32 | justifyContent: "space-around"
33 | },
34 | lockItem: {
35 | padding: 5,
36 | borderWidth: 1,
37 | borderColor: "#ddd"
38 | },
39 | lockContent: {
40 | flexDirection: "row"
41 | },
42 | timeEndingContent: {
43 | flexDirection: "row",
44 | paddingTop: 10
45 | },
46 | timeEndingText: {
47 | color: appDisableColor,
48 | paddingTop: 3,
49 | paddingRight: 3,
50 | fontSize: 16
51 | },
52 | buttonActiveContainer: {
53 | flexDirection: "row",
54 | justifyContent: "flex-end"
55 | },
56 | buttonActiveContent: {
57 | fontFamily: "Roboto",
58 | fontSize: 14,
59 | paddingLeft: 15,
60 | paddingRight: 15,
61 | color: "#2F80ED"
62 | },
63 | timeEndingDayText: {
64 | color: appDisableColor,
65 | fontWeight: "bold",
66 | fontSize: 20
67 | },
68 | animatedCircular: {
69 | paddingTop: 30,
70 | justifyContent: "center",
71 | alignItems: "center"
72 | },
73 | lockItemContent: {
74 | justifyContent: "center",
75 | paddingLeft: 10
76 | },
77 | lockItemText: {
78 | fontSize: 14,
79 | fontWeight: "500",
80 | color: "#000"
81 | },
82 | buttonContainer: {
83 | margin: 10,
84 | justifyContent: "center",
85 | alignItems: "center"
86 | },
87 | buttonContent: {
88 | fontFamily: "Roboto",
89 | fontSize: 14,
90 | alignItems: "center",
91 | color: "#2F80ED"
92 | }
93 | });
94 |
--------------------------------------------------------------------------------
/src/actions/rentCarList.js:
--------------------------------------------------------------------------------
1 | import firebase from "firebase";
2 | import { GET_ALL_CARS } from "./types";
3 | import Toast from "react-native-toast-message";
4 |
5 | export const getAllCar = () => dispatch => {
6 | let dataList = [];
7 | firebase
8 | .database()
9 | .ref("rentCarsList")
10 | .orderByChild("name")
11 | .once("value")
12 | .then(snapshot => {
13 | snapshot.forEach(child => {
14 | dataList.push(child.val());
15 | });
16 | dispatch({
17 | type: GET_ALL_CARS,
18 | payload: dataList
19 | });
20 | })
21 | .catch(error => {
22 | dispatch({
23 | type: GET_ALL_CARS,
24 | payload: []
25 | });
26 | });
27 | };
28 |
29 | //CREATE
30 | export const createCarList = (item, props) => async dispatch => {
31 | let carListRef = firebase.database().ref("rentCarsList");
32 | let newCarRef = carListRef.push();
33 | await newCarRef
34 | .set(item)
35 | .then(uploadImageAsync(item.image, item.name))
36 | .then(resp => {
37 | setTimeout(() => {
38 | props.navigation.goBack();
39 | Toast.show({
40 | text1: "Congrats",
41 | text2: "Car added succesfully 👋"
42 | });
43 | }, 2000);
44 | dispatch({
45 | type: CREATE_A_CAR,
46 | payload: true
47 | });
48 | })
49 | .catch(err => {
50 | dispatch({
51 | type: CREATE_A_CAR,
52 | payload: false
53 | });
54 | });
55 | };
56 |
57 | async function uploadImageAsync(uri, name) {
58 | const blob = await new Promise((resolve, reject) => {
59 | const xhr = new XMLHttpRequest();
60 | xhr.onload = function () {
61 | resolve(xhr.response);
62 | };
63 | xhr.onerror = function (e) {
64 | reject(new TypeError("Network request failed"));
65 | };
66 | xhr.responseType = "blob";
67 | xhr.open("GET", uri, true);
68 | xhr.send(null);
69 | });
70 |
71 | const ref = firebase
72 | .storage()
73 | .ref()
74 | .child("uploads/" + name);
75 | const snapshot = await ref.put(blob);
76 |
77 | // We're done with the blob, close and release it
78 | blob.close();
79 |
80 | return await snapshot.ref.getDownloadURL();
81 | }
82 |
--------------------------------------------------------------------------------
/src/utilities/AppUtils.js:
--------------------------------------------------------------------------------
1 | import { Alert } from "react-native";
2 | import * as ImagePicker from "expo-image-picker";
3 |
4 | export const fuelData = [
5 | {
6 | value: "E85"
7 | },
8 | {
9 | value: "Gasoline"
10 | },
11 | {
12 | value: "Diesel"
13 | }
14 | ];
15 |
16 | export const typeData = [
17 | {
18 | value: "SEDAN"
19 | },
20 | {
21 | value: "COUPE"
22 | },
23 | {
24 | value: "SPORTS CAR"
25 | },
26 | {
27 | value: "STATION WAGON"
28 | }
29 | ];
30 |
31 | export const transmissionData = [
32 | {
33 | value: "Manual"
34 | },
35 | {
36 | value: "Automatic"
37 | },
38 | {
39 | value: "Continuously variable transmission"
40 | }
41 | ];
42 |
43 | export const seatingData = [
44 | {
45 | value: "1"
46 | },
47 | {
48 | value: "2"
49 | },
50 | {
51 | value: "3"
52 | },
53 | {
54 | value: "4"
55 | },
56 | {
57 | value: "5"
58 | },
59 | {
60 | value: "6"
61 | }
62 | ];
63 |
64 | export const commonNavigation = name => {
65 | return {
66 | title: name,
67 | headerStyle: {
68 | backgroundColor: "#56CCF2",
69 | elevation: 0,
70 | shadowOpacity: 0
71 | },
72 | headerTintColor: "#ffffff",
73 | headerTitleStyle: {
74 | fontWeight: "bold",
75 | color: "#ffffff"
76 | }
77 | };
78 | };
79 |
80 | export const isEmpty = values => {
81 | let isEmptys = false;
82 | Object.entries(values).map(([key, value]) => {
83 | if (key === "image" && value === null) {
84 | isEmptys = true;
85 | } else {
86 | if (value.length === 0) {
87 | isEmptys = true;
88 | }
89 | }
90 | });
91 |
92 | return isEmptys;
93 | };
94 |
95 | export const showAlert = name =>
96 | Alert.alert(
97 | "Error",
98 | name,
99 | [{ text: "OK", onPress: () => console.log("OK Pressed") }],
100 | { cancelable: false }
101 | );
102 |
103 | export const pickImages = async () => {
104 | let result = await ImagePicker.launchImageLibraryAsync({
105 | mediaTypes: ImagePicker.MediaTypeOptions.All,
106 | multiple: true,
107 | allowsEditing: true,
108 | aspect: [4, 3],
109 | quality: 1
110 | });
111 |
112 | if (!result.cancelled) {
113 | return result.uri;
114 | } else {
115 | return null;
116 | }
117 | };
118 |
119 | export const checkImageStatus = async () => {
120 | if (Platform.OS !== "web") {
121 | const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
122 | if (status !== "granted") {
123 | alert("Sorry, we need camera roll permissions to make this work!");
124 | }
125 | }
126 | };
127 |
--------------------------------------------------------------------------------
/src/screens/car/drivingScreen/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import { Text, View, Image, TouchableOpacity } from "react-native";
3 | import { commonNavigation } from "../../../utilities/AppUtils";
4 | import ActiveCar from "../../../components/activeCar/index";
5 | import { styles } from "./styles";
6 | import firebase from "firebase";
7 |
8 | const DriveNowScreen = props => {
9 | const [isDriving, setDriving] = useState(false);
10 | const [carDetails, setCarDetails] = useState(false);
11 | useEffect(() => {
12 | getData();
13 | }, []);
14 |
15 | const getData = () => {
16 | firebase
17 | .database()
18 | .ref("registeredCar")
19 | .orderByChild("registeredBy")
20 | .equalTo("Hamza")
21 | .on("value", snapshot => {
22 | let isCarRegistered = false;
23 | let car = "";
24 | snapshot.forEach(function (data) {
25 | car = data.child("car").val();
26 | if (car) {
27 | getCarDetails(car);
28 | }
29 | if (data.child("isRegistered").val()) {
30 | isCarRegistered = true;
31 | }
32 | });
33 | setDriving(isCarRegistered);
34 | });
35 | };
36 | getCarDetails = car => {
37 | firebase
38 | .database()
39 | .ref("rentCarsList")
40 | .orderByChild("name")
41 | .equalTo(car)
42 | .on("value", snapshot => {
43 | snapshot.forEach(function (data) {
44 | setCarDetails(data.val());
45 | });
46 | });
47 | };
48 | return (
49 |
50 | {isDriving ? (
51 |
52 | ) : (
53 |
54 |
58 | Not driving a car yet
59 | {
62 | props.navigation.navigate("ReserveCar");
63 | }}
64 | >
65 | MAKE A RESERVATION
66 |
67 |
68 | Want to earn using your car?
69 | {
72 | props.navigation.navigate("ListYourCar");
73 | }}
74 | >
75 | LIST YOUR CAR
76 |
77 |
78 |
79 | )}
80 |
81 | );
82 | };
83 |
84 | DriveNowScreen.navigationOptions = commonNavigation("Drive Now");
85 | export default DriveNowScreen;
86 |
--------------------------------------------------------------------------------
/src/screens/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { createAppContainer } from "react-navigation";
3 | import { createBottomTabNavigator } from "react-navigation-tabs";
4 | import { createStackNavigator } from "react-navigation-stack";
5 | import { MaterialCommunityIcons } from "@expo/vector-icons";
6 |
7 | // import screen components
8 | import HomeScreen from "./home";
9 | import ListYourCarScreen from "./car/listYourCar/index";
10 | import ProfileScreen from "./profile";
11 | import SettingScreen from "./setting";
12 | import ReserveCarScreen from "./car/reserveCar/index";
13 | import CarScreen from "./car";
14 |
15 | const HomeStack = createStackNavigator({
16 | Home: HomeScreen
17 | });
18 |
19 | const CarStack = createStackNavigator(
20 | {
21 | Car: CarScreen,
22 | ListYourCar: ListYourCarScreen,
23 | ReserveCar: ReserveCarScreen
24 | },
25 | {
26 | defaultNavigationOptions: {
27 | headerStyle: {
28 | backgroundColor: "#56CCF2"
29 | },
30 | headerTintColor: "#fff",
31 | headerTitleStyle: {
32 | fontWeight: "bold"
33 | }
34 | }
35 | }
36 | );
37 |
38 | const ProfileStack = createStackNavigator({
39 | Profile: ProfileScreen
40 | });
41 |
42 | const SettingStack = createStackNavigator({
43 | Setting: SettingScreen
44 | });
45 |
46 | const TabNavigator = createBottomTabNavigator({
47 | HomeScreen: {
48 | screen: HomeStack,
49 | navigationOptions: {
50 | tabBarLabel: "Home",
51 | tabBarOptions: {
52 | activeTintColor: "#56CCF2",
53 | inactiveTintColor: "rgba(0, 0, 0, 0.38)"
54 | },
55 | tabBarIcon: ({ tintColor }) => (
56 |
57 | )
58 | }
59 | },
60 | CarScreen: {
61 | screen: CarStack,
62 | navigationOptions: {
63 | tabBarLabel: "Car",
64 | tabBarOptions: {
65 | activeTintColor: "#56CCF2",
66 | inactiveTintColor: "rgba(0, 0, 0, 0.38)"
67 | },
68 | tabBarIcon: ({ tintColor }) => (
69 |
70 | )
71 | }
72 | },
73 | ProfileScreen: {
74 | screen: ProfileStack,
75 | navigationOptions: {
76 | tabBarLabel: "profile",
77 | tabBarOptions: {
78 | activeTintColor: "#56CCF2",
79 | inactiveTintColor: "rgba(0, 0, 0, 0.38)"
80 | },
81 | tabBarIcon: ({ tintColor }) => (
82 |
83 | )
84 | }
85 | },
86 | SettingScreen: {
87 | screen: SettingStack,
88 | navigationOptions: {
89 | tabBarLabel: "Setting",
90 | tabBarOptions: {
91 | activeTintColor: "#56CCF2",
92 | inactiveTintColor: "rgba(0, 0, 0, 0.38)"
93 | },
94 | tabBarIcon: ({ tintColor }) => (
95 |
96 | )
97 | }
98 | }
99 | });
100 |
101 | export default createAppContainer(TabNavigator);
102 |
--------------------------------------------------------------------------------
/src/screens/car/listYourCar/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import { Dropdown } from "react-native-material-dropdown";
3 | import { SliderPicker } from "react-native-slider-picker";
4 | import { globalStyles } from "../../../styles/global";
5 | import { styles } from "./styles";
6 | import ImagePickerComp from "../../../utilities/ImagePicker";
7 | import { useForm } from "../../../customHooks/useForm";
8 | import { AnimatedCircularProgress } from "react-native-circular-progress";
9 | import { createCarList } from "../../../actions/rentCarList";
10 | import { connect } from "react-redux";
11 | import {
12 | fuelData,
13 | typeData,
14 | seatingData,
15 | transmissionData,
16 | commonNavigation,
17 | showAlert,
18 | pickImages,
19 | isEmpty,
20 | checkImageStatus
21 | } from "../../../utilities/AppUtils";
22 | import {
23 | TextInput,
24 | View,
25 | Text,
26 | YellowBox,
27 | LogBox,
28 | TouchableOpacity,
29 | ScrollView
30 | } from "react-native";
31 |
32 | LogBox.ignoreLogs(["Warning: ..."]);
33 | LogBox.ignoreAllLogs();
34 |
35 | const ListYourCarScreen = props => {
36 | const [values, handleChange] = useForm({
37 | name: "",
38 | color: "",
39 | type: "",
40 | fuel: "",
41 | seating: "",
42 | address: "",
43 | transmission: ""
44 | });
45 | const [image, setImage] = useState(null);
46 | const [rate, setRate] = useState(25);
47 | const [Loading, isLoading] = useState(false);
48 |
49 | const handleSubmit = e => {
50 | const object = {
51 | ...values,
52 | rate,
53 | image
54 | };
55 | if (isEmpty(object)) {
56 | showAlert("Kindly fill all the fields");
57 | } else {
58 | isLoading(true);
59 | props.createCarList(object, props);
60 | }
61 | };
62 |
63 | useEffect(() => {
64 | YellowBox.ignoreWarnings(["Animated: `useNativeDriver`"]);
65 | checkImageStatus();
66 | }, []);
67 |
68 | return (
69 |
70 | {Loading ? (
71 |
80 | ) : (
81 |
82 |
83 | Car Information
84 | handleChange("name", txt)}
88 | value={values.name}
89 | />
90 | handleChange("color", txt)}
94 | value={values.color}
95 | />
96 |
97 |
98 | handleChange("type", txt)}
105 | />
106 |
107 |
108 | handleChange("fuel", txt)}
115 | />
116 |
117 |
118 |
119 |
120 | handleChange("transmission", txt)}
126 | />
127 |
128 |
129 | handleChange("seating", txt)}
136 | />
137 |
138 |
139 | Rate
140 | {
142 | setRate(position);
143 | }}
144 | defaultValue={values.rate}
145 | maxValue={100}
146 | labelFontColor={"#6c7682"}
147 | labelFontWeight={"600"}
148 | fillColor={"#3B5998"}
149 | labelFontWeight={"bold"}
150 | heightPercentage={1}
151 | widthPercentage={80}
152 | />
153 | {values.rate}
154 | Address line
155 | handleChange("address", txt)}
159 | value={values.address}
160 | />
161 | setImage(await pickImages())}
164 | />
165 |
169 | Submit
170 |
171 |
172 |
173 | )}
174 |
175 | );
176 | };
177 |
178 | ListYourCarScreen.navigationOptions = commonNavigation("List your car");
179 |
180 | const mapStateToProps = state => ({
181 | status: state.my_car.status
182 | });
183 |
184 | export default connect(mapStateToProps, { createCarList })(ListYourCarScreen);
185 |
--------------------------------------------------------------------------------
/src/components/activeCar/index.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import { Text, TouchableOpacity, View, Image } from "react-native";
3 | import { styles } from "./styles";
4 | import firebase from "firebase";
5 | import { connect } from "react-redux";
6 | import { returned_car } from "../../actions/returnedCar";
7 | import { AnimatedCircularProgress } from "react-native-circular-progress";
8 | const ActiveCarScreen = props => {
9 | const [active, isCarActive] = useState(false);
10 | const [loading, isLoading] = useState(false);
11 |
12 | useEffect(() => {
13 | getData();
14 | }, []);
15 |
16 | const isCarStarted = () => {
17 | firebase
18 | .database()
19 | .ref("registeredCar")
20 | .orderByChild("registeredBy")
21 | .equalTo("Hamza")
22 | .once("value", snapshot => {
23 | snapshot.forEach(function (data) {
24 | data.ref.child("isDriving").set(true);
25 | });
26 | });
27 | };
28 | const getData = () => {
29 | firebase
30 | .database()
31 | .ref("registeredCar")
32 | .orderByChild("registeredBy")
33 | .equalTo("Hamza")
34 | .on("value", snapshot => {
35 | let isCarStarted = false;
36 | snapshot.forEach(function (data) {
37 | if (data.child("isDriving").val()) {
38 | isCarStarted = true;
39 | }
40 | });
41 | isCarActive(isCarStarted);
42 | });
43 | };
44 |
45 | const setPastBooking = () => {
46 | props.returned_car(props.carDetails, props.navigate);
47 | returnedCar();
48 | };
49 |
50 | const returnedCar = () => {
51 | firebase
52 | .database()
53 | .ref("registeredCar")
54 | .orderByChild("registeredBy")
55 | .equalTo("Hamza")
56 | .once("value", snapshot => {
57 | snapshot.forEach(function (data) {
58 | data.ref.child("isRegistered").set(false);
59 | });
60 | });
61 | };
62 |
63 | return (
64 |
65 |
66 | {props.carDetails.name}
67 |
68 |
69 | {props.carDetails.color}
70 |
71 |
72 |
76 |
77 |
78 |
79 |
80 | Car Type
81 |
82 | {props.carDetails.type}
83 |
84 |
85 |
86 | Seater
87 |
88 | {props.carDetails.seating}
89 |
90 |
91 |
92 | Transmission
93 |
94 | {props.carDetails.transmission}
95 |
96 |
97 | {loading && (
98 | {
106 | // isCarActive(!isCarActive);
107 | isCarActive(true);
108 | isLoading(false);
109 | }}
110 | backgroundColor="#3d5875"
111 | />
112 | )}
113 | {!active ? (
114 |
115 |
116 |
117 | Booking starts at
118 |
119 |
126 | Wed 09/09/2020
127 |
128 |
129 |
137 | {
140 | // props.navigation.navigate("Reservation");
141 | isCarStarted();
142 | isLoading(true);
143 | }}
144 | >
145 | START DRIVING
146 |
147 |
148 | ) : (
149 |
150 |
151 |
152 |
153 |
157 |
158 |
159 |
163 |
164 |
165 | LOCK CAR
166 |
167 |
168 |
169 | Time ending in
170 | 1 Day
171 |
172 |
173 |
181 | {
184 | // props.navigation.navigate("Reservation");
185 | //isLoading(true);
186 | setPastBooking();
187 | }}
188 | >
189 | EXTEND
190 | RETURN
191 |
192 |
193 | )}
194 |
195 | );
196 | };
197 | const mapStateToProps = state => ({
198 | isDataLoaded: state.reserve_car.isDataLoaded
199 | });
200 |
201 | export default connect(mapStateToProps, { returned_car })(ActiveCarScreen);
202 |
--------------------------------------------------------------------------------