Creating a Login & Logout and Dashboard Screen in React Native

Creating a login & logout screen in React Native involves a combination of design, functionality, and security considerations.One crucial aspect of any mobile application is authentication – the process of allowing users to securely access their accounts. In this article, we will creating a login and logout and dashboard screen in React Native. From designing the login form to implementing navigation and handling API calls, we'll cover every step necessary to create a polished Login & Logout & Dashboard authentication experience for your app users.Below will be the directory structure , we will create components like NavigationContainer,CustomToastProvider,AuthProvider and also create login and logout services inside services folder. In this way you can create each service file js which will responsible for the communication to API. For example AuthService.js will responsible for authorization of users and if user valid store information using react-native-community/async-storage.ProfileService.js will call api related to profile data like wise etc. you can create other service file also inside service folder based on your App reuirement. i am assumming that you have setup your project in your localhost environment, so directory structure will be like below. See help create your first app expo.

Making Login logout dashboard screen in React Native

Main App React File

First Below Will be your app.js file and in this file you can see we have wrapped , in such a way so that they will available in all screens and you can easily manage states, props. As you can see in code below that we have imported screen file like SignInScreen ,SplashScreen,DashboardNavigator,AuthContext,CustomToastProvider from a specific folder. So in this way you can manage your code.

									     
// App.js
import React, { useEffect, useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { View, StyleSheet,Text,TouchableOpacity  } from 'react-native';
import SignInScreen from './src/screens/auth/SignInScreen';
import SplashScreen from './src/screens/SplashScreen';
import DashboardNavigator from './src/components/DashboardNavigator'; 
import { AuthProvider } from './src/components/AuthContext';
import CustomToastProvider from './src/components/CustomToastProvider'; 
const Stack = createStackNavigator();

const App = () => {
  
  return (
    <NavigationContainer>
    <CustomToastProvider> 
     <AuthProvider>
            <View style={styles.container}>
                <Stack.Navigator initialRouteName="Splash" headerShown="false" >
                <Stack.Screen name="Loading" component={SplashScreen} />
                <Stack.Screen name="SignIn" component={SignInScreen} options={{ headerShown: false }} />
                <Stack.Screen name="Dashboard" component={DashboardNavigator} options={{ title: '',headerLeft: () => null,headerShown: true,headerTransparent: false,headerStyle: {backgroundColor: 'rgb(30, 144, 255)',elevation: 4,height:50 }}}/>
              </Stack.Navigator>
            </View>
     </AuthProvider>
     </CustomToastProvider>
     </NavigationContainer>
  );
};
const styles = StyleSheet.create({
  container: {
    flex: 1, 
  },
});
export default App;										
									

SignIn Screen Or Login Screen

Login form screen will have email and password as a form fields. we have imported AuthContext to access login function. When user click on signin or login button signIn() call api and validate user also store information in local storage if user is valid. For notification to the user for any succes or failture we used Toast Notification

									     
// SignInScreen.js
import React, { useEffect, useState } from 'react';
import {
  Alert,
  Text,
  View,
  TextInput,
  TouchableOpacity,
  Image,
  KeyboardAvoidingView,
  Dimensions,
  ActivityIndicator,Keyboard
} from 'react-native';

import { useAuth } from '../../components/AuthContext';
import styles from "../../css/login";
import {apiUrl} from  '../../config/constants';

import { useToast, Toast} from "react-native-toast-notifications";
var height = Dimensions.get('window').height;
var width = Dimensions.get('window').width;

const SignInScreen = ({ navigation }) => {

  const toast = useToast();
  const [isLoading, setIsLoading] = useState(false);

  const { login } = useAuth(); 
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleReset = () => {
    setEmail('');
    setPassword('');
  };

  const signIn = async () => {
    Keyboard.dismiss();
    Toast.hideAll();
    try {
      setIsLoading(true);
      const user = { email: email, password: password };
      if (email && password) {
        const response = await login(user);
        if (response.status===1) {
              toast.show(
                response.msg,
                {
                  type: "custom_toast",
                  duration: 700,
                  data: {
                    title: "Success",
                  },
                }
              );
              handleReset();
             navigation.navigate('Dashboard');
          } else {
            toast.show(
              response.msg,
              {
                type: "custom_toast",
                duration: 700,
                data: {
                  title: "Error",
                },
              }
            );
            setIsLoading(false);
            handleReset();
            navigation.navigate('SignIn');
          }
        } else {
          toast.show(
            'Email and password are required.',
            {
              type: "custom_toast",
              duration: 700,
              data: {
                title: "Error",
              },
            }
          );
          navigation.navigate('SignIn');
        }
    } catch (error) {
      setIsLoading(false);
      handleReset();
      console.error('Error during login:', error);
      toast.show(
        'Email and password are required.',
        {
          type: "custom_toast",
          duration: 700,
          data: {
            title: "Error",
          },
        }
      );
    }finally {
      handleReset();
      setIsLoading(false);
    }
  };

  const handleSignUpPress = () => {
    navigation.navigate('SignUp');
  };

  const handleForgetPasswordPress = () => {
    navigation.navigate('ForgetPassword');
  };

  return (
    <View style={styles.mainContainer}>

    <KeyboardAvoidingView
      style={styles.container}
      behavior="padding"
    >
      
      <View style={(styles.row, styles.imageBox, styles.logo)}>
        <Image style={{ width: 190, height: 32 }} source={{ uri: apiUrl + 'assets/images/signin-logo.png' }} />
      </View>

      <View style={{ width: width - 90, alignItems: 'center', justifyContent: 'center' }}>
        <Text style={styles.pageTitle}>Login Here</Text>
      </View>
      {isLoading && <ActivityIndicator size="large" color="blue" />}
      <TextInput style={styles.inputBox}
        underlineColorAndroid='rgba(0,0,0,0)'
        placeholder="Email"
        placeholderTextColor="#999999"
        selectionColor="#000"
        keyboardType="email-address"
        onSubmitEditing={() => email.focus()}
        value={email}
        onChangeText={setEmail}
      />
      <TextInput style={styles.inputBox}
        underlineColorAndroid='rgba(0,0,0,0)'
        placeholder="Password"
        secureTextEntry={true}
        selectionColor="#000"
        placeholderTextColor="#999999"
        value={password}
        onChangeText={setPassword}
      />
      <View style={styles.scrollboxActionContainer}>
        <View style={styles.buttonSignup}>
          <TouchableOpacity onPress={signIn}>
            <Text style={styles.buttonSignupText}>Login</Text>
          </TouchableOpacity>
        </View>
      </View>
      <View style={{ flexDirection: "row" }}>
        <View style={{ flex: 1, paddingLeft: 10, }}>
          <TouchableOpacity style={{ alignSelf: 'stretch' }} onPress={handleSignUpPress}>
            <Text style={styles.button_1}>Create Account?</Text>
          </TouchableOpacity>
        </View>
        <View style={{ borderLeftWidth: 1, borderLeftColor: 'white' }} />
        <View style={{ flex: 1, paddingRight: 10 }}>
          <TouchableOpacity style={{ alignSelf: 'stretch' }} onPress={handleForgetPasswordPress}>
            <Text style={styles.button_2}>Forgot Password?</Text>
          </TouchableOpacity>
        </View>
      </View>
      
     </KeyboardAvoidingView>
    <View style={styles.signupTextCont}>
    </View>
  </View>
  );
};
export default SignInScreen;										
									

Auth Context

To manage user authentication state across the application, integrate an Auth Provider using Context API.This centralizes authentication logic and enables seamless communication between components, ensuring a consistent user experience throughout the app. You can see that we have imported AuthService.js file. this file have functions axios which call api and response back.

									     
// AuthContext.js
import React, { createContext, useContext, useEffect, useState } from 'react';
import AuthService from '../services/AuthService'; 

const AuthContext = createContext();

export const AuthProvider = ({ children }) => {
  const [authenticated, setAuthenticated] = useState(false);
   
  useEffect(() => {
    const checkAuthentication = async () => {
      const isAuthenticated = await AuthService.isAuthenticated();
      setAuthenticated(isAuthenticated);
    };

    checkAuthentication();
  }, []);

  const login = async (credentials) => {
        const response = await AuthService.login(credentials);
        if (response.status===1) {
            setAuthenticated(true);
            return response;
        } else {
          setAuthenticated(false);
          return response;
        }
  };

  const logout = async () => {
    await AuthService.logout();
    setAuthenticated(false);
  };

  return (
    <AuthContext.Provider value={{ authenticated, login, logout }}>
      {children}
    </AuthContext.Provider>
  );
};

export const useAuth = () => useContext(AuthContext);										
									

AuthService

The purpose of this class is to provide methods for handling authentication-related tasks in a React Native application. It encapsulates functionality such as logging in, logging out, checking authentication status, and retrieving user data and authentication tokens.

  • login(credentials): This method takes user credentials (e.g., username and password) as input and attempts to log the user in by sending a request to the server. If the login is successful, it saves the user data and token locally and returns the server response. If there's an error during login, it throws an exception with an appropriate error message.

  • logout(): This method implements the logout logic by removing the user data and token stored locally. It doesn't require any input parameters and doesn't return anything.

  • isAuthenticated(): This method checks whether the user is currently authenticated by verifying the presence of a user token. It returns a boolean value indicating the authentication status.

  • getToken(): This method retrieves the authentication token from local storage and returns it. It's useful for making authenticated API requests.

  • getUserData(): This method retrieves user data from local storage and returns it. This data might include user information like username, email, etc.

									     
// AuthService.js
import { saveUserData,saveUserToken,getUserToken,removeUserToken,removeUserData,getUserData } from '../components/storage';
import {apiUrl,axiosHeaders} from  '../config/constants';
import { post } from '../components/RequestCall';
class AuthService {
  async login(credentials) {
      try {
        const result = await post('/user/login/', credentials, axiosHeaders, apiUrl);
        if (result.status === 1) {
          saveUserData(result);
          saveUserToken(result.profile.userId);
          return result;
        } else {
           //console.error('Error fetching data:', result.msg);
           return result;
        }
      } catch (error) {
         //console.error('Error fetching data:', error);
         return { status: 0, msg: error.message };
      }
  }

  async logout() {
    // Implement logout logic here
    // Typically involves clearing the token from AsyncStorage
    removeUserData();
  }

  async isAuthenticated() {
    // Check if the user is authenticated
    // Typically involves checking if a token exists in AsyncStorage
    const token = await getUserToken();
    return !!token;
  }

  async getToken() {
    // Retrieve the authentication token from AsyncStorage
    return getUserToken();
  }

  async getUserData() {
    // Retrieve the authentication token from AsyncStorage
    return getUserData();
  }
}

export default new AuthService();										
									

RequestCall utility

RequestCall React code defines utility functions for making HTTP requests using the Axios library.

									     
//RequestCall.js
import axios from 'axios';
const post = async (endpoint, data = {}, headers = {}, apiUrl = '') => {
  try {
    const instance = axios.create({
      baseURL: apiUrl,
      headers: headers,
    });

    const response = await instance.post(endpoint, data);
    return response.data;
  } catch (error) {
    throw error;
  }
};

const postFormData = async (endpoint, data = {}, userId, headers = {}, apiUrl = '') => {
  
  try {
    const instance = axios.create({
      baseURL: apiUrl,
      headers: headers,
    });

    const formData =  new FormData();
    formData.append('photo', data);
    formData.append('userId', userId);
    
    const response = await instance.post(endpoint, formData);
    return response.data;
  } catch (error) {
    throw error;
  }
};

const get = async (endpoint, params = {}, headers = {}, apiUrl = '') => {
    try {
      const instance = axios.create({
        baseURL: apiUrl,
        headers: headers,
      });
  
      const response = await instance.get(endpoint, { params });
      return response.data;
    } catch (error) {
      throw error;
    }
  };
export { get,post,postFormData };										
									

Storage Component

  1. saveUserData: Saves user data to AsyncStorage under the key userData. It converts the data to a JSON string before storing it.

  2. saveUserToken: Saves the user token to AsyncStorage under the key token. It also converts the token to a JSON string before storing it.

  3. getUserData: Retrieves user data from AsyncStorage using the key userData. It parses the JSON string retrieved from AsyncStorage and returns the parsed data.

  4. getUserToken: Retrieves the user token from AsyncStorage using the key token. It parses the JSON string retrieved from AsyncStorage and returns the parsed token.

  5. removeUserData: Removes both user data and token from AsyncStorage by removing the corresponding keys (userData and token).

  6. removeUserToken: Removes the user token from AsyncStorage by removing the key token.

  7. removeSpecificKey: Removes a specific key from AsyncStorage.

  8. saveToken: Saves a token with a custom key to AsyncStorage.

  9. updateData: Updates the user data stored in AsyncStorage by merging it with the new value provided. If the user data contains a profile object, it updates the profile_photo property with the new value.

									     
// storage.js
import AsyncStorage from '@react-native-community/async-storage';
const STORAGE_KEY = 'userData';
const TOKEN_KEY = 'token';
export const saveUserData = async (userData) => {
  try {
    await AsyncStorage.setItem(STORAGE_KEY, JSON.stringify(userData));
  } catch (error) {
    console.error('Error saving data to AsyncStorage:', error);
  }
};
export const saveUserToken = async (token) => {
  try {
    //await AsyncStorage.setItem(TOKEN_KEY, JSON.stringify(userData.token));
    await AsyncStorage.setItem(TOKEN_KEY, JSON.stringify(token));
  } catch (error) {
    console.error('Error saving data to AsyncStorage:', error);
  }
};
export const getUserData = async () => {
  try {
    const userDataString = await AsyncStorage.getItem(STORAGE_KEY);
    return JSON.parse(userDataString);
  } catch (error) {
    console.error('Error retrieving data from AsyncStorage:', error);
    return null;
  }
};

export const getUserToken = async () => {
  try {
    const token = await AsyncStorage.getItem(TOKEN_KEY);
    return JSON.parse(token);
  } catch (error) {
    //console.error('Error retrieving data from AsyncStorage:', error);
    return null;
  }
};

export const removeUserData = async () => {
  try {
    await AsyncStorage.removeItem(STORAGE_KEY);
    await AsyncStorage.removeItem(TOKEN_KEY);
  } catch (error) {
    console.error('Error removing data from AsyncStorage:', error);
  }
};

export const removeUserToken = async () => {
  try {
    await AsyncStorage.removeItem(TOKEN_KEY);
  } catch (error) {
    console.error('Error removing data from AsyncStorage:', error);
  }
};

export const removeSpecificKey = async (key) => {
  try {
    await AsyncStorage.removeItem(key);
  } catch (error) {
    console.error(`Error removing key ${key} from AsyncStorage:`, error);
  }
};

export const saveToken = async (key,value) => {
  try {
    await AsyncStorage.setItem(key,value);
  } catch (error) {
    console.error(`Error removing key ${key} from AsyncStorage:`, error);
  }
};


export const updateData = async (newValue) => {
  try {
    const existingValue = await AsyncStorage.getItem(STORAGE_KEY);
    if (existingValue !== null) {
      const parsedValue = JSON.parse(existingValue);

      if (parsedValue.profile) {
         parsedValue.profile.profile_photo = newValue.profile_photo;
      }

      const updatedValue = JSON.stringify(parsedValue);
      await AsyncStorage.setItem(STORAGE_KEY, updatedValue);
      
    } else {
      console.log(`Value with key ${STORAGE_KEY} doesn't exist in AsyncStorage`);
    }
  } catch (error) {
    console.error(`Error updating value with key ${key} in AsyncStorage:`, error);
  }
};										
									

Constant Config

This is a constant file where you can place global constant which you need to inlcude in your mobile application.Where you can place all of your configuration constant.

									     
//constants.js
export const apiUrl = "https://yourlearn.in/";
export const axiosHeaders = {
	'Accept': 'application/json',
	'Content-Type': 'application/json',
	'api-key': '123123',
	'user-id': '7574874873'
};
export const netErrorMsg = "You're not connected to the internet.\n Please connect and retry.";
export const axiosFlashMessageTimeOut = 3000;
export const alertInfoMessageTimeOut = 3000;										
									

Custom Toast Provider Component

We need a component for alert message in react native application, We will use react native toast notifications, package for this purpose. The CustomToastProvider component appears to be a custom component used in your React Native application. Based on its name, it likely provides a context or a higher-order component to manage and display custom toast notifications throughout your app.It could create a React context to manage the state and functionality related to displaying toast notifications

									     
// CustomToastProvider.js
import React from 'react';
import { ToastProvider } from 'react-native-toast-notifications';
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { View, Text, TouchableOpacity } from 'react-native';

const CustomToastProvider = ({ children }) => {
  return (
    <ToastProvider
      placement="top" // You can adjust placement as needed
      dangerIcon={<MaterialCommunityIcons name="close" color="#fff" />}
      successIcon={<MaterialCommunityIcons name="check" color="#fff" size={18} />}
      offset={110}
      animationType= "zoom-in"
      toastStyle={{
        maxWidth: '90%', 
      }}
      renderType={{
        custom_toast: (toast) => (
          <View
            style={{
              paddingHorizontal: 15,
              paddingVertical: 10,
              backgroundColor: "#fff",
              marginVertical: 4,
              borderRadius: 8,
              borderLeftColor: "#007bff",
              elevation: 3,
              borderLeftWidth: 6,
              justifyContent: "center",
              paddingLeft: 16,
            }}
          >
            <Text
              style={{
                fontSize: 14,
                color: "#333",
                fontWeight: "bold",
              }}
            >
              {toast.data.title}
            </Text>
            <Text style={{ color: "#000", marginTop: 2 }}>{toast.message}</Text>
          </View>
        ),
        with_close_button: (toast) => (
          <View
            style={{
              paddingHorizontal: 15,
              paddingVertical: 10,
              backgroundColor: "#fff",
              marginVertical: 4,
              borderRadius: 8,
              borderLeftColor: "#007bff",
              borderLeftWidth: 6,
              justifyContent: "center",
              paddingHorizontal: 16,
              flexDirection: "row",
              elevation: 3,
            }}
          >
            <Text style={{ color: "#000", marginRight: 16 }}>{toast.message}</Text>
            <TouchableOpacity
              onPress={() => toast.onHide()}
              style={{
                marginLeft: "auto",
                width: 25,
                height: 25,
                borderRadius: 5,
                backgroundColor: "#fff",
                justifyContent: "center",
                alignItems: "center",
              }}
            >
              <Text style={{ color: "#000", fontWeight: "500", marginBottom: 2.5 }}>
                x
              </Text>
            </TouchableOpacity>
          </View>
        ),
      }}
    >
      {children}
    </ToastProvider>
  );
};
export default CustomToastProvider;										
									

Dashboard Navigator

Dashboard Navigator defines a React Native component called DashboardNavigator. It serves as a navigation drawer for the dashboard screens of a mobile application.Overall, this component creates a navigation drawer for the dashboard screens of the application, allowing users to navigate between different screens such as home, settings, sharing, and logout.

You can add manny screen const screens array and import at the top as you can already see others screens also imported.

									     
//DashboardNavigator.js
import React, { useState, useEffect } from 'react';
import { Text,View,ScrollView,SafeAreaView,StyleSheet,Dimensions,useWindowDimensions   } from 'react-native';
import { createDrawerNavigator,DrawerItem } from '@react-navigation/drawer';
import CustomDrawerHeader from '../components/CustomDrawerHeader'; 
import { FontAwesome } from '@expo/vector-icons'; 
import HomeScreen from '../screens/DashboardScreen';
import SettingsScreen from '../screens/Accounts/BookView';
import ShareScreen from '../screens/Accounts/BookView';
import LogoutScreen from '../screens/LogoutScreen';
import AuthService from '../services/AuthService';

var height = Dimensions.get('window').height;
const Drawer = createDrawerNavigator();

const DashboardNavigator = ({ navigation,route }) => {

  const [defaultImage, setDefaultImage] = useState(null);
  const screens = [
    { name: "Home", component: HomeScreen,'icon':"home" },
    { name: "Settings", component: SettingsScreen,'icon':"cog" },
    { name: "Share", component: ShareScreen,'icon':"share" },
    { name: "Logout", component: LogoutScreen,'icon':"sign-out" },
  ];

  useEffect(() => {
    if (route.params && route.params.newPhotoUrl) {
      setDefaultImage(route.params.newPhotoUrl);
    }
  }, [route.params]);


  const signOut = async () => {
    try {
      await AuthService.logout();
      navigation.replace('SignIn');
    } catch (error) {
      console.error('Error signing out:', error);
    }
  };

  const  FlatListItemSeparator = () => {
    return (
      <View style={{ height: 1, width: "260%", backgroundColor: "#CED0CE",marginLeft:-150,borderBottomColor: '#ccc', marginTop: '4%' }} />
    );
  };

  return (
   
  <SafeAreaView style={styles.mainContainer} forceInset={{ top: 'always', horizontal: 'never' }}>

      <Drawer.Navigator
        initialRouteName={screens[0].name}
        
        screenOptions={{
          activeTintColor:'#FFF', 
          drawerActiveTintColor: '#999', 
          drawerInactiveTintColor: '#FFF', 
          activeBackgroundColor:'#FFF', 
          itemsContainerStyle: {
            marginVertical: 0,
          },
          iconContainerStyle: {
            opacity: 1
          },
          drawerLabelStyle: {
            fontSize: 12, 
            fontFamily: 'notoserif', 
            marginVertical: 0,
          }
        }}
        drawerContent={props => <CustomDrawerHeader {...props} defaultImage={defaultImage} />} 
      >
        {screens.map((screen, index) => (
          <Drawer.Screen
            key={index}
            name={screen.name}
            component={screen.component}
            options={{
                drawerLabel: ({ focused, color, size }) => (
                  <View style={{  alignItems: 'flex-start', justifyContent: 'center', marginVertical: -9 }}>
                    <Text style={{ color: focused ? '#05508f' : '#999', }}>
                        <View style={{ flexDirection: 'row', alignItems: 'center'}}>
                            <FontAwesome name={screen.icon} size={12} color={focused ? '#05508f' : '#999'} /> 
                            <Text style={{ marginLeft: 15 }}>{screen.name}</Text>
                        </View>
                    </Text>
                    <FlatListItemSeparator />
                  </View>
              ),
              title: screen.name,
            }}
            
          />
        ))}
      </Drawer.Navigator>
    </SafeAreaView>
    
  );
};

const styles = StyleSheet.create({
  mainContainer: {
    flex: 1,
    backgroundColor: '#ffffff',
    alignItems: 'stretch',
    justifyContent: 'center',
    height: height,
  },
});
export default DashboardNavigator;										
									

LogoutScreen

Logout screen will logout the user and clear storage.

									     
// LogoutScreen.js
import React, { useEffect } from 'react';
import AuthService from '../services/AuthService';
const LogoutScreen = ({ navigation }) => {
  useEffect(() => {
    signOut();
  }, []);

  const signOut = async () => {
    try {
      await AuthService.logout();
      navigation.replace('SignIn');
    } catch (error) {
      console.error('Error signing out:', error);
    }
  };
  return null;
  
};
export default LogoutScreen;										
									

Custom Drawer Header

Custome drawer header is a component which will display app logo and user name and user type with there profile photo.

login/logout screen in React Native

									     
//CustomDrawerHeader.js
import React, { useEffect, useState } from 'react';
import { DrawerContentScrollView, DrawerItemList } from '@react-navigation/drawer';
import { View, Text, Image, StyleSheet ,TouchableOpacity} from 'react-native';
import {apiUrl} from  '../config/constants';
import AuthService from '../services/AuthService'; 

const CustomDrawerHeader = (props) => {

  const [userInfo, setUserInfo] = useState(null);
 
  useEffect(() => {
    const checkData = async () => {
      const userData = await AuthService.getUserData();
      if(userData){
        setUserInfo(userData.profile);
      }
    };
    checkData();
  }, []);

  return (
    
    <DrawerContentScrollView {...props} >
      <View style={styles.headerContainer}>
        <View style={styles.centerContainer}>
        <View style={styles.leftContainer}>
          <Image
              source={{ uri: apiUrl + 'assets/images/signin-logo.png' }}
              style={styles.logo}
            />
        </View>
          <View style={styles.userInfo}>
            <Text style={styles.welcomeText}>Welcome {userInfo?.username}</Text>
            <Text style={styles.userRole}>{userInfo?.usertypename}</Text>
          </View>
        </View>
        
        <View style={styles.rightContainer}>
           <View style={styles.avatarContainer}>
            <Image
              source={{ uri: props.defaultImage ? props.defaultImage : userInfo?.profile_photo}}
              style={styles.avatar}
            />
          </View>
        </View>
      </View>
      <FlatListItemSeparator />
      <DrawerItemList {...props} />
    </DrawerContentScrollView>
  );
};

const  FlatListItemSeparator = () => {
  return (
    <View style={{ height: 1, width: "150%", backgroundColor: "#CED0CE",marginLeft:-150,borderBottomColor: '#ccc', marginTop: '4%' }} />
  );
};

const styles = StyleSheet.create({
  headerContainer: {
    flexDirection: 'row', 
    //borderBottomWidth: 1,
    //borderBottomColor: '#ccc',
    paddingBottom:15,
    paddingTop:1,
  },
  leftContainer: {
    flex: 1,
    flexDirection: 'row',
    alignItems: 'center',
  },
  centerContainer: {
    justifyContent: 'center',
    alignItems: 'center',
    //marginLeft: 10,
  },
  rightContainer: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  logo: {
    width: 200,
    height: 40,
    resizeMode: 'contain',
  },
  userInfo: {
    marginLeft: 5,
  },
  welcomeText: {
    fontSize: 12,
    fontWeight: 'bold',
    fontFamily: 'monospace', 
    textAlign:'center'
  },
  userRole: {
    fontSize: 12,
    color: '#666',
    fontWeight: 'bold',
    fontFamily: 'monospace', 
  },
  avatarContainer: {
    borderWidth: 1, 
    borderColor: '#000', 
    borderRadius: 32, 
    borderColor: 'navy',
  },
  avatar: {
    width: 65,
    height: 65,
    borderRadius: 32,
  },
});
export default CustomDrawerHeader;										
									

Dashboard Screen

Below is dashboard screen when authorization is successfull. it will show dashboard with navigation drawer. On click signout local sotorage will be cleared and then redirect to login or sign in form or screen.

									     
//DashboardScreen.js
import React from 'react';
import { View, Text,Button  } from 'react-native';
import { useAuth } from '../services/AuthContext'
const DashboardScreen = ({ navigation }) => {
  const { state, logout } = useAuth();
  if (!state.isAuthenticated) {
    navigation.navigate('Login');
    return null; 
  }
  const handleLogout = () => {
    logout();
    navigation.navigate('Login');
     return null;
  };
  return (
    <View>
      <Text>Welcome, {state.user.username}!</Text>
      <Text>Dashboard Screen</Text>
      <Button title="Logout" onPress={handleLogout} />
    </View>
  );
};
export default DashboardScreen;										
									

Conclusion:

Creating a login/logout screen in React Native is a fundamental aspect of building secure and user-friendly mobile applications. By prioritizing design, functionality, and security considerations, developers can ensure a seamless authentication experience for app users.