Skip to content

Commit

Permalink
Refactor/#555 프로젝트 동의를 구하는 모달을 confirmModal로 리팩터링 (#556)
Browse files Browse the repository at this point in the history
* feat: 전역에 ConfirmModalProvider 추가

* refactor: 나만의 파트 등록 시에 확인 모달에 useConfirm 적용

* feat: 모달 너비를 고려하여 회원 탈퇴 메세지 길이 수정

* design: confirm modal 너비 300에서 320으로 변경

- 짧은 문장도 잘 담지 못해서 줄바꿈이 일어남. 그래서 너비를 늘림

* refactor: 프로필 변경 페이지에서 회원 탈퇴 시 useConfirm 적용

* fix: 회원 탈퇴 시 마이페이지로 뒤로 가지 못하도록 수정

* refactor: 내 파트 삭제 시에 확인하는 과정에서 useConfirm 적용

* refactor: 이벤트 핸들러 네이밍 handle- prefix 사용

* chore: 사용하지 않는 modal 컴포넌트 삭제

---------

Co-authored-by: 윤정민 <[email protected]>
  • Loading branch information
ukkodeveloper and cruelladevil authored Apr 7, 2024
1 parent b007310 commit ea7a498
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 232 deletions.
106 changes: 31 additions & 75 deletions frontend/src/features/killingParts/components/RegisterPart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
<>
<RegisterButton onClick={openRegisterModal}>등록</RegisterButton>
<Modal isOpen={isOpen} closeModal={closeModal}>
<ModalTitle>
<TitleColumn>{user?.nickname}님의 파트 저장</TitleColumn>
</ModalTitle>
<ModalContent>
<Message>
<Part>{voteTimeText}</Part>
</Message>
<Spacing direction="vertical" size={6} />
const isConfirmed = await confirmPopup({
title: `${user?.nickname}님의 파트 저장`,
content: (
<ContentContainer>
<Spacing direction="vertical" size={10} />
<Part>{voteTimeText}</Part>
<Spacing direction="vertical" size={10} />
<Message>나만의 파트로 등록하시겠습니까?</Message>
</ModalContent>
<ButtonContainer>
<Cancel type="button" onClick={closeModal}>
취소
</Cancel>
<Confirm type="button" onClick={submitKillingPart}>
등록
</Confirm>
</ButtonContainer>
</Modal>
</>
);
</ContentContainer>
),
});

if (isConfirmed) {
await createKillingPart(songId, { startSecond: partStartTime, length: interval });
navigate(-1);
}
};

return <RegisterButton onClick={handleClickRegisterPart}>등록</RegisterButton>;
};

export default RegisterPart;
Expand All @@ -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;
Expand All @@ -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;
`;
67 changes: 0 additions & 67 deletions frontend/src/features/member/components/WithdrawalModal.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
const WITHDRAWAL_MESSAGE = '회원 탈퇴시 활동한 모든 이력이 삭제됩니다.\n정말 회원 탈퇴하겠습니까?';
const WITHDRAWAL_MESSAGE = '회원 탈퇴시 모든 이력이 삭제됩니다.\n정말 회원 탈퇴하겠습니까?';

export default WITHDRAWAL_MESSAGE;
34 changes: 18 additions & 16 deletions frontend/src/features/songs/components/KillingPartTrack.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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';

Expand All @@ -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,
Expand All @@ -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;

Expand Down Expand Up @@ -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: <h3>정말 삭제하시겠습니까?</h3>,
confirmation: '삭제',
denial: '취소',
});

await deleteMemberPart();
if (isConfirmed) {
if (!hideMyPart) return;

hideMyPart();
pause();
closeMyPartModal();
showToast('내 파트가 삭제되었습니다.');
await deleteMemberPart();
hideMyPart();
pause();
showToast('내 파트가 삭제되었습니다.');
}
};

return (
Expand Down Expand Up @@ -185,7 +188,7 @@ const KillingPartTrack = ({
<>
<DeleteButton
type="button"
onClick={openMyPartModal}
onClick={handleClickDeletePart}
aria-label="나의 킬링파트 삭제하기"
>
<ButtonIcon src={trashIcon} alt="" />
Expand All @@ -211,12 +214,11 @@ const KillingPartTrack = ({
</>
)}
</ButtonContainer>

{isNowPlayingTrack && (
<ProgressBar value={currentPlayTime} max={partLength} aria-hidden="true" />
)}

<MyPartModal isOpen={isMyPartModal} closeModal={closeMyPartModal} onDelete={deleteMyPart} />

<LoginModal
isOpen={isLoginModalOpen}
message={
Expand Down
57 changes: 0 additions & 57 deletions frontend/src/features/songs/components/MyPartModal.tsx

This file was deleted.

15 changes: 9 additions & 6 deletions frontend/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import React from 'react';
import { createRoot } from 'react-dom/client';
import { RouterProvider } from 'react-router-dom';
import { ThemeProvider } from 'styled-components';
import ConfirmModalProvider from '@/shared/components/ConfirmModal/ConfirmModalProvider';
import GlobalStyles from '@/shared/styles/GlobalStyles';
import AuthProvider from './features/auth/components/AuthProvider';
import { loadIFrameApi } from './features/youtube/remotes/loadIframeApi';
Expand Down Expand Up @@ -34,12 +35,14 @@ async function main() {
<AuthProvider>
<GlobalStyles />
<ThemeProvider theme={theme}>
<QueryClientProvider client={queryClient}>
<ToastProvider>
<RouterProvider router={router} />
</ToastProvider>
<ReactQueryDevtools />
</QueryClientProvider>
<ToastProvider>
<QueryClientProvider client={queryClient}>
<ConfirmModalProvider>
<RouterProvider router={router} />
</ConfirmModalProvider>
<ReactQueryDevtools />
</QueryClientProvider>
</ToastProvider>
</ThemeProvider>
</AuthProvider>
</React.StrictMode>
Expand Down
Loading

0 comments on commit ea7a498

Please sign in to comment.