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:
HyeonJongKim
2025-11-05 19:41:05 +09:00
parent 50f062b3cf
commit 24435e47d6
30 changed files with 790 additions and 1869 deletions

View File

@@ -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>
</>
);
};