diff --git a/apps/timo-web/app/[locale]/(main)/settings/_hooks/useSettingsProfile.ts b/apps/timo-web/app/[locale]/(main)/settings/_hooks/useSettingsProfile.ts
index db1e587a..c6239fe3 100644
--- a/apps/timo-web/app/[locale]/(main)/settings/_hooks/useSettingsProfile.ts
+++ b/apps/timo-web/app/[locale]/(main)/settings/_hooks/useSettingsProfile.ts
@@ -18,6 +18,7 @@ import {
} from "@/api/generated/endpoints/user/user";
import { UpdateLanguageRequestLanguage } from "@/api/generated/models";
import { useSettingsLanguageParam } from "@/app/[locale]/(main)/settings/_hooks/useSettingsLanguageParam";
+import { useLogoutAction } from "@/app/[locale]/(main)/settings/_queries/use-logout";
import { useMyProfile } from "@/queries/use-my-profile";
const LANGUAGE_REQUEST_MAP: Record<
@@ -42,6 +43,7 @@ export const useSettingsProfile = () => {
const tCommon = useTranslations("Common");
const { language, locale, setLanguage, commitLanguage } =
useSettingsLanguageParam();
+ const { mutate: logoutMutate, isPending: isLoggingOut } = useLogoutAction();
const { data: profile } = useMyProfile();
const [isCalendarConnected, setIsCalendarConnected] = useState(
@@ -101,10 +103,8 @@ export const useSettingsProfile = () => {
};
const handleLogout = () => {
- // TODO: API - 로그아웃 처리 및 브라우저 저장 데이터 파기
- console.log("로그아웃 API 호출");
- // TODO: 로그인 페이지 라우트 추가 후 이동 연결 (뒤로가기로 재접근 차단 포함)
- console.log("[Login] 페이지로 이동합니다.");
+ if (isLoggingOut) return;
+ logoutMutate();
};
const isLanguageDirty = language !== locale;
diff --git a/apps/timo-web/app/[locale]/(main)/settings/_queries/use-logout.ts b/apps/timo-web/app/[locale]/(main)/settings/_queries/use-logout.ts
new file mode 100644
index 00000000..a0bfac9a
--- /dev/null
+++ b/apps/timo-web/app/[locale]/(main)/settings/_queries/use-logout.ts
@@ -0,0 +1,17 @@
+"use client";
+
+import { useMutation } from "@tanstack/react-query";
+
+import { logout } from "@/api/generated/endpoints/auth/auth";
+import { useClearSession } from "@/hooks/useClearSession";
+
+export const useLogoutAction = () => {
+ const clearSession = useClearSession();
+
+ return useMutation({
+ mutationFn: () => logout(),
+ onSettled: () => {
+ clearSession();
+ },
+ });
+};
diff --git a/apps/timo-web/app/[locale]/(main)/settings/withdrawal/_containers/SettingsWithdrawalContainer.tsx b/apps/timo-web/app/[locale]/(main)/settings/withdrawal/_containers/SettingsWithdrawalContainer.tsx
index 6f449f87..7e21684a 100644
--- a/apps/timo-web/app/[locale]/(main)/settings/withdrawal/_containers/SettingsWithdrawalContainer.tsx
+++ b/apps/timo-web/app/[locale]/(main)/settings/withdrawal/_containers/SettingsWithdrawalContainer.tsx
@@ -1,13 +1,18 @@
"use client";
import { useTranslations } from "next-intl";
+import { useState } from "react";
import type { SettingsWithdrawalLabels } from "@/app/[locale]/(main)/settings/withdrawal/_types/withdrawal-type";
import { SettingsWithdrawalView } from "@/app/[locale]/(main)/settings/withdrawal/_components/SettingsWithdrawalView";
+import { useWithdrawAction } from "@/app/[locale]/(main)/settings/withdrawal/_queries/use-withdraw";
+import { AnimatedToast } from "@/components/toast/AnimatedToast";
export const SettingsWithdrawalContainer = () => {
const t = useTranslations("Settings.withdrawal");
+ const { mutate: withdrawMutate, isPending } = useWithdrawAction();
+ const [isErrorToastOpen, setIsErrorToastOpen] = useState(false);
const labels: SettingsWithdrawalLabels = {
title: t("title"),
@@ -23,13 +28,26 @@ export const SettingsWithdrawalContainer = () => {
};
const handleWithdraw = () => {
+ if (isPending) return;
// TODO: 실제 확인 모달로 교체
const confirmed = window.confirm(t("confirmMessage"));
if (!confirmed) return;
- // TODO: API - 회원 탈퇴 및 데이터 영구 삭제
- console.log("회원 탈퇴 API를 호출합니다.");
+ withdrawMutate(undefined, {
+ onError: () => {
+ setIsErrorToastOpen(true);
+ },
+ });
};
- return ;
+ return (
+ <>
+
+ setIsErrorToastOpen(false)}
+ message={t("withdrawError")}
+ />
+ >
+ );
};
diff --git a/apps/timo-web/app/[locale]/(main)/settings/withdrawal/_queries/use-withdraw.ts b/apps/timo-web/app/[locale]/(main)/settings/withdrawal/_queries/use-withdraw.ts
new file mode 100644
index 00000000..0e1025e7
--- /dev/null
+++ b/apps/timo-web/app/[locale]/(main)/settings/withdrawal/_queries/use-withdraw.ts
@@ -0,0 +1,17 @@
+"use client";
+
+import { useMutation } from "@tanstack/react-query";
+
+import { withdraw } from "@/api/generated/endpoints/auth/auth";
+import { useClearSession } from "@/hooks/useClearSession";
+
+export const useWithdrawAction = () => {
+ const clearSession = useClearSession();
+
+ return useMutation({
+ mutationFn: () => withdraw(),
+ onSuccess: () => {
+ clearSession();
+ },
+ });
+};
diff --git a/apps/timo-web/hooks/useClearSession.ts b/apps/timo-web/hooks/useClearSession.ts
new file mode 100644
index 00000000..911d8f93
--- /dev/null
+++ b/apps/timo-web/hooks/useClearSession.ts
@@ -0,0 +1,19 @@
+"use client";
+
+import { useQueryClient } from "@tanstack/react-query";
+
+import { ROUTES } from "@/constants/routes";
+import { useRouter } from "@/i18n/navigation";
+import { useAuthStore } from "@/stores/auth/useAuthStore";
+
+export const useClearSession = () => {
+ const router = useRouter();
+ const queryClient = useQueryClient();
+ const clearAccessToken = useAuthStore((state) => state.clearAccessToken);
+
+ return () => {
+ clearAccessToken();
+ queryClient.clear();
+ router.replace(ROUTES.LOGIN);
+ };
+};
diff --git a/apps/timo-web/messages/en.json b/apps/timo-web/messages/en.json
index bcbbbdf6..ae342cf0 100644
--- a/apps/timo-web/messages/en.json
+++ b/apps/timo-web/messages/en.json
@@ -92,7 +92,8 @@
"warningCalendar": "The linked calendar connection will be disconnected.",
"warningIrreversible": "Deleted accounts cannot be recovered.",
"withdraw": "Withdraw",
- "confirmMessage": "Are you sure you want to withdraw? All your data will be deleted and cannot be undone."
+ "confirmMessage": "Are you sure you want to withdraw? All your data will be deleted and cannot be undone.",
+ "withdrawError": "An error occurred during withdrawal. Please try again later."
}
},
"Statistics": {
diff --git a/apps/timo-web/messages/ko.json b/apps/timo-web/messages/ko.json
index 2f30bd57..8b999477 100644
--- a/apps/timo-web/messages/ko.json
+++ b/apps/timo-web/messages/ko.json
@@ -92,7 +92,8 @@
"warningCalendar": "연동된 캘린더 연결이 해제됩니다.",
"warningIrreversible": "삭제된 계정은 복구할 수 없습니다.",
"withdraw": "탈퇴하기",
- "confirmMessage": "정말 탈퇴하시겠어요? 탈퇴 후에는 모든 데이터가 삭제되며 되돌릴 수 없어요."
+ "confirmMessage": "정말 탈퇴하시겠어요? 탈퇴 후에는 모든 데이터가 삭제되며 되돌릴 수 없어요.",
+ "withdrawError": "탈퇴 처리 중 오류가 발생했습니다. 잠시 후 다시 시도해 주세요."
}
},
"Statistics": {