diff --git a/src/components/Backdrop/index.tsx b/src/components/Backdrop/index.tsx index cd697593..ed30e8ed 100644 --- a/src/components/Backdrop/index.tsx +++ b/src/components/Backdrop/index.tsx @@ -13,7 +13,10 @@ export interface BackdropProps { onClick: () => void; } -/** AnimatePortal 컴포넌트로 감싸서 사용 */ +/** + * @desc 1. < AnimatePortal > 컴포넌트와 함께 사용 + * @desc 2. < AnimatePresence > + 컴포넌트와 함께 사용 + * */ export default function Backdrop({ isVisible = true, className = "", diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index 822058f4..68dddbd8 100644 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -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"; @@ -22,8 +22,9 @@ export interface ModalProps { onClose: () => void; } +/** @desc < AnimatePresence > 컴포넌트로 감싸서 사용해주세요. */ export default function Modal({ - isVisible = false, + isVisible = true, size = "default", showBackdrop = true, onClose, @@ -32,7 +33,7 @@ export default function Modal({ useScrollLock(isVisible); return ( - + {children} - + ); } diff --git a/src/components/SnackBar/index.tsx b/src/components/SnackBar/index.tsx index d1b40b31..a72a7ee3 100644 --- a/src/components/SnackBar/index.tsx +++ b/src/components/SnackBar/index.tsx @@ -6,8 +6,14 @@ interface SnackBarProps { text: string; } +//TODO: SnackBar animation 변경 const SnackBar = forwardRef( ({ text }: SnackBarProps, ref: React.ForwardedRef) => { + // const [isPresent, safeToRemove] = usePresence(); + // useEffect(() => { + // !isPresent && setTimeout(safeToRemove, 2000); + // }, [isPresent, safeToRemove]); + return {text}; }, ); diff --git a/src/features/auth/components/LoginAlertModal/index.tsx b/src/features/auth/components/LoginAlertModal/index.tsx index 23755e58..b783dec5 100644 --- a/src/features/auth/components/LoginAlertModal/index.tsx +++ b/src/features/auth/components/LoginAlertModal/index.tsx @@ -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(); @@ -29,7 +25,7 @@ export default function LoginAlertModal({ return ( <> - + 로그인이 필요해요 diff --git a/src/features/bookmarks/components/BookmarkButton.tsx b/src/features/bookmarks/components/BookmarkButton.tsx index 21c884fb..233514f0 100644 --- a/src/features/bookmarks/components/BookmarkButton.tsx +++ b/src/features/bookmarks/components/BookmarkButton.tsx @@ -1,3 +1,4 @@ +import { AnimatePresence } from "framer-motion"; import { useEffect, useState } from "react"; import Button from "@/components/Button"; @@ -59,10 +60,12 @@ export default function BookmarkButton({ animeId }: BookmarkButtonProps) { > {isBookmarked ? "입덕한 애니" : "입덕하기"} - setIsLoginModalVisible(false)} - /> + + + {isLoginModalVisible && ( + setIsLoginModalVisible(false)} /> + )} + ); } diff --git a/src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx b/src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx index 03da1cc1..b12e128f 100644 --- a/src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx +++ b/src/features/reviews/components/ReviewCard/ReviewMoreButton.tsx @@ -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"; @@ -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: "유저가 생성한 짧은 리뷰입니다.", @@ -62,53 +63,59 @@ export default function ReviewMoreButton() { color="neutral" onClick={handleDropDownModalToggle} /> - - - USER_MOCK_DATA.isMine - ? handleReviewEditClick() - : handleReviewSpoilerReport() - } - > - {USER_MOCK_DATA.isMine ? "수정하기" : "스포일러 신고"} - - - USER_MOCK_DATA.isMine - ? handleReviewDeleteClick() - : handleReviewEtcReport() - } - > - {USER_MOCK_DATA.isMine ? "삭제하기" : "기타 신고"} - - + + {isDropDownModalOpen && ( + + + USER_MOCK_DATA.isMine + ? handleReviewEditClick() + : handleReviewSpoilerReport() + } + > + {USER_MOCK_DATA.isMine ? "수정하기" : "스포일러 신고"} + + + USER_MOCK_DATA.isMine + ? handleReviewDeleteClick() + : handleReviewEtcReport() + } + > + {USER_MOCK_DATA.isMine ? "삭제하기" : "기타 신고"} + + + )} - setIsReviewModalVisible(false)} - onReview={() => setIsReviewModalVisible(false)} - userReviewData={USER_MOCK_REVIEW_DATA} - > - 내 별점 - - - - + {isReviewModalVisible && ( + setIsReviewModalVisible(false)} + onReview={() => setIsReviewModalVisible(false)} + userReviewData={USER_MOCK_REVIEW_DATA} + > + 내 별점 + + + + + )} + diff --git a/src/features/reviews/components/ReviewRating/ShortReviewModal.tsx b/src/features/reviews/components/ReviewRating/ShortReviewModal.tsx index 1fb8051d..833ba0eb 100644 --- a/src/features/reviews/components/ReviewRating/ShortReviewModal.tsx +++ b/src/features/reviews/components/ReviewRating/ShortReviewModal.tsx @@ -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, @@ -126,7 +124,7 @@ export default function ShortReviewModal({ // }; return ( - + 한 줄 리뷰 모달 {children} diff --git a/src/features/reviews/components/ReviewRating/index.tsx b/src/features/reviews/components/ReviewRating/index.tsx index f08250b5..9a1625c6 100644 --- a/src/features/reviews/components/ReviewRating/index.tsx +++ b/src/features/reviews/components/ReviewRating/index.tsx @@ -1,3 +1,4 @@ +import { AnimatePresence } from "framer-motion"; import { useState } from "react"; import Rating from "@/components/Rating"; @@ -42,15 +43,23 @@ export default function ReviewRating({ animeId }: ReviewRatingProps) { )} {hasReviewed && "TODO: 사용자 리뷰 렌더링 "} - setIsReviewModalVisible(false)} - onReview={() => setIsReviewModalVisible(false)} - /> - setIsLoginModalVisible(false)} - /> + + + {isReviewModalVisible && ( + setIsReviewModalVisible(false)} + onReview={() => setIsReviewModalVisible(false)} + /> + )} + + {isLoginModalVisible && ( + setIsLoginModalVisible(false)} + /> + )} + ); } diff --git a/src/features/users/components/DropDownModal/index.tsx b/src/features/users/components/DropDownModal/index.tsx index 2ff759a0..2c084dc4 100644 --- a/src/features/users/components/DropDownModal/index.tsx +++ b/src/features/users/components/DropDownModal/index.tsx @@ -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) { + useScrollLock(true); + return ( - + {/* 애니메이션 props: variants, animate, exit */} @@ -32,7 +33,7 @@ export default function DropDownModal({ 취소 - + ); } diff --git a/src/features/users/components/ProfileImageSection/ProfileReportModal.tsx b/src/features/users/components/ProfileImageSection/ProfileReportModal.tsx index a3a1c2a4..e6be35fa 100644 --- a/src/features/users/components/ProfileImageSection/ProfileReportModal.tsx +++ b/src/features/users/components/ProfileImageSection/ProfileReportModal.tsx @@ -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) => setSelected(e.target.value); const handleReportSumbit = () => { onClose(); showSnackBar(); - setSelected(OPTION[0].value); }; return ( <> - + + {/* */}
신고하기 diff --git a/src/features/users/components/ProfileImageSection/ProfileSetupButton.tsx b/src/features/users/components/ProfileImageSection/ProfileSetupButton.tsx index 2f2dd366..9e5083df 100644 --- a/src/features/users/components/ProfileImageSection/ProfileSetupButton.tsx +++ b/src/features/users/components/ProfileImageSection/ProfileSetupButton.tsx @@ -1,3 +1,4 @@ +import { AnimatePresence } from "framer-motion"; import { useState } from "react"; import { useNavigate } from "react-router-dom"; @@ -37,34 +38,42 @@ export default function ProfileSetupButton({ - - - 프로필 링크 복사 - - - isMine ? handleLinkToEditClick() : handleReportClick() - } - > - {isMine ? "프로필 수정" : "신고하기"} - - - + + + {isDropDownModalOpen && ( + + + 프로필 링크 복사 + + + isMine ? handleLinkToEditClick() : handleReportClick() + } + > + {isMine ? "프로필 수정" : "신고하기"} + + + )} + + {isReportModalOpen && ( + + )} + ); } diff --git a/src/features/users/routes/Profile/AboutMe/StatModal.tsx b/src/features/users/routes/Profile/AboutMe/StatModal.tsx index 547020ea..94bb45bc 100644 --- a/src/features/users/routes/Profile/AboutMe/StatModal.tsx +++ b/src/features/users/routes/Profile/AboutMe/StatModal.tsx @@ -11,18 +11,13 @@ interface StatItemProps { } interface StatModalProps { - isVisible: boolean; items: StatItemProps[]; onClose: () => void; } -export default function StatModal({ - isVisible, - items, - onClose, -}: StatModalProps) { +export default function StatModal({ items, onClose }: StatModalProps) { return ( - + {items.map((item, index) => ( diff --git a/src/features/users/routes/Profile/AboutMe/index.tsx b/src/features/users/routes/Profile/AboutMe/index.tsx index 33d74510..c178fa64 100644 --- a/src/features/users/routes/Profile/AboutMe/index.tsx +++ b/src/features/users/routes/Profile/AboutMe/index.tsx @@ -1,3 +1,4 @@ +import { AnimatePresence } from "framer-motion"; import { useState } from "react"; import Stat from "@/components/Stat"; @@ -53,11 +54,11 @@ export default function AboutMe() { - + + {isStatModalVisible && ( + + )} + ); }