Add i18n localization foundation to additional-service entity

- Convert 10 constant files to i18n-compatible getter functions:
  - ars/constant.ts: ARS status codes and payment methods
  - sms-payment/constant.ts: SMS payment status codes
  - link-pay/constant.ts: Link payment status codes
  - account-holder-auth/constant.ts: Account holder verification
  - account-holder-search/constant.ts: Account holder search types
  - face-auth/constant.ts: Face authentication types
  - fund-account/constant.ts: Fund account status codes
  - alimtalk/constant.ts: Alimtalk status and transaction types
  - payout/constant.ts: Payout search types
  - key-in/constant.ts: Key-in cancel types

- Refactor lib/payment-status-utils.ts to curried functions with TFunction

- Add 63 translation keys to additionalService namespace in ko.json/en.json

- Localize 2 UI components as examples:
  - ui/filter/ars-filter.tsx
  - ui/ars/resend-sms-bottom-sheet.tsx

🤖 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-30 18:06:52 +09:00
parent e60fe0f014
commit ee932f2a46
15 changed files with 345 additions and 199 deletions

View File

@@ -1,55 +1,57 @@
export const getPaymentStatusText = (status?: string): string => { import { TFunction } from 'i18next';
export const getPaymentStatusText = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const statusMap: Record<string, string> = { const statusMap: Record<string, string> = {
// 숫자 문자열 매핑 // Numeric string mapping
'0': '미완료/활성화', '0': t('additionalService.linkPay.incompleteActive'),
'1': '입금요청', '1': t('additionalService.linkPay.depositRequest'),
'2': '결제완료', '2': t('additionalService.linkPay.paymentComplete'),
'3': '결제실패', '3': t('additionalService.linkPay.paymentFail'),
'4': '결제중단', '4': t('additionalService.linkPay.paymentStopped'),
// 문자열 키 매핑 (하위 호환성) // String key mapping (backward compatibility)
'ALL': '전체', 'ALL': t('transaction.constants.all'),
'ACTIVE': '미완료/활성화', 'ACTIVE': t('additionalService.linkPay.incompleteActive'),
'DEPOSIT_REQUEST': '입금요청', 'DEPOSIT_REQUEST': t('additionalService.linkPay.depositRequest'),
'PAYMENT_COMPLETE': '결제완료', 'PAYMENT_COMPLETE': t('additionalService.linkPay.paymentComplete'),
'PAYMENT_FAIL': '결제실패', 'PAYMENT_FAIL': t('additionalService.linkPay.paymentFail'),
'INACTIVE': '결제중단/비활성화' 'INACTIVE': t('additionalService.linkPay.paymentStoppedInactive')
}; };
return statusMap[status] || status; return statusMap[status] || status;
}; };
export const getProcessStatusText = (status?: string): string => { export const getProcessStatusText = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const processStatusMap: Record<string, string> = { const processStatusMap: Record<string, string> = {
'SEND_REQUEST': '발송요청', 'SEND_REQUEST': t('additionalService.linkPay.sendRequest'),
'SEND_CANCEL': '발송취소', 'SEND_CANCEL': t('additionalService.linkPay.sendCancel'),
'PENDING': '대기중' 'PENDING': t('additionalService.linkPay.pending')
}; };
return processStatusMap[status] || status; return processStatusMap[status] || status;
}; };
export const getSendMethodText = (method?: string): string => { export const getSendMethodText = (t: TFunction) => (method?: string): string => {
if (!method) return ''; if (!method) return '';
const sendMethodMap: Record<string, string> = { const sendMethodMap: Record<string, string> = {
'SMS': 'SMS', 'SMS': 'SMS',
'EMAIL': '이메일', 'EMAIL': t('additionalService.linkPay.email'),
'KAKAO': '알림톡' 'KAKAO': t('additionalService.linkPay.alimtalk')
}; };
return sendMethodMap[method] || method; return sendMethodMap[method] || method;
}; };
export const getResultStatusText = (status?: string): string => { export const getResultStatusText = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const resultStatusMap: Record<string, string> = { const resultStatusMap: Record<string, string> = {
'SUCCESS': '성공', 'SUCCESS': t('additionalService.common.success'),
'FAIL': '실패' 'FAIL': t('additionalService.common.fail')
}; };
return resultStatusMap[status] || status; return resultStatusMap[status] || status;

View File

@@ -1,31 +1,32 @@
import { TFunction } from 'i18next';
import { AccountHolderAuthStatus } from "./types"; import { AccountHolderAuthStatus } from "./types";
export const authStatusBtnGroup = [ export const getAuthStatusBtnGroup = (t: TFunction) => [
{ name: '전체', value: AccountHolderAuthStatus.ALL }, { name: t('transaction.constants.all'), value: AccountHolderAuthStatus.ALL },
{ name: '요청', value: AccountHolderAuthStatus.REQUEST}, { name: t('additionalService.common.request'), value: AccountHolderAuthStatus.REQUEST},
{ name: '성공', value: AccountHolderAuthStatus.SUCCESS}, { name: t('additionalService.common.success'), value: AccountHolderAuthStatus.SUCCESS},
{ name: '실패', value: AccountHolderAuthStatus.FAIL} { name: t('additionalService.common.fail'), value: AccountHolderAuthStatus.FAIL}
] ]
export const getAuthStatusText = (status?: string): string => { export const getAuthStatusText = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const AuthStatusMap: Record<string, string> = { const AuthStatusMap: Record<string, string> = {
'REQUEST' : '요청', 'REQUEST' : t('additionalService.common.request'),
'SUCCESS' : '성공', 'SUCCESS' : t('additionalService.common.success'),
'FAIL' : '실패' 'FAIL' : t('additionalService.common.fail')
} }
return AuthStatusMap[status] || status; return AuthStatusMap[status] || status;
} }
export const getAuthResultText = (status?: string): string => { export const getAuthResultText = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const AuthResultMap: Record<string, string> = { const AuthResultMap: Record<string, string> = {
'MATCHED' : '예금주명 일치', 'MATCHED' : t('additionalService.accountHolderAuth.accountHolderNameMatch'),
'NOT_MATCHED' : '예금주명 불일치', 'NOT_MATCHED' : t('additionalService.accountHolderAuth.accountHolderNameMismatch'),
'FAILED' : '인증실패 (계좌 오류 등)' 'FAILED' : t('additionalService.accountHolderAuth.authFailedAccountError')
} }
return AuthResultMap[status] || status; return AuthResultMap[status] || status;

View File

@@ -1,25 +1,26 @@
import { TFunction } from 'i18next';
import { ProcessResult } from "../types"; import { ProcessResult } from "../types";
import { AccountHolderResultStatus, AccountHolderSearchCl } from "./types"; import { AccountHolderResultStatus, AccountHolderSearchCl } from "./types";
export const resultStatusBtnGroup = [ export const getResultStatusBtnGroup = (t: TFunction) => [
{ name: '전체', value: AccountHolderResultStatus.ALL }, { name: t('transaction.constants.all'), value: AccountHolderResultStatus.ALL },
{ name: '성공', value: AccountHolderResultStatus.SUCCESS }, { name: t('additionalService.common.success'), value: AccountHolderResultStatus.SUCCESS },
{ name: '실패', value: AccountHolderResultStatus.FAIL }, { name: t('additionalService.common.fail'), value: AccountHolderResultStatus.FAIL },
] ]
export const SearchTypeOption = [ export const getSearchTypeOption = (t: TFunction) => [
{ name: '예금주', value: AccountHolderSearchCl.ACCOUNT_NAME }, { name: t('additionalService.accountHolderSearch.accountHolder'), value: AccountHolderSearchCl.ACCOUNT_NAME },
{ name: '계좌번호', value: AccountHolderSearchCl.ACCOUNT_NO }, { name: t('additionalService.accountHolderSearch.accountNumber'), value: AccountHolderSearchCl.ACCOUNT_NO },
]; ];
export const getAccountHolderStatusText = (status?: string): string => { export const getAccountHolderStatusText = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const resultStatusMap: Record<string, string> = { const resultStatusMap: Record<string, string> = {
'SUCCESS': '성공', 'SUCCESS': t('additionalService.common.success'),
'FAIL': '실패' 'FAIL': t('additionalService.common.fail')
}; };
return resultStatusMap[status] || status; return resultStatusMap[status] || status;
} }

