계정 관리 페이지 및 컴포넌트 다국어화 완료
- 계정 관리 페이지 전체 다국어화 (8개 페이지) * 사용자 관리: 계정 추가, 메뉴 권한, 계정 정보, 로그인 인증정보 * 비밀번호 관리: 로그인/취소 비밀번호 변경 - 계정 엔티티 컴포넌트 다국어화 * account-tab: 사용자 관리/비밀번호 관리 탭 * account-user-tab: 로그인 인증정보/계정권한 서브탭 * password-manage-wrap: 비밀번호 변경 버튼 * user-manage-wrap: 등록 현황, 사용자 추가 버튼 * user-login-auth-info-wrap: 이메일/휴대폰 관리 인터페이스 - 계정 추가 페이지 상세 다국어화 * 폼 라벨: 사용자ID, 비밀번호, 로그인 범위 * 본인인증 정보 입력 섹션 * 유효성 검사 메시지 * 성공/실패 알림 메시지 - 메뉴 권한 페이지 다국어화 * 권한 설정 안내 메시지 * 저장/실행/다운로드 권한 라벨 * 탭 변경 시 초기화 안내 - 번역 키 추가: account 네임스페이스 50개 키 - 모든 폼, 버튼, 알림 메시지 일관된 다국어 지원 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,15 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import {
|
||||
AccountTabKeys,
|
||||
AccountTabProps
|
||||
import {
|
||||
AccountTabKeys,
|
||||
AccountTabProps
|
||||
} from '../model/types';
|
||||
|
||||
export const AccountTab = ({
|
||||
activeTab
|
||||
}: AccountTabProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigation = (tab: AccountTabKeys) => {
|
||||
@@ -23,14 +25,14 @@ export const AccountTab = ({
|
||||
return(
|
||||
<>
|
||||
<div className="subTab">
|
||||
<button
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === AccountTabKeys.UserManage)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation(AccountTabKeys.UserManage) }
|
||||
>사용자 관리</button>
|
||||
<button
|
||||
onClick={ () => onClickToNavigation(AccountTabKeys.UserManage) }
|
||||
>{t('account.userManagement')}</button>
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === AccountTabKeys.PasswordManage)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation(AccountTabKeys.PasswordManage) }
|
||||
>비밀번호 관리</button>
|
||||
onClick={ () => onClickToNavigation(AccountTabKeys.PasswordManage) }
|
||||
>{t('account.passwordManagement')}</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import {
|
||||
import {
|
||||
AccountUserTabKeys,
|
||||
AccountUserTabProps
|
||||
AccountUserTabProps
|
||||
} from '../model/types';
|
||||
|
||||
export const AccountUserTab = ({
|
||||
@@ -12,6 +13,7 @@ export const AccountUserTab = ({
|
||||
idCL,
|
||||
status,
|
||||
}: AccountUserTabProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigation = (tab: AccountUserTabKeys) => {
|
||||
@@ -41,14 +43,14 @@ export const AccountUserTab = ({
|
||||
return(
|
||||
<>
|
||||
<div className="subTab">
|
||||
<button
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === AccountUserTabKeys.LoginAuthInfo)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation(AccountUserTabKeys.LoginAuthInfo) }
|
||||
>로그인 인증정보</button>
|
||||
<button
|
||||
onClick={ () => onClickToNavigation(AccountUserTabKeys.LoginAuthInfo) }
|
||||
>{t('account.loginAuthInfo')}</button>
|
||||
<button
|
||||
className={`subtab-btn ${(activeTab === AccountUserTabKeys.AccountAuth)? 'active': ''}` }
|
||||
onClick={ () => onClickToNavigation( AccountUserTabKeys.AccountAuth) }
|
||||
>계정권한</button>
|
||||
onClick={ () => onClickToNavigation( AccountUserTabKeys.AccountAuth) }
|
||||
>{t('account.accountPermission')}</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
|
||||
export const PasswordManageWrap = () => {
|
||||
const { t } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
return (
|
||||
@@ -9,16 +11,16 @@ export const PasswordManageWrap = () => {
|
||||
<div className="ing-list">
|
||||
<div className="pwd-manage mt-20">
|
||||
<div className="pwd-buttons">
|
||||
<button
|
||||
<button
|
||||
className="btn-44 btn-white pwd-btn"
|
||||
type="button"
|
||||
onClick={ () => navigate(PATHS.account.password.modifyLoginPassword) }
|
||||
>로그인 비밀번호 변경</button>
|
||||
<button
|
||||
>{t('account.changeLoginPassword')}</button>
|
||||
<button
|
||||
className="btn-44 btn-white pwd-btn"
|
||||
type="button"
|
||||
onClick={ () => navigate(PATHS.account.password.modifyCancelPassword) }
|
||||
>거래취소 비밀번호 변경</button>
|
||||
>{t('account.changeCancelPassword')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { UserFindAuthMethodParams, UserAuthMethodData, AuthMethodModifyItem } from '@/entities/user/model/types';
|
||||
import { useUserFindAuthMethodMutation } from '@/entities/user/api/use-user-find-authmethod-mutation';
|
||||
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
|
||||
@@ -13,6 +14,7 @@ export const UserLoginAuthInfoWrap = ({
|
||||
idCL,
|
||||
status,
|
||||
}: UserFindAuthMethodParams) => {
|
||||
const { t } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
const [pageParam] = useState(DEFAULT_PAGE_PARAM);
|
||||
const [authMethodData, setAuthMethodData] = useState<UserAuthMethodData>();
|
||||
@@ -26,7 +28,7 @@ export const UserLoginAuthInfoWrap = ({
|
||||
const { mutateAsync: userFindAuthMethod } = useUserFindAuthMethodMutation();
|
||||
const { mutateAsync: userModifyAuthMethod } = useUserModifyAuthMethodMutation({
|
||||
onSuccess: () => {
|
||||
snackBar('사용자 정보가 성공적으로 저장되었습니다.');
|
||||
snackBar(t('account.userInfoSavedSuccessfully'));
|
||||
navigate(PATHS.account.user.manage, {
|
||||
state: {
|
||||
mid: mid,
|
||||
@@ -34,7 +36,7 @@ export const UserLoginAuthInfoWrap = ({
|
||||
});
|
||||
},
|
||||
onError: (error) => {
|
||||
snackBar(error?.response?.data?.message || '사용자 정보 저장에 실패했습니다.');
|
||||
snackBar(error?.response?.data?.message || t('account.userInfoSaveFailed'));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -395,11 +397,11 @@ export const UserLoginAuthInfoWrap = ({
|
||||
<div className="settings-login-auth pb-86">
|
||||
<div className="group">
|
||||
<div className="group-header">
|
||||
<div className="title">이메일 주소</div>
|
||||
<div className="title">{t('account.emailAddress')}</div>
|
||||
<button
|
||||
className="ic20 plus"
|
||||
type="button"
|
||||
aria-label="추가"
|
||||
aria-label={t('common.add')}
|
||||
onClick={handleAddEmail}
|
||||
disabled={!isEmailAddButtonEnabled()}
|
||||
></button>
|
||||
@@ -415,7 +417,7 @@ export const UserLoginAuthInfoWrap = ({
|
||||
<button
|
||||
className="icon-btn minus"
|
||||
type="button"
|
||||
aria-label="삭제"
|
||||
aria-label={t('common.delete')}
|
||||
onClick={() => handleRemoveExistingEmail(index)}
|
||||
disabled={!isDeleteButtonEnabled()}
|
||||
></button>
|
||||
@@ -433,7 +435,7 @@ export const UserLoginAuthInfoWrap = ({
|
||||
<button
|
||||
className="icon-btn minus"
|
||||
type="button"
|
||||
aria-label="삭제"
|
||||
aria-label={t('common.delete')}
|
||||
onClick={() => handleRemoveNewEmail(index)}
|
||||
disabled={!isDeleteButtonEnabled()}
|
||||
></button>
|
||||
@@ -443,11 +445,11 @@ export const UserLoginAuthInfoWrap = ({
|
||||
|
||||
<div className="group">
|
||||
<div className="group-header">
|
||||
<div className="title">휴대폰 번호</div>
|
||||
<div className="title">{t('account.phoneNumber')}</div>
|
||||
<button
|
||||
className="ic20 plus"
|
||||
type="button"
|
||||
aria-label="추가"
|
||||
aria-label={t('common.add')}
|
||||
onClick={handleAddPhone}
|
||||
disabled={!isPhoneAddButtonEnabled()}
|
||||
></button>
|
||||
@@ -457,13 +459,13 @@ export const UserLoginAuthInfoWrap = ({
|
||||
<input
|
||||
type="tel"
|
||||
value={phone.content}
|
||||
placeholder="휴대폰 번호 입력"
|
||||
placeholder={t('account.enterPhoneNumber')}
|
||||
readOnly
|
||||
/>
|
||||
<button
|
||||
className="icon-btn minus"
|
||||
type="button"
|
||||
aria-label="삭제"
|
||||
aria-label={t('common.delete')}
|
||||
onClick={() => handleRemoveExistingPhone(index)}
|
||||
disabled={!isDeleteButtonEnabled()}
|
||||
></button>
|
||||
@@ -474,20 +476,20 @@ export const UserLoginAuthInfoWrap = ({
|
||||
<input
|
||||
type="tel"
|
||||
value={phone}
|
||||
placeholder="휴대폰 번호 입력"
|
||||
placeholder={t('account.enterPhoneNumber')}
|
||||
onChange={(e) => handleNewPhoneChange(index, e.target.value)}
|
||||
readOnly={readOnlyPhones.has(index) || index !== editablePhoneIndex}
|
||||
/>
|
||||
<button
|
||||
className="icon-btn minus"
|
||||
type="button"
|
||||
aria-label="삭제"
|
||||
aria-label={t('common.delete')}
|
||||
onClick={() => handleRemoveNewPhone(index)}
|
||||
disabled={!isDeleteButtonEnabled()}
|
||||
></button>
|
||||
</div>
|
||||
))}
|
||||
<div className="notice-bar">※ 탭을 변경하면 미저장 내용은 초기화됩니다.</div>
|
||||
<div className="notice-bar">{t('account.tabChangeResetNotice')}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
@@ -496,7 +498,7 @@ export const UserLoginAuthInfoWrap = ({
|
||||
disabled={!isSaveButtonEnabled()}
|
||||
onClick={handleSave}
|
||||
>
|
||||
저장
|
||||
{t('common.save')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ChangeEvent, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
|
||||
@@ -8,6 +9,7 @@ import { UserListItem } from '@/entities/user/model/types';
|
||||
import { useStore } from '@/shared/model/store';
|
||||
|
||||
export const UserManageWrap = () => {
|
||||
const { t } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
const midOptions = useStore.getState().UserStore.selectOptionsMids;
|
||||
const userMid = useStore.getState().UserStore.mid;
|
||||
@@ -60,7 +62,7 @@ export const UserManageWrap = () => {
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="ing-title">등록 현황</div>
|
||||
<div className="ing-title">{t('account.registrationStatus')}</div>
|
||||
</div>
|
||||
|
||||
<div style={{ flex: 1, overflow: 'hidden', minHeight: 0 }}>
|
||||
@@ -76,7 +78,7 @@ export const UserManageWrap = () => {
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToNavigation() }
|
||||
>사용자 추가</button>
|
||||
>{t('account.addUser')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user