[BBEB] 글쓰기

올챙이·2023년 10월 15일

봉봉이봉

목록 보기
7/8
post-thumbnail

Intro 😊

생각보다 구현하는데 오래 걸렸던 페이지입니다.
원래라면 저런식으로 제목란, 태그란, 내용란 전부를 textfield로 구현해야했지만 textfield 내부에는 사진을 첨부할 수 없었기 때문에 계속해서 오류가 났습니다. 저는 그 사실을 모르고 계속해서 구현을 해보려고 시도하다가 오래 걸렸습니다.

팀원중 한명이 toast Editor을 사용하는 방법을 알려줘서 내용란은 editor을 사용하기로 했습니다.
이곳을 참고해서 만들었습니다!

글쓰기📝

  • 제목

    게시글의 제목을 작성할 수 있습니다.
              <Stack alignItems="center">
                <TextField
                  label="제목"
                  placeholder="제목을 입력하세요."
                  variant="outlined"
                  style={{ width: "71%", backgroundColor: "#FFF" }}
                  value={title}
                  onChange={(e) => setTitle(e.target.value)}
                />
              </Stack>
  • 태그

    게시글의 태그를 입력할 수 있습니다.
    태그는 무한으로 입력 가능하며, 클릭하면 삭제되도록 구현하였습니다.
    map을 사용해서 쉽게 구현할 수 있었습니다!👍
  const handleTagInputChange = (event) => {
    setTagInput(event.target.value);
  };

  const handleTagInputKeyPress = (event) => {
    if (event.key === "Enter" && tagInput.trim() !== "") {
      const newTag = tagInput.trim();
      setTags([...tags, newTag]);
      setPostTags([...postTags, { value: newTag }]);
      setTagInput("");
    }
  };

  const handleTagClick = (tagToRemove) => {
    const updatedTags = tags.filter((tag) => tag !== tagToRemove);
    setTags(updatedTags);

    const updatedPostTags = postTags.filter(
      (tagObj) => tagObj.value !== tagToRemove
    );
    setPostTags(updatedPostTags);
  };
              <Stack alignItems="center">
                <TextField
                  label="태그"
                  placeholder="태그를 입력하세요."
                  variant="outlined"
                  value={tagInput}
                  onChange={handleTagInputChange}
                  onKeyPress={handleTagInputKeyPress}
                  style={{ width: "71%", backgroundColor: "#FFF" }}
                />
                <Stack
                  direction="row"
                  flexWrap="wrap"
                  justifyContent="flex-start"
                  alignItems="center"
                  style={{ width: "71%" }}
                >
                  {tags.map((tag, index) => (
                    <Chip
                      key={index}
                      label={tag}
                      onClick={() => handleTagClick(tag)}
                      style={{
                        margin: "4px",
                        whiteSpace: "nowrap",
                        overflow: "hidden",
                        textOverflow: "ellipsis",
                        maxWidth: "100%",
                        color: "#FF8181",
                        backgroundColor: "#FAF3F0",
                        border: "1px solid #FF8181",
                        cursor: "pointer",
                      }}
                    />
                  ))}
                </Stack>
              </Stack>
  • 내용

    가장 구현하기 힘들었지만 toast editor로 간편하게 구현할 수 있었던거...
    조금 억울하긴 했지만 그만큼 기억에 오래 남아서 나중에 글쓰기 페이지를 구현할 때 좀 더 수월하게 작업할 수 있을 것 같아요!!
              <Editor
                ref={editorRef}
                initialValue="내용을 입력하세요."
                value={editorContent}
                previewStyle="vertical"
                height="450px"
                initialEditType="markdown"
                useCommandShortcut={false}
                hideModeSwitch={true}
                onChange={(e) => setEditorContent(e)}
              />

글쓰기 모달창 ✉

글쓰기 클릭시 나오는 모달창입니다!
로그아웃 상태에 나오는 모달창과 구분해두었습니다.

  • 썸네일


    왼쪽 하단의 이미지를 클릭한다면 다음과 같이 사진을 선택할 수 있는 창이 나오는데 썸네일 설정이 가능하게 해놨습니다. 이때 선택한 썸네일은 게시판 페이지에서 렌더링됩니다.
            <Stack alignItems="center">
              <label htmlFor="thumbnailInput">
                <img
                  src={writepoto}
                  alt="writeouto"
                  width="40px"
                  height="40px"
                ></img>
              </label>
              <input
                id="thumbnailInput"
                type="file"
                accept="image/*"
                style={{ display: "none" }}
                onChange={handleThumbnailChange}
              />
            </Stack>
  • 체크박스

    모달창의 글쓰기 버튼은 디폴트로 클릭 되지 않게 설정해 두었습니다.
    바로 위에 있는 체크박스를 클릭해야지 활성화 되게끔 구현했습니다.
            <Stack
              bgcolor="#D76464"
              direction="row"
              sx={{
                color: "white",
                borderRadius: "20px",
                alignItems: "center",
                width: "170px",
                height: "30px",
                "& .MuiIconButton-root": {
                  backgroundColor: "white",
                },
              }}
            >
              <Stack fontSize="15px" marginLeft="30%">
                확인 했어요~!
              </Stack>
              <Checkbox
                sx={{
                  color: "white",
                  "&.Mui-checked": {
                    color: "white",
                  },
                }}
                checked={isChecked}
                onChange={handleCheckboxChange}
              />
            </Stack>
  • 글쓰기

    모달창에서 글쓰기 버튼을 누르면 최종적으로 글이 업로드됩니다.
            <Stack
              bgcolor="#7AAAA7"
              sx={{
                cursor: isChecked ? "pointer" : "default",
                color: "white",
                borderRadius: "20px",
                alignItems: "center",
                width: "170px",
                height: "30px",
                justifyContent: "center",
                opacity: isChecked ? 1 : 0.5,
              }}
              onClick={handleWriteClick}
            >
              <Stack fontSize="15px">글쓰기</Stack>
            </Stack>
  • 관리자 권한

관리자 권한을 가진 사용자가 고정글을 선택할 수 있도록 체크박스를 만들어주었습니다.
이 체크박스는 관리자 권한을 가진 사용자에게만 보이도록 설정해두었습니다.
관리자 권한이 있는지 없는지 판별하기 위해서 JWT decode을 해주었습니다.

  useEffect(() => {
    if (accessToken) {
      const decoded = jwt_decode(accessToken);
      setDecodedToken(decoded);
      console.log(accessToken);
      if (decoded && decoded.auth === "ROLE_ADMIN") {
        setIsAdmin(true);
      }
      console.log(decoded);
    }
  }, [accessToken]);
              {isAdmin && isLogin && (
                <Stack justifyContent="flex-end" alignItems="center">
                  <Checkbox
                    checked={checked}
                    onChange={() => setChecked(!checked)}
                  />
                </Stack>
              )}

보여지는거 수정 📩

마크다운 형식을 올바르게 출력하기 위한 기능을 구현해야 합니다.
현재 프로젝트에서 게시글이 보여지는 페이지에 다음과 같은 코드를 추가해주었습니다.

            <Stack
              width="75%"
              minHeight="18.7vh"
              height="fit-content"
              margin="10% 0 10% 0"
              justifyContent="center"
              alignItems="center"
              bgcolor="white"
            >
              {postData?.contents.map((content, i) => (
                <ReactMarkdown key={i} children={content.value} />
              ))}
            </Stack>

0개의 댓글