View File

@@ -1,90 +1,91 @@
import { TFunction } from 'i18next';
import { AlimtalkAlimCl, AlimtalkSearchCl, AlimTalkSendCl, AlimtalkSendType, ServiceCode } from "./types"; import { AlimtalkAlimCl, AlimtalkSearchCl, AlimTalkSendCl, AlimtalkSendType, ServiceCode } from "./types";
export const AlimtalkSearchClOptionGroup = [ export const getAlimtalkSearchClOptionGroup = (t: TFunction) => [
{ name: '주문자', value: AlimtalkSearchCl.BUYER_NAME }, { name: t('additionalService.alimtalk.buyer'), value: AlimtalkSearchCl.BUYER_NAME },
{ name: 'TID', value: AlimtalkSearchCl.TID }, { name: t('transaction.constants.tid'), value: AlimtalkSearchCl.TID },
]; ];
export const AlimtalkServiceCodeOptionGroup = [ export const getAlimtalkServiceCodeOptionGroup = (t: TFunction) => [
{ name: '전체', value: '' }, { name: t('transaction.constants.all'), value: '' },
{ name: '카드', value: ServiceCode.CARD }, { name: t('transaction.constants.card'), value: ServiceCode.CARD },
{ name: '계좌이체', value: ServiceCode.BANK }, { name: t('transaction.constants.accountTransfer'), value: ServiceCode.BANK },
{ name: '가상계좌', value: ServiceCode.VBANK }, { name: t('transaction.constants.virtualAccount'), value: ServiceCode.VBANK },
{ name: '휴대폰', value: ServiceCode.PHONE } { name: t('transaction.constants.mobilePhone'), value: ServiceCode.PHONE }
] ]
// 알림구분 - 카드/계좌이체/휴대폰용 // Notification type - For Card/Account Transfer/Mobile
export const AlimtalkAlimClBtnGroupForGeneral = [ export const getAlimtalkAlimClBtnGroupForGeneral = (t: TFunction) => [
{ name: '전체', value: '' }, { name: t('transaction.constants.all'), value: '' },
{ name: '승인', value: AlimtalkAlimCl.APPROVAL }, { name: t('transaction.constants.approval'), value: AlimtalkAlimCl.APPROVAL },
{ name: '취소', value: AlimtalkAlimCl.CANCEL } { name: t('transaction.constants.cancel'), value: AlimtalkAlimCl.CANCEL }
] ]
// 알림구분 - 가상계좌용 // Notification type - For Virtual Account
export const AlimtalkAlimClBtnGroupForVBank = [ export const getAlimtalkAlimClBtnGroupForVBank = (t: TFunction) => [
{ name: '전체', value: '' }, { name: t('transaction.constants.all'), value: '' },
{ name: '입금요청', value: AlimtalkAlimCl.DEPOSIT_REQUEST }, { name: t('additionalService.alimtalk.depositRequest'), value: AlimtalkAlimCl.DEPOSIT_REQUEST },
{ name: '입금완료', value: AlimtalkAlimCl.DEPOSIT_COMPLETE }, { name: t('additionalService.alimtalk.depositComplete'), value: AlimtalkAlimCl.DEPOSIT_COMPLETE },
{ name: '환불', value: AlimtalkAlimCl.REFUND } { name: t('transaction.constants.refund'), value: AlimtalkAlimCl.REFUND }
] ]
export const AlimtalkSendTypeBtnGroup = [ export const getAlimtalkSendTypeBtnGroup = (t: TFunction) => [
{ name: '전체', value: AlimtalkSendType.ALL }, { name: t('transaction.constants.all'), value: AlimtalkSendType.ALL },
{ name: '카카오톡', value: AlimtalkSendType.KAKAOTALK }, { name: t('additionalService.alimtalk.kakaotalk'), value: AlimtalkSendType.KAKAOTALK },
{ name: 'FB SMS', value: AlimtalkSendType.FB_SMS } { name: t('additionalService.alimtalk.fbSms'), value: AlimtalkSendType.FB_SMS }
] ]
export const AlimtalkSendClBtnGroup = [ export const getAlimtalkSendClBtnGroup = (t: TFunction) => [
{ name: '전체', value: AlimTalkSendCl.ALL }, { name: t('transaction.constants.all'), value: AlimTalkSendCl.ALL },
{ name: '요청', value: AlimTalkSendCl.REQUEST }, { name: t('additionalService.common.request'), value: AlimTalkSendCl.REQUEST },
{ name: '성공', value: AlimTalkSendCl.SUCCESS }, { name: t('additionalService.common.success'), value: AlimTalkSendCl.SUCCESS },
{ name: '실패', value: AlimTalkSendCl.FAIL } { name: t('additionalService.common.fail'), value: AlimTalkSendCl.FAIL }
] ]
export const getAlimtalkAlimClText = (status?: string): string => { export const getAlimtalkAlimClText = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const alimClMap: Record<string, string> = { const alimClMap: Record<string, string> = {
'APPROVAL' : '승인', 'APPROVAL' : t('transaction.constants.approval'),
'CANCEL' : '취소', 'CANCEL' : t('transaction.constants.cancel'),
'DEPOSIT_REQUEST' : '입금요청', 'DEPOSIT_REQUEST' : t('additionalService.alimtalk.depositRequest'),
'DEPOSIT_COMPLETE' : '입금완료', 'DEPOSIT_COMPLETE' : t('additionalService.alimtalk.depositComplete'),
'REFUND' : '환불' 'REFUND' : t('transaction.constants.refund')
} }
return alimClMap[status] || status; return alimClMap[status] || status;
} }
export const getAlimtalkSendTypeText = (status?: string): string => { export const getAlimtalkSendTypeText = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const sendTypeMap: Record<string, string> = { const sendTypeMap: Record<string, string> = {
"KAKAOTALK": '카카오톡', "KAKAOTALK": t('additionalService.alimtalk.kakaotalk'),
'FB SMS': '페이스북', 'FB SMS': t('additionalService.alimtalk.fbSms'),
}; };
return sendTypeMap[status] || status; return sendTypeMap[status] || status;
} }
export const getAlimtalkSendClTypeText = (status?: string): string => { export const getAlimtalkSendClTypeText = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const sendClMap: Record<string, string> = { const sendClMap: Record<string, string> = {
'REQUEST': '요청', 'REQUEST': t('additionalService.common.request'),
'SUCCESS': '성공', 'SUCCESS': t('additionalService.common.success'),
'FAIL': '실패' 'FAIL': t('additionalService.common.fail')
}; };
return sendClMap[status] || status; return sendClMap[status] || status;
} }
export const getAlimtalkServiceCodeText = (status?: string): string => { export const getAlimtalkServiceCodeText = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const serviceCodeMap: Record<string, string> = { const serviceCodeMap: Record<string, string> = {
'CARD': '신용카드', 'CARD': t('transaction.constants.creditCard'),
'BANK': '계좌이체', 'BANK': t('transaction.constants.accountTransfer'),
'VBANK': '가상계좌', 'VBANK': t('transaction.constants.virtualAccount'),
'PHONE': '휴대폰' 'PHONE': t('transaction.constants.mobilePhone')
} }
return serviceCodeMap[status] || status; return serviceCodeMap[status] || status;

View File

@@ -1,30 +1,33 @@
import { TFunction } from 'i18next';
import { ArsPaymentMethod, OrderStatus, PaymentStatus } from './types'; import { ArsPaymentMethod, OrderStatus, PaymentStatus } from './types';
export const ArsPaymentStatusBtnGroup = [ export const getArsPaymentStatusBtnGroup = (t: TFunction) => [
{name: '전체', value: PaymentStatus.ALL }, {name: t('transaction.constants.all'), value: PaymentStatus.ALL },
{name: '결제완료', value: PaymentStatus.COMPLETE }, {name: t('additionalService.ars.paymentComplete'), value: PaymentStatus.COMPLETE },
{name: '미결제', value: PaymentStatus.UNPAID } {name: t('additionalService.ars.unpaid'), value: PaymentStatus.UNPAID }
]; ];
export const ArsOrderStatusBtnGroup = [
{name: '전체', value: OrderStatus.ALL }, export const getArsOrderStatusBtnGroup = (t: TFunction) => [
{name: '결제대기', value: OrderStatus.PENDING }, {name: t('transaction.constants.all'), value: OrderStatus.ALL },
{name: '결제성공', value: OrderStatus.SUCCESS }, {name: t('additionalService.ars.pendingPayment'), value: OrderStatus.PENDING },
{name: '기간만료', value: OrderStatus.EXPIRED }, {name: t('additionalService.ars.paymentSuccess'), value: OrderStatus.SUCCESS },
{name: '취소완료', value: OrderStatus.CANCELED }, {name: t('additionalService.ars.expired'), value: OrderStatus.EXPIRED },
{name: t('additionalService.ars.canceled'), value: OrderStatus.CANCELED },
]; ];
export const ArsPaymentMethodBtnGroup = [
export const getArsPaymentMethodBtnGroup = (t: TFunction) => [
{name: 'SMS', value: ArsPaymentMethod.SMS }, {name: 'SMS', value: ArsPaymentMethod.SMS },
{name: 'ARS', value: ArsPaymentMethod.ARS }, {name: 'ARS', value: ArsPaymentMethod.ARS },
]; ];
export const getArsPaymentStatusName = (status?: string): string => { export const getArsPaymentStatusName = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const found = ArsPaymentStatusBtnGroup.find(item => item.value === status); const found = getArsPaymentStatusBtnGroup(t).find(item => item.value === status);
return found ? found.name : status; return found ? found.name : status;
} }
export const getArsOrderStatusName = (status?: string): string => { export const getArsOrderStatusName = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const found = ArsOrderStatusBtnGroup.find(item => item.value === status); const found = getArsOrderStatusBtnGroup(t).find(item => item.value === status);
return found ? found.name : status; return found ? found.name : status;
} }

