Skip to content

Commit

Permalink
Merge pull request #205 from oduck-team/fix/195
Browse files Browse the repository at this point in the history
모달 컴포넌트의 state가 유지되지 않도록 수정한다.
  • Loading branch information
presentKey authored Oct 7, 2023
2 parents 588a4c1 + 5e1467b commit 2b32d8b
Show file tree
Hide file tree
Showing 13 changed files with 151 additions and 124 deletions.
5 changes: 4 additions & 1 deletion src/components/Backdrop/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ export interface BackdropProps {
onClick: () => void;
}

/** AnimatePortal 컴포넌트로 감싸서 사용 */
/**
* @desc 1. < AnimatePortal > 컴포넌트와 함께 사용
* @desc 2. < AnimatePresence > + <Portal> 컴포넌트와 함께 사용
* */
export default function Backdrop({
isVisible = true,
className = "",
Expand Down
9 changes: 5 additions & 4 deletions src/components/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Variants } from "framer-motion";
import useScrollLock from "@/hooks/useScrollLock";
import { StrictPropsWithChildren } from "@/types";

import AnimatePortal from "../Portal/AnimatePortal";
import Portal from "../Portal";

import ModalActions from "./ModalActions";
import ModalContent from "./ModalContent";
Expand All @@ -22,8 +22,9 @@ export interface ModalProps {
onClose: () => void;
}

/** @desc < AnimatePresence > 컴포넌트로 감싸서 사용해주세요. */
export default function Modal({
isVisible = false,
isVisible = true,
size = "default",
showBackdrop = true,
onClose,
Expand All @@ -32,7 +33,7 @@ export default function Modal({
useScrollLock(isVisible);

return (
<AnimatePortal isVisible={isVisible}>
<Portal>
<Backdrop isVisible={showBackdrop} onClick={onClose} />
<ModalContainer
aria-modal={isVisible}
Expand All @@ -46,7 +47,7 @@ export default function Modal({
>
{children}
</ModalContainer>
</AnimatePortal>
</Portal>
);
}

Expand Down
6 changes: 6 additions & 0 deletions src/components/SnackBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,14 @@ interface SnackBarProps {
text: string;
}

//TODO: SnackBar animation 변경
const SnackBar = forwardRef(
({ text }: SnackBarProps, ref: React.ForwardedRef<HTMLDivElement>) => {
// const [isPresent, safeToRemove] = usePresence();
// useEffect(() => {
// !isPresent && setTimeout(safeToRemove, 2000);
// }, [isPresent, safeToRemove]);

return <SnackBarContainer ref={ref}>{text}</SnackBarContainer>;
},
);
Expand Down
8 changes: 2 additions & 6 deletions src/features/auth/components/LoginAlertModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,10 @@ import useRedirect from "@/hooks/useRedirect";
import { Text } from "./style";

interface LoginAlertModalProps {
isVisible: boolean;
onClose: () => void;
}

export default function LoginAlertModal({
isVisible,
onClose,
}: LoginAlertModalProps) {
export default function LoginAlertModal({ onClose }: LoginAlertModalProps) {
const location = useLocation();
const navigate = useNavigate();
const { setRedirect } = useRedirect();
Expand All @@ -29,7 +25,7 @@ export default function LoginAlertModal({

return (
<>
<Modal isVisible={isVisible} size="md" onClose={onClose}>
<Modal size="md" onClose={onClose}>
<Modal.Content>
<Text>로그인이 필요해요</Text>
</Modal.Content>
Expand Down
11 changes: 7 additions & 4 deletions src/features/bookmarks/components/BookmarkButton.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AnimatePresence } from "framer-motion";
import { useEffect, useState } from "react";

import Button from "@/components/Button";
Expand Down Expand Up @@ -59,10 +60,12 @@ export default function BookmarkButton({ animeId }: BookmarkButtonProps) {
>
{isBookmarked ? "입덕한 애니" : "입덕하기"}
</Button>
<LoginAlertModal
isVisible={isLoginModalVisible}
onClose={() => setIsLoginModalVisible(false)}
/>

<AnimatePresence>
{isLoginModalVisible && (
<LoginAlertModal onClose={() => setIsLoginModalVisible(false)} />
)}
</AnimatePresence>
</>
);
}
101 changes: 54 additions & 47 deletions src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useTheme } from "@emotion/react";
import { DotsThree } from "@phosphor-icons/react";
import { AnimatePresence } from "framer-motion";
import { useState } from "react";

import Button from "@/components/Button";
Expand All @@ -13,7 +14,7 @@ import ShortReviewModal from "../ReviewRating/ShortReviewModal";

import { MyRating, RatingContainer } from "./ReviewMoreButton.style";

const USER_MOCK_DATA = { isMine: false };
const USER_MOCK_DATA = { isMine: true };
const USER_MOCK_REVIEW_DATA = {
score: 7,
content: "유저가 생성한 짧은 리뷰입니다.",
Expand Down Expand Up @@ -62,53 +63,59 @@ export default function ReviewMoreButton() {
color="neutral"
onClick={handleDropDownModalToggle}
/>
<DropDownModal
isVisible={isDropDownModalOpen}
onDropDownModalToggle={handleDropDownModalToggle}
>
<DropDownModal.Button
name={USER_MOCK_DATA.isMine ? "수정하기" : "스포일러 신고"}
size="lg"
variant="solid"
color="neutral"
onClick={() =>
USER_MOCK_DATA.isMine
? handleReviewEditClick()
: handleReviewSpoilerReport()
}
>
{USER_MOCK_DATA.isMine ? "수정하기" : "스포일러 신고"}
</DropDownModal.Button>
<DropDownModal.Button
name={USER_MOCK_DATA.isMine ? "삭제하기" : "기타 신고"}
size="lg"
variant="solid"
color="neutral"
onClick={() =>
USER_MOCK_DATA.isMine
? handleReviewDeleteClick()
: handleReviewEtcReport()
}
>
{USER_MOCK_DATA.isMine ? "삭제하기" : "기타 신고"}
</DropDownModal.Button>
</DropDownModal>
<AnimatePresence>
{isDropDownModalOpen && (
<DropDownModal
key="DropDownModal"
onDropDownModalToggle={handleDropDownModalToggle}
>
<DropDownModal.Button
name={USER_MOCK_DATA.isMine ? "수정하기" : "스포일러 신고"}
size="lg"
variant="solid"
color="neutral"
onClick={() =>
USER_MOCK_DATA.isMine
? handleReviewEditClick()
: handleReviewSpoilerReport()
}
>
{USER_MOCK_DATA.isMine ? "수정하기" : "스포일러 신고"}
</DropDownModal.Button>
<DropDownModal.Button
name={USER_MOCK_DATA.isMine ? "삭제하기" : "기타 신고"}
size="lg"
variant="solid"
color="neutral"
onClick={() =>
USER_MOCK_DATA.isMine
? handleReviewDeleteClick()
: handleReviewEtcReport()
}
>
{USER_MOCK_DATA.isMine ? "삭제하기" : "기타 신고"}
</DropDownModal.Button>
</DropDownModal>
)}

<ShortReviewModal
isVisible={isReviewModalVisible}
onClose={() => setIsReviewModalVisible(false)}
onReview={() => setIsReviewModalVisible(false)}
userReviewData={USER_MOCK_REVIEW_DATA}
>
<MyRating>내 별점</MyRating>
<RatingContainer>
<Rating
size="lg"
onRate={handleRate}
value={USER_MOCK_REVIEW_DATA.score}
/>
</RatingContainer>
</ShortReviewModal>
{isReviewModalVisible && (
<ShortReviewModal
key="ShortReviewModal"
onClose={() => setIsReviewModalVisible(false)}
onReview={() => setIsReviewModalVisible(false)}
userReviewData={USER_MOCK_REVIEW_DATA}
>
<MyRating>내 별점</MyRating>
<RatingContainer>
<Rating
size="lg"
onRate={handleRate}
value={USER_MOCK_REVIEW_DATA.score}
/>
</RatingContainer>
</ShortReviewModal>
)}
</AnimatePresence>

<SnackBar ref={snackBarRef} text="신고가 접수되었습니다" />
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,12 @@ interface MOCK_USER_REVIEW_DATA {
}

interface ShortReviewModalProps {
isVisible: boolean;
onClose: () => void;
onReview: () => void;
userReviewData?: MOCK_USER_REVIEW_DATA;
}

export default function ShortReviewModal({
isVisible,
onClose,
onReview,
userReviewData,
Expand Down Expand Up @@ -126,7 +124,7 @@ export default function ShortReviewModal({
// };

return (
<Modal isVisible={isVisible} onClose={onClose}>
<Modal onClose={onClose}>
<Modal.Content>
<Title>한 줄 리뷰 모달</Title>
{children}
Expand Down
27 changes: 18 additions & 9 deletions src/features/reviews/components/ReviewRating/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AnimatePresence } from "framer-motion";
import { useState } from "react";

import Rating from "@/components/Rating";
Expand Down Expand Up @@ -42,15 +43,23 @@ export default function ReviewRating({ animeId }: ReviewRatingProps) {
</ReviewRecommend>
)}
{hasReviewed && "TODO: 사용자 리뷰 렌더링 "}
<ShortReviewModal
isVisible={isReviewModalVisible}
onClose={() => setIsReviewModalVisible(false)}
onReview={() => setIsReviewModalVisible(false)}
/>
<LoginAlertModal
isVisible={isLoginModalVisible}
onClose={() => setIsLoginModalVisible(false)}
/>

<AnimatePresence>
{isReviewModalVisible && (
<ShortReviewModal
key="ShortReviewModal"
onClose={() => setIsReviewModalVisible(false)}
onReview={() => setIsReviewModalVisible(false)}
/>
)}

{isLoginModalVisible && (
<LoginAlertModal
key="LoginAlertModal"
onClose={() => setIsLoginModalVisible(false)}
/>
)}
</AnimatePresence>
</>
);
}
11 changes: 6 additions & 5 deletions src/features/users/components/DropDownModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import { Variants } from "framer-motion";

import Button from "@/components/Button";
import AnimatePortal from "@/components/Portal/AnimatePortal";
import Portal from "@/components/Portal";
import useScrollLock from "@/hooks/useScrollLock";
import { StrictPropsWithChildren } from "@/types";

import { ButtonContainer, Backdrop } from "./style";

export interface DropDownModalProps {
isVisible: boolean;
onDropDownModalToggle: () => void;
}

export default function DropDownModal({
isVisible,
onDropDownModalToggle,
children,
}: StrictPropsWithChildren<DropDownModalProps>) {
useScrollLock(true);

return (
<AnimatePortal isVisible={isVisible}>
<Portal>
<Backdrop onClick={onDropDownModalToggle} />
{/* 애니메이션 props: variants, animate, exit */}
<ButtonContainer variants={variants} animate="animate" exit="exit">
Expand All @@ -32,7 +33,7 @@ export default function DropDownModal({
취소
</Button>
</ButtonContainer>
</AnimatePortal>
</Portal>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,26 @@ const OPTION = [
];

interface ProfileReportModalProps {
isVisible: boolean;
onClose: () => void;
}

export default function ProfileReportModal({
isVisible,
onClose,
}: ProfileReportModalProps) {
const { snackBarRef, showSnackBar } = useSnackBar();

const [selected, setSelected] = useState(OPTION[0].value);

const handleSelectChange = (e: React.ChangeEvent<HTMLSelectElement>) =>
setSelected(e.target.value);
const handleReportSumbit = () => {
onClose();
showSnackBar();
setSelected(OPTION[0].value);
};

return (
<>
<Modal isVisible={isVisible} onClose={onClose}>
<Modal onClose={onClose}>
{/* <Modal isVisible={isVisible} onClose={onClose}> */}
<Modal.Content>
<Header>
<Title>신고하기</Title>
Expand Down
Loading

0 comments on commit 2b32d8b

Please sign in to comment.