Localize link-payment main pages

- Added linkPayment translation keys to en.json:
  - title, detailTitle, waitDetailTitle, applyTitle, messagePreview
  - resendSuccess, resendFailed, resendError, resendConfirm
  - deleteSuccess, deleteConfirm, resend, delete
  - separateApprovalTitle, separateApprovalDetail, warning
- Localized link-payment-history-page.tsx:
  - Header title, access check comment
- Localized link-payment-wait-send-page.tsx:
  - Header title, page comment
- Localized link-payment-detail-page.tsx:
  - Header title, button labels (resend, separate approval detail)
  - Success/error messages for resend operations
  - Dialog button labels and confirmation message
  - Code comments from Korean to English
- Localized link-payment-wait-detail-page.tsx:
  - Header title, button label (delete)
  - Success message for delete operation
  - Dialog button labels and confirmation message
- All files: Added useTranslation hook import

Note: Apply and separate-approval subdirectories still need localization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jay Sheen
2025-10-31 13:20:13 +09:00
parent b9aab1d0fd
commit 5ef6407e9b
5 changed files with 54 additions and 28 deletions

View File

@@ -997,6 +997,24 @@
"disbursementAmount": "Disbursement Amount", "disbursementAmount": "Disbursement Amount",
"requestFailed": "Request failed." "requestFailed": "Request failed."
}, },
"linkPayment": {
"title": "Link Payment",
"detailTitle": "Link Payment Detail",
"waitDetailTitle": "Link Payment Detail - Pending Send",
"applyTitle": "Link Payment Request",
"messagePreview": "Message Preview",
"separateApprovalTitle": "Separate Approval Detail",
"resendSuccess": "Resend successful.",
"resendFailed": "Resend failed.",
"resendError": "An error occurred during resend.",
"resendConfirm": "Do you want to resend?",
"deleteSuccess": "Delete successful.",
"deleteConfirm": "Do you want to delete?",
"resend": "Resend",
"delete": "Delete",
"separateApprovalDetail": "Separate Approval Detail",
"warning": "Warning"
},
"keyIn": { "keyIn": {
"fullCancel": "Full Cancel", "fullCancel": "Full Cancel",
"partialCancel": "Partial Cancel", "partialCancel": "Partial Cancel",

View File

@@ -20,8 +20,10 @@ import { useExtensionLinkPayHistoryResendMutation } from '@/entities/additional-
import { ExtensionLinkPayHistoryDetailParams, ExtensionLinkPayHistoryResendParams } from '@/entities/additional-service/model/link-pay/types'; import { ExtensionLinkPayHistoryDetailParams, ExtensionLinkPayHistoryResendParams } from '@/entities/additional-service/model/link-pay/types';
import { snackBar } from '@/shared/lib'; import { snackBar } from '@/shared/lib';
import moment from 'moment'; import moment from 'moment';
import { useTranslation } from 'react-i18next';
export const LinkPaymentDetailPage = () => { export const LinkPaymentDetailPage = () => {
const { t } = useTranslation();
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const location = useLocation(); const location = useLocation();
@@ -33,17 +35,17 @@ export const LinkPaymentDetailPage = () => {
const [detailExposure, setDetailExposure] = useState<boolean>(false); const [detailExposure, setDetailExposure] = useState<boolean>(false);
const [showPayment, setShowPayment] = useState<boolean>(false); const [showPayment, setShowPayment] = useState<boolean>(false);
useSetHeaderTitle('링크결제 상세'); useSetHeaderTitle(t('additionalService.linkPayment.detailTitle'));
useSetHeaderType(HeaderType.RightClose); useSetHeaderType(HeaderType.RightClose);
useSetOnBack(() => { useSetOnBack(() => {
navigate(-1); // 브라우저 히스토리를 이용한 뒤로가기 navigate(-1); // Go back using browser history
}); });
useSetFooterMode(false); useSetFooterMode(false);
const { mutateAsync: linkPayHistoryDetail } = useExtensionLinkPayHistoryDetailMutation(); const { mutateAsync: linkPayHistoryDetail } = useExtensionLinkPayHistoryDetailMutation();
const { mutateAsync: linkPayHistoryResend } = useExtensionLinkPayHistoryResendMutation(); const { mutateAsync: linkPayHistoryResend } = useExtensionLinkPayHistoryResendMutation();
// 상세내역 조회 // Query detail information
const callDetail = () => { const callDetail = () => {
let detailParam: ExtensionLinkPayHistoryDetailParams = { let detailParam: ExtensionLinkPayHistoryDetailParams = {
mid: mid, mid: mid,
@@ -59,7 +61,7 @@ export const LinkPaymentDetailPage = () => {
}) })
} }
//재발송 API // Resend API
const resendPayment = () => { const resendPayment = () => {
let resendParam: ExtensionLinkPayHistoryResendParams = { let resendParam: ExtensionLinkPayHistoryResendParams = {
mid: mid, mid: mid,
@@ -69,23 +71,23 @@ export const LinkPaymentDetailPage = () => {
linkPayHistoryResend(resendParam) linkPayHistoryResend(resendParam)
.then((response) => { .then((response) => {
if (response.status) { if (response.status) {
snackBar("재발송을 성공하였습니다."); snackBar(t('additionalService.linkPayment.resendSuccess'));
callDetail(); callDetail();
} else { } else {
const errorMessage = response.error?.message || '재발송이 실패하였습니다.'; const errorMessage = response.error?.message || t('additionalService.linkPayment.resendFailed');
snackBar(`[실패] ${errorMessage}`); snackBar(`[${t('common.failed')}] ${errorMessage}`);
} }
}) })
.catch((error) => { .catch((error) => {
const errorMessage = error?.response?.data?.error?.message || const errorMessage = error?.response?.data?.error?.message ||
error?.message || error?.message ||
'재발송 중 오류가 발생했습니다.'; t('additionalService.linkPayment.resendError');
snackBar(`[실패] ${errorMessage}`); snackBar(`[${t('common.failed')}] ${errorMessage}`);
}); });
} }
const onClickToResend = () => { const onClickToResend = () => {
let msg = '재발송 하시겠습니까?'; let msg = t('additionalService.linkPayment.resendConfirm');
overlay.open(({ overlay.open(({
isOpen, isOpen,
@@ -99,7 +101,7 @@ export const LinkPaymentDetailPage = () => {
onClose={close} onClose={close}
onConfirmClick={() => resendPayment()} onConfirmClick={() => resendPayment()}
message={msg} message={msg}
buttonLabel={['취소', '확인']} buttonLabel={[t('common.cancel'), t('common.confirm')]}
/> />
); );
}); });
@@ -111,14 +113,14 @@ export const LinkPaymentDetailPage = () => {
}); });
}; };
// 재발송 버튼 활성화 조건 체크 // Check if resend button should be enabled
const isResendEnabled = () => { const isResendEnabled = () => {
// paymentStatus "ACTIVE"이고 // paymentStatus must be "ACTIVE"
if (paymentInfo?.paymentStatus !== 'ACTIVE') { if (paymentInfo?.paymentStatus !== 'ACTIVE') {
return false; return false;
} }
// paymentLimitDate가 오늘 날짜를 지나지 않았을 때 // paymentLimitDate must not have passed today's date
if (paymentInfo?.paymentLimitDate) { if (paymentInfo?.paymentLimitDate) {
const limitDate = moment(paymentInfo.paymentLimitDate, 'YYYYMMDD'); const limitDate = moment(paymentInfo.paymentLimitDate, 'YYYYMMDD');
const today = moment().startOf('day'); const today = moment().startOf('day');
@@ -158,7 +160,7 @@ export const LinkPaymentDetailPage = () => {
className="btn-50 btn-blue flex-1" className="btn-50 btn-blue flex-1"
onClick={() => onClickToSeparateApproval()} onClick={() => onClickToSeparateApproval()}
disabled={detailExposure} disabled={detailExposure}
> </button> >{t('additionalService.linkPayment.separateApprovalDetail')}</button>
</div> </div>
</div> </div>
<div className="apply-row"> <div className="apply-row">
@@ -166,7 +168,7 @@ export const LinkPaymentDetailPage = () => {
className="btn-50 btn-blue flex-1" className="btn-50 btn-blue flex-1"
onClick={() => onClickToResend()} onClick={() => onClickToResend()}
disabled={!isResendEnabled()} disabled={!isResendEnabled()}
></button> >{t('additionalService.linkPayment.resend')}</button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -13,22 +13,24 @@ import {
} from '@/widgets/sub-layout/use-sub-layout'; } from '@/widgets/sub-layout/use-sub-layout';
import { LinkPaymentTabKeys } from '@/entities/additional-service/model/link-pay/types'; import { LinkPaymentTabKeys } from '@/entities/additional-service/model/link-pay/types';
import { useExtensionAccessCheck } from '@/shared/lib/hooks/use-extension-access-check'; import { useExtensionAccessCheck } from '@/shared/lib/hooks/use-extension-access-check';
import { useTranslation } from 'react-i18next';
/** /**
* 발송내역 탭 화면 * Shipping history tab screen
*/ */
export const LinkPaymentHistoryPage = () => { export const LinkPaymentHistoryPage = () => {
const { t } = useTranslation();
const { navigate } = useNavigate(); const { navigate } = useNavigate();
// 권한 체크 // Access check
const { hasAccess, AccessDeniedDialog } = useExtensionAccessCheck({ const { hasAccess, AccessDeniedDialog } = useExtensionAccessCheck({
extensionCode: 'LINKPAY' extensionCode: 'LINKPAY'
}); });
const [activeTab, setActiveTab] = useState<LinkPaymentTabKeys>(LinkPaymentTabKeys.ShippingHistory) const [activeTab, setActiveTab] = useState<LinkPaymentTabKeys>(LinkPaymentTabKeys.ShippingHistory)
useSetHeaderTitle('링크결제') useSetHeaderTitle(t('additionalService.linkPayment.title'))
useSetHeaderType(HeaderType.LeftArrow); useSetHeaderType(HeaderType.LeftArrow);
useSetFooterMode(false); useSetFooterMode(false);
useSetOnBack(() => { useSetOnBack(() => {

View File

@@ -18,15 +18,17 @@ import { PaymentInfoWrap } from '@/entities/additional-service/ui/info-wrap/paym
import { useExtensionLinkPayWaitDeleteMutation } from '@/entities/additional-service/api/link-payment/use-extension-link-pay-wait-delete-mutation'; import { useExtensionLinkPayWaitDeleteMutation } from '@/entities/additional-service/api/link-payment/use-extension-link-pay-wait-delete-mutation';
import { ExtensionLinkPayWaitDeleteParams, ExtensionLinkPayWaitDetailParams, LinkPaymentProcessStatus } from '@/entities/additional-service/model/link-pay/types'; import { ExtensionLinkPayWaitDeleteParams, ExtensionLinkPayWaitDetailParams, LinkPaymentProcessStatus } from '@/entities/additional-service/model/link-pay/types';
import { snackBar } from '@/shared/lib'; import { snackBar } from '@/shared/lib';
import { useTranslation } from 'react-i18next';
export const LinkPaymentWaitDetailPage = () => { export const LinkPaymentWaitDetailPage = () => {
const { t } = useTranslation();
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const location = useLocation(); const location = useLocation();
const { mid, requestId } = location.state || {}; const { mid, requestId } = location.state || {};
const [titleInfo, setTitleInfo] = useState<TitleInfo>(); const [titleInfo, setTitleInfo] = useState<TitleInfo>();
const [paymentInfo, setPaymentInfo] = useState<PaymentInfo>(); const [paymentInfo, setPaymentInfo] = useState<PaymentInfo>();
useSetHeaderTitle('링크결제 상세 발송대기'); useSetHeaderTitle(t('additionalService.linkPayment.waitDetailTitle'));
useSetHeaderType(HeaderType.RightClose); useSetHeaderType(HeaderType.RightClose);
useSetOnBack(() => { useSetOnBack(() => {
navigate(PATHS.additionalService.linkPayment.pendingSend); navigate(PATHS.additionalService.linkPayment.pendingSend);
@@ -57,15 +59,15 @@ export const LinkPaymentWaitDetailPage = () => {
linkPayWaitDelete(deleteParam) linkPayWaitDelete(deleteParam)
.then((rs) => { .then((rs) => {
callDetail(); callDetail();
snackBar("삭제를 성공하였습니다.") snackBar(t('additionalService.linkPayment.deleteSuccess'))
}) })
.catch((error) => { .catch((error) => {
snackBar(`[실패] ${error?.response?.data?.message}`) snackBar(`[${t('common.failed')}] ${error?.response?.data?.message}`)
}); });
} }
const onClickToCancel = () => { const onClickToCancel = () => {
let msg = '삭제 하시겠습니까?'; let msg = t('additionalService.linkPayment.deleteConfirm');
overlay.open(({ overlay.open(({
isOpen, isOpen,
@@ -79,7 +81,7 @@ export const LinkPaymentWaitDetailPage = () => {
onClose={close} onClose={close}
onConfirmClick={() => deletePayment()} onConfirmClick={() => deletePayment()}
message={msg} message={msg}
buttonLabel={['취소', '확인']} buttonLabel={[t('common.cancel'), t('common.confirm')]}
/> />
); );
}); });
@@ -113,7 +115,7 @@ export const LinkPaymentWaitDetailPage = () => {
className="btn-50 btn-blue flex-1" className="btn-50 btn-blue flex-1"
onClick={() => onClickToCancel()} onClick={() => onClickToCancel()}
disabled={paymentInfo?.processStatus !== LinkPaymentProcessStatus.SEND_REQUEST} disabled={paymentInfo?.processStatus !== LinkPaymentProcessStatus.SEND_REQUEST}
></button> >{t('additionalService.linkPayment.delete')}</button>
</div> </div>
</div> </div>
</main > </main >

View File

@@ -12,16 +12,18 @@ import {
useSetOnBack useSetOnBack
} from '@/widgets/sub-layout/use-sub-layout'; } from '@/widgets/sub-layout/use-sub-layout';
import { LinkPaymentTabKeys } from '@/entities/additional-service/model/link-pay/types'; import { LinkPaymentTabKeys } from '@/entities/additional-service/model/link-pay/types';
import { useTranslation } from 'react-i18next';
/** /**
* 발송대기 탭 화면 * Pending send tab screen
*/ */
export const LinkPaymentWaitSendPage = () => { export const LinkPaymentWaitSendPage = () => {
const { t } = useTranslation();
const { navigate } = useNavigate(); const { navigate } = useNavigate();
const [activeTab, setActiveTab] = useState<LinkPaymentTabKeys>(LinkPaymentTabKeys.PendingSend) const [activeTab, setActiveTab] = useState<LinkPaymentTabKeys>(LinkPaymentTabKeys.PendingSend)
useSetHeaderTitle('링크결제') useSetHeaderTitle(t('additionalService.linkPayment.title'))
useSetHeaderType(HeaderType.LeftArrow); useSetHeaderType(HeaderType.LeftArrow);
useSetFooterMode(false); useSetFooterMode(false);
useSetOnBack(() => { useSetOnBack(() => {