2024-03-07 20:55:44 +09:00

233 lines
7.0 KiB
TypeScript

import { AppDispatch } from "app/store";
import React, { useState, useCallback, useEffect } from "react";
import styles from "styles/app.module.scss";
import { useDispatch, useSelector } from "react-redux";
import { getTranslationID } from "translation";
import { useTranslation } from "react-i18next";
import {
changePoNumber,
changeNewOrder,
selectPoNumber,
selectNewOrder,
selectInputValidationErrors,
orderLicenseAsync,
cleanupApps,
selectIsLoading,
} from "features/license/licenseOrder";
import {
clearHierarchicalElement,
getMyAccountAsync,
} from "features/license/partnerLicense";
import close from "../../assets/images/close.svg";
import progress_activit from "../../assets/images/progress_activit.svg";
interface LicenseOrderPopupProps {
onClose: () => void;
}
export const LicenseOrderPopup: React.FC<LicenseOrderPopupProps> = (props) => {
const { onClose } = props;
const dispatch: AppDispatch = useDispatch();
const { t } = useTranslation();
const initCount = useSelector(selectNewOrder);
const [count, setCount] = useState<number>(initCount);
const [poNumberInputValue, setpoNumberInputValue] = useState<string>();
const isLoading = useSelector(selectIsLoading);
useEffect(
() => () => {
// useEffectのreturnとしてcleanupAppsを実行することで、ポップアップのアンマウント時に初期化を行う
dispatch(cleanupApps());
},
[dispatch]
);
// ポップアップを閉じる処理
const closePopup = useCallback(() => {
if (isLoading) return;
setIsPushOrderButton(false);
onClose();
}, [isLoading, onClose]);
// 画面からのパラメータ
const poNumber = useSelector(selectPoNumber);
const orderCount = useSelector(selectNewOrder);
const [isPushOrderButton, setIsPushOrderButton] = useState<boolean>(false);
// エラー宣言
const {
hasErrorEmptyPoNumber,
hasErrorIncorrectPoNumber,
hasErrorIncorrectNewOrder,
} = useSelector(selectInputValidationErrors);
// 注文ボタン押下時
const onOrderLicense = useCallback(async () => {
setIsPushOrderButton(true);
// エラーチェックを実施
if (
hasErrorEmptyPoNumber ||
hasErrorIncorrectPoNumber ||
hasErrorIncorrectNewOrder
) {
return;
}
// ダイアログ確認
if (
/* eslint-disable-next-line no-alert */
!window.confirm(
t(getTranslationID("licenseOrderPage.message.confirmOrder"))
)
) {
return;
}
// 注文APIの呼び出し
const { meta } = await dispatch(
orderLicenseAsync({
poNumber,
orderCount,
})
);
setIsPushOrderButton(false);
if (meta.requestStatus === "fulfilled") {
dispatch(getMyAccountAsync());
dispatch(clearHierarchicalElement());
closePopup();
}
}, [
dispatch,
closePopup,
t,
hasErrorEmptyPoNumber,
hasErrorIncorrectPoNumber,
hasErrorIncorrectNewOrder,
poNumber,
orderCount,
]);
// HTML
return (
<div className={`${styles.modal} ${styles.isShow}`}>
<div className={styles.modalBox}>
<p className={styles.modalTitle}>
{t(getTranslationID("licenseOrderPage.label.title"))}
<button type="button" onClick={closePopup}>
<img src={close} className={styles.modalTitleIcon} alt="close" />
</button>
</p>
<form className={styles.form}>
<dl className={`${styles.formList} ${styles.hasbg}`}>
<dt className={styles.formTitle} />
<dt>{t(getTranslationID("licenseOrderPage.label.licenses"))}</dt>
<dd>
<input
type="text"
size={40}
name=""
value={t(
getTranslationID("licenseOrderPage.label.licenseTypeText")
)}
maxLength={16}
className={styles.formInput}
readOnly
/>
</dd>
<dt>{t(getTranslationID("licenseOrderPage.label.poNumber"))}</dt>
<dd>
<input
type="text"
size={40}
name="poNumber"
value={poNumberInputValue}
maxLength={50}
className={styles.formInput}
onChange={(e) => {
const input = e.target.value.toUpperCase();
setpoNumberInputValue(input);
}}
onBlur={(e) => {
dispatch(changePoNumber({ poNumber: e.target.value }));
}}
/>
{isPushOrderButton && hasErrorEmptyPoNumber && (
<span className={styles.formError}>
{t(
getTranslationID("licenseOrderPage.message.inputEmptyError")
)}
</span>
)}
{isPushOrderButton && hasErrorIncorrectPoNumber && (
<span className={styles.formError}>
{t(
getTranslationID(
"licenseOrderPage.message.poNumberIncorrectError"
)
)}
</span>
)}
</dd>
<dt>{t(getTranslationID("licenseOrderPage.label.newOrder"))}</dt>
<dd>
<input
type="number"
size={4}
name="newOrder"
value={count}
min={1}
max={9999}
step={1}
maxLength={4}
className={styles.formInput}
onChange={(e) => {
const input = Number(
e.target.value.replace(/[-.]/g, "").substring(0, 4)
);
setCount(input);
}}
onBlur={(e) => {
dispatch(
changeNewOrder({ newOrder: Number(e.target.value) })
);
}}
/>
{isPushOrderButton && hasErrorIncorrectNewOrder && (
<span className={styles.formError}>
{t(
getTranslationID(
"licenseOrderPage.message.newOrderIncorrectError"
)
)}
</span>
)}
</dd>
<dd className={`${styles.full} ${styles.alignCenter}`}>
<input
type="button"
name="submit"
value={t(
getTranslationID("licenseOrderPage.label.orderButton")
)}
className={`${styles.formSubmit} ${styles.marginBtm1} ${
!isLoading ? styles.isActive : ""
}`}
onClick={onOrderLicense}
/>
<img
style={{ display: isLoading ? "inline" : "none" }}
src={progress_activit}
className={styles.icLoading}
alt="Loading"
/>
</dd>
</dl>
</form>
</div>
</div>
);
};