Files
nice-app-web/src/pages/transaction/billing/charge-page.tsx
focp212@naver.com 20e532bd68 toast timer 추가
2025-10-23 16:35:39 +09:00

243 lines
8.3 KiB
TypeScript

import { ChangeEvent, useState } from 'react';
import { PATHS } from '@/shared/constants/paths';
import { IMAGE_ROOT } from '@/shared/constants/common';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { CalendarType, HeaderType } from '@/entities/common/model/types';
import { useBillingChargeMutation } from '@/entities/transaction/api/use-billing-charge-mutation';
import {
useSetOnBack,
useSetHeaderTitle,
useSetHeaderType,
useSetFooterMode
} from '@/widgets/sub-layout/use-sub-layout';
import { NumericFormat, PatternFormat } from 'react-number-format';
import { showAlert } from '@/widgets/show-alert';
import moment from 'moment';
import NiceCalendar from '@/shared/ui/calendar/nice-calendar';
import { notiBar, snackBar } from '@/shared/lib';
export const BillingChargePage = () => {
const { navigate } = useNavigate();
const [billKey, setBillKey] = useState<string>('');
const [productName, setProductName] = useState<string>('');
const [productAmount, setProductAmount] = useState<number>(0);
const [orderNumber, setOrderNumber] = useState<string>('');
const [buyerName, setBuyerName] = useState<string>('');
const [paymentRequestDate, setPaymentRequestDate] = useState<string>(moment().format('YYYY.MM.DD'));
const [installmentMonth, setInstallmentMonth] = useState<string>('00');
const [calendarOpen, setCalendarOpen] = useState<boolean>(false);
useSetHeaderTitle('빌링 결제 신청');
useSetHeaderType(HeaderType.RightClose);
useSetOnBack(() => {
navigate(PATHS.transaction.billing.list);
});
useSetFooterMode(false);
const { mutateAsync: billingCharge } = useBillingChargeMutation();
const setNewDate = (date: string) => {
setPaymentRequestDate(moment(date).format('YYYY.MM.DD'));
setCalendarOpen(false);
};
const onClickToOpenCalendar = () => {
setCalendarOpen(true);
};
const onClickToBillingCharge = () => {
if(!billKey){
showAlert('빌키는 필수 입력 항목입니다.');
return;
}
else if(!productName){
showAlert('상품명은 필수 입력 항목입니다.');
}
else if(!productAmount){
showAlert('상품금액은 필수 입력 항목입니다.');
}
else if(productAmount <= 0){
showAlert('상품금액은 0보다 커야 합니다.');
}
else if(!orderNumber){
showAlert('주문번호는 필수 입력 항목입니다.');
}
else if(!buyerName){
showAlert('구매자명은 필수 입력 항목입니다.');
}
let params = {
billKey: billKey,
productName: productName,
productAmount: productAmount,
orderNumber: orderNumber,
buyerName: buyerName,
paymentRequestDate: moment(paymentRequestDate).format('YYYYMMDD'),
installmentMonth: installmentMonth
};
billingCharge(params).then((rs) => {
snackBar('결제 신청을 성공하였습니다.', function(){
navigate(PATHS.transaction.billing.list);
}, 3000);
}).catch((e: any) => {
/*
if(e.response?.data?.message){
showAlert(e.response?.data?.message);
return;
}
*/
});
};
const onChangeBillKey = (value: string) => {
const pattern = /^[A-Za-z0-9]+$/;
if(pattern.test(value) || value === ''){
setBillKey(value);
}
};
const makeInstallmentMonthSelect = () => {
let rs = [];
rs.push(
<option
key={ `key-installment` }
value=''
></option>
);
rs.push(
<option
key={ `key-installment-0` }
value='00'
></option>
);
for(let i=2;i<=24;i++){
let val = (i < 10)? '0'+i: ''+i;
rs.push(
<option
key={ `key-installment-${i}`}
value={ val }
>{i}</option>
);
};
return rs;
};
return (
<>
<main>
<div className="tab-content">
<div className="tab-pane sub active">
<div className="option-list">
<div className="billing-title"> </div>
<div className="billing-form">
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<input
type="text"
value={ billKey }
onChange={ (e: ChangeEvent<HTMLInputElement>) => onChangeBillKey(e.target.value) }
/>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<input
type="text"
value={ productName }
onChange={ (e: ChangeEvent<HTMLInputElement>) => setProductName(e.target.value) }
/>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<NumericFormat
value={ productAmount }
allowNegative={ false }
displayType="input"
onChange={ (e: ChangeEvent<HTMLInputElement>) => setProductAmount(parseInt(e.target.value)) }
></NumericFormat>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<input
type="text"
value={ orderNumber }
onChange={ (e: ChangeEvent<HTMLInputElement>) => setOrderNumber(e.target.value) }
/>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> <span>*</span></div>
<div className="billing-field">
<input
type="text"
value={ buyerName }
onChange={ (e: ChangeEvent<HTMLInputElement>) => setBuyerName(e.target.value) }
/>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> </div>
<div className="billing-field">
<div className="input-wrapper date wid-100">
<input
type="text"
placeholder="날짜 선택"
value={ paymentRequestDate }
readOnly={ true }
/>
<button
className="date-btn"
type="button"
onClick={ () => onClickToOpenCalendar() }
>
<img
src={ IMAGE_ROOT + '/ico_date.svg' }
alt="clear"
/>
</button>
</div>
</div>
</div>
<div className="billing-row">
<div className="billing-label"> </div>
<div className="billing-field">
<select
value={ installmentMonth }
onChange={ (e: ChangeEvent<HTMLSelectElement>) => setBuyerName(e.target.value) }
>
{ makeInstallmentMonthSelect() }
</select>
</div>
</div>
</div>
</div>
<div className="apply-row">
<button
className="btn-50 btn-blue flex-1"
onClick={ () => onClickToBillingCharge() }
> </button>
</div>
</div>
</div>
</main>
<NiceCalendar
calendarOpen={ calendarOpen }
setCalendarOpen={ setCalendarOpen }
calendarType={ CalendarType.Single }
setNewDate={ setNewDate }
></NiceCalendar>
</>
);
};