Coursemology/coursemology2

View on GitHub
client/app/bundles/course/enrol-requests/pages/UserRequests/index.tsx

Summary

Maintainability
A
3 hrs
Test Coverage
import { FC, useEffect, useState } from 'react';
import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';

import Page from 'lib/components/core/layouts/Page';
import LoadingIndicator from 'lib/components/core/LoadingIndicator';
import Note from 'lib/components/core/Note';
import { useAppDispatch, useAppSelector } from 'lib/hooks/store';
import toast from 'lib/hooks/toast';

import UserManagementTabs from '../../../users/components/navigation/UserManagementTabs';
import PendingEnrolRequestsButtons from '../../components/buttons/PendingEnrolRequestsButtons';
import EnrolRequestsTable from '../../components/tables/EnrolRequestsTable';
import { fetchEnrolRequests } from '../../operations';
import {
  getAllEnrolRequestEntities,
  getManageCourseUserPermissions,
  getManageCourseUsersSharedData,
} from '../../selectors';

type Props = WrappedComponentProps;

const translations = defineMessages({
  manageUsersHeader: {
    id: 'course.enrolRequests.UserRequests.manageUsersHeader',
    defaultMessage: 'Manage Users',
  },
  pending: {
    id: 'course.enrolRequests.UserRequests.pending',
    defaultMessage: 'Pending Enrolment Requests',
  },
  approved: {
    id: 'course.enrolRequests.UserRequests.approved',
    defaultMessage: 'Approved Enrolment Requests',
  },
  rejected: {
    id: 'course.enrolRequests.UserRequests.rejected',
    defaultMessage: 'Rejected Enrolment Requests',
  },
  noEnrolRequests: {
    id: 'course.enrolRequests.UserRequests.noEnrolRequests',
    defaultMessage: 'There is no enrol request.',
  },
  fetchEnrolRequestsFailure: {
    id: 'course.enrolRequests.UserRequests.fetchEnrolRequestsFailure',
    defaultMessage: 'Failed to fetch enrol requests',
  },
});

const UserRequests: FC<Props> = (props) => {
  const { intl } = props;
  const [isLoading, setIsLoading] = useState(true);
  const enrolRequests = useAppSelector(getAllEnrolRequestEntities);
  const permissions = useAppSelector(getManageCourseUserPermissions);
  const sharedData = useAppSelector(getManageCourseUsersSharedData);
  const pendingEnrolRequests = enrolRequests.filter(
    (enrolRequest) => enrolRequest.status === 'pending',
  );
  const approvedEnrolRequests = enrolRequests.filter(
    (enrolRequest) => enrolRequest.status === 'approved',
  );
  const rejectedEnrolRequests = enrolRequests.filter(
    (enrolRequest) => enrolRequest.status === 'rejected',
  );

  const dispatch = useAppDispatch();

  useEffect(() => {
    setIsLoading(true);
    dispatch(fetchEnrolRequests())
      .finally(() => {
        setIsLoading(false);
      })
      .catch(() =>
        toast.error(intl.formatMessage(translations.fetchEnrolRequestsFailure)),
      );
  }, [dispatch]);

  const renderEmptyState = (): JSX.Element | undefined => {
    if (
      pendingEnrolRequests.length === 0 &&
      approvedEnrolRequests.length === 0 &&
      rejectedEnrolRequests.length === 0
    ) {
      return (
        <Page.PaddedSection>
          <Note message={intl.formatMessage(translations.noEnrolRequests)} />
        </Page.PaddedSection>
      );
    }
    return undefined;
  };

  return (
    <Page title={intl.formatMessage(translations.manageUsersHeader)} unpadded>
      {isLoading ? (
        <LoadingIndicator />
      ) : (
        <>
          <UserManagementTabs
            permissions={permissions}
            sharedData={sharedData}
          />
          {renderEmptyState()}
          {pendingEnrolRequests.length > 0 && (
            <EnrolRequestsTable
              enrolRequests={pendingEnrolRequests}
              pendingEnrolRequests
              renderRowActionComponent={(enrolRequest): JSX.Element => (
                <PendingEnrolRequestsButtons enrolRequest={enrolRequest} />
              )}
              title={intl.formatMessage(translations.pending)}
            />
          )}
          {approvedEnrolRequests.length > 0 && (
            <EnrolRequestsTable
              approvedEnrolRequests
              enrolRequests={approvedEnrolRequests}
              title={intl.formatMessage(translations.approved)}
            />
          )}
          {rejectedEnrolRequests.length > 0 && (
            <EnrolRequestsTable
              enrolRequests={rejectedEnrolRequests}
              rejectedEnrolRequests
              title={intl.formatMessage(translations.rejected)}
            />
          )}
        </>
      )}
    </Page>
  );
};

const handle = translations.manageUsersHeader;

export default Object.assign(injectIntl(UserRequests), { handle });