Coursemology/coursemology2

View on GitHub
client/app/bundles/course/achievement/pages/AchievementShow/index.tsx

Summary

Maintainability
B
4 hrs
Test Coverage
import { FC, useEffect, useState } from 'react';
import { defineMessages, injectIntl, WrappedComponentProps } from 'react-intl';
import { useParams } from 'react-router-dom';
import { Grid, Tooltip, Typography } from '@mui/material';

import { getAchievementBadgeUrl } from 'course/helper/achievements';
import AvatarWithLabel from 'lib/components/core/AvatarWithLabel';
import Page from 'lib/components/core/layouts/Page';
import Link from 'lib/components/core/Link';
import LoadingIndicator from 'lib/components/core/LoadingIndicator';
import { getCourseUserURL } from 'lib/helpers/url-builders';
import { getCourseId } from 'lib/helpers/url-helpers';
import { useAppDispatch, useAppSelector } from 'lib/hooks/store';

import AchievementManagementButtons from '../../components/buttons/AchievementManagementButtons';
import { loadAchievement } from '../../operations';
import {
  getAchievementEntity,
  getAchievementMiniEntity,
} from '../../selectors';

type Props = WrappedComponentProps;

const translations = defineMessages({
  header: {
    id: 'course.achievement.AchievementShow.header',
    defaultMessage: 'Achievement - {title}',
  },
  studentsWithAchievement: {
    id: 'course.achievement.AchievementShow.studentsWithAchievement',
    defaultMessage: 'Students with this achievement',
  },
});

const AchievementShow: FC<Props> = (props) => {
  const { intl } = props;
  const courseId = getCourseId();
  const [isLoading, setIsLoading] = useState(true);
  const dispatch = useAppDispatch();
  const { achievementId } = useParams();
  const achievementMiniEntity = useAppSelector((state) =>
    getAchievementMiniEntity(state, +achievementId!),
  );
  const achievement = useAppSelector((state) =>
    getAchievementEntity(state, +achievementId!),
  );

  useEffect(() => {
    if (achievementId) {
      dispatch(loadAchievement(+achievementId)).finally(() =>
        setIsLoading(false),
      );
    }
  }, [dispatch, achievementId]);

  if (!achievementMiniEntity && isLoading) {
    return <LoadingIndicator />;
  }
  if (!achievementMiniEntity) {
    return null;
  }

  return (
    <Page
      actions={
        achievementMiniEntity.permissions?.canManage && (
          <AchievementManagementButtons
            key={achievementMiniEntity.id}
            achievement={achievementMiniEntity}
            navigateToIndex
          />
        )
      }
      backTo={`/courses/${courseId}/achievements/`}
      title={intl.formatMessage(translations.header, {
        title: achievementMiniEntity.title,
      })}
    >
      {isLoading ? (
        <LoadingIndicator />
      ) : (
        achievement && (
          <Grid container>
            <Grid className="flex justify-center" item xs={12}>
              <div className="flex max-w-7xl items-center space-x-8 p-8">
                <Tooltip title={achievement.achievementStatus ?? ''}>
                  <img
                    alt={achievement.badge.name}
                    className="h-32"
                    src={getAchievementBadgeUrl(
                      achievement.badge.url,
                      achievement.permissions.canDisplayBadge,
                    )}
                  />
                </Tooltip>

                <Typography
                  className="whitespace-normal"
                  dangerouslySetInnerHTML={{
                    __html: achievement.description,
                  }}
                />
              </div>
            </Grid>

            <Grid display="flex" item justifyContent="center" xs={12}>
              <Typography variant="h5">
                {intl.formatMessage(translations.studentsWithAchievement)}
              </Typography>
            </Grid>

            {achievement.achievementUsers.map((courseUser) => {
              if (courseUser.obtainedAt !== null)
                return (
                  <Grid key={courseUser.id} item lg={1} sm={3} xs={4}>
                    <Link to={getCourseUserURL(courseId, courseUser.id)}>
                      <AvatarWithLabel
                        imageUrl={courseUser.imageUrl!}
                        label={courseUser.name}
                        size="sm"
                      />
                    </Link>
                  </Grid>
                );
              return null;
            })}
          </Grid>
        )
      )}
    </Page>
  );
};

export default injectIntl(AchievementShow);