DEV Community

Navnit Rai
Navnit Rai

Posted on

Users

import {
  Box,
  Button,
  Grid,
  Heading,
  HStack,
  Table,
  TableCaption,
  TableContainer,
  Tbody,
  Td,
  Th,
  Thead,
  Tr,
} from '@chakra-ui/react'; // Importing Chakra UI components for layout and styling
import React, { useEffect } from 'react'; // Importing React and useEffect hook
import { RiDeleteBin7Fill } from 'react-icons/ri'; // Importing delete icon
import cursor from '../../../assets/images/cursor.png'; // Custom cursor image
import Sidebar from '../Sidebar'; // Importing Sidebar component
import { useDispatch, useSelector } from 'react-redux'; // For accessing Redux store
import {
  deleteUser, // Action to delete user
  getAllUsers, // Action to fetch all users
  updateUserRole, // Action to update user role
} from '../../../redux/actions/admin'; // Importing actions
import toast from 'react-hot-toast'; // For toast notifications

// Users component to display all users in a table
const Users = () => {
  // Extracting users, loading state, error, and message from Redux store
  const { users, loading, error, message } = useSelector(state => state.admin);

  const dispatch = useDispatch(); // Hook to access dispatch function

  // Handler to update user role
  const updateHandler = userId => {
    dispatch(updateUserRole(userId));
  };

  // Handler to delete a user
  const deleteButtonHandler = userId => {
    dispatch(deleteUser(userId));
  };

  // useEffect to fetch users and handle errors/messages
  useEffect(() => {
    if (error) {
      toast.error(error); // Show error notification
      dispatch({ type: 'clearError' }); // Clear error from Redux store
    }

    if (message) {
      toast.success(message); // Show success notification
      dispatch({ type: 'clearMessage' }); // Clear message from Redux store
    }

    dispatch(getAllUsers()); // Fetch all users
  }, [dispatch, error, message]); // Dependencies for useEffect

  return (
    <Grid
      css={{
        cursor: `url(${cursor}), default`, // Custom cursor style
      }}
      minH={'100vh'} // Minimum height for the grid
      templateColumns={['1fr', '5fr 1fr']} // Responsive layout
    >
      <Box p={['0', '16']} overflowX="auto"> // Main box for users table
        <Heading
          textTransform={'uppercase'} // Uppercase title
          children="All Users"
          my="16"
          textAlign={['center', 'left']} // Responsive text alignment
        />

        <TableContainer w={['100vw', 'full']}> // Table container
          <Table variant={'simple'} size="lg"> // Table component
            <TableCaption>All available users in the database</TableCaption> // Table caption

            <Thead> // Table header
              <Tr>
                <Th>Id</Th>
                <Th>Name</Th>
                <Th>Email</Th>
                <Th>Role</Th>
                <Th>Subscription</Th>
                <Th isNumeric>Action</Th>
              </Tr>
            </Thead>

            <Tbody> // Table body
              {users && // Check if users exist
                users.map(item => ( // Map over users to create rows
                  <Row
                    updateHandler={updateHandler} // Pass update handler
                    deleteButtonHandler={deleteButtonHandler} // Pass delete handler
                    key={item._id} // Unique key for each row
                    item={item} // Pass user item
                    loading={loading} // Pass loading state
                  />
                ))}
            </Tbody>
          </Table>
        </TableContainer>
      </Box>

      <Sidebar /> // Rendering Sidebar component
    </Grid>
  );
};

export default Users; // Exporting Users component

// Row component for rendering individual user data
function Row({ item, updateHandler, deleteButtonHandler, loading }) {
  return (
    <Tr> // Table row for a user
      <Td>#{item._id}</Td> // User ID
      <Td>{item.name}</Td> // User name
      <Td>{item.email}</Td> // User email
      <Td>{item.role}</Td> // User role
      <Td>
        {item.subscription && item.subscription.status === 'active'
          ? 'Active' // Display 'Active' if subscription is active
          : 'Not Active'} // Display 'Not Active' otherwise
      </Td>

      <Td isNumeric> // Numeric action column
        <HStack justifyContent={'flex-end'}> // Horizontal stack for buttons
          <Button
            onClick={() => updateHandler(item._id)} // Change role button
            variant={'outline'} // Outline variant
            color="purple.500" // Color
            isLoading={loading} // Loading state for button
          >
            Change Role
          </Button>

          <Button
            onClick={() => deleteButtonHandler(item._id)} // Delete button
            color={'purple.600'} // Color
            isLoading={loading} // Loading state for button
          >
            <RiDeleteBin7Fill /> // Delete icon
          </Button>
        </HStack>
      </Td>
    </Tr>
  );
}

Enter fullscreen mode Exit fullscreen mode

Top comments (0)