View File

@@ -1,35 +1,36 @@
import { TFunction } from 'i18next';
import { FaceAuthResult, FaceAuthTransType } from "./types"; import { FaceAuthResult, FaceAuthTransType } from "./types";
export const AuthResultBtnGroup = [ export const getAuthResultBtnGroup = (t: TFunction) => [
{ name: '전체', value: FaceAuthResult.ALL }, { name: t('transaction.constants.all'), value: FaceAuthResult.ALL },
{ name: '성공', value: FaceAuthResult.SUCCESS }, { name: t('additionalService.common.success'), value: FaceAuthResult.SUCCESS },
{ name: '실패', value: FaceAuthResult.FAIL }, { name: t('additionalService.common.fail'), value: FaceAuthResult.FAIL },
]; ];
export const TransactionTypeBtnGroup = [ export const getTransactionTypeBtnGroup = (t: TFunction) => [
{ name: '전체', value: FaceAuthTransType.ALL }, { name: t('transaction.constants.all'), value: FaceAuthTransType.ALL },
{ name: '인증', value: FaceAuthTransType.AUTH }, { name: t('additionalService.faceAuth.authentication'), value: FaceAuthTransType.AUTH },
{ name: '등록', value: FaceAuthTransType.REGISTER }, { name: t('additionalService.faceAuth.registration'), value: FaceAuthTransType.REGISTER },
]; ];
export const getAuthResultStatusText = (status?: string): string => { export const getAuthResultStatusText = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const authResultMap: Record<string, string> = { const authResultMap: Record<string, string> = {
'SUCCESS': '성공', 'SUCCESS': t('additionalService.common.success'),
'FAIL': '실패' 'FAIL': t('additionalService.common.fail')
} }
return authResultMap[status] || status; return authResultMap[status] || status;
} }
export const getTransTypeText = (transType?: string): string => { export const getTransTypeText = (t: TFunction) => (transType?: string): string => {
if (!transType) return ''; if (!transType) return '';
const transTypeMap: Record<string, string> = { const transTypeMap: Record<string, string> = {
'REGISTER': '등록', 'REGISTER': t('additionalService.faceAuth.registration'),
'AUTH': '인증' 'AUTH': t('additionalService.faceAuth.authentication')
} }
return transTypeMap[transType] || transType; return transTypeMap[transType] || transType;

View File

@@ -1,3 +1,4 @@
import { TFunction } from 'i18next';
import { import {
FundAccountReceiveAccountNameNo, FundAccountReceiveAccountNameNo,
FundAccountResultStatus, FundAccountResultStatus,
@@ -6,41 +7,41 @@ import {
FundAccountStatus FundAccountStatus
} from './types'; } from './types';
export const FundAccountStatusBtnGroup = [ export const getFundAccountStatusBtnGroup = (t: TFunction) => [
{ name: '전체', value: FundAccountStatus.ALL }, { name: t('transaction.constants.all'), value: FundAccountStatus.ALL },
{ name: '등록완료', value: FundAccountStatus.REGIST_COMPLETE }, { name: t('additionalService.fundAccount.registrationComplete'), value: FundAccountStatus.REGIST_COMPLETE },
{ name: '이체요청', value: FundAccountStatus.TRANSFER_REQUEST }, { name: t('additionalService.fundAccount.transferRequest'), value: FundAccountStatus.TRANSFER_REQUEST },
{ name: '요청성공', value: FundAccountStatus.REQUEST_SUCCESS }, { name: t('additionalService.fundAccount.requestSuccess'), value: FundAccountStatus.REQUEST_SUCCESS },
{ name: '요청실패', value: FundAccountStatus.REQUEST_FAIL } { name: t('additionalService.fundAccount.requestFail'), value: FundAccountStatus.REQUEST_FAIL }
]; ];
export const FundAccountResultStatusBtnGroup = [ export const getFundAccountResultStatusBtnGroup = (t: TFunction) => [
{ name: '전체', value: FundAccountResultStatus.ALL }, { name: t('transaction.constants.all'), value: FundAccountResultStatus.ALL },
{ name: '요청', value: FundAccountResultStatus.REQUEST }, { name: t('additionalService.common.request'), value: FundAccountResultStatus.REQUEST },
{ name: '성공', value: FundAccountResultStatus.SUCCESS }, { name: t('additionalService.common.success'), value: FundAccountResultStatus.SUCCESS },
{ name: '실패', value: FundAccountResultStatus.FAIL }, { name: t('additionalService.common.fail'), value: FundAccountResultStatus.FAIL },
] ]
export const getFundAccountStatusName = (status?: string): string => { export const getFundAccountStatusName = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const found = FundAccountStatusBtnGroup.find(item => item.value === status); const found = getFundAccountStatusBtnGroup(t).find(item => item.value === status);
return found ? found.name : status; return found ? found.name : status;
}; };
export const getFundAccountResultStatusName = (status?: string): string => { export const getFundAccountResultStatusName = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const found = FundAccountResultStatusBtnGroup.find(item => item.value === status); const found = getFundAccountResultStatusBtnGroup(t).find(item => item.value === status);
return found ? found.name : status; return found ? found.name : status;
} }
export const FundAccountResultSearchDateTypeBtnGroup = [ export const getFundAccountResultSearchDateTypeBtnGroup = (t: TFunction) => [
{ name: '요청일자', value: FundAccountSearchDateType.REQUEST_DATE }, { name: t('additionalService.fundAccount.requestDate'), value: FundAccountSearchDateType.REQUEST_DATE },
{ name: '이체일자', value: FundAccountSearchDateType.APPLICATION_DATE } { name: t('additionalService.fundAccount.transferDate'), value: FundAccountSearchDateType.APPLICATION_DATE }
]; ];
export const FundAccountSearchClOptionsGroup = [ export const getFundAccountSearchClOptionsGroup = (t: TFunction) => [
{ name: '수취인', value: FundAccountSearchCl.ACCOUNT_NAME }, { name: t('additionalService.fundAccount.recipient'), value: FundAccountSearchCl.ACCOUNT_NAME },
{ name: '계좌번호', value: FundAccountSearchCl.ACCOUNT_NO }, { name: t('additionalService.fundAccount.accountNumber'), value: FundAccountSearchCl.ACCOUNT_NO },
]; ];

View File

@@ -1,15 +1,15 @@
import { TFunction } from 'i18next';
import { KeyInPaymentTansactionType } from "./types"; import { KeyInPaymentTansactionType } from "./types";
// contant로 옮기기 export const getKeyInPaymentPaymentStatusBtnGroup = (t: TFunction) => [
export const keyInPaymentPaymentStatusBtnGroup = [ { name: t('transaction.constants.all'), value: KeyInPaymentTansactionType.ALL },
{ name: '전체', value: KeyInPaymentTansactionType.ALL }, { name: t('transaction.constants.approval'), value: KeyInPaymentTansactionType.APPROVAL },
{ name: '승인', value: KeyInPaymentTansactionType.APPROVAL }, { name: t('additionalService.keyIn.fullCancel'), value: KeyInPaymentTansactionType.FULL_CANCEL },
{ name: '전취소', value: KeyInPaymentTansactionType.FULL_CANCEL }, { name: t('additionalService.keyIn.partialCancel'), value: KeyInPaymentTansactionType.PARTIAL_CANCEL }
{ name: '후취소', value: KeyInPaymentTansactionType.PARTIAL_CANCEL }
]; ];
export const getKeyInPaymentPaymentStatusName = (status?: string): string => { export const getKeyInPaymentPaymentStatusName = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const found = keyInPaymentPaymentStatusBtnGroup.find(item => item.value === status); const found = getKeyInPaymentPaymentStatusBtnGroup(t).find(item => item.value === status);
return found ? found.name : status; return found ? found.name : status;
} }

