Coursemology/coursemology2

View on GitHub
client/app/bundles/course/group/pages/GroupIndex/index.jsx

Summary

Maintainability
A
2 hrs
Test Coverage
import { useEffect, useState } from 'react';
import { defineMessages, injectIntl } from 'react-intl';
import { Outlet, useNavigate, useParams } from 'react-router-dom';
import { Tab, Tabs } from '@mui/material';
import PropTypes from 'prop-types';

import CourseAPI from 'api/course';
import Page from 'lib/components/core/layouts/Page';
import Link from 'lib/components/core/Link';
import LoadingIndicator from 'lib/components/core/LoadingIndicator';
import Note from 'lib/components/core/Note';
import toast from 'lib/hooks/toast';

import GroupNew from '../GroupNew';

const translations = defineMessages({
  groups: {
    id: 'course.group.GroupIndex.groups',
    defaultMessage: 'Groups',
  },
  noCategory: {
    id: 'course.group.GroupIndex.noCategory',
    defaultMessage: "You don't have a group category created! Create one now!",
  },
  fetchCategoriesFailure: {
    id: 'course.group.GroupIndex.fetchCategoriesFailure',
    defaultMessage: 'Failed to retrieve group categories.',
  },
});

const GroupIndex = (props) => {
  const { intl } = props;
  const [isLoading, setIsLoading] = useState(true);
  const [groupCategories, setGroupCategories] = useState({
    groupCategories: [],
    permissions: { canCreate: false },
  });
  const { groupCategoryId } = useParams();
  const navigate = useNavigate();

  useEffect(() => {
    CourseAPI.groups
      .fetchGroupCategories()
      .then((response) => {
        // Navigate to the first tab if the url endpoint is of /groups only.
        if (!groupCategoryId && response.data.groupCategories.length > 0) {
          navigate(`${response.data.groupCategories[0].id}`);
        }
        setGroupCategories(response.data);
        setIsLoading(false);
      })
      .catch(() => {
        toast.error(intl.formatMessage(translations.fetchCategoriesFailure));
        setIsLoading(false);
      });
  }, []);

  const headerToolbars = groupCategories.permissions.canCreate && <GroupNew />;

  const renderTabs =
    groupCategories.groupCategories.length > 1 ? (
      <Tabs
        scrollButtons="auto"
        value={
          parseInt(groupCategoryId, 10) ?? groupCategories.groupCategories[0].id
        }
        variant="scrollable"
      >
        {groupCategories.groupCategories.map((category) => (
          <Tab
            key={category.id}
            className="no-underline outline-none"
            component={Link}
            label={category.name}
            to={String(category.id)}
            value={category.id}
          />
        ))}
      </Tabs>
    ) : null;

  const renderBody =
    groupCategories.groupCategories.length === 0 ? (
      <Note message={intl.formatMessage(translations.noCategory)} />
    ) : (
      <>
        <Page.UnpaddedSection>{renderTabs}</Page.UnpaddedSection>
        <Outlet />
      </>
    );

  return (
    <Page
      actions={headerToolbars}
      title={intl.formatMessage(translations.groups)}
    >
      {isLoading ? <LoadingIndicator /> : renderBody}
    </Page>
  );
};

GroupIndex.propTypes = {
  intl: PropTypes.object.isRequired,
};

const handle = translations.groups;

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