From 02cacb9aab3b069d0b835afe56cb686329b16f7b Mon Sep 17 00:00:00 2001 From: Jay Sheen Date: Thu, 23 Oct 2025 10:32:24 +0900 Subject: [PATCH 1/3] =?UTF-8?q?refactor:=20XKeypad=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EB=A1=A4=EB=B0=B1=20=EB=B0=8F=20=EC=9D=BC=EB=B0=98=20password?= =?UTF-8?q?=20input=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - XKeypad 관련 모든 코드 제거 - 일반 password input 필드로 복원 - 불필요한 ref, useEffect 제거 - select 요소 value 속성으로 변경 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../password/modify-cancel-password-page.tsx | 176 ++---------------- 1 file changed, 17 insertions(+), 159 deletions(-) diff --git a/src/pages/account/password/modify-cancel-password-page.tsx b/src/pages/account/password/modify-cancel-password-page.tsx index 19f884d..41a60dd 100644 --- a/src/pages/account/password/modify-cancel-password-page.tsx +++ b/src/pages/account/password/modify-cancel-password-page.tsx @@ -1,4 +1,4 @@ -import { useState, useRef, useEffect, ChangeEvent } from 'react'; +import { useState } from 'react'; import { PATHS } from '@/shared/constants/paths'; import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { HeaderType } from '@/entities/common/model/types'; @@ -10,7 +10,7 @@ import { } from '@/widgets/sub-layout/use-sub-layout'; import { useUserChangeCancelPasswordMutation } from '@/entities/user/api/use-user-change-cancel-password-mutation'; import { useStore } from '@/shared/model/store'; -import { XKeypad, XKeypadManager, createPasswordKeypad } from '@/utils/xkeypad'; +import { snackBar } from '@/shared/lib/toast'; export const PasswordModifyCancelPasswordPage = () => { const { navigate } = useNavigate(); @@ -20,69 +20,20 @@ export const PasswordModifyCancelPasswordPage = () => { const [mid, setMid] = useState(userMid); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); - const [isKeypadLoaded, setIsKeypadLoaded] = useState(false); - - // Input refs for xkeypad - const passwordInputRef = useRef(null); - const confirmPasswordInputRef = useRef(null); - - // XKeypad instances - const passwordKeypadRef = useRef(null); - const confirmPasswordKeypadRef = useRef(null); - - // RSA Keys (실제 프로덕션에서는 서버에서 받아와야 함) - const RSA_MODULUS = "C4F7B39E2E93DB19C016C7A0C1C05B028A1D57CB9B91E13F5B7353F8FB5AC6CE6BE31ABEB8E8F7AD18B90C08F4EBC011A6A8FCE614EA879ED5B96296B969CE92923BC9BAD6FD87F00E08F529F93010EA77E40937BDAC1C866E79ACE2F2822A3ECD982F90532D5301CF90D9BF89E953A0593AB6C5F31E99B690DD582FB85F85A9"; - const RSA_EXPONENT = "10001"; const changeCancelPasswordMutation = useUserChangeCancelPasswordMutation({ onSuccess: () => { - // snackBar('비밀번호가 성공적으로 변경되었습니다.'); - // Clear form and keypads + snackBar('비밀번호가 성공적으로 변경되었습니다.'); + // Clear form setPassword(''); setConfirmPassword(''); - if (passwordKeypadRef.current) passwordKeypadRef.current.clear(); - if (confirmPasswordKeypadRef.current) confirmPasswordKeypadRef.current.clear(); - if (passwordInputRef.current) passwordInputRef.current.value = ''; - if (confirmPasswordInputRef.current) confirmPasswordInputRef.current.value = ''; // Navigate back navigate(PATHS.account.password.manage); }, onError: (error) => { - // snackBar(error?.response?.data?.message || '비밀번호 변경에 실패했습니다.'); + snackBar(error?.response?.data?.message || '비밀번호 변경에 실패했습니다.'); } }); - // Initialize XKeypad - useEffect(() => { - const initializeKeypad = async () => { - try { - const manager = XKeypadManager.getInstance({ - modulus: RSA_MODULUS, - exponent: RSA_EXPONENT - }); - - await manager.loadScripts(); - - // RSA 키 설정을 명시적으로 다시 한번 수행 - manager.setRSAPublicKey(RSA_MODULUS, RSA_EXPONENT); - - setIsKeypadLoaded(true); - } catch (error) { - console.error('Failed to load XKeypad:', error); - } - }; - - initializeKeypad(); - - return () => { - // Cleanup keypads on unmount - if (passwordKeypadRef.current) { - passwordKeypadRef.current.destroy(); - } - if (confirmPasswordKeypadRef.current) { - confirmPasswordKeypadRef.current.destroy(); - } - }; - }, []); useSetHeaderTitle('거래취소 비밀번호 변경'); useSetHeaderType(HeaderType.LeftArrow); @@ -100,97 +51,10 @@ export const PasswordModifyCancelPasswordPage = () => { ); }; - // Handle password keypad - const handlePasswordKeypad = async () => { - if (!passwordInputRef.current || !isKeypadLoaded) return; - - // Close other keypad if open - if (confirmPasswordKeypadRef.current) { - confirmPasswordKeypadRef.current.close(); - } - - // Create or initialize password keypad - if (!passwordKeypadRef.current) { - passwordKeypadRef.current = createPasswordKeypad(passwordInputRef.current, { - keyType: 'qwertysmart', - viewType: 'half', - maxInputSize: 16, - useOverlay: true, - useModal: false, - hasPressEffect: true, - isE2E: false, // E2E 모드 비활성화 - onInputChange: (length: number) => { - // Update password state as typing - if (passwordKeypadRef.current) { - const plainText = passwordKeypadRef.current.getPlainText(); - console.log('passwordKeypadRef:', plainText, passwordInputRef.current?.value); - setPassword(plainText); - } - }, - onKeypadClose: () => { - // Final update when keypad closes - if (passwordKeypadRef.current) { - const plainText = passwordKeypadRef.current.getPlainText(); - setPassword(plainText); - } - } - }); - } - - const result = await passwordKeypadRef.current.initialize(passwordInputRef.current); - if (result !== 0) { - console.error('Failed to initialize password keypad'); - } - }; - - // Handle confirm password keypad - const handleConfirmPasswordKeypad = async () => { - if (!confirmPasswordInputRef.current || !isKeypadLoaded) return; - - // Close other keypad if open - if (passwordKeypadRef.current) { - passwordKeypadRef.current.close(); - } - - // Create or initialize confirm password keypad - if (!confirmPasswordKeypadRef.current) { - confirmPasswordKeypadRef.current = createPasswordKeypad(confirmPasswordInputRef.current, { - keyType: 'qwertysmart', - viewType: 'half', - maxInputSize: 16, - useOverlay: true, - useModal: false, - hasPressEffect: true, - isE2E: false, // E2E 모드 비활성화 - onInputChange: (length: number) => { - // Update confirm password state as typing - if (confirmPasswordKeypadRef.current) { - const plainText = confirmPasswordKeypadRef.current.getPlainText(); - console.log('confirmPasswordKeypadRef:', plainText, confirmPasswordInputRef.current?.value); - setConfirmPassword(plainText); - } - }, - onKeypadClose: () => { - // Final update when keypad closes - if (confirmPasswordKeypadRef.current) { - const plainText = confirmPasswordKeypadRef.current.getPlainText(); - setConfirmPassword(plainText); - } - } - }); - } - - const result = await confirmPasswordKeypadRef.current.initialize(confirmPasswordInputRef.current); - if (result !== 0) { - console.error('Failed to initialize confirm password keypad'); - } - }; - // 저장 버튼 클릭 핸들러 const handleSave = () => { if (!isFormValid()) return; - // 평문 비밀번호 사용 (E2E 모드가 꺼져있으므로) changeCancelPasswordMutation.mutate({ mid, password: password @@ -206,17 +70,17 @@ export const PasswordModifyCancelPasswordPage = () => {
가맹점 *
- setMid(e.target.value)} > { - midOptions.map((value, index) => ( + midOptions.map((value) => ( + key={value.value} + value={value.value} + >{value.name} )) } @@ -224,27 +88,21 @@ export const PasswordModifyCancelPasswordPage = () => {
변경 비밀번호 *
setPassword(e.target.value)} />
변경 비밀번호 재입력 *
setConfirmPassword(e.target.value)} />
{confirmPassword && password !== confirmPassword && ( From 79271caab34dd2ba59380febd01fe984f09b3f06 Mon Sep 17 00:00:00 2001 From: Jay Sheen Date: Thu, 23 Oct 2025 10:34:28 +0900 Subject: [PATCH 2/3] refactor: Update account authentication and password input components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace XKeypad with standard password input fields - Update user authentication and login info components - Modify password modification and account pages - Add sub-layout widget enhancements 🤖 Generated with Claude Code Co-Authored-By: Claude --- src/entities/account/ui/user-account-auth-wrap.tsx | 4 ++-- .../account/ui/user-login-auth-info-wrap.tsx | 9 +++++---- src/entities/account/ui/user-manage-wrap.tsx | 3 ++- .../password/modify-login-password-page.tsx | 5 +++-- src/pages/account/user/add-account-page.tsx | 11 ++++++----- src/pages/account/user/menu-auth-page.tsx | 14 +++++++------- src/widgets/sub-layout/index.tsx | 6 ++++++ 7 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/entities/account/ui/user-account-auth-wrap.tsx b/src/entities/account/ui/user-account-auth-wrap.tsx index ab037a2..4d22192 100644 --- a/src/entities/account/ui/user-account-auth-wrap.tsx +++ b/src/entities/account/ui/user-account-auth-wrap.tsx @@ -111,7 +111,7 @@ export const UserAccountAuthWrap = ({ ] return ( <> -
+
계정 상태
@@ -144,7 +144,7 @@ export const UserAccountAuthWrap = ({ menuGrants={ permissions } > -
+
-
- +
- { getAlimtalkList() } -
+ {getAlimtalkList()}
-
+ + + ); }; \ No newline at end of file diff --git a/src/pages/additional-service/ars/list-page.tsx b/src/pages/additional-service/ars/list-page.tsx index 36adde8..d90381b 100644 --- a/src/pages/additional-service/ars/list-page.tsx +++ b/src/pages/additional-service/ars/list-page.tsx @@ -3,9 +3,9 @@ import { useNavigate } from '@/shared/lib/hooks/use-navigate'; import { IMAGE_ROOT } from '@/shared/constants/common'; import { DefaultRequestPagination, HeaderType, SortTypeKeys } from '@/entities/common/model/types'; import { - useSetHeaderTitle, - useSetHeaderType, - useSetFooterMode, + useSetHeaderTitle, + useSetHeaderType, + useSetFooterMode, useSetOnBack } from '@/widgets/sub-layout/use-sub-layout'; import { JSX, useEffect, useState } from 'react'; @@ -20,37 +20,15 @@ import { SortTypeBox } from '@/entities/common/ui/sort-type-box'; import { ArsPaymentStatusBtnGroup } from '@/entities/additional-service/model/ars/constant'; import { ArsFilter } from '@/entities/additional-service/ui/filter/ars-filter'; import { useStore } from '@/shared/model/store'; -import useIntersectionObserver from '@/widgets/intersection-observer'; export const ArsListPage = () => { const { navigate } = useNavigate(); - const [onActionIntersect, setOnActionIntersect] = useState(false); - const onIntersect: IntersectionObserverCallback = (entries: Array) => { - entries.forEach((entry: IntersectionObserverEntry) => { - if (entry.isIntersecting) { - console.log('Element is now intersecting with the root. [' + onActionIntersect + ']'); - if (onActionIntersect) { - callList(); - } - } - else { - console.log('Element is no longer intersecting with the root.'); - } - }); - }; - - const { setTarget } = useIntersectionObserver({ - threshold: 1, - onIntersect - }); - const userMid = useStore.getState().UserStore.mid; const [sortType, setSortType] = useState(SortTypeKeys.LATEST); const [listItems, setListItems] = useState>([]); const [filterOn, setFilterOn] = useState(false); - const [nextCursor, setNextCursor] = useState(null); const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM); const [mid, setMid] = useState(userMid); const [moid, setMoid] = useState(''); @@ -63,7 +41,7 @@ export const ArsListPage = () => { const { mutateAsync: extensionArsList } = useExtensionArsListMutation(); const { mutateAsync: extensionArsDownloadExcel } = useExtensionArsDownloadExcelMutation(); - + useSetHeaderTitle('신용카드 ARS 결제'); useSetHeaderType(HeaderType.LeftArrow); useSetFooterMode(false); @@ -73,17 +51,8 @@ export const ArsListPage = () => { const callList = (option?: { sortType?: SortTypeKeys, - paymentStatus?: PaymentStatus, - resetPage?: boolean + paymentStatus?: PaymentStatus }) => { - setOnActionIntersect(false); - - const currentPageParam = option?.resetPage - ? { ...DEFAULT_PAGE_PARAM, sortType: option?.sortType ?? sortType } - : { ...pageParam, sortType: option?.sortType ?? sortType }; - - setPageParam(currentPageParam); - let params: ExtensionArsListParams = { mid: mid, moid: moid, @@ -93,25 +62,16 @@ export const ArsListPage = () => { orderStatus: orderStatus, minAmount: minAmount, maxAmount: maxAmount, - page: currentPageParam + page: pageParam }; + + if (params.page) { + params.page.sortType = option?.sortType || sortType; + setPageParam(params.page); + } + extensionArsList(params).then((rs: ExtensionArsListResponse) => { - // resetPage면 기존 리스트 무시, 아니면 추가 - setListItems(option?.resetPage ? rs.content : [ - ...listItems, - ...rs.content - ]); - if (rs.hasNext) { - setNextCursor(rs.nextCursor); - setPageParam({ - ...currentPageParam, - cursor: rs.nextCursor - }); - setOnActionIntersect(true) - } - else { - setNextCursor(null); - } + setListItems(rs.content); }); }; @@ -146,21 +106,21 @@ export const ArsListPage = () => { const onClickToSort = (sort: SortTypeKeys) => { setSortType(sort); callList({ - sortType: sort, - resetPage: true + sortType: sort }); }; const onClickToPaymentStatus = (val: PaymentStatus) => { setPaymentStatus(val); callList({ - paymentStatus: val, - resetPage: true + paymentStatus: val }); }; useEffect(() => { - // 필터 조건이 변경되면 첫 페이지부터 다시 시작 - callList({ resetPage: true }); + callList(); + }, []); + useEffect(() => { + callList(); }, [ mid, moid, @@ -173,33 +133,36 @@ export const ArsListPage = () => { ]); const getListDateGroup = () => { - let rs: JSX.Element[] = []; + let rs = []; let date = ''; - let list: ArsListContent[] = []; + let list = []; for (let i = 0; i < listItems.length; i++) { - // paymentDate format: "20211018140420" (YYYYMMDDHHmmss) - let paymentDate = listItems[i]?.paymentDate || ''; - let itemDate = paymentDate.substring(0, 8); - if (i === 0) { - date = itemDate; - } - if (date !== itemDate) { - // 날짜가 바뀌면 이전 리스트를 푸시 (날짜 업데이트 전에!) - if (list.length > 0) { - rs.push( - - ); + let item = listItems[i]; + if (!!item) { + let paymentDate = item?.paymentDate || ''; + let itemDate = paymentDate.substring(0, 8); + if (!!itemDate) { + if (i === 0) { + date = itemDate; + } + if (date !== itemDate) { + date = itemDate; + if (list.length > 0) { + rs.push( + + ); + } + list = []; + } + list.push(item); } - date = itemDate; // 그 다음에 날짜 업데이트 - list = []; } - list.push(listItems[i] as any); } if (list.length > 0) { rs.push( @@ -223,30 +186,30 @@ export const ArsListPage = () => {
- -
- @@ -255,56 +218,55 @@ export const ArsListPage = () => {
{ ArsPaymentStatusBtnGroup.map((value, index) => ( - onClickToPaymentStatus(value.value) } - >{ value.name } + onClickToPaymentStatus(value.value)} + >{value.name} )) }
- +
- { getListDateGroup() } -
+ {getListDateGroup()}
); diff --git a/src/pages/additional-service/fund-account/result-detail-page.tsx b/src/pages/additional-service/fund-account/result-detail-page.tsx index fc53148..20eb1b9 100644 --- a/src/pages/additional-service/fund-account/result-detail-page.tsx +++ b/src/pages/additional-service/fund-account/result-detail-page.tsx @@ -11,11 +11,14 @@ 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'; export const FundAccountResultDetailPage = () => { const { navigate } = useNavigate(); @@ -25,8 +28,10 @@ export const FundAccountResultDetailPage = () => { const mid = location.state.mid; const [detail, setDetail] = useState(); + const [email, setEmail] = useState(''); const { mutateAsync: extensionFundAccountResultDetail } = useExtensionFundAccountResultDetailMutation(); + const { mutateAsync: extensionFundAccountDownlaodReceipt } = useExtensionFundAccountDownloadReceiptMutation(); const callDetail = () => { let params: ExtensionFundAccountResultDetailParams = { @@ -39,6 +44,17 @@ export const FundAccountResultDetailPage = () => { }); }; + const onClickToDownload = () => { + let params: ExtensionFundAccountDownloadReceiptParams = { + mid: mid, + tid: tid, + email: email + }; + extensionFundAccountDownlaodReceipt(params).then((rs: ExtensionFundAccountDownloadReceiptResponse) => { + console.log(rs); + }); + }; + useSetHeaderTitle('자금이체 상세'); useSetHeaderType(HeaderType.LeftArrow); useSetFooterMode(false); @@ -72,7 +88,11 @@ export const FundAccountResultDetailPage = () => { {/* ✅ resultMessage가 "정상"일 때만 표시 */} {detail?.resultMessage === '정상' && (
- @@ -104,7 +124,7 @@ export const FundAccountResultDetailPage = () => {
  • 은행 - {detail?.bankCode} + {detail?.bankName}
  • 계좌번호 diff --git a/src/pages/additional-service/fund-account/transfer-detail-page.tsx b/src/pages/additional-service/fund-account/transfer-detail-page.tsx index dd66d53..ea1546c 100644 --- a/src/pages/additional-service/fund-account/transfer-detail-page.tsx +++ b/src/pages/additional-service/fund-account/transfer-detail-page.tsx @@ -11,27 +11,25 @@ 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, ExtensionFundAccountTransferRequestParams, ExtensionFundAccountTransferRequestResponse, FundAccountStatus } from '@/entities/additional-service/model/fund-account/types'; +import { ExtensionFundAccountTransferDetailParams, ExtensionFundAccountTransferDetailResponse, ExtensionFundAccountTransferRegistParams, 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 { useExtensionFundAccountTransferRequestMutation } from '@/entities/additional-service/api/fund-account/use-extension-fund-account-transfer-request-mutation'; +import { useExtensionFundAccountTransferRegistMutation } from '@/entities/additional-service/api/fund-account/use-extension-fund-account-transfer-regist-mutation'; export const FundAccountTransferDetailPage = () => { const { navigate } = useNavigate(); const location = useLocation(); - const tid = location.state.tid; - const mid = location.state.mid; + const seq = location.state.seq; const [detail, setDetail] = useState(); const { mutateAsync: extensionFundAccountTransferDetail } = useExtensionFundAccountTransferDetailMutation(); - const { mutateAsync: extensionFundAccountTransferRequest } = useExtensionFundAccountTransferRequestMutation(); + const { mutateAsync: extensionFundAccountTransferRequest } = useExtensionFundAccountTransferRegistMutation(); const callDetail = () => { let params: ExtensionFundAccountTransferDetailParams = { - tid: tid, - mid: mid, + seq: seq }; extensionFundAccountTransferDetail(params).then((rs: ExtensionFundAccountTransferDetailResponse) => { @@ -50,26 +48,26 @@ export const FundAccountTransferDetailPage = () => { callDetail(); }, []); - const onClickToRequest = () => { - if (!detail) { - alert('상세 정보를 불러오는 중입니다.'); - return; - } + // const onClickToRequest = () => { + // if (!detail) { + // alert('상세 정보를 불러오는 중입니다.'); + // return; + // } - let params: ExtensionFundAccountTransferRequestParams = { - mid: mid, - bankCode: detail.bankCode || '', - accountNo: detail.accountNo || '', - accountName: detail.accountName || '', - amount: detail.amount || 0, - moid: detail.moid || '' - }; - extensionFundAccountTransferRequest(params).then((rs: ExtensionFundAccountTransferRequestResponse) => { - console.log(rs) - alert(rs.status ? '이체 요청이 완료되었습니다.' : '이체 요청에 실패했습니다.'); - navigate(PATHS.additionalService.fundAccount.transferList); - }); - }; + // let params: ExtensionFundAccountTransferRegistParams = { + // mid: mid, + // bankCode: detail.bankCode || '', + // accountNo: detail.accountNo || '', + // accountName: detail.accountName || '', + // amount: detail.amount || 0, + // moid: detail.moid || '' + // }; + // extensionFundAccountTransferRequest(params).then((rs: ExtensionFundAccountTransferRequestResponse) => { + // console.log(rs) + // alert(rs.status ? '이체 요청이 완료되었습니다.' : '이체 요청에 실패했습니다.'); + // navigate(PATHS.additionalService.fundAccount.transferList); + // }); + // }; return ( <> @@ -138,7 +136,7 @@ export const FundAccountTransferDetailPage = () => {
    diff --git a/src/pages/additional-service/fund-account/transfer-request-page.tsx b/src/pages/additional-service/fund-account/transfer-request-page.tsx index 2858648..a7d12f6 100644 --- a/src/pages/additional-service/fund-account/transfer-request-page.tsx +++ b/src/pages/additional-service/fund-account/transfer-request-page.tsx @@ -7,15 +7,15 @@ import { useSetFooterMode, useSetOnBack } from '@/widgets/sub-layout/use-sub-layout'; -import { ChangeEvent, useEffect, useState } from 'react'; -import { useExtensionFundAccountTransferRequestMutation } from '@/entities/additional-service/api/fund-account/use-extension-fund-account-transfer-request-mutation'; -import { ExtensionFundAccountTransferRequestParams, ExtensionFundAccountTransferRequestResponse } from '@/entities/additional-service/model/fund-account/types'; +import { ChangeEvent, useState } from 'react'; +import { ExtensionFundAccountTransferRegistParams, ExtensionFundAccountTransferRegistResponse } from '@/entities/additional-service/model/fund-account/types'; import { useStore } from '@/shared/model/store'; +import { snackBar } from '@/shared/lib'; +import { useExtensionFundAccountTransferRegistMutation } from '@/entities/additional-service/api/fund-account/use-extension-fund-account-transfer-regist-mutation'; export const FundAccountTransferRequestPage = () => { const { navigate } = useNavigate(); - const midOptions = useStore.getState().UserStore.selectOptionsMids; const userMid = useStore.getState().UserStore.mid; @@ -27,7 +27,7 @@ export const FundAccountTransferRequestPage = () => { const [moid, setMoid] = useState(''); const [depositParameter, setDepositParameter] = useState(''); - const { mutateAsync: extensionFundAccountRequest } = useExtensionFundAccountTransferRequestMutation(); + const { mutateAsync: extensionFundAccountRegist } = useExtensionFundAccountTransferRegistMutation(); useSetHeaderTitle('자금이체 이체등록'); useSetHeaderType(HeaderType.RightClose); @@ -36,8 +36,17 @@ export const FundAccountTransferRequestPage = () => { navigate(PATHS.additionalService.fundAccount.transferList); }); - const callExtensionFundAccountTransferRequest = () => { - let params: ExtensionFundAccountTransferRequestParams = { + const resetForm = () => { + setBankCode(''); + setAccountNo(''); + setAccountName(''); + setAmount(0); + setMoid(''); + setDepositParameter(''); + }; + + const callExtensionFundAccountTransferRegist = () => { + let params: ExtensionFundAccountTransferRegistParams = { mid: mid, bankCode: bankCode, accountNo: accountNo, @@ -46,8 +55,13 @@ export const FundAccountTransferRequestPage = () => { moid: moid, depositParameter: depositParameter }; - extensionFundAccountRequest(params).then((rs: ExtensionFundAccountTransferRequestResponse) => { - navigate(PATHS.additionalService.payout.list); + extensionFundAccountRegist(params).then((rs: ExtensionFundAccountTransferRegistResponse) => { + if (rs.status) { + snackBar("이체등록을 성공하였습니다.") + resetForm(); + } else { + snackBar("이체등록이 실패하였습니다.") + } }); }; @@ -72,10 +86,7 @@ export const FundAccountTransferRequestPage = () => {
    가맹점*
    - setMid(e.target.value)}> { midOptions.map((value, index) => (
    diff --git a/src/pages/additional-service/link-payment/separate-approval/link-payment-separate-approval-page.tsx b/src/pages/additional-service/link-payment/separate-approval/link-payment-separate-approval-page.tsx index 7574cda..1bf080b 100644 --- a/src/pages/additional-service/link-payment/separate-approval/link-payment-separate-approval-page.tsx +++ b/src/pages/additional-service/link-payment/separate-approval/link-payment-separate-approval-page.tsx @@ -256,7 +256,12 @@ export const LinkPaymentSeparateApprovalPage = () => {
  • • 유효기간: - {item.paymentLimitDate} + + {item.paymentLimitDate + ? moment(item.paymentLimitDate, 'YYYYMMDD').format('YYYY/MM/DD') + : '-' + } +
  • • 연장횟수: @@ -272,13 +277,11 @@ export const LinkPaymentSeparateApprovalPage = () => { onChange={(e) => handleExtendPeriodChange(itemId, e.target.value)} > - - - - - - - + {[1, 2, 3, 4, 5, 6, 7].map(days => { + const baseDate = moment(item.paymentLimitDate, 'YYYYMMDD'); + const targetDate = baseDate.clone().add(days, 'days').format('YYYY/MM/DD'); + return ; + })}
  • diff --git a/src/pages/additional-service/payout/list-page.tsx b/src/pages/additional-service/payout/list-page.tsx index b4fe353..5f6f5a2 100644 --- a/src/pages/additional-service/payout/list-page.tsx +++ b/src/pages/additional-service/payout/list-page.tsx @@ -28,36 +28,14 @@ import { PayoutDisbursementStatusBtnGroup } from '@/entities/additional-service/ import { ListDateGroup } from '@/entities/additional-service/ui/list-date-group'; import { AdditionalServiceCategory } from '@/entities/additional-service/model/types'; import { useStore } from '@/shared/model/store'; -import useIntersectionObserver from '@/widgets/intersection-observer'; export const PayoutListPage = () => { const { navigate } = useNavigate(); const userMid = useStore.getState().UserStore.mid; - const [onActionIntersect, setOnActionIntersect] = useState(false); - const onIntersect: IntersectionObserverCallback = (entries: Array) => { - entries.forEach((entry: IntersectionObserverEntry) => { - if (entry.isIntersecting) { - console.log('Element is now intersecting with the root. [' + onActionIntersect + ']'); - if (onActionIntersect) { - callExtensionPayoutList(); - } - } - else { - console.log('Element is no longer intersecting with the root.'); - } - }); - }; - - const { setTarget } = useIntersectionObserver({ - threshold: 1, - onIntersect - }); - const [sortType, setSortType] = useState(SortTypeKeys.LATEST); const [listItems, setListItems] = useState>([]); const [filterOn, setFilterOn] = useState(false); - const [nextCursor, setNextCursor] = useState(null); const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM); const [mid, setMid] = useState(userMid); const [searchDateType, setSearchDateType] = useState(PayoutSearchDateType.REQUEST_DATE); @@ -83,17 +61,8 @@ export const PayoutListPage = () => { const callExtensionPayoutList = (option?: { sortType?: SortTypeKeys, - status?: PayoutDisbursementStatus, - resetPage?: boolean + status?: PayoutDisbursementStatus }) => { - setOnActionIntersect(false); - - const currentPageParam = option?.resetPage - ? { ...DEFAULT_PAGE_PARAM, sortType: option?.sortType ?? sortType } - : { ...pageParam, sortType: option?.sortType ?? sortType }; - - setPageParam(currentPageParam); - let newMinAmount = minAmount; if(!!minAmount && typeof(minAmount) === 'string'){ newMinAmount = parseInt(minAmount); @@ -110,25 +79,16 @@ export const PayoutListPage = () => { status: option?.status ?? status, minAmount: newMinAmount, maxAmount: newMaxAmount, - page: currentPageParam + page: pageParam }; + + if(params.page){ + params.page.sortType = option?.sortType || sortType; + setPageParam(params.page); + } + extensionPayoutList(params).then((rs: ExtensionPayoutListResponse) => { - // resetPage면 기존 리스트 무시, 아니면 추가 - setListItems(option?.resetPage ? rs.content : [ - ...listItems, - ...rs.content - ]); - if (rs.hasNext) { - setNextCursor(rs.nextCursor); - setPageParam({ - ...currentPageParam, - cursor: rs.nextCursor - }); - setOnActionIntersect(true) - } - else { - setNextCursor(null); - } + setListItems(rs.content); }); }; @@ -156,21 +116,18 @@ export const PayoutListPage = () => { const onClickToSort = (sort: SortTypeKeys) => { setSortType(sort); callExtensionPayoutList({ - sortType: sort, - resetPage: true + sortType: sort }); }; const onClickToDisbursementStatus = (val: PayoutDisbursementStatus) => { setStatus(val); callExtensionPayoutList({ - status: val, - resetPage: true + status: val }); }; useEffect(() => { - // 필터 조건이 변경되면 첫 페이지부터 다시 시작 - callExtensionPayoutList({ resetPage: true }); + callExtensionPayoutList(); }, [ mid, searchDateType, @@ -298,7 +255,6 @@ export const PayoutListPage = () => {
    { getListDateGroup() } -
    diff --git a/src/shared/api/api-url-additional-service.ts b/src/shared/api/api-url-additional-service.ts index 3f61148..a59876f 100644 --- a/src/shared/api/api-url-additional-service.ts +++ b/src/shared/api/api-url-additional-service.ts @@ -173,6 +173,10 @@ export const API_URL_ADDITIONAL_SERVICE = { }, // Fund Account Management 부가서비스 > 자금이체 API + extensionFundAccountTransferRegist: () => { + // POST: 자금이체 > 이체등록 + return `${API_BASE_URL}/api/v1/${API_URL_KEY}/extension/fund-account/transfer/regist` + }, extensionFundAccountTransferRequest: () => { // POST: 자금이체 > 이체신청 return `${API_BASE_URL}/api/v1/${API_URL_KEY}/extension/fund-account/transfer/request`; diff --git a/src/shared/ui/assets/css/style-fix.css b/src/shared/ui/assets/css/style-fix.css index 4899f27..d5ec029 100644 --- a/src/shared/ui/assets/css/style-fix.css +++ b/src/shared/ui/assets/css/style-fix.css @@ -176,16 +176,22 @@ main.home-main{ } .approval-cards-wrapper { + display: flex; + flex-direction: column; gap: 16px; + padding: 16px; padding-bottom: 2px; } .separate-approval-main .apply-row.two-button { + display: flex; + gap: 8px; flex-shrink: 0; position: sticky; bottom: 0; background: white; z-index: 10; + padding: 16px; } /* 분할승인 안내 박스 */ @@ -215,13 +221,15 @@ main.home-main{ border: 2px solid var(--color-d6d6d6); border-radius: 16px; padding: 16px; - margin-bottom: 16px; - transition: all 0.4s ease; + margin-bottom: 0; + transition: all 0.3s ease; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); } .approval-card.selected { border-color: var(--color-3E6AFC); background: var(--color-F4F8FF); + box-shadow: 0 4px 12px rgba(62, 106, 252, 0.2); } .approval-card .card-checkbox { @@ -270,6 +278,8 @@ main.home-main{ /* 분할승인 카드 헤더 */ .approval-card .card-header { + display: flex; + align-items: center; gap: 8px; margin-bottom: 16px; padding-bottom: 12px; @@ -309,6 +319,8 @@ main.home-main{ } .approval-card .info-list { + display: flex; + flex-direction: column; list-style: none; padding: 0; margin: 0; @@ -316,6 +328,7 @@ main.home-main{ } .approval-card .info-list li { + display: flex; align-items: center; font-size: var(--fs-14); color: var(--color-2D3436); @@ -351,6 +364,7 @@ main.home-main{ } .approval-card .period-selector select { + flex: 1; height: 36px; font-size: var(--fs-14); padding: 6px 30px 6px 12px; @@ -358,6 +372,7 @@ main.home-main{ border-radius: 4px; background-color: var(--color-white); transition: all 0.2s ease; + cursor: pointer; } /* Scrollbar hide utility class */