Files
nice-app-web/src/pages/additional-service/payout/request-page.tsx
Jay Sheen c2e8da956a Localize payout pages (detail, list, request)
- Added payout-specific translation keys to en.json:
  - depositBalance, subId, disbursementAmount, requestFailed
- Added common translation keys: filter, download, searchOptions, failed, clear, currency.krw
- Localized detail-page.tsx:
  - Header title, button text, detail section title
  - All KV labels (disbursementStatus, transactionType, etc.)
  - Updated code comments from Korean to English
- Localized list-page.tsx:
  - Header title, aria-labels, alt texts
  - Deposit balance label and currency unit
  - Request button text
- Localized request-page.tsx:
  - Header title, form labels, placeholder text
  - Success/error messages in snackBar calls
  - Added useTranslation hook import

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 13:06:28 +09:00

151 lines
5.5 KiB
TypeScript

import { IMAGE_ROOT } from "@/shared/constants/common";
import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { CalendarType, HeaderType } from '@/entities/common/model/types';
import {
useSetHeaderTitle,
useSetHeaderType,
useSetFooterMode,
useSetOnBack
} from '@/widgets/sub-layout/use-sub-layout';
import { ChangeEvent, useState } from "react";
import { useExtensionPayoutRequestMutation } from "@/entities/additional-service/api/payout/use-extension-payout-request-mutation";
import { ExtensionPayoutRequestParams, ExtensionPayoutRequestResponse } from "@/entities/additional-service/model/payout/types";
import NiceCalendar from "@/shared/ui/calendar/nice-calendar";
import { useStore } from "@/shared/model/store";
import moment from 'moment';
import { NumericFormat } from "react-number-format";
import { snackBar } from "@/shared/lib";
import { useTranslation } from 'react-i18next';
export const PayoutRequestPage = () => {
const { t } = useTranslation();
const { navigate } = useNavigate();
const userMid = useStore.getState().UserStore.mid;
const [calendarOpen, setCalendarOpen] = useState<boolean>(false);
const [mid, setMid] = useState<string>(userMid);
const [submallId, setSubmallId] = useState<string>('');
const [disbursementAmount, setDisbursementAmount] = useState<number>(0);
const [settlementDate, setSettlementDate] = useState<string>('');
const { mutateAsync: extensionPayoutRequest } = useExtensionPayoutRequestMutation();
useSetHeaderTitle(t('additionalService.payout.requestTitle'));
useSetHeaderType(HeaderType.RightClose);
useSetFooterMode(false);
useSetOnBack(() => {
navigate(PATHS.additionalService.payout.list);
});
const callExtensionPayoutRequest = () => {
let params: ExtensionPayoutRequestParams = {
mid: mid,
submallId: submallId,
disbursementAmount: disbursementAmount,
settlementDate: settlementDate,
};
extensionPayoutRequest(params)
.then((rs) => {
if (rs.status) {
snackBar(t('additionalService.payout.requestSuccess'))
} else {
snackBar(`[${t('common.failed')}] ${rs.error?.message}`)
}
})
.catch((error) => {
snackBar(`[${t('common.failed')}] ${error?.response?.data?.message} ` || `[${t('common.failed')}] ${t('additionalService.payout.requestFailed')}`)
})
;
};
const isFormValid = () => {
return (
submallId.trim() !== '' &&
disbursementAmount > 0 &&
settlementDate.trim() !== ''
);
};
const setNewDate = (date: string) => {
setSettlementDate(moment(date).format('YYYYMMDD'));
setCalendarOpen(false);
};
return (
<>
<main>
<div className="tab-content">
<div className="tab-pane sub active">
<div className="ing-list">
<div className="billing-form gap-30">
<div className="billing-row">
<div className="billing-label">{t('additionalService.payout.subId')}</div>
<div className="billing-field">
<input
type="text"
value={submallId}
onChange={(e: ChangeEvent<HTMLInputElement>) => setSubmallId(e.target.value)}
/>
</div>
</div>
<div className="billing-row">
<div className="billing-label">{t('additionalService.payout.disbursementAmount')}</div>
<div className="billing-field">
<NumericFormat
value={disbursementAmount}
allowNegative={false}
thousandSeparator={true}
displayType="input"
onValueChange={(values) => {
const { floatValue } = values;
setDisbursementAmount(floatValue ?? 0);
}}
/>
</div>
</div>
<div className="billing-row">
<div className="billing-label">{t('additionalService.payout.disbursementDate')}</div>
<div className="billing-field">
<div className="input-wrapper date wid-100">
<input
type="text"
placeholder={t('additionalService.payout.dateSelectPlaceholder')}
value={settlementDate ? moment(settlementDate).format('YYYY.MM.DD') : ''}
/>
<button
className="date-btn"
type="button"
onClick={() => setCalendarOpen(true)}
>
<img
src={IMAGE_ROOT + '/ico_date.svg'}
alt={t('common.clear')}
/>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
<div className="apply-row">
<button
className="btn-50 btn-blue flex-1"
onClick={callExtensionPayoutRequest}
disabled={!isFormValid()}
>{t('common.request')}</button>
</div>
<NiceCalendar
calendarOpen={calendarOpen}
setCalendarOpen={setCalendarOpen}
calendarType={CalendarType.Single}
setNewDate={setNewDate}
minDate={new Date()}
></NiceCalendar>
</>
);
};