Refactor additional service details and fix various bugs
- Convert detail pages to modal components for better UX - Fix seq type from string to number for ARS and Alimtalk - Add seq field to list item types - Fix validation for card number input (remove formatting chars) - Fix SMS payment resend seq parameter issue - Improve z-index handling for snackBar and dialogs - Add useSetHeaderTitle to link payment history wrap - Remove unused detail page files - Update payout filter and various detail components 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
VITE_APP_ENV=development
|
||||
# VITE_APP_AUTH_PROXY_HOST='http://3.35.79.250:8090'
|
||||
# VITE_APP_API_PROXY_HOST='http://3.35.79.250:8080'
|
||||
VITE_APP_AUTH_PROXY_HOST='https://auth.nicepay.co.kr'
|
||||
VITE_APP_API_PROXY_HOST='https://rest.nicepay.co.kr'
|
||||
VITE_APP_AUTH_PROXY_HOST='http://3.35.79.250:8090'
|
||||
VITE_APP_API_PROXY_HOST='http://3.35.79.250:8080'
|
||||
# VITE_APP_AUTH_PROXY_HOST='https://auth.nicepay.co.kr'
|
||||
#VITE_APP_API_PROXY_HOST='https://rest.nicepay.co.kr'
|
||||
GENERATE_SOURCEMAP=false
|
||||
SENTRY_AUTH_TOKEN=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
|
||||
@@ -46,7 +46,16 @@ export interface ExtensionAlimtalkSettingSaveParams {
|
||||
sendUserInfo?: SendUserInfo;
|
||||
};
|
||||
|
||||
export interface ExtensionAlimtalkSettingSaveResponse {};
|
||||
export interface ExtensionAlimtalkSettingSaveResponse {
|
||||
status: boolean;
|
||||
error?: {
|
||||
root?: string;
|
||||
errKey?: string;
|
||||
code?: string;
|
||||
message?: string;
|
||||
timestamp?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export interface ExtensionAlimtalkSettingDetailParams {
|
||||
mid: string;
|
||||
|
||||
@@ -332,7 +332,19 @@ export interface ExtensionLinkPayWaitDeleteParams extends ExtensionRequestParams
|
||||
}
|
||||
|
||||
export interface ExtensionLinkPayWaitDeleteRespone {
|
||||
status: boolean
|
||||
status: boolean;
|
||||
error?: {
|
||||
root?: string;
|
||||
errKey?: string;
|
||||
code?: string;
|
||||
message?: string;
|
||||
timestamp?: string;
|
||||
details?: {
|
||||
validationErrors?: {
|
||||
[key: string]: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 분리승인 상세 조회 Request
|
||||
@@ -369,7 +381,7 @@ export interface ExtensionLInkPaySeparateActionParams extends ExtensionRequestPa
|
||||
}
|
||||
|
||||
export interface ExtensionLinkPaySeparateActionResponse {
|
||||
success : boolean;
|
||||
success: boolean;
|
||||
totalCount: number;
|
||||
successCount: number;
|
||||
failCount: number;
|
||||
|
||||
@@ -8,6 +8,7 @@ import { getAuthResultStatusText } from '@/entities/additional-service/model/fac
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
export interface AccountHolderAuthDetailProps {
|
||||
detailOn: boolean;
|
||||
@@ -33,7 +34,12 @@ export const AccountHolderAuthDetail = ({
|
||||
tid: tid
|
||||
}
|
||||
accountHolderAuthDetail(accountHolderAuthDetailParams).then((rs: ExtensionAccountHolderAuthDetailResponse) => {
|
||||
setDetail(rs);
|
||||
setDetail(rs);
|
||||
}).catch((e: any) => {
|
||||
if (e.response?.data?.error?.message) {
|
||||
showAlert(e.response?.data?.error?.message);
|
||||
return;
|
||||
}
|
||||
});
|
||||
};
|
||||
const onClickToClose = () => {
|
||||
@@ -45,77 +51,77 @@ export const AccountHolderAuthDetail = ({
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if(!!mid && !!tid){
|
||||
if (!!mid && !!tid) {
|
||||
callDetail();
|
||||
}
|
||||
}, [mid, tid]);
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
animate={(detailOn) ? 'visible' : 'hidden'}
|
||||
variants={DetailMotionVariants}
|
||||
transition={DetailMotionDuration}
|
||||
style={DetailMotionStyle}
|
||||
>
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('additionalService.accountHolderAuth.detailTitle') }</div>
|
||||
<div className="full-menu-title center">{t('additionalService.accountHolderAuth.detailTitle')}</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
onClickToCallback={onClickToClose}
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">{detail?.accountName}</span>
|
||||
</div>
|
||||
<span className="num-store">{detail?.accountNo}</span>
|
||||
<div className="num-day">{getDate(detail?.requestDate)}</div>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('transaction.sections.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.companyName')}</span>
|
||||
<span className="v">{detail?.companyName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.mid')}</span>
|
||||
<span className="v">{detail?.mid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.accountHolderAuth.requestDate')}</span>
|
||||
<span className="v">{getDate(detail?.requestDate)}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.bank')}</span>
|
||||
<span className="v">{detail?.bankName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.accountNo')}</span>
|
||||
<span className="v">{detail?.accountNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.accountHolder')}</span>
|
||||
<span className="v">{detail?.accountName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('common.result')}</span>
|
||||
<span className="v">{getAuthStatusText(t)(detail?.authStatus)}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.failureReason')}</span>
|
||||
<span className="v">{detail?.failReason ? getAuthResultStatusText(t)(detail?.failReason) : '-' }</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">{detail?.accountName}</span>
|
||||
</div>
|
||||
<span className="num-store">{detail?.accountNo}</span>
|
||||
<div className="num-day">{getDate(detail?.requestDate)}</div>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('transaction.sections.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.companyName')}</span>
|
||||
<span className="v">{detail?.companyName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.mid')}</span>
|
||||
<span className="v">{detail?.mid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.accountHolderAuth.requestDate')}</span>
|
||||
<span className="v">{getDate(detail?.requestDate)}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.bank')}</span>
|
||||
<span className="v">{detail?.bankName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.accountNo')}</span>
|
||||
<span className="v">{detail?.accountNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.accountHolder')}</span>
|
||||
<span className="v">{detail?.accountName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('common.result')}</span>
|
||||
<span className="v">{getAuthStatusText(t)(detail?.authStatus)}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.failureReason')}</span>
|
||||
<span className="v">{detail?.failReason ? getAuthResultStatusText(t)(detail?.failReason) : '-'}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -10,6 +10,7 @@ import { useExtensionArsDetailMutation } from '@/entities/additional-service/api
|
||||
import { useExtensionArsResendMutation } from '@/entities/additional-service/api/ars/use-extension-ars-resend-mutation';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
import { ArsResendSmsBottomSheet } from '../resend-sms-bottom-sheet';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
export interface ArsDetailProps {
|
||||
detailOn: boolean;
|
||||
@@ -39,6 +40,11 @@ export const ArsDetail = ({
|
||||
};
|
||||
extensionArsDetail(arsDetailParams).then((rs: ExtensionArsDetailResponse) => {
|
||||
setDetail(rs);
|
||||
}).catch((e: any) => {
|
||||
if (e.response?.data?.error?.message) {
|
||||
showAlert(e.response?.data?.error?.message);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -101,76 +107,76 @@ export const ArsDetail = ({
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">
|
||||
{t('home.money', { value: new Intl.NumberFormat('en-US').format(Number(detail?.amount) || 0) })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="num-store">{detail?.corpName}</div>
|
||||
<div className="num-day">{getDate(detail?.paymentDate)}</div>
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">
|
||||
{t('home.money', { value: new Intl.NumberFormat('en-US').format(Number(detail?.amount) || 0) })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('additionalService.ars.transactionInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.mid')}</span>
|
||||
<span className="v">{detail?.mid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.paymentMethod')}</span>
|
||||
<span className="v">{detail?.arsPaymentMethod}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.paymentStatus')}</span>
|
||||
<span className="v">{getArsPaymentStatusName(t)(detail?.paymentStatus)}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.orderStatus')}</span>
|
||||
<span className="v">{getArsOrderStatusName(t)(detail?.orderStatus)}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.orderDateTime')}</span>
|
||||
<span className="v">{
|
||||
detail?.paymentDate ? moment(detail.paymentDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '-'
|
||||
}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.productName')}</span>
|
||||
<span className="v">{detail?.goodsName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.orderNumber')}</span>
|
||||
<span className="v">{detail?.tid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.buyer')}</span>
|
||||
<span className="v">{detail?.buyerName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.phoneNumber')}</span>
|
||||
<span className="v">{detail?.maskPhoneNumber}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.email')}</span>
|
||||
<span className="v">{detail?.email}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.sendVerificationCode')}</span>
|
||||
<span className="v">{detail?.smsVerificationCode}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="num-store">{detail?.corpName}</div>
|
||||
<div className="num-day">{getDate(detail?.paymentDate)}</div>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('additionalService.ars.transactionInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.mid')}</span>
|
||||
<span className="v">{detail?.mid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.paymentMethod')}</span>
|
||||
<span className="v">{detail?.arsPaymentMethod}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.paymentStatus')}</span>
|
||||
<span className="v">{getArsPaymentStatusName(t)(detail?.paymentStatus)}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.orderStatus')}</span>
|
||||
<span className="v">{getArsOrderStatusName(t)(detail?.orderStatus)}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.orderDateTime')}</span>
|
||||
<span className="v">{
|
||||
detail?.paymentDate ? moment(detail.paymentDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '-'
|
||||
}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.productName')}</span>
|
||||
<span className="v">{detail?.goodsName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.orderNumber')}</span>
|
||||
<span className="v">{detail?.tid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.buyer')}</span>
|
||||
<span className="v">{detail?.buyerName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.phoneNumber')}</span>
|
||||
<span className="v">{detail?.maskPhoneNumber}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.email')}</span>
|
||||
<span className="v">{detail?.email}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.ars.sendVerificationCode')}</span>
|
||||
<span className="v">{detail?.smsVerificationCode}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{detail?.arsPaymentMethod === ArsPaymentMethod.SMS && (
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToOpenResendBottomSheet()}
|
||||
//disabled={ detail?.orderStatus !== OrderStatus.PENDING }
|
||||
>{t('additionalService.ars.smsResend')}</button>
|
||||
</div>
|
||||
{detail?.arsPaymentMethod === ArsPaymentMethod.SMS && (
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToOpenResendBottomSheet()}
|
||||
//disabled={ detail?.orderStatus !== OrderStatus.PENDING }
|
||||
>{t('additionalService.ars.smsResend')}</button>
|
||||
</div>
|
||||
)}
|
||||
)}
|
||||
</div>
|
||||
<ArsResendSmsBottomSheet
|
||||
setBottomSheetOn={setBottomSheetOn}
|
||||
|
||||
@@ -13,6 +13,7 @@ import { useExtensionFundAccountDownloadReceiptMutation } from '@/entities/addit
|
||||
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
export interface FundAccountResultDetailProps {
|
||||
detailOn: boolean;
|
||||
@@ -26,8 +27,8 @@ export const FundAccountResultDetail = ({
|
||||
mid,
|
||||
tid
|
||||
}: FundAccountResultDetailProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [detail, setDetail] = useState<ExtensionFundAccountResultDetailResponse>();
|
||||
const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false);
|
||||
|
||||
@@ -43,6 +44,11 @@ export const FundAccountResultDetail = ({
|
||||
extensionFundAccountResultDetail(params).then((rs: ExtensionFundAccountResultDetailResponse) => {
|
||||
console.log(rs.requestDate)
|
||||
setDetail(rs);
|
||||
}).catch((e: any) => {
|
||||
if (e.response?.data?.error?.message) {
|
||||
showAlert(e.response?.data?.error?.message);
|
||||
return;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -51,7 +57,7 @@ export const FundAccountResultDetail = ({
|
||||
};
|
||||
|
||||
const onSendRequest = (selectedEmail?: string) => {
|
||||
if(selectedEmail){
|
||||
if (selectedEmail) {
|
||||
let params: ExtensionFundAccountDownloadReceiptParams = {
|
||||
mid: mid,
|
||||
tid: tid,
|
||||
@@ -63,107 +69,107 @@ export const FundAccountResultDetail = ({
|
||||
}
|
||||
setEmailBottomSheetOn(false);
|
||||
};
|
||||
|
||||
|
||||
const onClickToClose = () => {
|
||||
setDetailOn(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if(!!mid && !!tid){
|
||||
if (!!mid && !!tid) {
|
||||
callDetail();
|
||||
}
|
||||
}, [mid, tid]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
animate={(detailOn) ? 'visible' : 'hidden'}
|
||||
variants={DetailMotionVariants}
|
||||
transition={DetailMotionDuration}
|
||||
style={DetailMotionStyle}
|
||||
>
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('additionalService.fundAccount.transferDetailTitle') }</div>
|
||||
<div className="full-menu-title center">{t('additionalService.fundAccount.transferDetailTitle')}</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
onClickToCallback={onClickToClose}
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">
|
||||
{t('home.money', { value: new Intl.NumberFormat('en-US').format(detail?.amount || 0) })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="num-store">{detail?.accountName}({detail?.accountNo})</div>
|
||||
{detail?.applicationDate && (
|
||||
<div className="num-day"> {moment(detail?.applicationDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss')}</div>
|
||||
)}
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">
|
||||
{t('home.money', { value: new Intl.NumberFormat('en-US').format(detail?.amount || 0) })}
|
||||
</span>
|
||||
</div>
|
||||
{/* ✅ resultMessage가 "정상"일 때만 표시 */}
|
||||
{detail?.resultMessage === '정상' && (
|
||||
<div className="receipt-row">
|
||||
<button
|
||||
type="button"
|
||||
className="receipt-btn"
|
||||
onClick={ onClickToOpenEmailBottomSheet }
|
||||
>
|
||||
<span className="icon-24 download"></span>
|
||||
<span>{t('additionalService.fundAccount.depositCertificate')}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="num-store">{detail?.accountName}({detail?.accountNo})</div>
|
||||
{detail?.applicationDate && (
|
||||
<div className="num-day"> {moment(detail?.applicationDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss')}</div>
|
||||
)}
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('additionalService.fundAccount.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.requestDateTime')}</span>
|
||||
<span className="v">{moment(detail?.requestDate,'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss')}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.transferDateTime')}</span>
|
||||
<span className="v">{detail?.applicationDate ? moment(detail?.applicationDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.transferResult')}</span>
|
||||
<span className="v">{detail?.resultMessage || '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.failureReason')}</span>
|
||||
<span className="v">{detail?.failReason || '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.beneficiaryName')}</span>
|
||||
<span className="v">{detail?.accountName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.bank')}</span>
|
||||
<span className="v">{detail?.bankName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.accountNumber')}</span>
|
||||
<span className="v">{detail?.accountNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">MID</span>
|
||||
<span className="v">{mid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.orderNumber')}</span>
|
||||
<span className="v">{detail?.moid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">TID</span>
|
||||
<span className="v">{detail?.tid}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{/* ✅ resultMessage가 "정상"일 때만 표시 */}
|
||||
{detail?.resultMessage === '정상' && (
|
||||
<div className="receipt-row">
|
||||
<button
|
||||
type="button"
|
||||
className="receipt-btn"
|
||||
onClick={onClickToOpenEmailBottomSheet}
|
||||
>
|
||||
<span className="icon-24 download"></span>
|
||||
<span>{t('additionalService.fundAccount.depositCertificate')}</span>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('additionalService.fundAccount.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.requestDateTime')}</span>
|
||||
<span className="v">{moment(detail?.requestDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss')}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.transferDateTime')}</span>
|
||||
<span className="v">{detail?.applicationDate ? moment(detail?.applicationDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.transferResult')}</span>
|
||||
<span className="v">{detail?.resultMessage || '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.failureReason')}</span>
|
||||
<span className="v">{detail?.failReason || '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.beneficiaryName')}</span>
|
||||
<span className="v">{detail?.accountName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.bank')}</span>
|
||||
<span className="v">{detail?.bankName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.accountNumber')}</span>
|
||||
<span className="v">{detail?.accountNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">MID</span>
|
||||
<span className="v">{mid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.orderNumber')}</span>
|
||||
<span className="v">{detail?.moid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">TID</span>
|
||||
<span className="v">{detail?.tid}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
<EmailBottomSheet
|
||||
|
||||
@@ -11,6 +11,7 @@ import { snackBar } from '@/shared/lib';
|
||||
import { useExtensionFundAccountTransferRequestMutation } from '@/entities/additional-service/api/fund-account/use-extension-fund-account-transfer-request-mutation';
|
||||
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
export interface FundAccountTransferDetailProps {
|
||||
detailOn: boolean;
|
||||
@@ -39,27 +40,35 @@ export const FundAccountTransferDetail = ({
|
||||
|
||||
extensionFundAccountTransferDetail(params).then((rs: ExtensionFundAccountTransferDetailResponse) => {
|
||||
setDetail(rs);
|
||||
});
|
||||
}).catch((e: any) => {
|
||||
if (e.response?.data?.error?.message) {
|
||||
showAlert(e.response?.data?.error?.message);
|
||||
return;
|
||||
}
|
||||
});;
|
||||
};
|
||||
|
||||
|
||||
const onClickToRequest = () => {
|
||||
let params: ExtensionFundAccountTransferRequestParams = {
|
||||
seq: seq
|
||||
};
|
||||
extensionFundAccountTransferRequest(params).then((rs: ExtensionFundAccountTransferRequestResponse) => {
|
||||
if(rs.status){
|
||||
if (rs.status) {
|
||||
callDetail();
|
||||
snackBar(t('additionalService.fundAccount.transferRequestSuccess'))
|
||||
}
|
||||
else{
|
||||
else {
|
||||
const errorMessage = rs.error?.message || t('additionalService.fundAccount.transferRequestFailed');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
}
|
||||
}).catch((error) => {
|
||||
const errorMessage = error?.response?.data?.error?.message ||
|
||||
error?.message ||
|
||||
t('additionalService.fundAccount.transferRequestError');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
console.log(error);
|
||||
const errorMessage = error?.response?.data?.error?.message || error?.message || t('additionalService.fundAccount.transferRequestError');
|
||||
if (error.response?.data?.error?.root !== "SystemErrorCode") {
|
||||
snackBar(`[${t('common.failed')}] ${error.response?.data?.error?.message}`)
|
||||
} else {
|
||||
showAlert(`[${t('common.failed')}] ${errorMessage}`);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -68,92 +77,92 @@ export const FundAccountTransferDetail = ({
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if(!!seq){
|
||||
if (!!seq) {
|
||||
callDetail();
|
||||
}
|
||||
}, [seq]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
animate={(detailOn) ? 'visible' : 'hidden'}
|
||||
variants={DetailMotionVariants}
|
||||
transition={DetailMotionDuration}
|
||||
style={DetailMotionStyle}
|
||||
>
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('additionalService.fundAccount.transferDetailTitle') }</div>
|
||||
<div className="full-menu-title center">{t('additionalService.fundAccount.transferDetailTitle')}</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
onClickToCallback={onClickToClose}
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">
|
||||
{t('home.money', { value: new Intl.NumberFormat('en-US').format(detail?.amount || 0) })}
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">
|
||||
{t('home.money', { value: new Intl.NumberFormat('en-US').format(detail?.amount || 0) })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="num-store">{detail?.accountName}({detail?.accountNo})</div>
|
||||
<div className="num-day">
|
||||
{detail?.registDate ? moment(detail.registDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '-'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('additionalService.fundAccount.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.registrationDateTime')}</span>
|
||||
<span className="v">
|
||||
{detail?.registDate ? moment(detail.registDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '-'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="num-store">{detail?.accountName}({detail?.accountNo})</div>
|
||||
<div className="num-day">
|
||||
{detail?.registDate ? moment(detail.registDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '-'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('additionalService.fundAccount.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.registrationDateTime')}</span>
|
||||
<span className="v">
|
||||
{detail?.registDate ? moment(detail.registDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '-'}
|
||||
</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.processingResult')}</span>
|
||||
<span className="v">{getFundAccountStatusName(t)(detail?.resultStatus) || '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.requestDate')}</span>
|
||||
<span className="v">
|
||||
{detail?.requestDate ? moment(detail.requestDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD') : '-'}
|
||||
</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.transferResult')}</span>
|
||||
<span className="v">{detail?.resultMessage || '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.beneficiaryName')}</span>
|
||||
<span className="v">{detail?.accountName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.bank')}</span>
|
||||
<span className="v">{detail?.bankCode || '-'} </span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.accountNumber')}</span>
|
||||
<span className="v">{detail?.accountNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">MID</span>
|
||||
<span className="v">{detail?.mid}</span>
|
||||
</li>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.processingResult')}</span>
|
||||
<span className="v">{getFundAccountStatusName(t)(detail?.resultStatus) || '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.requestDate')}</span>
|
||||
<span className="v">
|
||||
{detail?.requestDate ? moment(detail.requestDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD') : '-'}
|
||||
</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.transferResult')}</span>
|
||||
<span className="v">{detail?.resultMessage || '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.beneficiaryName')}</span>
|
||||
<span className="v">{detail?.accountName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.bank')}</span>
|
||||
<span className="v">{detail?.bankCode || '-'} </span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.accountNumber')}</span>
|
||||
<span className="v">{detail?.accountNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">MID</span>
|
||||
<span className="v">{detail?.mid}</span>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToRequest()}
|
||||
disabled={detail?.resultStatus !== FundAccountStatus.REGIST_COMPLETE}
|
||||
>{t('additionalService.fundAccount.transferRequestButton')}</button>
|
||||
</div>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToRequest()}
|
||||
disabled={detail?.resultStatus !== FundAccountStatus.REGIST_COMPLETE}
|
||||
>{t('additionalService.fundAccount.transferRequestButton')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
|
||||
@@ -24,6 +24,7 @@ import moment from 'moment';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
export interface LinkPaymentHistoryDetailProps {
|
||||
detailOn: boolean;
|
||||
@@ -66,7 +67,12 @@ export const LinkPaymentHistoryDetail = ({
|
||||
setDetailInfo(rs.detailInfo)
|
||||
setPaymentInfo(rs.paymentInfo)
|
||||
setDetailExposure(rs.detailExposure ?? false)
|
||||
})
|
||||
}).catch((e: any) => {
|
||||
if (e.response?.data?.error?.message) {
|
||||
showAlert(e.response?.data?.error?.message);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Resend API
|
||||
@@ -88,9 +94,15 @@ export const LinkPaymentHistoryDetail = ({
|
||||
})
|
||||
.catch((error) => {
|
||||
const errorMessage = error?.response?.data?.error?.message ||
|
||||
error?.message ||
|
||||
t('additionalService.linkPayment.resendError');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
error?.message ||
|
||||
t('additionalService.linkPayment.resendError');
|
||||
console.log(error)
|
||||
if (error.response?.data?.error?.root !== "SystemErrorCode") {
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
}
|
||||
else {
|
||||
showAlert(`[${t('common.failed')}] ${errorMessage}`)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -143,64 +155,64 @@ export const LinkPaymentHistoryDetail = ({
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if(!!mid && !!requestId){
|
||||
if (!!mid && !!requestId) {
|
||||
callDetail();
|
||||
}
|
||||
}, [mid, requestId, subReqId]);
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
animate={(detailOn) ? 'visible' : 'hidden'}
|
||||
variants={DetailMotionVariants}
|
||||
transition={DetailMotionDuration}
|
||||
style={DetailMotionStyle}
|
||||
>
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('additionalService.linkPayment.detailTitle') }</div>
|
||||
<div className="full-menu-title center">{t('additionalService.linkPayment.detailTitle')}</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
onClickToCallback={onClickToClose}
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pay-top">
|
||||
<TitleInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentHistory}
|
||||
titleInfo={titleInfo}
|
||||
></TitleInfoWrap>
|
||||
</div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-divider"></div>
|
||||
<PaymentInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentHistory}
|
||||
paymentInfo={paymentInfo}
|
||||
></PaymentInfoWrap>
|
||||
<div className="detail-divider"></div>
|
||||
<DetailInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentHistory}
|
||||
detailInfo={detailInfo}
|
||||
></DetailInfoWrap>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="link-payment-detail-button" style={{ paddingBottom: '100px' }}>
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToSeparateApproval()}
|
||||
disabled={detailExposure}
|
||||
>{t('additionalService.linkPayment.separateApprovalDetail')}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<div className="pay-top">
|
||||
<TitleInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentHistory}
|
||||
titleInfo={titleInfo}
|
||||
></TitleInfoWrap>
|
||||
</div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-divider"></div>
|
||||
<PaymentInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentHistory}
|
||||
paymentInfo={paymentInfo}
|
||||
></PaymentInfoWrap>
|
||||
<div className="detail-divider"></div>
|
||||
<DetailInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentHistory}
|
||||
detailInfo={detailInfo}
|
||||
></DetailInfoWrap>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="link-payment-detail-button" style={{ paddingBottom: '100px' }}>
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToResend()}
|
||||
disabled={!isResendEnabled()}
|
||||
>{t('additionalService.linkPayment.resend')}</button>
|
||||
onClick={() => onClickToSeparateApproval()}
|
||||
disabled={detailExposure}
|
||||
>{t('additionalService.linkPayment.separateApprovalDetail')}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToResend()}
|
||||
disabled={!isResendEnabled()}
|
||||
>{t('additionalService.linkPayment.resend')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -12,6 +12,8 @@ import { snackBar } from '@/shared/lib';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
import { P } from 'node_modules/framer-motion/dist/types.d-Cjd591yU';
|
||||
|
||||
export interface LinkPaymentWaitDetailProps {
|
||||
detailOn: boolean;
|
||||
@@ -38,12 +40,15 @@ export const LinkPaymentWaitDetail = ({
|
||||
mid: mid,
|
||||
requestId: requestId
|
||||
}
|
||||
|
||||
linkPayWaitDetail(detailParam).then((rs: DetailResponse) => {
|
||||
setTitleInfo(rs.titleInfo)
|
||||
setPaymentInfo(rs.paymentInfo)
|
||||
})
|
||||
|
||||
}).catch((e: any) => {
|
||||
if (e.response?.data?.error?.message) {
|
||||
showAlert(e.response?.data?.error?.message);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const deletePayment = () => {
|
||||
@@ -53,11 +58,21 @@ export const LinkPaymentWaitDetail = ({
|
||||
}
|
||||
linkPayWaitDelete(deleteParam)
|
||||
.then((rs) => {
|
||||
callDetail();
|
||||
snackBar(t('additionalService.linkPayment.deleteSuccess'))
|
||||
if (rs.status) {
|
||||
callDetail();
|
||||
snackBar(t('additionalService.linkPayment.deleteSuccess'))
|
||||
} else {
|
||||
const errorMessage = rs.error?.message || t('additionalService.linkPayment.deleteSuccess');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
snackBar(`[${t('common.failed')}] ${error?.response?.data?.message}`)
|
||||
console.log(error)
|
||||
if (error.response?.data?.error?.root !== "SystemErrorCode") {
|
||||
snackBar(`[${t('common.failed')}] ${error?.response?.data?.error?.message}`)
|
||||
} else {
|
||||
showAlert(`[${t('common.failed')}] ${error?.response?.data?.error?.message}`)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -89,52 +104,52 @@ export const LinkPaymentWaitDetail = ({
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if(!!mid && !!requestId){
|
||||
if (!!mid && !!requestId) {
|
||||
callDetail();
|
||||
}
|
||||
}, [mid, requestId]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
animate={(detailOn) ? 'visible' : 'hidden'}
|
||||
variants={DetailMotionVariants}
|
||||
transition={DetailMotionDuration}
|
||||
style={DetailMotionStyle}
|
||||
>
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('additionalService.linkPayment.waitDetailTitle') }</div>
|
||||
<div className="full-menu-title center">{t('additionalService.linkPayment.waitDetailTitle')}</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
onClickToCallback={onClickToClose}
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pay-top">
|
||||
<TitleInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentWait}
|
||||
titleInfo={titleInfo}
|
||||
></TitleInfoWrap>
|
||||
</div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-divider"></div>
|
||||
<PaymentInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentWait}
|
||||
paymentInfo={paymentInfo}
|
||||
></PaymentInfoWrap>
|
||||
</div>
|
||||
<div className="pay-top">
|
||||
<TitleInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentWait}
|
||||
titleInfo={titleInfo}
|
||||
></TitleInfoWrap>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToCancel()}
|
||||
disabled={paymentInfo?.processStatus !== LinkPaymentProcessStatus.SEND_REQUEST}
|
||||
>{t('additionalService.linkPayment.delete')}</button>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-divider"></div>
|
||||
<PaymentInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentWait}
|
||||
paymentInfo={paymentInfo}
|
||||
></PaymentInfoWrap>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToCancel()}
|
||||
disabled={paymentInfo?.processStatus !== LinkPaymentProcessStatus.SEND_REQUEST}
|
||||
>{t('additionalService.linkPayment.delete')}</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -9,6 +9,7 @@ import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
import { DownloadTypeBottomSheet } from '@/entities/common/ui/download-type-bottom-sheet';
|
||||
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
|
||||
export interface PayoutDetailProps {
|
||||
@@ -39,9 +40,13 @@ export const PayoutDetail = ({
|
||||
tid: tid,
|
||||
mid: mid,
|
||||
};
|
||||
|
||||
extensionPayoutDetail(params).then((rs: ExtensionPayoutDetailResponse) => {
|
||||
setDetail(rs);
|
||||
}).catch((e: any) => {
|
||||
if (e.response?.data?.error?.message) {
|
||||
showAlert(e.response?.data?.error?.message);
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -121,71 +126,71 @@ export const PayoutDetail = ({
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">
|
||||
{t('home.money', { value: new Intl.NumberFormat('en-US').format(detail?.disbursementAmount || 0) })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="num-store">{detail?.companyName}</div>
|
||||
<div className="num-day">{detail?.settlementDate}</div>
|
||||
<div className="receipt-row">
|
||||
<button
|
||||
className="receipt-btn"
|
||||
type="button"
|
||||
onClick={onClickToDownload}
|
||||
>
|
||||
<span className="icon-24 download"></span>
|
||||
<span>{t('additionalService.payout.depositCertificate')}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">
|
||||
{t('home.money', { value: new Intl.NumberFormat('en-US').format(detail?.disbursementAmount || 0) })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('additionalService.payout.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.disbursementStatus')}</span>
|
||||
<span className="v">{detail?.disbursementStatus}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.transactionType')}</span>
|
||||
<span className="v">{detail?.transTypeName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('common.requestDate')}</span>
|
||||
<span className="v">{moment(detail?.requestDate).format('YYYY.MM.DD')}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.disbursementDateTime')}</span>
|
||||
<span className="v">{moment(detail?.settlementDateTime, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss')}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.businessNumber')}</span>
|
||||
<span className="v">{detail?.companyNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.accountHolder')}</span>
|
||||
<span className="v">{detail?.accountName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.bank')}</span>
|
||||
<span className="v">{detail?.bankName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.accountNumber')}</span>
|
||||
<span className="v">{detail?.accountNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.depositor')}</span>
|
||||
<span className="v">{detail?.depositName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.failureReason')}</span>
|
||||
<span className="v">{detail?.failReason}</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div className="num-store">{detail?.companyName}</div>
|
||||
<div className="num-day">{detail?.settlementDate}</div>
|
||||
<div className="receipt-row">
|
||||
<button
|
||||
className="receipt-btn"
|
||||
type="button"
|
||||
onClick={onClickToDownload}
|
||||
>
|
||||
<span className="icon-24 download"></span>
|
||||
<span>{t('additionalService.payout.depositCertificate')}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('additionalService.payout.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.disbursementStatus')}</span>
|
||||
<span className="v">{detail?.disbursementStatus}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.transactionType')}</span>
|
||||
<span className="v">{detail?.transTypeName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('common.requestDate')}</span>
|
||||
<span className="v">{moment(detail?.requestDate).format('YYYY.MM.DD')}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.disbursementDateTime')}</span>
|
||||
<span className="v">{moment(detail?.settlementDateTime, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss')}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.businessNumber')}</span>
|
||||
<span className="v">{detail?.companyNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.accountHolder')}</span>
|
||||
<span className="v">{detail?.accountName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.bank')}</span>
|
||||
<span className="v">{detail?.bankName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.accountNumber')}</span>
|
||||
<span className="v">{detail?.accountNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.depositor')}</span>
|
||||
<span className="v">{detail?.depositName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.failureReason')}</span>
|
||||
<span className="v">{detail?.failReason}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<DownloadTypeBottomSheet
|
||||
bottomSheetOn={downloadTypeBottomSheetOn}
|
||||
|
||||
@@ -65,8 +65,8 @@ export const PayoutFilter = ({
|
||||
|
||||
const [filterMid, setFilterMid] = useState<string>(mid);
|
||||
const [filterSearchDateType, setFilterSearchDateType] = useState<PayoutSearchDateType>(searchDateType);
|
||||
const [filterFromDate, setFilterFromDate] = useState<string>(moment(fromDate).format('YYYY.MM.DD'));
|
||||
const [filterToDate, setFilterToDate] = useState<string>(moment(toDate).format('YYYY.MM.DD'));
|
||||
const [filterFromDate, setFilterFromDate] = useState<string>(moment(fromDate).format('YYYYMMDD'));
|
||||
const [filterToDate, setFilterToDate] = useState<string>(moment(toDate).format('YYYYMMDD'));
|
||||
const [filterStatus, setFilterStatus] = useState<PayoutDisbursementStatus>(status);
|
||||
const [filterMinAmount, setFilterMinAmount] = useState<number | undefined>(minAmount);
|
||||
const [filterMaxAmount, setFilterMaxAmount] = useState<number | undefined>(maxAmount);
|
||||
|
||||
@@ -3,8 +3,8 @@ import { useTranslation } from 'react-i18next';
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
import { SmsPaymentDetailResendProps } from '../../../additional-service/model/sms-payment/types';
|
||||
import { useExtensionSmsResendMutation } from '../../api/sms-payment/use-extension-sms-resend-mutation';
|
||||
import appBridge from '@/shared/lib/appBridge';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
export const SmsPaymentDetailResend = ({
|
||||
bottomSmsPaymentDetailResendOn,
|
||||
@@ -19,7 +19,7 @@ export const SmsPaymentDetailResend = ({
|
||||
visible: { y: '0%' },
|
||||
};
|
||||
|
||||
const {mutateAsync : resendMessage } = useExtensionSmsResendMutation();
|
||||
const { mutateAsync: resendMessage } = useExtensionSmsResendMutation();
|
||||
|
||||
const onClickResend = () => {
|
||||
// sendMessage가 없으면 재발송 불가
|
||||
@@ -37,9 +37,13 @@ export const SmsPaymentDetailResend = ({
|
||||
} else {
|
||||
snackBar(t('additionalService.sms.sendFailed', { message: rs.error?.message }))
|
||||
}
|
||||
}).catch((error) => {
|
||||
snackBar(t('additionalService.sms.sendFailed', { message: error?.response?.data?.message || error?.response?.data?.error?.message }) || t('additionalService.sms.sendFailedGeneric'))
|
||||
setBottomSmsPaymentDetailResendOn(false)
|
||||
}).catch((e: any) => {
|
||||
console.log(e)
|
||||
if (e.response?.data?.error?.message) {
|
||||
showAlert(e.response?.data?.error?.message);
|
||||
setBottomSmsPaymentDetailResendOn(false)
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -50,14 +54,14 @@ export const SmsPaymentDetailResend = ({
|
||||
|
||||
return (
|
||||
<>
|
||||
{ bottomSmsPaymentDetailResendOn &&
|
||||
{bottomSmsPaymentDetailResendOn &&
|
||||
<div className="bg-dim"></div>
|
||||
}
|
||||
<motion.div
|
||||
<motion.div
|
||||
className="bottomsheet"
|
||||
initial="hidden"
|
||||
animate={ (bottomSmsPaymentDetailResendOn)? 'visible': 'hidden' }
|
||||
variants={ variants }
|
||||
animate={(bottomSmsPaymentDetailResendOn) ? 'visible' : 'hidden'}
|
||||
variants={variants}
|
||||
transition={{ duration: 0.5 }}
|
||||
>
|
||||
<div className="bottomsheet-header">
|
||||
@@ -68,9 +72,9 @@ export const SmsPaymentDetailResend = ({
|
||||
type="button"
|
||||
>
|
||||
<img
|
||||
src={ IMAGE_ROOT + '/ico_close.svg' }
|
||||
src={IMAGE_ROOT + '/ico_close.svg'}
|
||||
alt={t('common.close')}
|
||||
onClick={ () => onClickToClose() }
|
||||
onClick={() => onClickToClose()}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -26,6 +26,8 @@ import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
import { useExtensionAccessCheck } from '@/shared/lib/hooks/use-extension-access-check';
|
||||
import useIntersectionObserver from '@/widgets/intersection-observer';
|
||||
import { AccountHolderAuthDetail } from '@/entities/additional-service/ui/account-holder-auth/detail/account-holder-auth-detail';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
import { checkGrant } from '@/shared/lib/check-grant';
|
||||
|
||||
export const AccountHolderAuthPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
@@ -63,18 +65,18 @@ export const AccountHolderAuthPage = () => {
|
||||
const { mutateAsync: downloadExcel } = useExtensionAccountHolderAuthDownloadExcelMutation();
|
||||
const onIntersect: IntersectionObserverCallback = (entries: Array<IntersectionObserverEntry>) => {
|
||||
entries.forEach((entry: IntersectionObserverEntry) => {
|
||||
if(entry.isIntersecting){
|
||||
if(onActionIntersect && !!pageParam.cursor){
|
||||
if (entry.isIntersecting) {
|
||||
if (onActionIntersect && !!pageParam.cursor) {
|
||||
setOnActionIntersect(false);
|
||||
callList('page');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const { setTarget } = useIntersectionObserver({
|
||||
threshold: 1,
|
||||
onIntersect
|
||||
const { setTarget } = useIntersectionObserver({
|
||||
threshold: 1,
|
||||
onIntersect
|
||||
});
|
||||
|
||||
const callList = (type?: string) => {
|
||||
@@ -88,37 +90,37 @@ export const AccountHolderAuthPage = () => {
|
||||
...{ sortType: sortType }
|
||||
}
|
||||
};
|
||||
if(type !== 'page' && listParams.page){
|
||||
if (type !== 'page' && listParams.page) {
|
||||
listParams.page.cursor = null;
|
||||
}
|
||||
|
||||
accountHolderAuthList(listParams).then((rs) => {
|
||||
if(type === 'page'){
|
||||
if (type === 'page') {
|
||||
setListItems([
|
||||
...listItems,
|
||||
...rs.content
|
||||
]);
|
||||
}
|
||||
else{
|
||||
else {
|
||||
setListItems(rs.content);
|
||||
}
|
||||
if(rs.hasNext
|
||||
if (rs.hasNext
|
||||
&& rs.nextCursor !== pageParam.cursor
|
||||
&& rs.content.length === DEFAULT_PAGE_PARAM.size
|
||||
){
|
||||
) {
|
||||
setPageParam({
|
||||
...pageParam,
|
||||
...{ cursor: rs.nextCursor }
|
||||
});
|
||||
}
|
||||
else{
|
||||
else {
|
||||
setPageParam({
|
||||
...pageParam,
|
||||
...{ cursor: null }
|
||||
});
|
||||
}
|
||||
setOnActionIntersect(
|
||||
!!rs.hasNext
|
||||
!!rs.hasNext
|
||||
&& rs.nextCursor !== pageParam.cursor
|
||||
&& rs.content.length === DEFAULT_PAGE_PARAM.size
|
||||
);
|
||||
@@ -139,10 +141,10 @@ export const AccountHolderAuthPage = () => {
|
||||
};
|
||||
const setDetailData = (detailData: DetailData) => {
|
||||
setDetailOn(detailData.detailOn);
|
||||
if(detailData.mid){
|
||||
if (detailData.mid) {
|
||||
setDetailMid(detailData.mid);
|
||||
}
|
||||
if(detailData.tid){
|
||||
if (detailData.tid) {
|
||||
setDetailTid(detailData.tid);
|
||||
}
|
||||
};
|
||||
@@ -154,7 +156,7 @@ export const AccountHolderAuthPage = () => {
|
||||
|
||||
const onSendRequest = (selectedEmail?: string) => {
|
||||
if (selectedEmail) {
|
||||
const params: ExtensionAccountHolderAuthDownloadExcelParams = { // 추후 수정필요
|
||||
const params: ExtensionAccountHolderAuthDownloadExcelParams = {
|
||||
mid: mid,
|
||||
email: selectedEmail,
|
||||
fromDate: fromDate,
|
||||
@@ -244,12 +246,12 @@ export const AccountHolderAuthPage = () => {
|
||||
</div>
|
||||
</div>
|
||||
<AccountHolderAuthList
|
||||
additionalServiceCategory={ AdditionalServiceCategory.AccountHolderAuth }
|
||||
listItems={ listItems }
|
||||
mid={ mid }
|
||||
setDetailData={ setDetailData }
|
||||
additionalServiceCategory={AdditionalServiceCategory.AccountHolderAuth}
|
||||
listItems={listItems}
|
||||
mid={mid}
|
||||
setDetailData={setDetailData}
|
||||
></AccountHolderAuthList>
|
||||
<div ref={ setTarget }></div>
|
||||
<div ref={setTarget}></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
@@ -266,10 +268,10 @@ export const AccountHolderAuthPage = () => {
|
||||
setAuthStatus={setAuthStatus}
|
||||
></AccountHolderAuthFilter>
|
||||
<AccountHolderAuthDetail
|
||||
detailOn={ detailOn }
|
||||
setDetailOn={ setDetailOn }
|
||||
mid={ detailMid }
|
||||
tid={ detailTid }
|
||||
detailOn={detailOn}
|
||||
setDetailOn={setDetailOn}
|
||||
mid={detailMid}
|
||||
tid={detailTid}
|
||||
></AccountHolderAuthDetail>
|
||||
<EmailBottomSheet
|
||||
bottomSheetOn={emailBottomSheetOn}
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
useSetHeaderTitle,
|
||||
useSetHeaderType,
|
||||
useSetFooterMode,
|
||||
useSetOnBack
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { AdditionalServiceCategory, DetailInfo, DetailResponse, TitleInfo } from '@/entities/additional-service/model/types';
|
||||
import { TitleInfoWrap } from '@/entities/additional-service/ui/info-wrap/title-info-wrap';
|
||||
import { useLocation } from 'react-router';
|
||||
import { DetailInfoWrap } from '@/entities/additional-service/ui/info-wrap/detail-info-wrap';
|
||||
import { useExtensionAccountHolderAuthDetailMutation } from '@/entities/additional-service/api/account-holder-auth/use-extension-account-holder-auth-deatil-mutation';
|
||||
import { ExtensionAccountHolderAuthDetailParams, ExtensionAccountHolderAuthDetailResponse } from '@/entities/additional-service/model/account-holder-auth/types';
|
||||
import moment from 'moment';
|
||||
import { getAuthStatusText } from '@/entities/additional-service/model/account-holder-auth/constant';
|
||||
import { getAuthResultStatusText } from '@/entities/additional-service/model/face-auth/constant';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const AccountHolderAuthDetailPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
const { mid, tid } = location.state || {};
|
||||
const [detail, setDetail] = useState<ExtensionAccountHolderAuthDetailResponse>();
|
||||
|
||||
useSetHeaderTitle(t('additionalService.accountHolderAuth.detailTitle'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
useSetFooterMode(false);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.additionalService.accountHolderAuth.list);
|
||||
});
|
||||
|
||||
const { mutateAsync: accountHolderAuthDetail } = useExtensionAccountHolderAuthDetailMutation();
|
||||
|
||||
const callDetail = () => {
|
||||
let accountHolderAuthDetailParams: ExtensionAccountHolderAuthDetailParams = {
|
||||
mid: mid,
|
||||
tid: tid
|
||||
}
|
||||
accountHolderAuthDetail(accountHolderAuthDetailParams).then((rs: ExtensionAccountHolderAuthDetailResponse) => {
|
||||
setDetail(rs);
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
callDetail();
|
||||
}, []);
|
||||
|
||||
const getDate = (date?: string) => {
|
||||
return (date) ? moment(date, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '';
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">{detail?.accountName}</span>
|
||||
</div>
|
||||
<span className="num-store">{detail?.accountNo}</span>
|
||||
<div className="num-day">{getDate(detail?.requestDate)}</div>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('transaction.sections.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.companyName')}</span>
|
||||
<span className="v">{detail?.companyName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.mid')}</span>
|
||||
<span className="v">{detail?.mid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.accountHolderAuth.requestDate')}</span>
|
||||
<span className="v">{getDate(detail?.requestDate)}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.bank')}</span>
|
||||
<span className="v">{detail?.bankName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.accountNo')}</span>
|
||||
<span className="v">{detail?.accountNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.accountHolder')}</span>
|
||||
<span className="v">{detail?.accountName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('common.result')}</span>
|
||||
<span className="v">{getAuthStatusText(t)(detail?.authStatus)}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.failureReason')}</span>
|
||||
<span className="v">{detail?.failReason ? getAuthResultStatusText(t)(detail?.failReason) : '-' }</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main >
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -27,6 +27,8 @@ import { useExtensionAccessCheck } from '@/shared/lib/hooks/use-extension-access
|
||||
import useIntersectionObserver from '@/widgets/intersection-observer';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
import { AccountHolderSearchDetail } from '@/entities/additional-service/ui/account-holder-search/detail/account-holder-search-detail';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
import { checkGrant } from '@/shared/lib/check-grant';
|
||||
|
||||
export const AccountHolderSearchPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
@@ -176,10 +178,10 @@ export const AccountHolderSearchPage = () => {
|
||||
|
||||
const setDetailData = (detailData: DetailData) => {
|
||||
setDetailOn(detailData.detailOn);
|
||||
if(detailData.mid){
|
||||
if (detailData.mid) {
|
||||
setDetailMid(detailData.mid);
|
||||
}
|
||||
if(detailData.tid){
|
||||
if (detailData.tid) {
|
||||
setDetailTid(detailData.tid);
|
||||
}
|
||||
};
|
||||
@@ -262,9 +264,9 @@ export const AccountHolderSearchPage = () => {
|
||||
</div>
|
||||
</div>
|
||||
<AccountHolderSearchList
|
||||
listItems={ listItems }
|
||||
mid={ mid }
|
||||
setDetailData={ setDetailData }
|
||||
listItems={listItems}
|
||||
mid={mid}
|
||||
setDetailData={setDetailData}
|
||||
></AccountHolderSearchList>
|
||||
<div ref={setTarget}></div>
|
||||
</div>
|
||||
@@ -289,10 +291,10 @@ export const AccountHolderSearchPage = () => {
|
||||
setResultStatus={setResultStatus}
|
||||
></AccountHolderSearchFilter>
|
||||
<AccountHolderSearchDetail
|
||||
detailOn={ detailOn }
|
||||
setDetailOn={ setDetailOn }
|
||||
mid={ detailMid }
|
||||
tid={ detailTid }
|
||||
detailOn={detailOn}
|
||||
setDetailOn={setDetailOn}
|
||||
mid={detailMid}
|
||||
tid={detailTid}
|
||||
></AccountHolderSearchDetail>
|
||||
<EmailBottomSheet
|
||||
bottomSheetOn={emailBottomSheetOn}
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
import moment from 'moment';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
useSetHeaderTitle,
|
||||
useSetHeaderType,
|
||||
useSetFooterMode,
|
||||
useSetOnBack
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { AdditionalServiceCategory, DetailInfo, DetailResponse, TitleInfo } from '@/entities/additional-service/model/types';
|
||||
import { TitleInfoWrap } from '@/entities/additional-service/ui/info-wrap/title-info-wrap';
|
||||
import { useLocation } from 'react-router';
|
||||
import { DetailInfoWrap } from '@/entities/additional-service/ui/info-wrap/detail-info-wrap';
|
||||
import { ExtensionAccountHolderSearchDetailParams, ExtensionAccountHolderSearchDetailResponse } from '@/entities/additional-service/model/account-holder-search/types';
|
||||
import { useExtensionAccountHolderSearchDetailtMutation } from '@/entities/additional-service/api/account-holder-search/use-extension-account-holder-search-detail-mutation';
|
||||
import { getAccountHolderStatusText } from '@/entities/additional-service/model/account-holder-search/constant';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const AccountHolderSearchDetailPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
|
||||
const { mid, tid } = location.state || {};
|
||||
|
||||
const [detail, setDetail] = useState<ExtensionAccountHolderSearchDetailResponse>();
|
||||
|
||||
useSetHeaderTitle(t('additionalService.accountHolderSearch.detailTitle'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
useSetFooterMode(false);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.additionalService.accountHolderSearch.list);
|
||||
});
|
||||
|
||||
const { mutateAsync: accountHolderSearchDetail } = useExtensionAccountHolderSearchDetailtMutation();
|
||||
|
||||
const callDetail = () => {
|
||||
let accountHolderSearchDetailParams: ExtensionAccountHolderSearchDetailParams = {
|
||||
mid: mid,
|
||||
tid: tid
|
||||
}
|
||||
accountHolderSearchDetail(accountHolderSearchDetailParams).then((rs: ExtensionAccountHolderSearchDetailResponse) => {
|
||||
setDetail(rs);
|
||||
});
|
||||
};
|
||||
|
||||
const getDate = (date?: string) => {
|
||||
return (date) ? moment(date, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '';
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
callDetail();
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">{detail?.accountNo}</span>
|
||||
</div>
|
||||
<span className="num-day">{detail?.bankName}</span>
|
||||
<div className="num-day">{getDate(detail?.requestDate)}</div>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('transaction.sections.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.accountHolder')}</span>
|
||||
<span className="v">{detail?.accountName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.accountHolderAuth.requestDate')}</span>
|
||||
<span className="v">{getDate(detail?.requestDate)}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('common.result')}</span>
|
||||
<span className="v">{getAccountHolderStatusText(t)(detail?.resultStatus)}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.failureReason')}</span>
|
||||
<span className="v">{detail?.failReason ? detail?.failReason : '-' }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.bank')}</span>
|
||||
<span className="v">{detail?.bankName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.accountNo')}</span>
|
||||
<span className="v">{detail?.accountNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.accountHolderAuth.requestWay')}</span>
|
||||
<span className="v">{detail?.requestWay}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main >
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import { useStore } from '@/shared/model/store';
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
export const AccountHolderSearchRequestPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
@@ -73,12 +74,13 @@ export const AccountHolderSearchRequestPage = () => {
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error("Account holder search request failed: ", error)
|
||||
const errorMessage = error?.response?.data?.error?.message ||
|
||||
error?.message ||
|
||||
t('common.errorOccurred');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
.catch((e) => {
|
||||
const errorMessage = e?.response?.data?.error?.message || e?.message ||t('common.errorOccurred');
|
||||
if (e.response?.data?.error?.root !== "SystemErrorCode") {
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
} else {
|
||||
showAlert(`[${t('common.failed')}] ${errorMessage}`)
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import { SentryRoutes } from '@/shared/configs/sentry';
|
||||
import { ROUTE_NAMES } from '@/shared/constants/route-names';
|
||||
import { ListPage } from './list-page';
|
||||
import { ArsListPage } from './ars/list-page';
|
||||
import { ArsDetailPage } from './ars/detail-page';
|
||||
import { ArsRequestPage } from './ars/request-page';
|
||||
import { ArsRequestSuccessPage } from './ars/request-success-page';
|
||||
import { KeyInPaymentPage } from './key-in-payment/key-in-payment-page';
|
||||
@@ -27,8 +26,6 @@ import { PayoutRequestPage } from './payout/request-page';
|
||||
import { LinkPaymentApplyPage } from './link-payment/apply/link-payment-apply-page';
|
||||
import { LinkPaymentApplyConfirmPage } from './link-payment/apply/link-payment-apply-confirm-page';
|
||||
import { LinkPaymentApplySuccessPage } from './link-payment/apply/link-payment-apply-success-page';
|
||||
import { LinkPaymentDetailPage } from './link-payment/link-payment-detail-page';
|
||||
import { LinkPaymentWaitDetailPage } from './link-payment/link-payment-wait-detail-page';
|
||||
import { KeyInPaymentRequestPage } from './key-in-payment/requeset-page';
|
||||
import { KeyInPaymentRequestSuccessPage } from './key-in-payment/request-success-page';
|
||||
import { AccountHolderSearchRequestPage } from './account-holder-search/request-page';
|
||||
@@ -63,8 +60,6 @@ export const AdditionalServicePages = () => {
|
||||
<Route path={ROUTE_NAMES.additionalService.linkPayment.request} element={<LinkPaymentApplyPage />} />
|
||||
<Route path={ROUTE_NAMES.additionalService.linkPayment.requestConfirm} element={<LinkPaymentApplyConfirmPage />} />
|
||||
<Route path={ROUTE_NAMES.additionalService.linkPayment.confirmSuccess} element={<LinkPaymentApplySuccessPage />} />
|
||||
<Route path={ROUTE_NAMES.additionalService.linkPayment.detail} element={<LinkPaymentDetailPage />} />
|
||||
<Route path={ROUTE_NAMES.additionalService.linkPayment.pendingDetail} element={<LinkPaymentWaitDetailPage />} />
|
||||
<Route path={ROUTE_NAMES.additionalService.linkPayment.separateApproval} element={<LinkPaymentSeparateApprovalPage />} />
|
||||
</Route>
|
||||
<Route path={ROUTE_NAMES.additionalService.alimtalk.base}>
|
||||
|
||||
@@ -24,6 +24,7 @@ import { AlimTalkSettingServiceRow } from '@/entities/additional-service/ui/alim
|
||||
import { useStore } from '@/shared/model/store';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
export const AlimtalkSettingPage = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -79,171 +80,185 @@ export const AlimtalkSettingPage = () => {
|
||||
setUserVirtureAccountDepositCompleteFlag(sendUserInfo?.virtureAccountDepositCompleteFlag || false);
|
||||
setUserVirtureAccountRefundFlag(sendUserInfo?.virtureAccountRefundFlag || false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const callSettingSave = () => {
|
||||
let params: ExtensionAlimtalkSettingSaveParams = {
|
||||
mid: mid,
|
||||
sendMerchantInfo: {
|
||||
cardApprovalFlag: merchantCardApprovalFlag,
|
||||
cardCancelFlag: merchantCardCancelFlag,
|
||||
bankApprovalFlag: merchantBankApprovalFlag,
|
||||
bankCancelFlag: merchantBankCancelFlag,
|
||||
virtureAccountDepositRequestFlag: merchantVirtureAccountDepositRequestFlag,
|
||||
virtureAccountDepositCompleteFlag: merchantVirtureAccountDepositCompleteFlag,
|
||||
virtureAccountRefundFlag: merchantVirtureAccountRefundFlag
|
||||
},
|
||||
sendUserInfo: {
|
||||
cardApprovalFlag: userCardApprovalFlag,
|
||||
cardCancelFlag: userCardCancelFlag,
|
||||
bankApprovalFlag: userBankApprovalFlag,
|
||||
bankCancelFlag: userBankCancelFlag,
|
||||
virtureAccountDepositRequestFlag: userVirtureAccountDepositRequestFlag,
|
||||
virtureAccountDepositCompleteFlag: userVirtureAccountDepositCompleteFlag,
|
||||
virtureAccountRefundFlag: userVirtureAccountRefundFlag
|
||||
},
|
||||
};
|
||||
alimtalkSettingSave(params)
|
||||
.then((rs) => {
|
||||
snackBar(t('additionalService.alimtalk.saveSuccess'));
|
||||
})
|
||||
.catch((error) => {
|
||||
const failReason = error?.response?.data?.message || error?.message || t('additionalService.alimtalk.unknownError');
|
||||
snackBar(`[${t('common.failed')}] ${failReason}`);
|
||||
});
|
||||
};
|
||||
|
||||
useSetHeaderTitle(t('additionalService.alimtalk.title'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
useSetFooterMode(false);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.additionalService.alimtalk.list);
|
||||
});
|
||||
|
||||
const onClickToSave = () => {
|
||||
callSettingSave();
|
||||
};
|
||||
|
||||
// MID 초기값 설정
|
||||
useEffect(() => {
|
||||
if (!mid && midOptionsWithoutGids.length > 0) {
|
||||
// userMid가 옵션에 있으면 userMid 사용, 없으면 첫 번째 옵션 사용
|
||||
const midItem = midOptionsWithoutGids.filter((value) => value.value === userMid);
|
||||
const initialMid = (midItem.length > 0) ? userMid : midOptionsWithoutGids[0]?.value || '';
|
||||
if (initialMid) {
|
||||
setMid(initialMid);
|
||||
}).catch((e: any) => {
|
||||
if (e.response?.data.error?.message) {
|
||||
showAlert(e.response?.data?.error?.message);
|
||||
return
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const callSettingSave = () => {
|
||||
let params: ExtensionAlimtalkSettingSaveParams = {
|
||||
mid: mid,
|
||||
sendMerchantInfo: {
|
||||
cardApprovalFlag: merchantCardApprovalFlag,
|
||||
cardCancelFlag: merchantCardCancelFlag,
|
||||
bankApprovalFlag: merchantBankApprovalFlag,
|
||||
bankCancelFlag: merchantBankCancelFlag,
|
||||
virtureAccountDepositRequestFlag: merchantVirtureAccountDepositRequestFlag,
|
||||
virtureAccountDepositCompleteFlag: merchantVirtureAccountDepositCompleteFlag,
|
||||
virtureAccountRefundFlag: merchantVirtureAccountRefundFlag
|
||||
},
|
||||
sendUserInfo: {
|
||||
cardApprovalFlag: userCardApprovalFlag,
|
||||
cardCancelFlag: userCardCancelFlag,
|
||||
bankApprovalFlag: userBankApprovalFlag,
|
||||
bankCancelFlag: userBankCancelFlag,
|
||||
virtureAccountDepositRequestFlag: userVirtureAccountDepositRequestFlag,
|
||||
virtureAccountDepositCompleteFlag: userVirtureAccountDepositCompleteFlag,
|
||||
virtureAccountRefundFlag: userVirtureAccountRefundFlag
|
||||
},
|
||||
};
|
||||
alimtalkSettingSave(params)
|
||||
.then((rs) => {
|
||||
if (rs.status) {
|
||||
snackBar(t('additionalService.alimtalk.saveSuccess'));
|
||||
} else {
|
||||
snackBar(`[${t('common.failed')}] ${rs.error?.message}`)
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
const failReason = e?.response?.data?.message || e?.message || t('additionalService.alimtalk.unknownError');
|
||||
console.log(e)
|
||||
if (e.response?.data?.error?.root !== "SystemErrorCode") {
|
||||
snackBar(`[${t('common.failed')}] ${failReason}`);
|
||||
} else {
|
||||
showAlert(`[${t('common.failed')}] ${failReason}`)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
useSetHeaderTitle(t('additionalService.alimtalk.title'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
useSetFooterMode(false);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.additionalService.alimtalk.list);
|
||||
});
|
||||
|
||||
const onClickToSave = () => {
|
||||
callSettingSave();
|
||||
};
|
||||
|
||||
// MID 초기값 설정
|
||||
useEffect(() => {
|
||||
if (!mid && midOptionsWithoutGids.length > 0) {
|
||||
// userMid가 옵션에 있으면 userMid 사용, 없으면 첫 번째 옵션 사용
|
||||
const midItem = midOptionsWithoutGids.filter((value) => value.value === userMid);
|
||||
const initialMid = (midItem.length > 0) ? userMid : midOptionsWithoutGids[0]?.value || '';
|
||||
if (initialMid) {
|
||||
setMid(initialMid);
|
||||
}
|
||||
}, [midOptionsWithoutGids, userMid]);
|
||||
}
|
||||
}, [midOptionsWithoutGids, userMid]);
|
||||
|
||||
// mid가 설정되면 설정 정보 불러오기
|
||||
useEffect(() => {
|
||||
if (mid) {
|
||||
callSettingDetail();
|
||||
}
|
||||
}, [mid]);
|
||||
// mid가 설정되면 설정 정보 불러오기
|
||||
useEffect(() => {
|
||||
if (mid) {
|
||||
callSettingDetail();
|
||||
}
|
||||
}, [mid]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="option-list">
|
||||
<div className="service-settings">
|
||||
<div className="service-notice">
|
||||
<div>{t('additionalService.alimtalk.settingNotice1')}</div>
|
||||
<div>{t('additionalService.alimtalk.settingNotice2')}</div>
|
||||
</div>
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="option-list">
|
||||
<div className="service-settings">
|
||||
<div className="service-notice">
|
||||
<div>{t('additionalService.alimtalk.settingNotice1')}</div>
|
||||
<div>{t('additionalService.alimtalk.settingNotice2')}</div>
|
||||
</div>
|
||||
|
||||
<div className="service-merchant">
|
||||
<div className="service-title">{t('additionalService.alimtalk.merchant')}</div>
|
||||
<div className="service-select">
|
||||
<select
|
||||
value={mid}
|
||||
onChange={(e) => setMid(e.target.value)}>
|
||||
{
|
||||
midOptionsWithoutGids.map((value) => (
|
||||
<option
|
||||
key={value.value}
|
||||
value={value.value}
|
||||
>{value.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
<span className="ic20 arrow-down" aria-hidden="true"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="service-section">
|
||||
<div className="service-row align-right">
|
||||
<span>{t('additionalService.alimtalk.sendToMerchant')}</span>
|
||||
<span>{t('additionalService.alimtalk.sendToCustomer')}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="service-section">
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.creditCardApproval')}
|
||||
merchantFlag={merchantCardApprovalFlag}
|
||||
userFlag={userCardApprovalFlag}
|
||||
setMerchantFlag={setMerchantCardApprovalFlag}
|
||||
setUserFlag={setUserCardApprovalFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.creditCardCancel')}
|
||||
merchantFlag={merchantCardCancelFlag}
|
||||
userFlag={userCardCancelFlag}
|
||||
setMerchantFlag={setMerchantCardCancelFlag}
|
||||
setUserFlag={setUserCardCancelFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.bankTransferApproval')}
|
||||
merchantFlag={merchantBankApprovalFlag}
|
||||
userFlag={userBankApprovalFlag}
|
||||
setMerchantFlag={setMerchantBankApprovalFlag}
|
||||
setUserFlag={setUserBankApprovalFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.bankTransferCancel')}
|
||||
merchantFlag={merchantBankCancelFlag}
|
||||
userFlag={userBankCancelFlag}
|
||||
setMerchantFlag={setMerchantBankCancelFlag}
|
||||
setUserFlag={setUserBankCancelFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.virtualAccountDepositRequest')}
|
||||
merchantFlag={merchantVirtureAccountDepositRequestFlag}
|
||||
userFlag={userVirtureAccountDepositRequestFlag}
|
||||
setMerchantFlag={setMerchantVirtureAccountDepositRequestFlag}
|
||||
setUserFlag={setUserVirtureAccountDepositRequestFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.virtualAccountDepositComplete')}
|
||||
merchantFlag={merchantVirtureAccountDepositCompleteFlag}
|
||||
userFlag={userVirtureAccountDepositCompleteFlag}
|
||||
setMerchantFlag={setMerchantVirtureAccountDepositCompleteFlag}
|
||||
setUserFlag={setUserVirtureAccountDepositCompleteFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.virtualAccountRefund')}
|
||||
merchantFlag={merchantVirtureAccountRefundFlag}
|
||||
userFlag={userVirtureAccountRefundFlag}
|
||||
setMerchantFlag={setMerchantVirtureAccountRefundFlag}
|
||||
setUserFlag={setUserVirtureAccountRefundFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<div className="service-merchant">
|
||||
<div className="service-title">{t('additionalService.alimtalk.merchant')}</div>
|
||||
<div className="service-select">
|
||||
<select
|
||||
value={mid}
|
||||
onChange={(e) => setMid(e.target.value)}>
|
||||
{
|
||||
midOptionsWithoutGids.map((value) => (
|
||||
<option
|
||||
key={value.value}
|
||||
value={value.value}
|
||||
>{value.name}</option>
|
||||
))
|
||||
}
|
||||
</select>
|
||||
<span className="ic20 arrow-down" aria-hidden="true"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToSave()}
|
||||
>{t('common.save')}</button>
|
||||
|
||||
<div className="service-section">
|
||||
<div className="service-row align-right">
|
||||
<span>{t('additionalService.alimtalk.sendToMerchant')}</span>
|
||||
<span>{t('additionalService.alimtalk.sendToCustomer')}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="service-section">
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.creditCardApproval')}
|
||||
merchantFlag={merchantCardApprovalFlag}
|
||||
userFlag={userCardApprovalFlag}
|
||||
setMerchantFlag={setMerchantCardApprovalFlag}
|
||||
setUserFlag={setUserCardApprovalFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.creditCardCancel')}
|
||||
merchantFlag={merchantCardCancelFlag}
|
||||
userFlag={userCardCancelFlag}
|
||||
setMerchantFlag={setMerchantCardCancelFlag}
|
||||
setUserFlag={setUserCardCancelFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.bankTransferApproval')}
|
||||
merchantFlag={merchantBankApprovalFlag}
|
||||
userFlag={userBankApprovalFlag}
|
||||
setMerchantFlag={setMerchantBankApprovalFlag}
|
||||
setUserFlag={setUserBankApprovalFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.bankTransferCancel')}
|
||||
merchantFlag={merchantBankCancelFlag}
|
||||
userFlag={userBankCancelFlag}
|
||||
setMerchantFlag={setMerchantBankCancelFlag}
|
||||
setUserFlag={setUserBankCancelFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.virtualAccountDepositRequest')}
|
||||
merchantFlag={merchantVirtureAccountDepositRequestFlag}
|
||||
userFlag={userVirtureAccountDepositRequestFlag}
|
||||
setMerchantFlag={setMerchantVirtureAccountDepositRequestFlag}
|
||||
setUserFlag={setUserVirtureAccountDepositRequestFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.virtualAccountDepositComplete')}
|
||||
merchantFlag={merchantVirtureAccountDepositCompleteFlag}
|
||||
userFlag={userVirtureAccountDepositCompleteFlag}
|
||||
setMerchantFlag={setMerchantVirtureAccountDepositCompleteFlag}
|
||||
setUserFlag={setUserVirtureAccountDepositCompleteFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
<AlimTalkSettingServiceRow
|
||||
title={t('additionalService.alimtalk.virtualAccountRefund')}
|
||||
merchantFlag={merchantVirtureAccountRefundFlag}
|
||||
userFlag={userVirtureAccountRefundFlag}
|
||||
setMerchantFlag={setMerchantVirtureAccountRefundFlag}
|
||||
setUserFlag={setUserVirtureAccountRefundFlag}
|
||||
></AlimTalkSettingServiceRow>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToSave()}
|
||||
>{t('common.save')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,181 +0,0 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
useSetHeaderTitle,
|
||||
useSetHeaderType,
|
||||
useSetFooterMode,
|
||||
useSetOnBack
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { useLocation } from 'react-router';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { useExtensionArsDetailMutation } from '@/entities/additional-service/api/ars/use-extension-ars-detail-mutation';
|
||||
import {
|
||||
ExtensionArsDetailParams,
|
||||
ExtensionArsDetailResponse,
|
||||
ExtensionArsResendParams,
|
||||
ExtensionArsResendResponse,
|
||||
ArsPaymentMethod,
|
||||
OrderStatus
|
||||
} from '@/entities/additional-service/model/ars/types';
|
||||
import moment from 'moment';
|
||||
import { ArsResendSmsBottomSheet } from '@/entities/additional-service/ui/ars/resend-sms-bottom-sheet';
|
||||
import { useExtensionArsResendMutation } from '@/entities/additional-service/api/ars/use-extension-ars-resend-mutation';
|
||||
import { getArsOrderStatusName, getArsPaymentStatusName } from '@/entities/additional-service/model/ars/constant';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
|
||||
export const ArsDetailPage = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const tid = location.state.tid;
|
||||
const mid = location.state.mid;
|
||||
|
||||
const [detail, setDetail] = useState<ExtensionArsDetailResponse>();
|
||||
const [bottomSheetOn, setBottomSheetOn] = useState<boolean>(false);
|
||||
|
||||
const { mutateAsync: extensionArsDetail } = useExtensionArsDetailMutation();
|
||||
const { mutateAsync: extensionArsResend } = useExtensionArsResendMutation();
|
||||
const callDetail = () => {
|
||||
let params: ExtensionArsDetailParams = {
|
||||
tid: tid,
|
||||
mid: mid,
|
||||
};
|
||||
|
||||
extensionArsDetail(params).then((rs: ExtensionArsDetailResponse) => {
|
||||
setDetail(rs);
|
||||
});
|
||||
};
|
||||
|
||||
useSetHeaderTitle('ARS 결제 상세');
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
useSetFooterMode(false);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.additionalService.ars.list);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
callDetail();
|
||||
}, []);
|
||||
|
||||
const onClickToOpenResendBottomSheet = () => {
|
||||
setBottomSheetOn(true);
|
||||
};
|
||||
|
||||
const getDate = (date?: string) => {
|
||||
return (date)? moment(date.substr(0, 8)).format('YYYY.MM.DD'): '';
|
||||
};
|
||||
|
||||
const callResendSms = () => {
|
||||
let params: ExtensionArsResendParams = {
|
||||
mid: mid,
|
||||
tid: tid
|
||||
}
|
||||
extensionArsResend(params).then((rs: ExtensionArsResendResponse) => {
|
||||
if (rs.status) {
|
||||
snackBar("SMS 재전송을 성공하였습니다.");
|
||||
setBottomSheetOn(false);
|
||||
callDetail(); // 상세 정보 갱신
|
||||
} else {
|
||||
const errorMessage = rs.error?.message || 'SMS 재전송이 실패하였습니다.';
|
||||
snackBar(`[실패] ${errorMessage}`);
|
||||
}
|
||||
}).catch((error) => {
|
||||
const errorMessage = error?.response?.data?.error?.message ||
|
||||
error?.message ||
|
||||
'SMS 재전송 중 오류가 발생했습니다.';
|
||||
snackBar(`[실패] ${errorMessage}`);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<main className="full-height">
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">
|
||||
{t('home.money', { value: new Intl.NumberFormat('en-US').format(Number(detail?.amount) || 0) })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="num-store">{ detail?.corpName }</div>
|
||||
<div className="num-day">{ getDate(detail?.paymentDate) }</div>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">거래 정보</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">MID</span>
|
||||
<span className="v">{ detail?.mid }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">결제방식</span>
|
||||
<span className="v">{ detail?.arsPaymentMethod }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">결제상태</span>
|
||||
<span className="v">{ getArsPaymentStatusName(t)(detail?.paymentStatus) }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">주문상태</span>
|
||||
<span className="v">{ getArsOrderStatusName(t)(detail?.orderStatus) }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">주문일시</span>
|
||||
<span className="v">{
|
||||
detail?.paymentDate ? moment(detail.paymentDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '-'
|
||||
}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">상품명</span>
|
||||
<span className="v">{ detail?.goodsName }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">주문번호</span>
|
||||
<span className="v">{ detail?.tid }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">구매자</span>
|
||||
<span className="v">{ detail?.buyerName }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">휴대폰번호</span>
|
||||
<span className="v">{ detail?.maskPhoneNumber }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">이메일</span>
|
||||
<span className="v">{ detail?.email }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">발송 인증번호</span>
|
||||
<span className="v">{ detail?.smsVerificationCode }</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{detail?.arsPaymentMethod === ArsPaymentMethod.SMS && (
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToOpenResendBottomSheet() }
|
||||
//disabled={ detail?.orderStatus !== OrderStatus.PENDING }
|
||||
>SMS 재전송</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<ArsResendSmsBottomSheet
|
||||
setBottomSheetOn={ setBottomSheetOn }
|
||||
bottomSheetOn={ bottomSheetOn }
|
||||
phoneNumber={ detail?.phoneNumber }
|
||||
callResendSms={ callResendSms }
|
||||
></ArsResendSmsBottomSheet>
|
||||
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -17,6 +17,7 @@ import { ArsRequestSuccessPage } from './request-success-page';
|
||||
import { useStore } from '@/shared/model/store';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
import { NumericFormat, PatternFormat } from 'react-number-format';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
export const ArsRequestPage = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -69,9 +70,13 @@ export const ArsRequestPage = () => {
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
const errorMsg = error?.response?.data?.message || error?.response?.data?.error?.message || t('additionalService.ars.requestFailed');
|
||||
snackBar(`[${t('common.failed')}] ${errorMsg}`);
|
||||
.catch((e) => {
|
||||
const errorMsg = e?.response?.data?.message || e?.response?.data?.error?.message || t('additionalService.ars.requestFailed');
|
||||
if (e.response?.data?.error?.root !== "SystemErrorCode") {
|
||||
snackBar(`[${t('common.failed')}] ${errorMsg}`);
|
||||
} else {
|
||||
showAlert(`[${t('common.failed')}] ${errorMsg}`)
|
||||
}
|
||||
})
|
||||
|
||||
};
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
useSetHeaderTitle,
|
||||
useSetHeaderType,
|
||||
useSetFooterMode,
|
||||
useSetOnBack
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { useLocation } from 'react-router';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import {
|
||||
ExtensionFundAccountDownloadReceiptParams,
|
||||
ExtensionFundAccountDownloadReceiptResponse,
|
||||
ExtensionFundAccountResultDetailParams,
|
||||
ExtensionFundAccountResultDetailResponse,
|
||||
} from '@/entities/additional-service/model/fund-account/types';
|
||||
import moment from 'moment';
|
||||
import { useExtensionFundAccountResultDetailMutation } from '@/entities/additional-service/api/fund-account/use-extension-fund-account-result-detail-mutation';
|
||||
import { useExtensionFundAccountDownloadReceiptMutation } from '@/entities/additional-service/api/fund-account/use-extension-fund-account-download-certificate-mutation';
|
||||
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
|
||||
export const FundAccountResultDetailPage = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const tid = location.state.tid;
|
||||
const mid = location.state.mid;
|
||||
|
||||
const [detail, setDetail] = useState<ExtensionFundAccountResultDetailResponse>();
|
||||
const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false);
|
||||
|
||||
const { mutateAsync: extensionFundAccountResultDetail } = useExtensionFundAccountResultDetailMutation();
|
||||
const { mutateAsync: extensionFundAccountDownlaodReceipt } = useExtensionFundAccountDownloadReceiptMutation();
|
||||
|
||||
const callDetail = () => {
|
||||
let params: ExtensionFundAccountResultDetailParams = {
|
||||
mid: mid,
|
||||
tid: tid,
|
||||
};
|
||||
|
||||
extensionFundAccountResultDetail(params).then((rs: ExtensionFundAccountResultDetailResponse) => {
|
||||
console.log(rs.requestDate)
|
||||
setDetail(rs);
|
||||
});
|
||||
};
|
||||
|
||||
const onClickToOpenEmailBottomSheet = () => {
|
||||
setEmailBottomSheetOn(true);
|
||||
};
|
||||
|
||||
const onSendRequest = (selectedEmail?: string) => {
|
||||
if (selectedEmail) {
|
||||
let params: ExtensionFundAccountDownloadReceiptParams = {
|
||||
mid: mid,
|
||||
tid: tid,
|
||||
email: selectedEmail
|
||||
};
|
||||
extensionFundAccountDownlaodReceipt(params).then((rs: ExtensionFundAccountDownloadReceiptResponse) => {
|
||||
console.log('Receipt Download Status:', rs);
|
||||
});
|
||||
}
|
||||
setEmailBottomSheetOn(false);
|
||||
};
|
||||
|
||||
useSetHeaderTitle(t('additionalService.fundAccount.transferDetailTitle'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
useSetFooterMode(false);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.additionalService.fundAccount.resultList);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
callDetail();
|
||||
console.log(detail?.requestDate)
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<main className="full-height">
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">
|
||||
{t('home.money', { value: new Intl.NumberFormat('en-US').format(detail?.amount || 0) })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="num-store">{detail?.accountName}({detail?.accountNo})</div>
|
||||
{detail?.applicationDate && (
|
||||
<div className="num-day"> {moment(detail?.applicationDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss')}</div>
|
||||
)}
|
||||
</div>
|
||||
{/* ✅ resultMessage가 "정상"일 때만 표시 */}
|
||||
{detail?.resultMessage === '정상' && (
|
||||
<div className="receipt-row">
|
||||
<button
|
||||
type="button"
|
||||
className="receipt-btn"
|
||||
onClick={ onClickToOpenEmailBottomSheet }
|
||||
>
|
||||
<span className="icon-24 download"></span>
|
||||
<span>{t('additionalService.fundAccount.depositCertificate')}</span>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('additionalService.fundAccount.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.requestDateTime')}</span>
|
||||
<span className="v">{moment(detail?.requestDate,'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss')}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.transferDateTime')}</span>
|
||||
<span className="v">{detail?.applicationDate ? moment(detail?.applicationDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.transferResult')}</span>
|
||||
<span className="v">{detail?.resultMessage || '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.failureReason')}</span>
|
||||
<span className="v">{detail?.failReason || '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.beneficiaryName')}</span>
|
||||
<span className="v">{detail?.accountName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.bank')}</span>
|
||||
<span className="v">{detail?.bankName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.accountNumber')}</span>
|
||||
<span className="v">{detail?.accountNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">MID</span>
|
||||
<span className="v">{mid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('transaction.fields.orderNumber')}</span>
|
||||
<span className="v">{detail?.moid}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">TID</span>
|
||||
<span className="v">{detail?.tid}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<EmailBottomSheet
|
||||
bottomSheetOn={emailBottomSheetOn}
|
||||
setBottomSheetOn={setEmailBottomSheetOn}
|
||||
imageSave={false}
|
||||
sendEmail={true}
|
||||
sendRequest={onSendRequest}
|
||||
></EmailBottomSheet>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,145 +0,0 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
useSetHeaderTitle,
|
||||
useSetHeaderType,
|
||||
useSetFooterMode,
|
||||
useSetOnBack
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { useLocation } from 'react-router';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { useExtensionFundAccountTransferDetailMutation } from '@/entities/additional-service/api/fund-account/use-extension-fund-account-transfer-detail-mutation';
|
||||
import { ExtensionFundAccountTransferDetailParams, ExtensionFundAccountTransferDetailResponse, ExtensionFundAccountTransferRegistParams, ExtensionFundAccountTransferRequestParams, ExtensionFundAccountTransferRequestResponse, FundAccountStatus } from '@/entities/additional-service/model/fund-account/types';
|
||||
import { getFundAccountStatusName } from '@/entities/additional-service/model/fund-account/constant';
|
||||
import moment from 'moment';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
import { useExtensionFundAccountTransferRequestMutation } from '@/entities/additional-service/api/fund-account/use-extension-fund-account-transfer-request-mutation';
|
||||
|
||||
export const FundAccountTransferDetailPage = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const seq = location.state.seq;
|
||||
|
||||
const [detail, setDetail] = useState<ExtensionFundAccountTransferDetailResponse>();
|
||||
|
||||
const { mutateAsync: extensionFundAccountTransferDetail } = useExtensionFundAccountTransferDetailMutation();
|
||||
const { mutateAsync: extensionFundAccountTransferRequest } = useExtensionFundAccountTransferRequestMutation();
|
||||
|
||||
const callDetail = () => {
|
||||
let params: ExtensionFundAccountTransferDetailParams = {
|
||||
seq: seq
|
||||
};
|
||||
|
||||
extensionFundAccountTransferDetail(params).then((rs: ExtensionFundAccountTransferDetailResponse) => {
|
||||
setDetail(rs);
|
||||
});
|
||||
};
|
||||
|
||||
useSetHeaderTitle(t('additionalService.fundAccount.transferDetailTitle'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
useSetFooterMode(false);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.additionalService.fundAccount.transferList);
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
callDetail();
|
||||
}, []);
|
||||
|
||||
const onClickToRequest = () => {
|
||||
let params: ExtensionFundAccountTransferRequestParams = {
|
||||
seq: seq
|
||||
};
|
||||
extensionFundAccountTransferRequest(params).then((rs: ExtensionFundAccountTransferRequestResponse) => {
|
||||
if (rs.status) {
|
||||
callDetail();
|
||||
snackBar(t('additionalService.fundAccount.transferRequestSuccess'))
|
||||
} else {
|
||||
const errorMessage = rs.error?.message || t('additionalService.fundAccount.transferRequestFailed');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
}
|
||||
}).catch((error) => {
|
||||
const errorMessage = error?.response?.data?.error?.message ||
|
||||
error?.message ||
|
||||
t('additionalService.fundAccount.transferRequestError');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<main className="full-height">
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">
|
||||
{t('home.money', { value: new Intl.NumberFormat('en-US').format(detail?.amount || 0) })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="num-store">{detail?.accountName}({detail?.accountNo})</div>
|
||||
<div className="num-day">
|
||||
{detail?.registDate ? moment(detail.registDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '-'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('additionalService.fundAccount.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.registrationDateTime')}</span>
|
||||
<span className="v">
|
||||
{detail?.registDate ? moment(detail.registDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss') : '-'}
|
||||
</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.processingResult')}</span>
|
||||
<span className="v">{getFundAccountStatusName(t)(detail?.resultStatus) || '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.requestDate')}</span>
|
||||
<span className="v">
|
||||
{detail?.requestDate ? moment(detail.requestDate, 'YYYYMMDDHHmmss').format('YYYY.MM.DD') : '-'}
|
||||
</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.transferResult')}</span>
|
||||
<span className="v">{detail?.resultMessage || '-'}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.beneficiaryName')}</span>
|
||||
<span className="v">{detail?.accountName}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.bank')}</span>
|
||||
<span className="v">{detail?.bankCode || '-'} </span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.fundAccount.accountNumber')}</span>
|
||||
<span className="v">{detail?.accountNo}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">MID</span>
|
||||
<span className="v">{detail?.mid}</span>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToRequest()}
|
||||
disabled={detail?.resultStatus !== FundAccountStatus.REGIST_COMPLETE}
|
||||
>{t('additionalService.fundAccount.transferRequestButton')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -15,6 +15,7 @@ import { snackBar } from '@/shared/lib';
|
||||
import { useExtensionFundAccountTransferRegistMutation } from '@/entities/additional-service/api/fund-account/use-extension-fund-account-transfer-regist-mutation';
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { useExtensionFundAccountTransferRequestMutation } from '@/entities/additional-service/api/fund-account/use-extension-fund-account-transfer-request-mutation';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
|
||||
export const FundAccountTransferRequestPage = () => {
|
||||
@@ -80,11 +81,14 @@ export const FundAccountTransferRequestPage = () => {
|
||||
const errorMessage = rs.error?.message || t('additionalService.fundAccount.registrationFailed');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
}
|
||||
}).catch((error) => {
|
||||
const errorMessage = error?.response?.data?.error?.message ||
|
||||
error?.message ||
|
||||
t('additionalService.fundAccount.registrationError');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
}).catch((e) => {
|
||||
console.log(e)
|
||||
const errorMessage = e?.response?.data?.error?.message || e?.message || t('additionalService.fundAccount.registrationError');
|
||||
if (e.response?.data?.error?.root !== "SystemErrorCode") {
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
} else {
|
||||
showAlert(`[${t('common.failed')}] ${errorMessage}`)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import { useStore } from '@/shared/model/store';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
import { NumericFormat, PatternFormat } from 'react-number-format';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
export const KeyInPaymentRequestPage = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -94,21 +95,25 @@ export const KeyInPaymentRequestPage = () => {
|
||||
} else {
|
||||
// 실패: 화면 유지 & 입력 내용 유지
|
||||
const errorMessage = rs.data?.resultMessage ||
|
||||
rs.error?.message ||
|
||||
rs.resultMessage||
|
||||
t('additionalService.keyIn.requestFailed');
|
||||
rs.error?.message ||
|
||||
rs.resultMessage ||
|
||||
t('additionalService.keyIn.requestFailed');
|
||||
console.log('최종 errorMessage:', errorMessage);
|
||||
// HTML 태그 제거
|
||||
const cleanMessage = errorMessage.replace(/<br\s*\/?>/gi, ' ').trim();
|
||||
snackBar(`[${t('common.failed')}] ${cleanMessage}`);
|
||||
}
|
||||
}).catch((error) => {
|
||||
console.error('결제 실패:', error);
|
||||
console.error(error);
|
||||
const errorMessage = error?.response?.data?.data?.resultMessage ||
|
||||
error?.response?.data?.error?.message ||
|
||||
error?.message ||
|
||||
t('additionalService.keyIn.requestError');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
error?.response?.data?.error?.message ||
|
||||
error?.message ||
|
||||
t('additionalService.keyIn.requestError');
|
||||
if (error.response?.data?.error?.root !== "SystemErrorCode") {
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
} else {
|
||||
showAlert(`[${t('common.failed')}] ${errorMessage}`)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -199,8 +204,8 @@ export const KeyInPaymentRequestPage = () => {
|
||||
allowNegative={false}
|
||||
displayType="input"
|
||||
onValueChange={(values) => {
|
||||
const { floatValue} = values;
|
||||
setAmount( floatValue ?? 0);
|
||||
const { floatValue } = values;
|
||||
setAmount(floatValue ?? 0);
|
||||
}}
|
||||
></NumericFormat>
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,7 @@ import { PATHS } from '@/shared/constants/paths';
|
||||
import { useExtensionLinkPayRequestMutation } from '@/entities/additional-service/api/link-payment/use-extension-link-pay-request-mutation';
|
||||
import { ExtensionLinkPayRequestParams, ExtensionLinkPayRequestResponse, LinkPaymentFormData } from '@/entities/additional-service/model/link-pay/types';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
import { showAlert } from '@/widgets/show-alert';
|
||||
|
||||
export const LinkPaymentApplyConfirmPage = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -60,11 +61,14 @@ export const LinkPaymentApplyConfirmPage = () => {
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
// 네트워크 에러 등 예외 상황
|
||||
const errorMessage = error?.response?.data?.error?.message ||
|
||||
error?.message ||
|
||||
t('additionalService.linkPayment.requestError');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
if (error.response?.data?.error?.root !== "SystemErrorCode") {
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
} else {
|
||||
showAlert(`[${t('common.failed')}] ${errorMessage}`)
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,179 +0,0 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useLocation } from 'react-router';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
useSetOnBack,
|
||||
useSetHeaderTitle,
|
||||
useSetHeaderType,
|
||||
useSetFooterMode
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { overlay } from 'overlay-kit';
|
||||
import { Dialog } from '@/shared/ui/dialogs/dialog';
|
||||
import { useExtensionLinkPayHistoryDetailMutation } from '@/entities/additional-service/api/link-payment/use-extension-link-pay-history-detail-mutation';
|
||||
import { AdditionalServiceCategory, DetailInfo, DetailResponse, PaymentInfo, TitleInfo } from '@/entities/additional-service/model/types';
|
||||
import { TitleInfoWrap } from '@/entities/additional-service/ui/info-wrap/title-info-wrap';
|
||||
import { PaymentInfoWrap } from '@/entities/additional-service/ui/info-wrap/payment-info-wrap';
|
||||
import { DetailInfoWrap } from '@/entities/additional-service/ui/info-wrap/detail-info-wrap';
|
||||
import { useExtensionLinkPayHistoryResendMutation } from '@/entities/additional-service/api/link-payment/use-extension-link-pay-history-resend-mutation';
|
||||
import { ExtensionLinkPayHistoryDetailParams, ExtensionLinkPayHistoryResendParams } from '@/entities/additional-service/model/link-pay/types';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
import moment from 'moment';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const LinkPaymentDetailPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const { mid, tid, requestId, subReqId } = location.state || {};
|
||||
|
||||
const [titleInfo, setTitleInfo] = useState<TitleInfo>();
|
||||
const [detailInfo, setDetailInfo] = useState<DetailInfo>();
|
||||
const [paymentInfo, setPaymentInfo] = useState<PaymentInfo>();
|
||||
const [detailExposure, setDetailExposure] = useState<boolean>(false);
|
||||
const [showPayment, setShowPayment] = useState<boolean>(false);
|
||||
|
||||
useSetHeaderTitle(t('additionalService.linkPayment.detailTitle'));
|
||||
useSetHeaderType(HeaderType.RightClose);
|
||||
useSetOnBack(() => {
|
||||
navigate(-1); // Go back using browser history
|
||||
});
|
||||
useSetFooterMode(false);
|
||||
|
||||
const { mutateAsync: linkPayHistoryDetail } = useExtensionLinkPayHistoryDetailMutation();
|
||||
const { mutateAsync: linkPayHistoryResend } = useExtensionLinkPayHistoryResendMutation();
|
||||
|
||||
// Query detail information
|
||||
const callDetail = () => {
|
||||
let detailParam: ExtensionLinkPayHistoryDetailParams = {
|
||||
mid: mid,
|
||||
requestId: requestId,
|
||||
subReqId: subReqId
|
||||
}
|
||||
linkPayHistoryDetail(detailParam).then((rs: DetailResponse) => {
|
||||
console.log("Detail Info: ", rs)
|
||||
setTitleInfo(rs.titleInfo)
|
||||
setDetailInfo(rs.detailInfo)
|
||||
setPaymentInfo(rs.paymentInfo)
|
||||
setDetailExposure(rs.detailExposure ?? false)
|
||||
})
|
||||
}
|
||||
|
||||
// Resend API
|
||||
const resendPayment = () => {
|
||||
let resendParam: ExtensionLinkPayHistoryResendParams = {
|
||||
mid: mid,
|
||||
requestId: requestId,
|
||||
sendMethod: paymentInfo?.sendMethod
|
||||
}
|
||||
linkPayHistoryResend(resendParam)
|
||||
.then((response) => {
|
||||
if (response.status) {
|
||||
snackBar(t('additionalService.linkPayment.resendSuccess'));
|
||||
callDetail();
|
||||
} else {
|
||||
const errorMessage = response.error?.message || t('additionalService.linkPayment.resendFailed');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
const errorMessage = error?.response?.data?.error?.message ||
|
||||
error?.message ||
|
||||
t('additionalService.linkPayment.resendError');
|
||||
snackBar(`[${t('common.failed')}] ${errorMessage}`);
|
||||
});
|
||||
}
|
||||
|
||||
const onClickToResend = () => {
|
||||
let msg = t('additionalService.linkPayment.resendConfirm');
|
||||
|
||||
overlay.open(({
|
||||
isOpen,
|
||||
close,
|
||||
unmount
|
||||
}) => {
|
||||
return (
|
||||
<Dialog
|
||||
afterLeave={unmount}
|
||||
open={isOpen}
|
||||
onClose={close}
|
||||
onConfirmClick={() => resendPayment()}
|
||||
message={msg}
|
||||
buttonLabel={[t('common.cancel'), t('common.confirm')]}
|
||||
/>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const onClickToSeparateApproval = () => {
|
||||
navigate(PATHS.additionalService.linkPayment.separateApproval, {
|
||||
state: { mid, requestId }
|
||||
});
|
||||
};
|
||||
|
||||
// Check if resend button should be enabled
|
||||
const isResendEnabled = () => {
|
||||
// paymentStatus must be "ACTIVE"
|
||||
if (paymentInfo?.paymentStatus !== 'ACTIVE') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// paymentLimitDate must not have passed today's date
|
||||
if (paymentInfo?.paymentLimitDate) {
|
||||
const limitDate = moment(paymentInfo.paymentLimitDate, 'YYYYMMDD');
|
||||
const today = moment().startOf('day');
|
||||
return limitDate.isSameOrAfter(today);
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
callDetail();
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="pay-top">
|
||||
<TitleInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentHistory}
|
||||
titleInfo={titleInfo}
|
||||
></TitleInfoWrap>
|
||||
</div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-divider"></div>
|
||||
<PaymentInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentHistory}
|
||||
paymentInfo={paymentInfo}
|
||||
></PaymentInfoWrap>
|
||||
<div className="detail-divider"></div>
|
||||
<DetailInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentHistory}
|
||||
detailInfo={detailInfo}
|
||||
></DetailInfoWrap>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="link-payment-detail-button" style={{ paddingBottom: '85px' }}>
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToSeparateApproval()}
|
||||
disabled={detailExposure}
|
||||
>{t('additionalService.linkPayment.separateApprovalDetail')}</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToResend()}
|
||||
disabled={!isResendEnabled()}
|
||||
>{t('additionalService.linkPayment.resend')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main >
|
||||
</>
|
||||
)
|
||||
};
|
||||
@@ -1,124 +0,0 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useLocation } from 'react-router';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
useSetOnBack,
|
||||
useSetHeaderTitle,
|
||||
useSetHeaderType,
|
||||
useSetFooterMode
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { overlay } from 'overlay-kit';
|
||||
import { Dialog } from '@/shared/ui/dialogs/dialog';
|
||||
import { TitleInfoWrap } from '@/entities/additional-service/ui/info-wrap/title-info-wrap';
|
||||
import { AdditionalServiceCategory, DetailResponse, PaymentInfo, TitleInfo } from '@/entities/additional-service/model/types';
|
||||
import { useExtensionLinkPayWaitDetailMutation, } from '@/entities/additional-service/api/link-payment/use-extension-link-pay-wait-detail-mutation';
|
||||
import { PaymentInfoWrap } from '@/entities/additional-service/ui/info-wrap/payment-info-wrap';
|
||||
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 { snackBar } from '@/shared/lib';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const LinkPaymentWaitDetailPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
const location = useLocation();
|
||||
const { mid, requestId } = location.state || {};
|
||||
const [titleInfo, setTitleInfo] = useState<TitleInfo>();
|
||||
const [paymentInfo, setPaymentInfo] = useState<PaymentInfo>();
|
||||
|
||||
useSetHeaderTitle(t('additionalService.linkPayment.waitDetailTitle'));
|
||||
useSetHeaderType(HeaderType.RightClose);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.additionalService.linkPayment.pendingSend);
|
||||
});
|
||||
useSetFooterMode(false);
|
||||
|
||||
const { mutateAsync: linkPayWaitDetail } = useExtensionLinkPayWaitDetailMutation();
|
||||
const { mutateAsync: linkPayWaitDelete } = useExtensionLinkPayWaitDeleteMutation();
|
||||
|
||||
const callDetail = () => {
|
||||
let detailParam: ExtensionLinkPayWaitDetailParams = {
|
||||
mid: mid,
|
||||
requestId: requestId
|
||||
}
|
||||
|
||||
linkPayWaitDetail(detailParam).then((rs: DetailResponse) => {
|
||||
setTitleInfo(rs.titleInfo)
|
||||
setPaymentInfo(rs.paymentInfo)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const deletePayment = () => {
|
||||
let deleteParam: ExtensionLinkPayWaitDeleteParams = {
|
||||
mid: mid,
|
||||
requestId: requestId
|
||||
}
|
||||
linkPayWaitDelete(deleteParam)
|
||||
.then((rs) => {
|
||||
callDetail();
|
||||
snackBar(t('additionalService.linkPayment.deleteSuccess'))
|
||||
})
|
||||
.catch((error) => {
|
||||
snackBar(`[${t('common.failed')}] ${error?.response?.data?.message}`)
|
||||
});
|
||||
}
|
||||
|
||||
const onClickToCancel = () => {
|
||||
let msg = t('additionalService.linkPayment.deleteConfirm');
|
||||
|
||||
overlay.open(({
|
||||
isOpen,
|
||||
close,
|
||||
unmount
|
||||
}) => {
|
||||
return (
|
||||
<Dialog
|
||||
afterLeave={unmount}
|
||||
open={isOpen}
|
||||
onClose={close}
|
||||
onConfirmClick={() => deletePayment()}
|
||||
message={msg}
|
||||
buttonLabel={[t('common.cancel'), t('common.confirm')]}
|
||||
/>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
callDetail();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<main>
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="pay-top">
|
||||
<TitleInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentWait}
|
||||
titleInfo={titleInfo}
|
||||
></TitleInfoWrap>
|
||||
</div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-divider"></div>
|
||||
<PaymentInfoWrap
|
||||
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentWait}
|
||||
paymentInfo={paymentInfo}
|
||||
></PaymentInfoWrap>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToCancel()}
|
||||
disabled={paymentInfo?.processStatus !== LinkPaymentProcessStatus.SEND_REQUEST}
|
||||
>{t('additionalService.linkPayment.delete')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</main >
|
||||
</>
|
||||
)
|
||||
};
|
||||
@@ -1,190 +0,0 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
useSetHeaderTitle,
|
||||
useSetHeaderType,
|
||||
useSetFooterMode,
|
||||
useSetOnBack
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { useExtensionPayoutDetailMutation } from '@/entities/additional-service/api/payout/use-extension-payout-detail-mutation';
|
||||
import { useLocation } from 'react-router';
|
||||
import { ExtensionPayoutDetailDownloadCertificateParams, ExtensionPayoutDetailDownloadCertificateResponse, ExtensionPayoutDetailParams, ExtensionPayoutDetailResponse } from '@/entities/additional-service/model/payout/types';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { useExtensionPayoutDetailDownloadCertificateMutation } from '@/entities/additional-service/api/payout/use-extension-payout-detail-download-cetificate-mutation';
|
||||
import moment from 'moment';
|
||||
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
import { DownloadTypeBottomSheet } from '@/entities/common/ui/download-type-bottom-sheet';
|
||||
|
||||
export const PayoutDetailPage = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const tid = location.state.tid;
|
||||
const mid = location.state.mid;
|
||||
|
||||
const [detail, setDetail] = useState<ExtensionPayoutDetailResponse>();
|
||||
const [downloadTypeBottomSheetOn, setDownloadTypeBottomSheetOn] = useState<boolean>(false);
|
||||
const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false);
|
||||
|
||||
const { mutateAsync: extensionPayoutDetail } = useExtensionPayoutDetailMutation();
|
||||
const { mutateAsync: extensionPayoutDetailDownloadCertification } = useExtensionPayoutDetailDownloadCertificateMutation();
|
||||
|
||||
const callDetail = () => {
|
||||
let params: ExtensionPayoutDetailParams = {
|
||||
tid: tid,
|
||||
mid: mid,
|
||||
};
|
||||
|
||||
extensionPayoutDetail(params).then((rs: ExtensionPayoutDetailResponse) => {
|
||||
setDetail(rs);
|
||||
});
|
||||
};
|
||||
|
||||
useSetHeaderTitle(t('additionalService.payout.detailTitle'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
useSetFooterMode(false);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.additionalService.payout.list);
|
||||
});
|
||||
|
||||
const onClickToDownload = () => {
|
||||
setDownloadTypeBottomSheetOn(true);
|
||||
};
|
||||
|
||||
const onSelectDownloadType = (type: 'IMAGE' | 'EMAIL') => {
|
||||
if (type === 'IMAGE') {
|
||||
// Save image directly
|
||||
const params: ExtensionPayoutDetailDownloadCertificateParams = {
|
||||
mid: mid,
|
||||
tid: tid,
|
||||
requestType: 'IMAGE',
|
||||
email: ''
|
||||
};
|
||||
extensionPayoutDetailDownloadCertification(params)
|
||||
.then((rs: ExtensionPayoutDetailDownloadCertificateResponse) => {
|
||||
console.log('Certificate Download Status:', rs);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Certificate Download Failed:', error);
|
||||
});
|
||||
} else {
|
||||
// Open EmailBottomSheet for email option
|
||||
setEmailBottomSheetOn(true);
|
||||
}
|
||||
};
|
||||
|
||||
const onSendRequest = (selectedEmail?: string) => {
|
||||
if (selectedEmail) {
|
||||
const params: ExtensionPayoutDetailDownloadCertificateParams = {
|
||||
mid: mid,
|
||||
tid: tid,
|
||||
requestType: 'EMAIL',
|
||||
email: selectedEmail
|
||||
};
|
||||
extensionPayoutDetailDownloadCertification(params)
|
||||
.then((rs: ExtensionPayoutDetailDownloadCertificateResponse) => {
|
||||
console.log('Certificate Download Status:', rs);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Certificate Download Failed:', error);
|
||||
});
|
||||
}
|
||||
setEmailBottomSheetOn(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
callDetail();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<main className="full-height">
|
||||
<div className="tab-content">
|
||||
<div className="tab-pane sub active">
|
||||
<div className="pay-top">
|
||||
<div className="num-amount">
|
||||
<span className="amount">
|
||||
{t('home.money', { value: new Intl.NumberFormat('en-US').format(detail?.disbursementAmount || 0) })}
|
||||
</span>
|
||||
</div>
|
||||
<div className="num-store">{detail?.companyName}</div>
|
||||
<div className="num-day">{detail?.settlementDate}</div>
|
||||
<div className="receipt-row">
|
||||
<button
|
||||
className="receipt-btn"
|
||||
type="button"
|
||||
onClick={ onClickToDownload }
|
||||
>
|
||||
<span className="icon-24 download"></span>
|
||||
<span>{t('additionalService.payout.depositCertificate')}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="detail-divider"></div>
|
||||
<div className="pay-detail">
|
||||
<div className="detail-title">{t('additionalService.payout.detailInfo')}</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.disbursementStatus')}</span>
|
||||
<span className="v">{ detail?.disbursementStatus }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.transactionType')}</span>
|
||||
<span className="v">{ detail?.transTypeName }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('common.requestDate')}</span>
|
||||
<span className="v">{ moment(detail?.requestDate).format('YYYY.MM.DD') }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.disbursementDateTime')}</span>
|
||||
<span className="v">{moment(detail?.settlementDateTime,'YYYYMMDDHHmmss').format('YYYY.MM.DD HH:mm:ss')}</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.businessNumber')}</span>
|
||||
<span className="v">{ detail?.companyNo }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.accountHolder')}</span>
|
||||
<span className="v">{ detail?.accountName }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.bank')}</span>
|
||||
<span className="v">{ detail?.bankName }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.accountNumber')}</span>
|
||||
<span className="v">{ detail?.accountNo }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.depositor')}</span>
|
||||
<span className="v">{ detail?.depositName }</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">{t('additionalService.payout.failureReason')}</span>
|
||||
<span className="v">{ detail?.failReason }</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<DownloadTypeBottomSheet
|
||||
bottomSheetOn={downloadTypeBottomSheetOn}
|
||||
setBottomSheetOn={setDownloadTypeBottomSheetOn}
|
||||
onSelectType={onSelectDownloadType}
|
||||
/>
|
||||
<EmailBottomSheet
|
||||
bottomSheetOn={emailBottomSheetOn}
|
||||
setBottomSheetOn={setEmailBottomSheetOn}
|
||||
imageSave={false}
|
||||
sendEmail={true}
|
||||
sendRequest={onSendRequest}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -17,6 +17,7 @@ import moment from 'moment';
|
||||
import { NumericFormat } from "react-number-format";
|
||||
import { snackBar } from "@/shared/lib";
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { showAlert } from "@/widgets/show-alert";
|
||||
|
||||
export const PayoutRequestPage = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -53,10 +54,15 @@ export const PayoutRequestPage = () => {
|
||||
snackBar(`[${t('common.failed')}] ${rs.error?.message}`)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
snackBar(`[${t('common.failed')}] ${error?.response?.data?.message} ` || `[${t('common.failed')}] ${t('additionalService.payout.requestFailed')}`)
|
||||
})
|
||||
;
|
||||
.catch((e) => {
|
||||
console.log(e)
|
||||
if (e.response?.data?.error?.root !== "SystemErrorCode") {
|
||||
snackBar(`[${t('common.failed')}] ${e.response?.data?.error?.message}`)
|
||||
} else {
|
||||
showAlert(`[${t('common.failed')}] ${e?.response?.data?.error?.message} ` || `[${t('common.failed')}] ${t('additionalService.payout.requestFailed')}`);
|
||||
return;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const isFormValid = () => {
|
||||
|
||||
Reference in New Issue
Block a user