showConfirm Hook 에러 수정 및 계정권한 탭에 삭제 버튼 추가
문제: - showConfirm 함수 내부에서 useTranslation Hook 호출 - "Invalid hook call" 에러 발생 수정 사항: 1. showConfirm Hook 에러 수정 - ConfirmDialog 컴포넌트 분리 - 컴포넌트 내부에서 useTranslation 호출 - showConfirm은 일반 함수로 유지 2. 계정권한 탭에 삭제 버튼 추가 - account-auth-page.tsx에 삭제 기능 추가 - login-auth-info-page.tsx와 동일한 로직 적용 - 현재 로그인한 사용자가 아닐 경우에만 표시 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useLocation } from 'react-router';
|
import { useLocation } from 'react-router';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PATHS } from '@/shared/constants/paths';
|
import { PATHS } from '@/shared/constants/paths';
|
||||||
@@ -11,16 +11,41 @@ import {
|
|||||||
useSetHeaderTitle,
|
useSetHeaderTitle,
|
||||||
useSetHeaderType,
|
useSetHeaderType,
|
||||||
useSetFooterMode,
|
useSetFooterMode,
|
||||||
useSetOnBack
|
useSetOnBack,
|
||||||
|
useSetOnRightClick
|
||||||
} from '@/widgets/sub-layout/use-sub-layout';
|
} from '@/widgets/sub-layout/use-sub-layout';
|
||||||
|
import { useStore } from '@/shared/model/store';
|
||||||
|
import { useUserDeleteMutation } from '@/entities/user/api/use-user-delete-mutation';
|
||||||
|
import { showConfirm } from '@/widgets/show-confirm';
|
||||||
|
import { snackBar } from '@/shared/lib';
|
||||||
|
|
||||||
export const UserAccountAuthPage = () => {
|
export const UserAccountAuthPage = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { navigate } = useNavigate();
|
const { navigate } = useNavigate();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const { mid, usrid, idCL, status } = location.state || {};
|
const { mid, usrid, idCL, status } = location.state || {};
|
||||||
|
const { mutateAsync: userDelete } = useUserDeleteMutation();
|
||||||
|
const currentUsrid = useStore.getState().UserStore.userInfo.usrid;
|
||||||
|
|
||||||
const [activeTab, ] = useState<AccountUserTabKeys>(AccountUserTabKeys.AccountAuth);
|
const [activeTab, ] = useState<AccountUserTabKeys>(AccountUserTabKeys.AccountAuth);
|
||||||
|
|
||||||
|
const handleDeleteUser = async () => {
|
||||||
|
const confirmed = await showConfirm(t('account.deleteUserConfirm', '사용자를 삭제하시겠습니까?'));
|
||||||
|
if (!confirmed) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await userDelete({ mid, usrid });
|
||||||
|
if (result.status) {
|
||||||
|
snackBar(t('account.deleteUserSuccess', '사용자 삭제를 성공했습니다.'));
|
||||||
|
navigate(PATHS.account.user.manage, { state: { refresh: true } });
|
||||||
|
} else {
|
||||||
|
snackBar(result.error?.message || t('account.deleteUserFailed', '사용자 삭제를 실패했습니다.'));
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
snackBar(error.message || t('account.deleteUserFailed', '사용자 삭제를 실패했습니다.'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useSetHeaderTitle(t('account.userSettings'));
|
useSetHeaderTitle(t('account.userSettings'));
|
||||||
useSetHeaderType(HeaderType.LeftArrow);
|
useSetHeaderType(HeaderType.LeftArrow);
|
||||||
useSetFooterMode(false);
|
useSetFooterMode(false);
|
||||||
@@ -28,6 +53,10 @@ export const UserAccountAuthPage = () => {
|
|||||||
navigate(PATHS.account.user.manage);
|
navigate(PATHS.account.user.manage);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 현재 로그인한 사용자가 아닌 경우에만 삭제 버튼 표시
|
||||||
|
const isDeleteAllowed = usrid && currentUsrid && usrid !== currentUsrid;
|
||||||
|
useSetOnRightClick(isDeleteAllowed ? handleDeleteUser : undefined);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -2,10 +2,41 @@ import { Dialog } from '@/shared/ui/dialogs/dialog';
|
|||||||
import { overlay } from 'overlay-kit';
|
import { overlay } from 'overlay-kit';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
|
const ConfirmDialog = ({
|
||||||
|
msg,
|
||||||
|
isOpen,
|
||||||
|
close,
|
||||||
|
unmount,
|
||||||
|
onConfirm,
|
||||||
|
onCancel
|
||||||
|
}: {
|
||||||
|
msg: string;
|
||||||
|
isOpen: boolean;
|
||||||
|
close: () => void;
|
||||||
|
unmount: () => void;
|
||||||
|
onConfirm: () => void;
|
||||||
|
onCancel: () => void;
|
||||||
|
}) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
afterLeave={ unmount }
|
||||||
|
open={ isOpen }
|
||||||
|
onClose={ () => {
|
||||||
|
onCancel();
|
||||||
|
close();
|
||||||
|
}}
|
||||||
|
message={ msg }
|
||||||
|
buttonLabel={ [t('common.cancel'), t('common.confirm')] }
|
||||||
|
onConfirmClick={ onConfirm }
|
||||||
|
onCancelClick={ onCancel }
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const showConfirm = (msg: string): Promise<boolean> => {
|
export const showConfirm = (msg: string): Promise<boolean> => {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const { t } = useTranslation();
|
|
||||||
|
|
||||||
const onConfirmClick = () => {
|
const onConfirmClick = () => {
|
||||||
resolve(true);
|
resolve(true);
|
||||||
};
|
};
|
||||||
@@ -20,17 +51,13 @@ export const showConfirm = (msg: string): Promise<boolean> => {
|
|||||||
unmount
|
unmount
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Dialog
|
<ConfirmDialog
|
||||||
afterLeave={ unmount }
|
msg={ msg }
|
||||||
open={ isOpen }
|
isOpen={ isOpen }
|
||||||
onClose={ () => {
|
close={ close }
|
||||||
resolve(false);
|
unmount={ unmount }
|
||||||
close();
|
onConfirm={ onConfirmClick }
|
||||||
}}
|
onCancel={ onCancelClick }
|
||||||
message={ msg }
|
|
||||||
buttonLabel={ [t('common.cancel'), t('common.confirm')] }
|
|
||||||
onConfirmClick={ onConfirmClick }
|
|
||||||
onCancelClick={ onCancelClick }
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user