Creating the Employee Management Application using React-Native is skill developing project. In this project, the application admin can manage the employees by adding them dynamically, updating the details, and deleting the employee as per the requirement. In this article, we will develop this Employee management application using React-Native by adding more features to it.
Preview of the final output: Let us look at what the final output will look like.
Prerequisites & Technologies Used:
- Introduction to React Native
- React Native State
- React Native Props
- Expo CLI
- Node.js and npm (Node Package Manager)
Approach to creating Employee Management App using React-Native
- This application/project is mainly a multi-screen application.
- In this application, we have various functionalities like Searching for Employees in the list, sorting the employees, etc.
- The application admin can add the employees to the application, whereas the validation is been checked for the Employee ID. Also, the admin can update and delete the details of the employee as per the need.
- The application is styled with attractive styling, dynamic icons, and colors.
Steps to Create React Native Application:
Step 1: Create the project:
npx create-expo-app emp-app
Step 2: Navigate to the project
cd emp-app
Step 3: Install the packages as follows:
npm install expo/vector-icons react-native-paper react-native-screens react-native-elements
react-navigation/stack react-native-reanimated react-navigation/native react-native-vector-icons
react-native-gesture-handler react-native-safe-area-context react-native-vector-icons/MaterialIcons
Project Structure:
The updated dependencies in package.json file will look like:
"dependencies": {
"@expo/vector-icons": "^13.0.0",
"react-native-paper": "4.9.2",
"react-native-screens": "~3.20.0",
"react-native-elements": "*",
"@react-navigation/stack": "*",
"react-native-reanimated": "~2.14.4",
"@react-navigation/native": "6.0.0*",
"react-native-vector-icons": "10.0.3",
"react-native-gesture-handler": "~2.9.0",
"react-native-safe-area-context": "4.5.0",
"react-native-vector-icons/MaterialIcons": "*"
}
Example: In this example, we are following the above-explained approach.
// App.js import React, { useState, useEffect } from "react" ;
import { View,
Text,
TextInput,
Button,
FlatList,
TouchableOpacity,
Alert,
} from "react-native" ;
import { NavigationContainer } from "@react-navigation/native" ;
import { createStackNavigator } from "@react-navigation/stack" ;
import { FAB,
Card,
Title,
Paragraph,
Provider as PaperProvider,
Appbar,
} from "react-native-paper" ;
import { SearchBar } from "react-native-elements" ;
import Icon from "react-native-vector-icons/MaterialIcons" ;
import Animated, { useAnimatedStyle,
withSpring,
useSharedValue,
} from "react-native-reanimated" ;
import { styles } from "./styles" ;
const HomeScreen = ({ navigation }) => { const [employees, setEmployees] = useState([]);
const [search, setSearch] = useState( "" );
const [filteredEmployees, setFilteredEmployees] = useState([]);
const [sortOrder, setSortOrder] = useState( "asc" );
const fabScale = useSharedValue(1);
useEffect(() => {
const defaultEmployees = [
{
id: "1" ,
empId: "EMP001" ,
name: "Ramesh" ,
position: "Software Engineer" ,
},
{
id: "2" ,
empId: "EMP002" ,
name: "Suresh" ,
position: "Product Manager" ,
},
{
id: "3" ,
empId: "EMP003" ,
name: "Naresh" ,
position: "UI/UX Designer" ,
},
];
setEmployees(defaultEmployees);
}, []);
useEffect(() => {
const filtered = employees.filter((employee) =>
employee.name.toLowerCase().includes(search.toLowerCase())
);
setFilteredEmployees(filtered);
}, [search, employees]);
const handleSort = () => {
const newOrder = sortOrder === "asc" ? "desc" : "asc" ;
setSortOrder(newOrder);
const sortedEmployees = [...employees].sort((a, b) => {
if (newOrder === "asc" ) {
return a.name.localeCompare(b.name);
} else {
return b.name.localeCompare(a.name);
}
});
setEmployees(sortedEmployees);
};
const deleteEmployee = (id) => {
const updatedEmployees = employees.filter(
(employee) => employee.id !== id
);
setEmployees(updatedEmployees);
};
const editEmployee = (id, updatedEmployee) => {
const updatedEmployees = employees.map((employee) =>
employee.id === id ? updatedEmployee : employee
);
setEmployees(updatedEmployees);
};
const addEmployee = (newEmployee) => {
if (
employees.some((employee) => employee.empId === newEmployee.empId)
) {
Alert.alert( "Error" , "Employee with the same ID already exists." );
} else {
setEmployees([...employees, newEmployee]);
navigation.goBack();
}
};
const fabStyle = useAnimatedStyle(() => {
return {
transform: [{ scale: withSpring(fabScale.value) }],
};
});
return (
<View style={styles.container}>
<View style={styles.titleContainer}>
<Icon
name= "people"
size={24}
color= "white"
style={styles.titleIcon}
/>
<Text style={styles.title}>GeeksforGeeks Emp Management</Text>
</View>
<Appbar.Header style={styles.appbar}>
<SearchBar
placeholder= "Search Employees..."
onChangeText={setSearch}
value={search}
lightTheme
containerStyle={styles.searchBarContainer}
inputContainerStyle={styles.searchBarInputContainer}
/>
<Appbar.Action
icon={() => (
<Icon name= "filter-alt" size={24} color= "white" />
)}
onPress={handleSort}
/>
</Appbar.Header>
{(filteredEmployees.length === 0 && search !== "" ) ||
(employees.length === 0 && filteredEmployees.length === 0) ? (
<View style={styles.noRecordsContainer}>
<Text>No records found</Text>
</View>
) : (
<FlatList
data={filteredEmployees}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<Card style={styles.card}>
<Card.Content>
<Title>{item.name}</Title>
<Paragraph>ID: {item.empId}</Paragraph>
<Paragraph>Position: {item.position}</Paragraph>
</Card.Content>
<Card.Actions>
<TouchableOpacity
onPress={() =>
navigation.navigate( "Edit" , {
employee: item,
editEmployee: editEmployee,
})
}
>
<Icon
name= "edit"
size={24}
color= "#3498db"
style={styles.actionIcon}
/>
</TouchableOpacity>
<TouchableOpacity
onPress={() => deleteEmployee(item.id)}
>
<Icon
name= "delete"
size={24}
color= "#3498db"
style={styles.actionIcon}
/>
</TouchableOpacity>
</Card.Actions>
</Card>
)}
style={styles.employeeList}
/>
)}
<Animated.View style={[styles.fab, fabStyle]}>
<FAB
icon={() => <Icon name= "add" size={24} color= "white" />}
onPress={() => {
fabScale.value = 0.8;
navigation.navigate( "Add" , {
addEmployee: addEmployee,
});
}}
onStateChange={({ nativeEvent }) => {
if (nativeEvent.state === 2) {
fabScale.value = 1;
}
}}
/>
</Animated.View>
</View>
);
}; const AddEmpScreen = ({ route, navigation }) => { const [name, setName] = useState( "" );
const [position, setPosition] = useState( "" );
const [empId, setEmpId] = useState( "" );
const addEmployee = () => {
if (!empId || !name || !position) {
Alert.alert( "Error" , "Please fill in all the fields." );
return ;
}
const existingEmployees = route.params?.employees || [];
if (existingEmployees.some((employee) => employee.empId === empId)) {
Alert.alert( "Error" , "Employee with the same ID already exists." );
} else {
route.params?.addEmployee({
id: Date.now().toString(),
empId,
name,
position,
});
navigation.goBack();
}
};
return (
<View style={styles.container}>
<TextInput
placeholder= "Enter Employee ID"
value={empId}
onChangeText={(text) => setEmpId(text)}
style={styles.input}
/>
<TextInput
placeholder= "Enter Name"
value={name}
onChangeText={(text) => setName(text)}
style={styles.input}
/>
<TextInput
placeholder= "Enter Position"
value={position}
onChangeText={(text) => setPosition(text)}
style={styles.input}
/>
<Button title= "Add Employee" onPress={addEmployee} />
</View>
);
}; const EditEmpScreen = ({ route, navigation }) => { const { employee, editEmployee } = route.params;
const [empId, setEmpId] = useState(employee.empId);
const [name, setName] = useState(employee.name);
const [position, setPosition] = useState(employee.position);
const saveChanges = () => {
if (!empId || !name || !position) {
Alert.alert( "Error" , "Please fill in all the fields." );
return ;
}
const existingEmployees = route.params?.employees || [];
if (
existingEmployees.some(
(emp) => emp.id !== employee.id && emp.empId === empId
)
) {
Alert.alert( "Error" , "Employee with the same ID already exists." );
} else {
editEmployee(employee.id, { ...employee, empId, name, position });
navigation.goBack();
}
};
return (
<View style={styles.container}>
<TextInput
placeholder= "Enter Employee ID"
value={empId}
onChangeText={(text) => setEmpId(text)}
style={styles.input}
/>
<TextInput
placeholder= "Enter Name"
value={name}
onChangeText={(text) => setName(text)}
style={styles.input}
/>
<TextInput
placeholder= "Enter Position"
value={position}
onChangeText={(text) => setPosition(text)}
style={styles.input}
/>
<Button title= "Save Changes" onPress={saveChanges} />
</View>
);
}; const Stack = createStackNavigator(); const App = () => { return (
<PaperProvider>
<NavigationContainer>
<Stack.Navigator initialRouteName= "Home" >
<Stack.Screen name= "Home" component={HomeScreen} />
<Stack.Screen name= "Add" component={AddEmpScreen} />
<Stack.Screen name= "Edit" component={EditEmpScreen} />
</Stack.Navigator>
</NavigationContainer>
</PaperProvider>
);
}; export default App;
|
// styles.js import { StyleSheet } from 'react-native' ;
export const styles = StyleSheet.create({ container: {
flex: 1,
backgroundColor: '#f0f0f0' ,
},
titleContainer: {
backgroundColor: 'white' ,
flexDirection: 'row' ,
alignItems: 'center' ,
paddingVertical: 10,
paddingLeft: 10,
marginBottom: 5,
},
titleIcon: {
marginRight: 10,
color: 'green' ,
},
title: {
color: 'green' ,
fontSize: 20,
fontWeight: 'bold' ,
},
appbar: {
backgroundColor: 'green' ,
},
input: {
height: 40,
borderColor: 'gray' ,
borderWidth: 1,
marginBottom: 10,
padding: 10,
backgroundColor: 'white' ,
borderRadius: 5,
},
employeeList: {
flex: 1,
marginTop: 10,
paddingHorizontal: 10,
},
card: {
marginBottom: 10,
elevation: 4,
borderRadius: 10,
},
actionIcon: {
marginHorizontal: 10,
},
fab: {
position: 'absolute' ,
margin: 16,
right: 0,
bottom: 0,
backgroundColor: '#3498db' ,
borderRadius: 28,
},
searchBarContainer: {
backgroundColor: 'transparent' ,
borderTopColor: 'transparent' ,
borderBottomColor: 'transparent' ,
flex: 1,
},
searchBarInputContainer: {
backgroundColor: '#ecf0f1' ,
},
noRecordsContainer: {
flex: 1,
justifyContent: 'center' ,
alignItems: 'center' ,
},
}); |
Step to run the application:
Step 1: Navigate to the terminal or command prompt and type the required command there to run the React native application.
npx expo start
Step 2: Depending on your Operating System, type the following command in terminal
- To run on Android:
npx react-native run-android
- To run on IOS:
npx react-native run-ios
Output: