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 | 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 15x 15x 15x 15x 15x 15x 3x 1x 1x 9x 19x | import { Collapse } from "@mui/material"; import makeStyles from "@mui/styles/makeStyles"; import Alert from "components/Alert"; import Button from "components/Button"; import CenteredSpinner from "components/CenteredSpinner/CenteredSpinner"; import { EmailIcon } from "components/Icons"; import TextBody from "components/TextBody"; import { SectionTitle, useCommunityPageStyles, } from "features/communities/CommunityPage"; import { useListDiscussions } from "features/communities/hooks"; import { useTranslation } from "i18n"; import { COMMUNITIES } from "i18n/namespaces"; import { Community } from "proto/communities_pb"; import { useState } from "react"; import hasAtLeastOnePage from "utils/hasAtLeastOnePage"; import CreateDiscussionForm from "./CreateDiscussionForm"; import DiscussionCard from "./DiscussionCard"; import useDiscussionsListStyles from "./useDiscussionsListStyles"; const useStyles = makeStyles((theme) => ({ newPostButtonContainer: { "& > * + *": { marginInlineStart: theme.spacing(2), }, display: "flex", alignItems: "center", minHeight: theme.typography.pxToRem(40), }, })); export default function DiscussionsListPage({ community, }: { community: Community.AsObject; }) { const { t } = useTranslation([COMMUNITIES]); const classes = { ...useCommunityPageStyles(), ...useDiscussionsListStyles(), ...useStyles(), }; const hash = typeof window !== "undefined" ? window.location.hash : ""; const [isCreatingNewPost, setIsCreatingNewPost] = useState( hash.includes("new") ); const { isLoading: isDiscussionsLoading, isFetching: isDiscussionsFetching, error: discussionsError, data: discussions, hasNextPage: discussionsHasNextPage, fetchNextPage, } = useListDiscussions(community.communityId); // loading is false when refetched since there's old data in cache already const isRefetching = !isDiscussionsLoading && isDiscussionsFetching; return ( <> <div className={classes.discussionsHeader}> <SectionTitle icon={<EmailIcon />}> {t("communities:discussions_title")} </SectionTitle> </div> {discussionsError && ( <Alert severity="error">{discussionsError.message}</Alert> )} <Collapse in={!isCreatingNewPost}> <div className={classes.newPostButtonContainer}> <Button className={classes.createResourceButton} onClick={() => setIsCreatingNewPost(true)} > {t("communities:new_post_label")} </Button> {isRefetching && <CenteredSpinner />} </div> </Collapse> <Collapse in={isCreatingNewPost}> <CreateDiscussionForm communityId={community.communityId} onCancel={() => setIsCreatingNewPost(false)} onPostSuccess={() => setIsCreatingNewPost(false)} /> </Collapse> <div className={classes.discussionsContainer}> {isDiscussionsLoading ? ( <CenteredSpinner /> ) : hasAtLeastOnePage(discussions, "discussionsList") ? ( discussions.pages .flatMap((res) => res.discussionsList) .map((discussion) => ( <DiscussionCard discussion={discussion} key={`discussioncard-${discussion.thread!.threadId}`} /> )) ) : ( <TextBody>{t("communities:discussions_empty_state")}</TextBody> )} {discussionsHasNextPage && ( <div className={classes.loadMoreButton}> <Button onClick={() => fetchNextPage()}> {t("communities:see_more_discussions_label")} </Button> </div> )} </div> </> ); } |