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

96.29% Statements 26/27
100% Branches 5/5
83.33% Functions 5/6
96.15% Lines 25/26

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 1145x 5x 5x 5x 5x 5x 5x 5x 5x 5x   5x 5x 5x   5x 5x 5x   5x                                                           4x         9x 9x 9x   9x                                     3x 6x   6x                                                                  
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 hasAtLeastOnePage from "utils/hasAtLeastOnePage";
import makeStyles from "utils/makeStyles";
 
import { SectionTitle, useCommunityPageStyles } from "../CommunityPage";
import { useListCommunityEvents } from "../hooks";
import EventCard from "./EventCard";
 
const useStyles = makeStyles((theme) => ({
  section: {
    display: "grid",
    rowGap: theme.spacing(2),
  },
  centerSelf: {
    justifySelf: "center",
  },
  cardContainer: {
    display: "flex",
    flexDirection: "row",
    flexWrap: "wrap",
    gap: theme.spacing(2),
    [theme.breakpoints.down("sm")]: {
      overflowX: "auto",
      flexWrap: "nowrap",
    },
  },
  placeEventCard: {
    [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,
    },
  },
}));
 
export default function EventsSection({
  community,
}: {
  community: Community.AsObject;
}) {
  const { t } = useTranslation([GLOBAL, COMMUNITIES]);
  const classes = { ...useCommunityPageStyles(), ...useStyles() };
  const router = useRouter();
 
  const { data, error, hasNextPage, isLoading } = useListCommunityEvents({
    communityId: community.communityId,
    pageSize: 3,
    type: "summary",
  });
 
  return (
    <section className={classes.section}>
      <SectionTitle icon={<CalendarIcon />} variant="h2">
        {t("communities:events_title")}
      </SectionTitle>
 
      {error && <Alert severity="error">{error.message}</Alert>}
      {isLoading ? (
        <CenteredSpinner />
      ) : hasAtLeastOnePage(data, "eventsList") ? (
        <>
          <HorizontalScroller className={classes.cardContainer}>
            {data.pages
              .flatMap((page) => page.eventsList)
              .filter((event) => !event.isCancelled)
              .map((event) => (
                <EventCard
                  key={event.eventId}
                  event={event}
                  className={classes.placeEventCard}
                />
              ))}
          </HorizontalScroller>
          {hasNextPage && (
            <div className={classes.loadMoreButton}>
              <StyledLink
                href={routeToCommunity(
                  community.communityId,
                  community.slug,
                  "events",
                )}
              >
                {t("global:nav.show_all_events")}
              </StyledLink>
            </div>
          )}
        </>
      ) : (
        !error && <TextBody>{t("communities:events_empty_state")}</TextBody>
      )}
      <Button
        className={classes.centerSelf}
        onClick={() => router.push(routeToNewEvent(community.communityId))}
      >
        {t("communities:create_an_event")}
      </Button>
    </section>
  );
}