Skip to content

MessageListPage

안성재 edited this page Nov 15, 2023 · 1 revision

디자인

모바일

localhost_3000_post_411(Mobile)

태블릿

localhost_3000_post_411(Tablet)

PC

localhost_3000_post_411(PC)

실제 구현 코드

function MessageListPage() {
  const [wishDelete, setWishDelete] = useState(false);
  const { id } = useParams();
  const location = useLocation();
  const currentPath = location.pathname;
  const editURL = `${currentPath}/edit`;
  const isEditMode = currentPath.endsWith("/edit");
  const navigate = useNavigate();

  const {
    data: paperData,
    isLoading,
    error: loadError,
  } = useRequest({
    options: {
      url: `recipients/${id}/`,
    },
  });

  const { data: reactionListData } = useRequest({
    options: {
      url: `recipients/${id}/reactions/`,
    },
  });

  const { fetch: fetchDelete } = useRequest({
    skip: true,
    options: {
      url: `/recipients/${id}/`,
      method: "DELETE",
    },
  });

  const deletePaper = async () => {
    if (!wishDelete) return;
    if (!confirm("정말 삭제하시겠습니까?")) {
      setWishDelete(false);
      return;
    }
    const { error: deleteError } = await fetchDelete();
    if (deleteError) {
      throw new Error("롤링 페이퍼 삭제 실패");
    }
    navigate("/list");
  };

  const handleQuitClick = () => {
    navigate(currentPath.replace("/edit", ""));
  };

  const handleDeleteClick = () => {
    setWishDelete(true);
  };

  useEffect(() => {
    if (loadError) {
      alert("존재하지 않는 페이지입니다.");
      navigate("/list");
    }
  }, [loadError, navigate]);

  useEffect(() => {
    deletePaper();
  }, [wishDelete]);

  if (isLoading || loadError) {
    return;
  }

  return (
    <>
      <Helmet>
        <title>
          {isEditMode ? "롤링 페이퍼 편집 - Rolling" : "롤링 페이퍼 - Rolling"}
        </title>
      </Helmet>
      <S.Background
        $backgroundColor={paperData?.backgroundColor}
        $backgroundImageURL={paperData?.backgroundImageURL}
      >
        <S.NavBarContainer>
          <NavBar showButton={false} />
        </S.NavBarContainer>
        <NavBarSub paperData={paperData} reactionListData={reactionListData} />
        <S.MainDiv>
          {isEditMode ? (
            <>
              <S.DeleteButton>
                <Button size="full" onClick={handleDeleteClick}>
                  삭제하기
                </Button>
              </S.DeleteButton>
              <S.ButtonContainer>
                <S.StyledDeleteButton size="sm" onClick={handleDeleteClick}>
                  삭제하기
                </S.StyledDeleteButton>
                <S.StyledOutlinedButton size="sm" onClick={handleQuitClick}>
                  돌아가기
                </S.StyledOutlinedButton>
              </S.ButtonContainer>
            </>
          ) : (
            <S.EditButton>
              <Link to={editURL}>
                <S.StyledOutlinedButton size="sm">
                  편집하기
                </S.StyledOutlinedButton>
              </Link>
            </S.EditButton>
          )}
          <CardList isEditMode={isEditMode} id={id} />
        </S.MainDiv>
      </S.Background>
    </>
  );
}

설명

  • MessageListPage는 롤링 페이퍼 페이지를 렌더링합니다.
  • useParams 훅으로 접속한 URL의 파라미터를 받아서 사용합니다. id를 사용해서 현재 접속한 URL에 따라 서버의 올바른 주소로 API 요청을 보내도록 합니다.
  • 현재 URL을 통해 isEditMode의 값이 정해집니다. 편집 모드일 때는 보여지는 버튼이나 페이지의 타이틀이 달라지고, 자식 컴포넌트인 카드 리스트에도 prop으로 내려줍니다.
  • 롤링 페이퍼를 생성할 때 backgroundColorbackgroundImageURL을 받는데, backgroundImageURL이 없으면 backgroundColor가 배경색으로 스타일링되고, backgroundImageURL이 있으면 backgroundColor의 값이 존재하더라도 우선적으로 배경 이미지가 스타일링되도록 했습니다.
  • 편집하기 버튼을 통해 URL을 이동하고 편집 모드에 해당하는 화면을 렌더링하도록 했습니다.
  • 삭제하기 버튼을 통해 롤링 페이퍼를 삭제할 때는 wishDelete state를 사용해 서버에 DELETE 요청을 보내고 롤링 페이퍼 목록 페이지로 이동하도록 했습니다.
  • 추가 구현: 삭제하기 버튼을 눌렀을 때 바로 삭제되는 것이 아니라 확인창을 띄워 한 번 더 확인합니다.
  • 추가 구현: 돌아가기 버튼을 통해 편집 모드에서 통상 모드로 돌아갈 수 있도록 했습니다.
  • 추가 구현: 만약 존재하지 않는 id를 사용해서 URL에 접근했다면, 경고창을 띄우고 롤링 페이퍼 목록 페이지로 리다이렉트되도록 했습니다.

컴포넌트

페이지

Clone this wiki locally