Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/api/authApi.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { get, patch } from './base';
import { get, patch, del } from './base';
import { AUTH_URL } from '../constants/api';

export const getOAuthKakaoApi = async (code) => {
Expand All @@ -14,4 +14,9 @@ export const getUserInfoApi = async () => {
export const patchUserNicknameApi = async (data) => {
const response = await patch(AUTH_URL.nickname(data));
return response;
};

export const deleteUserApi = async () => {
const response = await del(AUTH_URL.deleteUser);
return response;
};
58 changes: 58 additions & 0 deletions src/components/modal/DeleteUserModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import Modal from "./Modal";
import styled from "styled-components";
import { Button, Div, Text } from "../common/div";
import { GRAY5, GRAY1, BLACK, RED } from "../../constants/color";

const Container = styled.div`
width: 260px;
padding: 22px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
top: 50%;
transform: translateY(-50%);
`;

const StyledButton = styled(Button)`
border-radius: 4px;
flex-grow: 1;
height: 30px;
line-height: 30px;
padding: 0;
`;

export const DeleteUserModal = ({ isOpen, closeModal, handleDeleteUser }) => {
return (
<Modal $isOpen={isOpen} $dim={true}>
<Container>
<Text $weight='BOLD' $size={16}>
회원 탈퇴
</Text>
<Text $weight='MEDIUM' $size={12} $color={GRAY5} $margin='12px 0 0'>
정말 탈퇴하시겠습니까?
</Text>
<Text $weight='MEDIUM' $size={12} $color={GRAY5} $margin='4px 0 0'>
모든 데이터가 삭제되며 복구할 수 없습니다.
</Text>
<Div $flex={true} $gap='5px' $margin='24px 0 0'>
<StyledButton
$backgroundColor={GRAY1}
$color={BLACK}
onClick={closeModal}
>
취소
</StyledButton>
<StyledButton
$backgroundColor={RED}
onClick={handleDeleteUser}
>
탈퇴
</StyledButton>
</Div>
</Container>
</Modal>
)
}



8 changes: 6 additions & 2 deletions src/components/pages/mypage/Links.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import styled from "styled-components";
import { Link } from "react-router-dom";
import { Div, Text } from "../../common/div";
import { BLACK, GRAY5 } from "../../../constants/color";
import { BLACK, GRAY5, RED } from "../../../constants/color";
import { GoIcon } from "../../../assets/icons";

const LinkButton = styled(Link)`
Expand All @@ -13,7 +13,7 @@ const LinkButton = styled(Link)`
height: 26px;
`;

const Links = ({ logout }) => {
const Links = ({ logout, handleShowDeleteUser }) => {
const handleClick = () => {
window.location.href = 'https://www.notion.so/MUSEE-11b0cdd700f78074b473f3759010de3e?pvs=4';
}
Expand All @@ -32,6 +32,10 @@ const Links = ({ logout }) => {
<Text $size={12} $color={GRAY5} $weight='MEDIUM'>로그아웃</Text>
<GoIcon />
</LinkButton>
<LinkButton onClick={handleShowDeleteUser}>
<Text $size={12} $color={RED} $weight='MEDIUM'>회원 탈퇴</Text>
<GoIcon />
</LinkButton>
</Div>
)
}
Expand Down
2 changes: 2 additions & 0 deletions src/constants/color.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,7 @@ export const BLACK = '#3C3C3C';
export const LIGHT_BLUE = '#E2EFFF';
export const BLUE = '#0A7AFF';

export const RED = '#FF3B30';

export const DIM = 'rgba(0, 0, 0, 0.4)';
export const DIM2 = 'rgba(0, 0, 0, 0.8)';
32 changes: 31 additions & 1 deletion src/hooks/AuthHooks.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useState } from "react";
import { useNavigate } from "react-router-dom"
import { getOAuthKakaoApi, getUserInfoApi, patchUserNicknameApi } from "../api/authApi";
import { getOAuthKakaoApi, getUserInfoApi, patchUserNicknameApi, deleteUserApi } from "../api/authApi";
import { useDispatch, useSelector } from "react-redux";
import { login, setToken, logout, setName } from "../store/slices/userSlice";
import { ToastMessage } from "../components/common/Toast";
Expand All @@ -10,6 +10,7 @@ export const useAuth = () =>{
const dispatch = useDispatch();
const { username, userTier } = useSelector((state) => state.user.value);
const [isShowNicknameEdit, setIsShowNicknameEdit] = useState(false);
const [isShowDeleteUser, setIsShowDeleteUser] = useState(false);
const [nickname, setNickname] = useState(username);
const nicknameDisabled = nickname === username;

Expand Down Expand Up @@ -61,10 +62,36 @@ export const useAuth = () =>{
}
}

const handleShowDeleteUser = () => {
setIsShowDeleteUser(true);
}

const handleCloseDeleteUser = () => {
setIsShowDeleteUser(false);
}

const handleDeleteUser = async () => {
try {
const response = await deleteUserApi();
if (response.status === 200) {
dispatch(logout());
ToastMessage.info('회원 탈퇴가 완료되었습니다.');
navigate("/login");
} else {
console.error(response);
ToastMessage.info('회원 탈퇴에 실패했습니다.');
}
} catch (error) {
console.error(error);
ToastMessage.info('회원 탈퇴에 실패했습니다.');
}
}

return {
username,
userTier,
isShowNicknameEdit,
isShowDeleteUser,
nickname,
nicknameDisabled,
setNickname,
Expand All @@ -73,5 +100,8 @@ export const useAuth = () =>{
handleShowNicknameEdit,
handleNicknameEdit,
handleCloseNicknameEdit,
handleShowDeleteUser,
handleCloseDeleteUser,
handleDeleteUser,
}
}
12 changes: 8 additions & 4 deletions src/hooks/CreateBookHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export const useCreateBook = (id) => {

const handleFileChange = (e) => {
const fileArr = Array.from(e.target.files);
const currentPhotoCount = editData?.photos?.length || 0; // 기존 사진 개수
const currentPhotoCount = (editData?.photos?.length || 0) + previewImages.length; // 기존 사진 + 이미 업로드된 사진 개수
const maxNewPhotos = 3 - currentPhotoCount; // 추가 가능한 사진 개수

// 선택된 파일이 제한을 초과하는 경우 제한만큼만 선택
Expand All @@ -92,9 +92,13 @@ export const useCreateBook = (id) => {
alert(`최대 ${3}장까지만 업로드할 수 있습니다. ${maxNewPhotos}장만 선택되었습니다.`);
}

setUploadPhotos(limitedFiles);
const fileURLs = limitedFiles.map(file => URL.createObjectURL(file));
setPreviewImages(fileURLs);
// 기존 업로드된 파일들과 새로운 파일들을 합침
const newUploadPhotos = [...uploadPhotos, ...limitedFiles];
setUploadPhotos(newUploadPhotos);

// 기존 미리보기 이미지들과 새로운 이미지들을 합침
const newFileURLs = limitedFiles.map(file => URL.createObjectURL(file));
setPreviewImages([...previewImages, ...newFileURLs]);

// 파일 input 초기화 (같은 파일을 다시 선택할 수 있도록)
e.target.value = '';
Expand Down
11 changes: 11 additions & 0 deletions src/pages/Mypage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,25 @@ import Navigation from "../components/common/Navigation";
import Profile from "../components/pages/mypage/Profile";
import Links from "../components/pages/mypage/Links";
import { NicknameEditModal }from "../components/modal/NicknmaeEdiModal";
import { DeleteUserModal } from "../components/modal/DeleteUserModal";
import { useAuth } from "../hooks/AuthHooks";

const Mypage = () => {
const {
username,
userTier,
isShowNicknameEdit,
isShowDeleteUser,
nickname,
nicknameDisabled,
setNickname,
handleLogout,
handleShowNicknameEdit,
handleNicknameEdit,
handleCloseNicknameEdit,
handleShowDeleteUser,
handleCloseDeleteUser,
handleDeleteUser,
} = useAuth();
return (
<>
Expand All @@ -31,6 +36,7 @@ const Mypage = () => {
/>
<Links
logout={handleLogout}
handleShowDeleteUser={handleShowDeleteUser}
/>
</Div>
<NicknameEditModal
Expand All @@ -41,6 +47,11 @@ const Mypage = () => {
setNickname={setNickname}
nicknameDisabled={nicknameDisabled}
/>
<DeleteUserModal
isOpen={isShowDeleteUser}
closeModal={handleCloseDeleteUser}
handleDeleteUser={handleDeleteUser}
/>
<Navigation />
</>
)
Expand Down