All files / app/features/communities/events EventsSection.tsx

97.14% Statements 34/35
100% Branches 5/5
90% Functions 9/10
96.66% Lines 29/30

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 106 107 108 109 110 111 112 113 114 115 116 117 118 1194x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x   4x 4x 4x   4x 4x 4x   4x             9x         4x                         6x                     9x       4x         9x 9x   9x                                     3x 6x   6x                                                        
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 { CalendarIcon } from "components/Icons";
import StyledLink from "components/StyledLink";
import TextBody from "components/TextBody";
import { useTranslation } from "i18n";
import { COMMUNITIES, GLOBAL } from "i18n/namespaces";
import { useRouter } from "next/router";
import { Community } from "proto/communities_pb";
import { routeToCommunity, routeToNewEvent } from "routes";
import { theme } from "theme";
import hasAtLeastOnePage from "utils/hasAtLeastOnePage";
 
import { SectionTitle } from "../CommunityPage";
import { useListCommunityEvents } from "../hooks";
import EventCard from "./EventCard";
 
const StyledLoadMoreButton = styled("div")(() => ({
  alignSelf: "center",
  display: "flex",
  justifyContent: "center",
  width: "100%",
}));
 
const StyledSection = styled("div")(() => ({
  display: "grid",
  rowGap: theme.spacing(2),
}));
 
const StyledCardContainer = styled(HorizontalScroller)(() => ({
  cardContainer: {
    display: "flex",
    flexDirection: "row",
    flexWrap: "wrap",
    gap: theme.spacing(2),
    [theme.breakpoints.down("sm")]: {
      overflowX: "auto",
      flexWrap: "nowrap",
    },
  },
}));
 
const StyledEventCard = styled(EventCard)(() => ({
  [theme.breakpoints.up("sm")]: {
    width: "calc(33.333% - 16px)", // 3 cards per row with gap
    maxWidth: "280px",
  },
  [theme.breakpoints.down("sm")]: {
    width: "200px", // Fixed width on mobile
    flexShrink: 0,
  },
}));
 
const StyledSelfCenteredButton = styled(Button)(() => ({
  justifySelf: "center",
}));
 
export default function EventsSection({
  community,
}: {
  community: Community.AsObject;
}) {
  const { t } = useTranslation([GLOBAL, COMMUNITIES]);
  const router = useRouter();
 
  const { data, error, hasNextPage, isLoading } = useListCommunityEvents({
    communityId: community.communityId,
    pageSize: 3,
    type: "summary",
  });
 
  return (
    <StyledSection>
      <SectionTitle icon={<CalendarIcon />} variant="h2">
        {t("communities:events_title")}
      </SectionTitle>
 
      {error && <Alert severity="error">{error.message}</Alert>}
      {isLoading ? (
        <CenteredSpinner />
      ) : hasAtLeastOnePage(data, "eventsList") ? (
        <>
          <StyledCardContainer>
            {data.pages
              .flatMap((page) => page.eventsList)
              .filter((event) => !event.isCancelled)
              .map((event) => (
                <StyledEventCard key={event.eventId} event={event} />
              ))}
          </StyledCardContainer>
          {hasNextPage && (
            <StyledLoadMoreButton>
              <StyledLink
                href={routeToCommunity(
                  community.communityId,
                  community.slug,
                  "events",
                )}
              >
                {t("global:nav.show_all_events")}
              </StyledLink>
            </StyledLoadMoreButton>
          )}
        </>
      ) : (
        !error && <TextBody>{t("communities:events_empty_state")}</TextBody>
      )}
      <StyledSelfCenteredButton
        onClick={() => router.push(routeToNewEvent(community.communityId))}
      >
        {t("communities:create_an_event")}
      </StyledSelfCenteredButton>
    </StyledSection>
  );
}