Open In App

Create an Employee Management using React-Native

Last Updated : 25 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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.

EMP

Prerequisites & Technologies Used:

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.

Javascript




// 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;


Javascript




// 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:

Output



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads