All files / client/src/views/program-item ProgramItemView.tsx

97.22% Statements 35/36
30.76% Branches 4/13
100% Functions 14/14
96.77% Lines 30/31

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 97 98 99 100 101 102 103 104 105                                356x 65x   65x   65x 109x   65x 109x   65x 109x 109x 109x     65x 109x 65x 109x 65x   65x                   65x 27x     65x   65x 191x     65x   191x     65x 109x     65x 9x     65x   27x                                                            
import { ReactElement, useEffect, useLayoutEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router";
import { Loading } from "client/components/Loading";
import { useAppSelector } from "client/utils/hooks";
import { ProgramItemEntry } from "client/views/program-item/ProgramItemEntry";
import {
  selectDirectSignups,
  selectLotterySignups,
} from "client/views/my-program-items/myProgramItemsSlice";
import { ProgramItemSignupStrategy } from "shared/types/models/programItem";
import { getLotterySignups } from "client/utils/getUpcomingProgramItems";
import { BackButton } from "client/components/BackButton";
import { getIsInGroup } from "client/views/group/groupUtils";
import { selectGroupMembers } from "client/views/group/groupSlice";
 
export const ProgramItemView = (): ReactElement => {
  const { t } = useTranslation();
 
  const { programItemId } = useParams() as { programItemId: string };
 
  const programItems = useAppSelector(
    (state) => state.allProgramItems.programItems,
  );
  const signups = useAppSelector(
    (state) => state.allProgramItems.directSignups,
  );
  const directSignups = useAppSelector(selectDirectSignups);
  const username = useAppSelector((state) => state.login.username);
  const loggedIn = useAppSelector((state) => state.login.loggedIn);
  const userGroup = useAppSelector((state) => state.login.userGroup);
 
  // Figure out if user has signed up to this program item
  const lotterySignups = useAppSelector(selectLotterySignups);
  const isGroupCreator = useAppSelector((state) => state.group.isGroupCreator);
  const groupMembers = useAppSelector(selectGroupMembers);
  const groupCode = useAppSelector((state) => state.group.groupCode);
  const isInGroup = getIsInGroup(groupCode);
 
  const ownOrGroupCreatorLotterySignups = getLotterySignups({
    lotterySignups,
    isGroupCreator,
    groupMembers,
    isInGroup,
    showAllProgramItems: true,
  });
 
  // Open the program item page at the top, regardless of where the user was
  // scrolled in the list (SPA navigation otherwise keeps the window scroll)
  useLayoutEffect(() => {
    window.scrollTo(0, 0);
  }, [/* effect dep */ programItemId]);
 
  const [loading, setLoading] = useState<boolean>(true);
 
  const foundProgramItem = programItems.find(
    (programItem) => programItem.programItemId === programItemId,
  );
  const programSignups =
    signups.find(
      (programItemSignup) =>
        programItemSignup.programItemId === foundProgramItem?.programItemId,
    )?.users ?? [];
 
  const signupQuestions = useAppSelector(
    (state) => state.admin.signupQuestions,
  );
 
  const publicSignupQuestion = signupQuestions.find(
    (s) => s.programItemId === programItemId && !s.private,
  );
 
  useEffect(() => {
    // eslint-disable-next-line react-hooks/set-state-in-effect
    setLoading(false);
  }, [/* effect dep */ foundProgramItem]);
 
  return (
    <div>
      <BackButton />
      {loading && <Loading />}
      {foundProgramItem && (
        <ProgramItemEntry
          isAlwaysExpanded={true}
          isRecentlyViewed={false}
          programItem={foundProgramItem}
          signups={programSignups}
          signupStrategy={
            foundProgramItem.signupStrategy ?? ProgramItemSignupStrategy.DIRECT
          }
          lotterySignups={ownOrGroupCreatorLotterySignups}
          directSignups={directSignups}
          username={username}
          loggedIn={loggedIn}
          userGroup={userGroup}
          publicSignupQuestion={publicSignupQuestion}
        />
      )}
      {!loading && !foundProgramItem && (
        <p>{t("invalidProgramItemId", { PROGRAM_ITEM_ID: programItemId })}</p>
      )}
    </div>
  );
};