From ea7a49858f1d4e46164fd997352f44e3a80c59eb Mon Sep 17 00:00:00 2001 From: ukkodeveloper Date: Sun, 7 Apr 2024 23:57:41 +0900 Subject: [PATCH] =?UTF-8?q?Refactor/#555=20=ED=94=84=EB=A1=9C=EC=A0=9D?= =?UTF-8?q?=ED=8A=B8=20=EB=8F=99=EC=9D=98=EB=A5=BC=20=EA=B5=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EB=AA=A8=EB=8B=AC=EC=9D=84=20confirmModal=EB=A1=9C?= =?UTF-8?q?=20=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81=20(#556)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 전역에 ConfirmModalProvider 추가 * refactor: 나만의 파트 등록 시에 확인 모달에 useConfirm 적용 * feat: 모달 너비를 고려하여 회원 탈퇴 메세지 길이 수정 * design: confirm modal 너비 300에서 320으로 변경 - 짧은 문장도 잘 담지 못해서 줄바꿈이 일어남. 그래서 너비를 늘림 * refactor: 프로필 변경 페이지에서 회원 탈퇴 시 useConfirm 적용 * fix: 회원 탈퇴 시 마이페이지로 뒤로 가지 못하도록 수정 * refactor: 내 파트 삭제 시에 확인하는 과정에서 useConfirm 적용 * refactor: 이벤트 핸들러 네이밍 handle- prefix 사용 * chore: 사용하지 않는 modal 컴포넌트 삭제 --------- Co-authored-by: 윤정민 --- .../killingParts/components/RegisterPart.tsx | 106 +++++------------- .../member/components/WithdrawalModal.tsx | 67 ----------- .../member/constants/withdrawalMessage.ts | 2 +- .../songs/components/KillingPartTrack.tsx | 34 +++--- .../features/songs/components/MyPartModal.tsx | 57 ---------- frontend/src/index.tsx | 15 ++- frontend/src/pages/EditProfilePage.tsx | 36 ++++-- .../components/ConfirmModal/ConfirmModal.tsx | 2 +- 8 files changed, 87 insertions(+), 232 deletions(-) delete mode 100644 frontend/src/features/member/components/WithdrawalModal.tsx delete mode 100644 frontend/src/features/songs/components/MyPartModal.tsx diff --git a/frontend/src/features/killingParts/components/RegisterPart.tsx b/frontend/src/features/killingParts/components/RegisterPart.tsx index bda701750..e341ac992 100644 --- a/frontend/src/features/killingParts/components/RegisterPart.tsx +++ b/frontend/src/features/killingParts/components/RegisterPart.tsx @@ -3,61 +3,48 @@ import styled from 'styled-components'; import { useAuthContext } from '@/features/auth/components/AuthProvider'; import useCollectingPartContext from '@/features/killingParts/hooks/useCollectingPartContext'; import useVideoPlayerContext from '@/features/youtube/hooks/useVideoPlayerContext'; -import useModal from '@/shared/components/Modal/hooks/useModal'; -import Modal from '@/shared/components/Modal/Modal'; +import { useConfirmContext } from '@/shared/components/ConfirmModal/hooks/useConfirmContext'; import Spacing from '@/shared/components/Spacing'; import { useMutation } from '@/shared/hooks/useMutation'; import { toPlayingTimeText } from '@/shared/utils/convertTime'; import { postKillingPart } from '../remotes/killingPart'; const RegisterPart = () => { - const { isOpen, openModal, closeModal } = useModal(); + const navigate = useNavigate(); const { user } = useAuthContext(); const { interval, partStartTime, songId } = useCollectingPartContext(); const video = useVideoPlayerContext(); + const { confirmPopup } = useConfirmContext(); + const { createKillingPart } = usePostKillingPart(); + const voteTimeText = toPlayingTimeText(partStartTime, partStartTime + interval); const { mutateData: createKillingPart } = useMutation(postKillingPart); const navigate = useNavigate(); // 현재 useMutation 훅이 response 객체를 리턴하지 않고 내부적으로 처리합니다. // 때문에 컴포넌트 단에서 createKillingPart 성공 여부에 따라 등록 완료 만료를 처리를 할 수 없어요! - // 현재 비로그인 시에 등록을 누르면 두 개의 모달이 뜹니다.정 - const submitKillingPart = async () => { - await createKillingPart(songId, { startSecond: partStartTime, length: interval }); - navigate(-1); - }; - - const openRegisterModal = () => { + // 현재 비로그인 시에 등록을 누르면 두 개의 모달이 뜹니다. + const handleClickRegisterPart = async () => { video.pause(); - openModal(); - }; - - const voteTimeText = toPlayingTimeText(partStartTime, partStartTime + interval); - return ( - <> - 등록 - - - {user?.nickname}님의 파트 저장 - - - - {voteTimeText} - - + const isConfirmed = await confirmPopup({ + title: `${user?.nickname}님의 파트 저장`, + content: ( + + + {voteTimeText} + 나만의 파트로 등록하시겠습니까? - - - - 취소 - - - 등록 - - - - - ); + + ), + }); + + if (isConfirmed) { + await createKillingPart(songId, { startSecond: partStartTime, length: interval }); + navigate(-1); + } + }; + + return 등록; }; export default RegisterPart; @@ -80,45 +67,8 @@ const RegisterButton = styled.button` } `; -const ModalTitle = styled.h3``; - -const TitleColumn = styled.div` - text-align: center; -`; - -const ModalContent = styled.div` - padding: 16px 0; - - font-size: 16px; - color: #b5b3bc; - text-align: center; - white-space: pre-line; -`; - const Message = styled.div``; -const Button = styled.button` - height: 36px; - color: ${({ theme: { color } }) => color.white}; - border-radius: 10px; -`; - -const Cancel = styled(Button)` - flex: 1; - background-color: ${({ theme: { color } }) => color.secondary}; -`; - -const Confirm = styled(Button)` - flex: 1; - background-color: ${({ theme: { color } }) => color.primary}; -`; - -const ButtonContainer = styled.div` - display: flex; - gap: 16px; - width: 100%; -`; - const Part = styled.span` padding: 6px 11px; @@ -128,3 +78,9 @@ const Part = styled.span` background-color: ${({ theme: { color } }) => color.disabled}; border-radius: 10px; `; + +const ContentContainer = styled.div` + display: flex; + flex-direction: column; + align-items: center; +`; diff --git a/frontend/src/features/member/components/WithdrawalModal.tsx b/frontend/src/features/member/components/WithdrawalModal.tsx deleted file mode 100644 index 8712d36ca..000000000 --- a/frontend/src/features/member/components/WithdrawalModal.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import styled from 'styled-components'; -import WITHDRAWAL_MESSAGE from '@/features/member/constants/withdrawalMessage'; -import Modal from '@/shared/components/Modal/Modal'; -import Spacing from '@/shared/components/Spacing'; - -interface WithdrawalModalProps { - isOpen: boolean; - closeModal: () => void; - onWithdraw: () => void; -} - -const WithdrawalModal = ({ isOpen, closeModal, onWithdraw }: WithdrawalModalProps) => { - return ( - - <> - {WITHDRAWAL_MESSAGE} - - - - 회원 탈퇴 - - - 닫기 - - - - - ); -}; - -export default WithdrawalModal; - -const ModalContent = styled.div` - align-self: start; - - font-size: 16px; - line-height: 200%; - color: ${({ theme }) => theme.color.subText}; - white-space: pre-line; -`; - -const Button = styled.button` - cursor: pointer; - - height: 36px; - - color: ${({ theme: { color } }) => color.white}; - - border: none; - border-radius: 10px; -`; - -const ConfirmButton = styled(Button)` - flex: 1; - background-color: ${({ theme: { color } }) => color.secondary}; -`; - -const CancelButton = styled(Button)` - flex: 1.5; - background-color: ${({ theme: { color } }) => color.primary}; -`; - -const ButtonContainer = styled.div` - display: flex; - gap: 16px; - width: 100%; -`; diff --git a/frontend/src/features/member/constants/withdrawalMessage.ts b/frontend/src/features/member/constants/withdrawalMessage.ts index 9652ddd85..fb1945d9d 100644 --- a/frontend/src/features/member/constants/withdrawalMessage.ts +++ b/frontend/src/features/member/constants/withdrawalMessage.ts @@ -1,3 +1,3 @@ -const WITHDRAWAL_MESSAGE = '회원 탈퇴시 활동한 모든 이력이 삭제됩니다.\n정말 회원 탈퇴하겠습니까?'; +const WITHDRAWAL_MESSAGE = '회원 탈퇴시 모든 이력이 삭제됩니다.\n정말 회원 탈퇴하겠습니까?'; export default WITHDRAWAL_MESSAGE; diff --git a/frontend/src/features/songs/components/KillingPartTrack.tsx b/frontend/src/features/songs/components/KillingPartTrack.tsx index 6c412c9ef..a1b79a5d7 100644 --- a/frontend/src/features/songs/components/KillingPartTrack.tsx +++ b/frontend/src/features/songs/components/KillingPartTrack.tsx @@ -8,6 +8,7 @@ import { useAuthContext } from '@/features/auth/components/AuthProvider'; import LoginModal from '@/features/auth/components/LoginModal'; import { deleteMemberParts } from '@/features/member/remotes/memberParts'; import useVideoPlayerContext from '@/features/youtube/hooks/useVideoPlayerContext'; +import { useConfirmContext } from '@/shared/components/ConfirmModal/hooks/useConfirmContext'; import useModal from '@/shared/components/Modal/hooks/useModal'; import useTimerContext from '@/shared/components/Timer/hooks/useTimerContext'; import useToastContext from '@/shared/components/Toast/hooks/useToastContext'; @@ -18,7 +19,6 @@ import { toPlayingTimeText } from '@/shared/utils/convertTime'; import copyClipboard from '@/shared/utils/copyClipBoard'; import formatOrdinals from '@/shared/utils/formatOrdinals'; import useKillingPartLikes from '../hooks/useKillingPartLikes'; -import MyPartModal from './MyPartModal'; import type { KillingPart } from '@/shared/types/song'; import type React from 'react'; @@ -45,6 +45,7 @@ const KillingPartTrack = ({ }: KillingPartTrackProps) => { const { showToast } = useToastContext(); const { seekTo, pause, playerState, videoPlayer } = useVideoPlayerContext(); + const { confirmPopup } = useConfirmContext(); const { heartIcon, toggleKillingPartLikes } = useKillingPartLikes({ likeCount, likeStatus, @@ -57,11 +58,6 @@ const KillingPartTrack = ({ closeModal: closeLoginModal, openModal: openLoginModal, } = useModal(); - const { - isOpen: isMyPartModal, - closeModal: closeMyPartModal, - openModal: openMyPartModal, - } = useModal(); const { user } = useAuthContext(); const isLoggedIn = user !== null; @@ -148,15 +144,22 @@ const KillingPartTrack = ({ const { mutateData: deleteMemberPart } = useMutation(() => deleteMemberParts(partId)); - const deleteMyPart = async () => { - if (!hideMyPart) return; + const handleClickDeletePart = async () => { + const isConfirmed = await confirmPopup({ + title: '내 파트 삭제', + content:

정말 삭제하시겠습니까?

, + confirmation: '삭제', + denial: '취소', + }); - await deleteMemberPart(); + if (isConfirmed) { + if (!hideMyPart) return; - hideMyPart(); - pause(); - closeMyPartModal(); - showToast('내 파트가 삭제되었습니다.'); + await deleteMemberPart(); + hideMyPart(); + pause(); + showToast('내 파트가 삭제되었습니다.'); + } }; return ( @@ -185,7 +188,7 @@ const KillingPartTrack = ({ <> @@ -211,12 +214,11 @@ const KillingPartTrack = ({ )} + {isNowPlayingTrack && (