View File

@@ -1,7 +1,8 @@
import { TFunction } from 'i18next';
import { LinkPaymentProcessStatus } from "./types"; import { LinkPaymentProcessStatus } from "./types";
export const ProcessStatusBtnGrouup = [ export const getProcessStatusBtnGroup = (t: TFunction) => [
{ name: '전체', value: LinkPaymentProcessStatus.ALL }, { name: t('transaction.constants.all'), value: LinkPaymentProcessStatus.ALL },
{ name: '발송요청', value: LinkPaymentProcessStatus.SEND_REQUEST }, { name: t('additionalService.linkPay.sendRequest'), value: LinkPaymentProcessStatus.SEND_REQUEST },
{ name: '발송취소', value: LinkPaymentProcessStatus.SEND_CANCEL } { name: t('additionalService.linkPay.sendCancel'), value: LinkPaymentProcessStatus.SEND_CANCEL }
] ]

View File

@@ -1,23 +1,25 @@
import { TFunction } from 'i18next';
import { PayoutSearchDateType, PayoutDisbursementStatus } from './types'; import { PayoutSearchDateType, PayoutDisbursementStatus } from './types';
export const PayoutSearchClBtnGroup = [ export const getPayoutSearchClBtnGroup = (t: TFunction) => [
{name: '요청일자', value: PayoutSearchDateType.REQUEST_DATE }, {name: t('additionalService.payout.requestDate'), value: PayoutSearchDateType.REQUEST_DATE },
{name: '지급일자', value: PayoutSearchDateType.SETTLEMENT_DATE } {name: t('additionalService.payout.disbursementDate'), value: PayoutSearchDateType.SETTLEMENT_DATE }
];
export const PayoutDisbursementStatusBtnGroup = [
{name: '전체', value: PayoutDisbursementStatus.ALL},
{name: '요청', value: PayoutDisbursementStatus.REQUEST},
{name: '성공', value: PayoutDisbursementStatus.SUCCESS},
{name: '실패', value: PayoutDisbursementStatus.FAIL},
]; ];
export const getPayoutStatusText = (status?: string): string => { export const getPayoutDisbursementStatusBtnGroup = (t: TFunction) => [
{name: t('transaction.constants.all'), value: PayoutDisbursementStatus.ALL},
{name: t('additionalService.common.request'), value: PayoutDisbursementStatus.REQUEST},
{name: t('additionalService.common.success'), value: PayoutDisbursementStatus.SUCCESS},
{name: t('additionalService.common.fail'), value: PayoutDisbursementStatus.FAIL},
];
export const getPayoutStatusText = (t: TFunction) => (status?: string): string => {
if (!status) return ''; if (!status) return '';
const statusMap: Record<string, string> = { const statusMap: Record<string, string> = {
"REQUEST" : "요청", "REQUEST" : t('additionalService.common.request'),
"SUCCESS" : "성공", "SUCCESS" : t('additionalService.common.success'),
"FAIL" : "실패" "FAIL" : t('additionalService.common.fail')
} }
return statusMap[status] || status; return statusMap[status] || status;

View File

@@ -1,13 +1,14 @@
import { TFunction } from 'i18next';
import { SmsCl } from './types'; import { SmsCl } from './types';
export const SmsClBtnGroup = [ export const getSmsClBtnGroup = (t: TFunction) => [
{ name: '', value: SmsCl.ALL }, { name: '', value: SmsCl.ALL },
{ name: '가상계좌 요청', value: SmsCl.VACCOUNT_REQ }, { name: t('additionalService.sms.virtualAccountRequest'), value: SmsCl.VACCOUNT_REQ },
{ name: '가상계좌 요청 + 입금', value: SmsCl.VACCOUNT_REQ_DEPOSIT } { name: t('additionalService.sms.virtualAccountRequestDeposit'), value: SmsCl.VACCOUNT_REQ_DEPOSIT }
]; ];
export const getSmsClName = (smsCl?: string): string => { export const getSmsClName = (t: TFunction) => (smsCl?: string): string => {
if (!smsCl) return ''; if (!smsCl) return '';
const found = SmsClBtnGroup.find(item => item.value === smsCl); const found = getSmsClBtnGroup(t).find(item => item.value === smsCl);
return found ? found.name : smsCl; return found ? found.name : smsCl;
}; };

View File

@@ -1,6 +1,8 @@
import { BottomSheetMotionDuration, BottomSheetMotionVaiants } from "@/entities/common/model/constant"; import { BottomSheetMotionDuration, BottomSheetMotionVaiants } from "@/entities/common/model/constant";
import { IMAGE_ROOT } from '@/shared/constants/common'; import { IMAGE_ROOT } from '@/shared/constants/common';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { useTranslation } from 'react-i18next';
export interface ArsResendSmsBottomSheetProps { export interface ArsResendSmsBottomSheetProps {
bottomSheetOn: boolean; bottomSheetOn: boolean;
setBottomSheetOn: (bottomSheetOn: boolean) => void; setBottomSheetOn: (bottomSheetOn: boolean) => void;
@@ -14,6 +16,7 @@ export const ArsResendSmsBottomSheet = ({
phoneNumber, phoneNumber,
callResendSms callResendSms
}: ArsResendSmsBottomSheetProps) => { }: ArsResendSmsBottomSheetProps) => {
const { t } = useTranslation();
const onClickToClose = () => { const onClickToClose = () => {
setBottomSheetOn(false); setBottomSheetOn(false);
@@ -40,14 +43,14 @@ export const ArsResendSmsBottomSheet = ({
> >
<div className="bottomsheet-header"> <div className="bottomsheet-header">
<div className="bottomsheet-title"> <div className="bottomsheet-title">
<h2>SMS </h2> <h2>{t('additionalService.common.resend')} SMS</h2>
<button <button
className="close-btn" className="close-btn"
type="button" type="button"
> >
<img <img
src={ IMAGE_ROOT + '/ico_close.svg' } src={ IMAGE_ROOT + '/ico_close.svg' }
alt="닫기" alt={t('common.close')}
onClick={ () => onClickToClose() } onClick={ () => onClickToClose() }
/> />
</button> </button>
@@ -55,7 +58,7 @@ export const ArsResendSmsBottomSheet = ({
</div> </div>
<div className="bottomsheet-content"> <div className="bottomsheet-content">
<div className="bottom-section"> <div className="bottom-section">
<p>[01095800212] SMS를 ?</p> <p>[{phoneNumber}] {t('transaction.sms.resendConfirmMessage')}</p>
</div> </div>
</div> </div>
<div className="bottomsheet-footer"> <div className="bottomsheet-footer">
@@ -63,7 +66,7 @@ export const ArsResendSmsBottomSheet = ({
className="btn-50 btn-blue flex-1" className="btn-50 btn-blue flex-1"
type="button" type="button"
onClick={ () => onCliickToResendSms() } onClick={ () => onCliickToResendSms() }
></button> >{t('transaction.apply')}</button>
</div> </div>
</motion.div> </motion.div>
</> </>

View File

@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { useTranslation } from 'react-i18next';
import { IMAGE_ROOT } from '@/shared/constants/common'; import { IMAGE_ROOT } from '@/shared/constants/common';
import { FilterSelect } from '@/shared/ui/filter/select'; import { FilterSelect } from '@/shared/ui/filter/select';
import { FilterCalendar } from '@/shared/ui/filter/calendar'; import { FilterCalendar } from '@/shared/ui/filter/calendar';
@@ -13,7 +14,7 @@ import {
import moment from 'moment'; import moment from 'moment';
import { FilterInput } from '@/shared/ui/filter/input'; import { FilterInput } from '@/shared/ui/filter/input';
import { OrderStatus, PaymentStatus } from '../../model/ars/types'; import { OrderStatus, PaymentStatus } from '../../model/ars/types';
import { ArsOrderStatusBtnGroup, ArsPaymentStatusBtnGroup } from '../../model/ars/constant'; import { getArsOrderStatusBtnGroup, getArsPaymentStatusBtnGroup } from '../../model/ars/constant';
import { useStore } from '@/shared/model/store'; import { useStore } from '@/shared/model/store';
import { FilterSelectMid } from '@/shared/ui/filter/select-mid'; import { FilterSelectMid } from '@/shared/ui/filter/select-mid';
@@ -68,6 +69,8 @@ export const ArsFilter = ({
const [filterMinAmount, setFilterMinAmount] = useState<number | undefined>(minAmount); const [filterMinAmount, setFilterMinAmount] = useState<number | undefined>(minAmount);
const [filterMaxAmount, setFilterMaxAmount] = useState<number | undefined>(maxAmount); const [filterMaxAmount, setFilterMaxAmount] = useState<number | undefined>(maxAmount);
const { t } = useTranslation();
const onClickToClose = () => { const onClickToClose = () => {
setFilterOn(false); setFilterOn(false);
}; };
@@ -100,7 +103,7 @@ export const ArsFilter = ({
> >
<div className="full-menu-container"> <div className="full-menu-container">
<div className="full-menu-header"> <div className="full-menu-header">
<div className="full-menu-title center"></div> <div className="full-menu-title center">{t('filter.filter')}</div>
<div className="full-menu-actions"> <div className="full-menu-actions">
<button <button
id="closeFullMenu" id="closeFullMenu"
@@ -108,7 +111,7 @@ export const ArsFilter = ({
> >
<img <img
src={ IMAGE_ROOT + '/ico_close.svg' } src={ IMAGE_ROOT + '/ico_close.svg' }
alt="닫기" alt={t('filter.close')}
onClick={ () => onClickToClose() } onClick={ () => onClickToClose() }
/> />
</button> </button>
@@ -116,36 +119,36 @@ export const ArsFilter = ({
</div> </div>
<div className="option-list pt-16"> <div className="option-list pt-16">
<FilterSelectMid <FilterSelectMid
title='가맹점' title={t('filter.merchant')}
selectSetter={ setFilterMid } selectSetter={ setFilterMid }
showType={ 'GID'} showType={ 'GID'}
></FilterSelectMid> ></FilterSelectMid>
<FilterInput <FilterInput
title='주문번호' title={t('transaction.constants.orderNumber')}
inputValue={ filterMoid } inputValue={ filterMoid }
inputSetter={ setFilterMoid } inputSetter={ setFilterMoid }
></FilterInput> ></FilterInput>
<FilterCalendar <FilterCalendar
title='조회기간' title={t('filter.period')}
startDate={ filterFromDate } startDate={ filterFromDate }
endDate={ filterToDate } endDate={ filterToDate }
setStartDate={ setFilterFromDate } setStartDate={ setFilterFromDate }
setEndDate={ setFilterToDate } setEndDate={ setFilterToDate }
></FilterCalendar> ></FilterCalendar>
<FilterButtonGroups <FilterButtonGroups
title='결제상태' title={t('transaction.filter.paymentStatus')}
activeValue={ filterPaymentStatus } activeValue={ filterPaymentStatus }
btnGroups={ ArsPaymentStatusBtnGroup } btnGroups={ getArsPaymentStatusBtnGroup(t) }
setter={ setFilterPaymentStatus } setter={ setFilterPaymentStatus }
></FilterButtonGroups> ></FilterButtonGroups>
<FilterButtonGroups <FilterButtonGroups
title='주문상태' title={t('transaction.filter.orderStatus')}
activeValue={ filterOrderStatus } activeValue={ filterOrderStatus }
btnGroups={ ArsOrderStatusBtnGroup } btnGroups={ getArsOrderStatusBtnGroup(t) }
setter={ setFilterOrderStatus } setter={ setFilterOrderStatus }
></FilterButtonGroups> ></FilterButtonGroups>
<FilterRangeAmount <FilterRangeAmount
title='거래금액' title={t('filter.transactionAmount')}
minAmount={ filterMinAmount } minAmount={ filterMinAmount }
maxAmount={ filterMaxAmount } maxAmount={ filterMaxAmount }
setMinAmount={ setFilterMinAmount } setMinAmount={ setFilterMinAmount }
@@ -156,7 +159,7 @@ export const ArsFilter = ({
<button <button
className="btn-50 btn-blue flex-1" className="btn-50 btn-blue flex-1"
onClick={ () => onClickToSetFilter() } onClick={ () => onClickToSetFilter() }
></button> >{t('filter.apply')}</button>
</div> </div>
</div> </div>
</motion.div> </motion.div>

View File

@@ -786,6 +786,69 @@
"reason": "Reason", "reason": "Reason",
"accountError": "Payment Account Error", "accountError": "Payment Account Error",
"agreeOrReject": "Agree/Reject Settlement" "agreeOrReject": "Agree/Reject Settlement"
},
"ars": {
"paymentComplete": "Payment Complete",
"unpaid": "Unpaid",
"pendingPayment": "Pending Payment",
"paymentSuccess": "Payment Success",
"expired": "Expired",
"canceled": "Canceled"
},
"sms": {
"virtualAccountRequest": "Virtual Account Request",
"virtualAccountRequestDeposit": "Virtual Account Request + Deposit"
},
"linkPay": {
"sendRequest": "Send Request",
"sendCancel": "Send Cancel",
"incompleteActive": "Incomplete/Active",
"depositRequest": "Deposit Request",
"paymentComplete": "Payment Complete",
"paymentFail": "Payment Failed",
"paymentStopped": "Payment Stopped",
"paymentStoppedInactive": "Payment Stopped/Inactive",
"pending": "Pending",
"email": "Email",
"alimtalk": "Alimtalk"
},
"accountHolderAuth": {
"accountHolderNameMatch": "Account Holder Name Match",
"accountHolderNameMismatch": "Account Holder Name Mismatch",
"authFailedAccountError": "Authentication Failed (Account Error, etc.)"
},
"accountHolderSearch": {
"accountHolder": "Account Holder",
"accountNumber": "Account Number"
},
"faceAuth": {
"authentication": "Authentication",
"registration": "Registration"
},
"fundAccount": {
"registrationComplete": "Registration Complete",
"transferRequest": "Transfer Request",
"requestSuccess": "Request Success",
"requestFail": "Request Failed",
"requestDate": "Request Date",
"transferDate": "Transfer Date",
"recipient": "Recipient",
"accountNumber": "Account Number"
},
"alimtalk": {
"buyer": "Buyer",
"depositRequest": "Deposit Request",
"depositComplete": "Deposit Complete",
"kakaotalk": "KakaoTalk",
"fbSms": "FB SMS"
},
"payout": {
"requestDate": "Request Date",
"disbursementDate": "Disbursement Date"
},
"keyIn": {
"fullCancel": "Full Cancel",
"partialCancel": "Partial Cancel"
} }
}, },
"merchant": { "merchant": {

View File

@@ -790,6 +790,69 @@
"reason": "사유", "reason": "사유",
"accountError": "지급 계좌오류", "accountError": "지급 계좌오류",
"agreeOrReject": "정산 동의/거절" "agreeOrReject": "정산 동의/거절"
},
"ars": {
"paymentComplete": "결제완료",
"unpaid": "미결제",
"pendingPayment": "결제대기",
"paymentSuccess": "결제성공",
"expired": "기간만료",
"canceled": "취소완료"
},
"sms": {
"virtualAccountRequest": "가상계좌 요청",
"virtualAccountRequestDeposit": "가상계좌 요청 + 입금"
},
"linkPay": {
"sendRequest": "발송요청",
"sendCancel": "발송취소",
"incompleteActive": "미완료/활성화",
"depositRequest": "입금요청",
"paymentComplete": "결제완료",
"paymentFail": "결제실패",
"paymentStopped": "결제중단",
"paymentStoppedInactive": "결제중단/비활성화",
"pending": "대기중",
"email": "이메일",
"alimtalk": "알림톡"
},
"accountHolderAuth": {
"accountHolderNameMatch": "예금주명 일치",
"accountHolderNameMismatch": "예금주명 불일치",
"authFailedAccountError": "인증실패 (계좌 오류 등)"
},
"accountHolderSearch": {
"accountHolder": "예금주",
"accountNumber": "계좌번호"
},
"faceAuth": {
"authentication": "인증",
"registration": "등록"
},
"fundAccount": {
"registrationComplete": "등록완료",
"transferRequest": "이체요청",
"requestSuccess": "요청성공",
"requestFail": "요청실패",
"requestDate": "요청일자",
"transferDate": "이체일자",
"recipient": "수취인",
"accountNumber": "계좌번호"
},
"alimtalk": {
"buyer": "주문자",
"depositRequest": "입금요청",
"depositComplete": "입금완료",
"kakaotalk": "카카오톡",
"fbSms": "FB SMS"
},
"payout": {
"requestDate": "요청일자",
"disbursementDate": "지급일자"
},
"keyIn": {
"fullCancel": "전취소",
"partialCancel": "후취소"
} }
}, },
"merchant": { "merchant": {