All files / components/Courses CourseMenu.tsx

94.44% Statements 17/18
88.88% Branches 16/18
100% Functions 7/7
94.11% Lines 16/17

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96                                      17x                             27x 16x   11x       17x                     511x                 511x   511x 473x     76x 38x 76x   38x 76x     38x               38x                        
import { Link } from "react-router";
import { NavDropdown } from "react-bootstrap";
import { useBackend } from "main/utils/useBackend";
import { type CurrentUser } from "main/utils/currentUser";
import { GraphIcon } from "main/components/Common/Icons";
 
export interface CourseAccess {
  id: number;
  courseName: string;
  term: string;
  school: { displayName: string; key: string };
  instructorEmail: string;
  studentAccess: boolean;
  staffAccess: boolean;
  instructorAccess: boolean;
  adminAccess: boolean;
}
 
function CourseMenuItem({ course }: { course: CourseAccess }) {
  return (
    <NavDropdown.Item as={Link} to={`/course/${course.id}`}>
      <GraphIcon className="me-2" width="16" height="16" />
      {`${course.courseName} ${course.term}, ${course.school.displayName}, ${course.instructorEmail}, ${course.id}`}
    </NavDropdown.Item>
  );
}
 
function CourseMenuSection({
  heading,
  courses,
}: {
  heading: string;
  courses: CourseAccess[];
}) {
  if (courses.length === 0) {
    return null;
  }
  return (
    <>
      <NavDropdown.Header>{heading}</NavDropdown.Header>
      {courses.map((course) => (
        <CourseMenuItem key={course.id} course={course} />
      ))}
    </>
  );
}
 
export default function CourseMenu({
  currentUser,
}: {
  currentUser: CurrentUser;
}): React.JSX.Element | null {
  const { data: courses } = useBackend<CourseAccess[]>(
    ["/api/courses/list"],
    { method: "GET", url: "/api/courses/list" },
    // Stryker disable next-line all : don't test default value of empty list
    [],
    true,
    { enabled: currentUser.loggedIn },
  );
 
  const courseList = courses ?? [];
 
  if (!currentUser.loggedIn || courseList.length === 0) {
    return null;
  }
 
  const instructorCourses = courseList.filter((c) => c.instructorAccess);
  const staffCourses = courseList.filter(
    (c) => c.staffAccess && !c.instructorAccess,
  );
  const studentCourses = courseList.filter(
    (c) => c.studentAccess && !c.instructorAccess && !c.staffAccess,
  );
 
  Iif (
    instructorCourses.length === 0 &&
    staffCourses.length === 0 &&
    studentCourses.length === 0
  ) {
    return null;
  }
 
  return (
    <NavDropdown
      title="Courses"
      id="appnavbar-courses-dropdown"
      data-testid="appnavbar-courses-dropdown"
    >
      <CourseMenuSection heading="Instructor" courses={instructorCourses} />
      <CourseMenuSection heading="Staff" courses={staffCourses} />
      <CourseMenuSection heading="Student" courses={studentCourses} />
    </NavDropdown>
  );
}