Files
nice-app-web/src/pages/transaction/billing/charge-page.tsx
focp212@naver.com 3982b3c745 catch
2025-11-05 17:29:07 +09:00

244 lines
8.5 KiB
TypeScript

import { ChangeEvent, useState } from 'react';
import { useTranslation } from 'react-i18next';
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';
import { BillingChargeParams, BillingChargeResponse } from '@/entities/transaction/model/types';
export const BillingChargePage = () => {
const { navigate } = useNavigate();
const { t } = useTranslation();
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(t('billing.charge'));
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: BillingChargeParams = {
billKey: billKey,
productName: productName,
productAmount: productAmount,
orderNumber: orderNumber,
buyerName: buyerName,
paymentRequestDate: moment(paymentRequestDate).format('YYYYMMDD'),
installmentMonth: installmentMonth
};
billingCharge(params).then((rs: BillingChargeResponse) => {
snackBar('결제 신청을 성공하였습니다.', function(){
navigate(PATHS.transaction.billing.list);
}, 3000);
}).catch((e: any) => {
if(e.response?.data?.error?.message){
showAlert(e.response?.data?.error?.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>
</>
);
};