Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
5 changes: 5 additions & 0 deletions frontend/src/api/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ export const fetchMyProfile = async () => {
const { data } = await axiosInstance.get('/members')
return data
}

export const withdrawMember = async () => {
const { data } = await axiosInstance.delete('/members/withdraw')
return data
}
31 changes: 31 additions & 0 deletions frontend/src/hooks/setting/useWithdrawSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { useQueryClient } from '@tanstack/react-query'
import { useNavigate } from 'react-router-dom'
import { useAuthStore } from '../../stores/authStore'
import { useWithdrawMember } from './userMutations'

export function useWithdrawSettings() {
const navigate = useNavigate()
const queryClient = useQueryClient()
const clearAuth = useAuthStore((state) => state.actions.clearAuth)
const { mutate: withdraw, isPending } = useWithdrawMember()

const confirmWithdraw = () => {
if (isPending) return

withdraw(undefined, {
onSuccess: () => {
queryClient.clear()
clearAuth()
navigate('/')
},
onError: () => {
alert('회원 탈퇴에 실패했습니다.')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

사용자 경험을 위해 alert 대신 토스트나 스낵바와 같은 UI 컴포넌트를 사용하여 에러 메시지를 표시하는 것을 고려해보세요. alert는 브라우저의 기본 기능을 사용하여 사용자 인터페이스의 일관성을 해치고, 사용자 경험을 저해할 수 있습니다.

},
})
}

return {
confirmWithdraw,
isPending,
}
}
8 changes: 7 additions & 1 deletion frontend/src/hooks/setting/userMutations.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useMutation } from '@tanstack/react-query'
import { updateMemberAgree, updateMemberProfileImage, updateMemberSNS } from '../../api/user'
import { updateMemberAgree, updateMemberProfileImage, updateMemberSNS, withdrawMember } from '../../api/user'

export const useUpdateMemberAgree = () => {
return useMutation({
Expand All @@ -18,3 +18,9 @@ export const useUpdateMemberProfileImage = () => {
mutationFn: updateMemberProfileImage,
})
}

export const useWithdrawMember = () => {
return useMutation({
mutationFn: withdrawMember,
})
}
21 changes: 12 additions & 9 deletions frontend/src/pages/setting/SettingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,25 @@ import { Button } from './_components/SettingButton'
import '../../styles/scrollbar.css'
import CloseIcon from '../../assets/icons/delete_normal.svg?react'
import LogoutIcon from '../../assets/icons/logout.svg?react'
import WithdrawlModal from './_components/WithdrawlModal'
import WithdrawModal from './_components/WithdrawModal'
import { useLogout } from '../../hooks/useLogout'
import ProfileSettings from './_containers/ProfileSettings'
import ConsentSettings from './_containers/ConsentSettings'
import { useWithdrawSettings } from '../../hooks/setting/useWithdrawSettings'

type SettingPageProps = {
onClose?: () => void
}

export default function SettingPage({ onClose }: SettingPageProps) {
const [activeTab, setActiveTab] = useState<'profile' | 'consent'>('profile')
const [showWithdrawlModal, setShowWithdrawlModal] = useState(false)
const [showWithdrawModal, setShowWithdrawModal] = useState(false)

const logout = useLogout()
const [loggingOut, setLoggingOut] = useState(false)

const { confirmWithdraw, isPending } = useWithdrawSettings()

const handleClickLogout = async () => {
if (loggingOut) return
setLoggingOut(true)
Expand All @@ -27,10 +30,6 @@ export default function SettingPage({ onClose }: SettingPageProps) {
onClose?.()
}

const handleWithdrawlConfirm = () => {
setShowWithdrawlModal(false)
}

return (
<div className="fixed inset-0 z-50 bg-neutral-black-opacity50 flex justify-center items-center tablet:py-10">
<div
Expand Down Expand Up @@ -78,7 +77,7 @@ export default function SettingPage({ onClose }: SettingPageProps) {
<div className="[&::-webkit-scrollbar]:hidden flex flex-1 flex-col p-8 gap-10 overflow-y-auto">
{activeTab === 'profile' && (
<ProfileSettings
onOpenWithdraw={() => setShowWithdrawlModal(true)}
onOpenWithdraw={() => setShowWithdrawModal(true)}
fetchEnabled={!loggingOut}
/>
)}
Expand All @@ -88,8 +87,12 @@ export default function SettingPage({ onClose }: SettingPageProps) {
</div>
</div>

{showWithdrawlModal && (
<WithdrawlModal onClose={() => setShowWithdrawlModal(false)} onConfirm={handleWithdrawlConfirm} />
{showWithdrawModal && (
<WithdrawModal
onClose={() => setShowWithdrawModal(false)}
onConfirm={confirmWithdraw}
isPending={isPending}
/>
)}
</div>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import Modal from '../../../components/Modal'
import { Button } from './SettingButton'

type WithdrawlModalProps = {
type WithdrawModalProps = {
onClose: () => void
onConfirm: () => void
isPending: boolean
}

export default function WithdrawlModal({ onClose, onConfirm }: WithdrawlModalProps) {
export default function WithdrawModal({ onClose, onConfirm, isPending }: WithdrawModalProps) {
return (
<Modal
title="계정을 탈퇴하시겠어요?"
Expand All @@ -17,6 +18,7 @@ export default function WithdrawlModal({ onClose, onConfirm }: WithdrawlModalPro
<Button
variant="ghost"
onClick={onClose}
disabled={isPending}
className="flex items-center justify-center gap-2 px-4 w-full !max-w-[103px] h-[40px] !rounded-[16px]
font-body-16b border border-gray-300"
>
Expand All @@ -25,6 +27,7 @@ export default function WithdrawlModal({ onClose, onConfirm }: WithdrawlModalPro
<Button
variant="danger"
onClick={onConfirm}
disabled={isPending}
className="flex items-center justify-center gap-2 px-4 w-full !max-w-[87px] h-[40px] !rounded-[16px]
font-body-16b"
>
Expand Down