All files / app/features/communities/discussions CreateDiscussionForm.tsx

100% Statements 33/33
100% Branches 1/1
100% Functions 9/9
100% Lines 28/28

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 1055x 5x 5x 5x 5x 5x 5x 5x 5x   5x   26x               26x   26x           26x           26x                               20x 26x           26x       26x     1x 1x 1x     26x 1x 1x 1x     26x 2x                                                        
import { Card, styled, Typography } from "@mui/material";
import Alert from "components/Alert";
import Button from "components/Button";
import MarkdownInput from "components/MarkdownInput";
import TextField from "components/TextField";
import { useTranslation } from "i18n";
import { COMMUNITIES, GLOBAL } from "i18n/namespaces";
import { useForm } from "react-hook-form";
import { theme } from "theme";
 
import { CreateDiscussionInput, useNewDiscussionMutation } from "../hooks";
 
const StyledWrapper = styled(Card)(() => ({
  "& > :not(:last-child)": {
    marginBlockEnd: theme.spacing(3),
  },
  marginBlockEnd: theme.spacing(5),
  padding: theme.spacing(3),
}));
 
const StyledTitle = styled(Typography)(() => ({ marginTop: 0 }));
 
const StyledForm = styled("form")(() => ({
  "& > * + *": {
    marginBlockStart: theme.spacing(3),
  },
}));
 
const StyledActionButtonsContainer = styled("div")(() => ({
  display: "flex",
  justifyContent: "flex-end",
  gap: 8,
}));
 
const StyledCancelButton = styled(Button)(() => ({
  backgroundColor: "var(--mui-palette-grey-50)",
  color: "var(--mui-palette-grey-800)",
  "&:hover": {
    backgroundColor: "var(--mui-palette-grey-100)",
  },
}));
 
interface CreateDiscussionFormProps {
  communityId: number;
  onCancel?(): void;
  onPostSuccess?(): void;
}
 
type CreateDiscussionData = Omit<CreateDiscussionInput, "ownerCommunityId">;
 
export default function CreateDiscussionForm({ communityId, onCancel, onPostSuccess }: CreateDiscussionFormProps) {
  const { t } = useTranslation([GLOBAL, COMMUNITIES]);
  const {
    control,
    handleSubmit,
    reset: resetForm,
    register,
  } = useForm<CreateDiscussionData>({
    mode: "onBlur",
  });
 
  const { error, isPending, mutate: createDiscussion, reset: resetMutation } = useNewDiscussionMutation(handleSuccess);
 
  function handleSuccess() {
    resetForm();
    resetMutation();
    onPostSuccess?.();
  }
 
  const handleCancel = () => {
    onCancel?.();
    resetForm();
    resetMutation();
  };
 
  const onSubmit = handleSubmit((data) => {
    createDiscussion({ ...data, ownerCommunityId: communityId });
  });
 
  return (
    <StyledWrapper>
      <StyledTitle variant="h2">{t("communities:create_new_discussion_title")}</StyledTitle>
      {error && <Alert severity="error">{error.message}</Alert>}
      <StyledForm onSubmit={onSubmit}>
        <TextField
          id="title"
          {...register("title", { required: true })}
          fullWidth
          label={t("communities:new_discussion_title")}
        />
        <Typography id="content-label" variant="h3">
          {t("communities:new_discussion_topic")}
        </Typography>
        <MarkdownInput control={control} id="content" labelId="content-label" name="content" />
        <StyledActionButtonsContainer>
          <StyledCancelButton onClick={handleCancel}>{t("global:cancel")}</StyledCancelButton>
          <Button loading={isPending} type="submit">
            {t("communities:post")}
          </Button>
        </StyledActionButtonsContainer>
      </StyledForm>
    </StyledWrapper>
  );
}