All files / app/features/communities/members CommunityMembersList.tsx

65.21% Statements 15/23
0% Branches 0/5
0% Functions 0/5
71.42% Lines 15/21

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 975x 5x 5x 5x 5x 5x 5x 5x 5x 5x   5x   5x 5x   5x                                             5x                                                                                                                  
import { styled } from "@mui/material";
import Alert from "components/Alert";
import Button from "components/Button";
import CenteredSpinner from "components/CenteredSpinner/CenteredSpinner";
import HorizontalScroller from "components/HorizontalScroller";
import { PersonIcon } from "components/Icons";
import TextBody from "components/TextBody";
import UsersList from "components/UsersList";
import { useTranslation } from "i18n";
import { COMMUNITIES, GLOBAL } from "i18n/namespaces";
import { Community } from "proto/communities_pb";
import hasAtLeastOnePage from "utils/hasAtLeastOnePage";
 
import { SectionTitle } from "../CommunityPage";
import { useListMembers } from "../hooks";
 
const StyledHorizontalScroller = styled(HorizontalScroller)(({ theme }) => ({
  [theme.breakpoints.down("sm")]: {
    //break out of page padding
    left: "50%",
    marginLeft: "-50vw",
    marginRight: "-50vw",
    position: "relative",
    right: "50%",
    width: "100vw",
  },
  [theme.breakpoints.up("sm")]: {
    display: "grid",
    gridTemplateColumns: "repeat(2, 1fr)",
    gap: theme.spacing(2),
  },
  [theme.breakpoints.up("md")]: {
    gridTemplateColumns: "repeat(3, 1fr)",
    gap: theme.spacing(3),
  },
  width: "100%",
  overflow: "hidden",
}));
 
const LoadMoreButtonWrapper = styled("div")(({ theme }) => ({
  display: "flex",
  justifyContent: "center",
  width: "100%",
  marginTop: theme.spacing(2),
}));
 
export default function CommunityMembersList({
  communityId,
}: {
  communityId: Community.AsObject["communityId"];
}) {
  const { t } = useTranslation([GLOBAL, COMMUNITIES]);
 
  const { data, isLoading, isFetching, error, fetchNextPage, hasNextPage } =
    useListMembers(communityId);
 
  const memberUserIdsList = data?.pages.flatMap(
    (page) => page.memberUserIdsList,
  );
 
  return (
    <>
      <SectionTitle icon={<PersonIcon />} variant="h2">
        {t("communities:members_title")}
      </SectionTitle>
 
      {error && <Alert severity="error">{error.message}</Alert>}
      {isLoading ? (
        <CenteredSpinner />
      ) : hasAtLeastOnePage(data, "memberUserIdsList") ? (
        <>
          <StyledHorizontalScroller>
            <UsersList
              userIds={memberUserIdsList}
              endChildren={
                hasNextPage && (
                  <LoadMoreButtonWrapper>
                    <Button
                      loading={isFetching}
                      onClick={() => fetchNextPage()}
                    >
                      Load more
                    </Button>
                  </LoadMoreButtonWrapper>
                )
              }
              titleIsLink
            />
          </StyledHorizontalScroller>
        </>
      ) : (
        !error && <TextBody>{t("communities:members_empty_state")}</TextBody>
      )}
    </>
  );
}