Загрузка данных
import {
BasicListItem,
SectionHeading,
TextInput,
BaseFormatContainer,
Text,
setAmountMask,
CurrencyType,
setSmallCardMask,
} from "@rshbintech.ckof.ownfin/core-ui";
import {
AmountInputLinkAF,
BottomSheetsCardSelectorAF,
BankCardAF,
} from "@rshbintech.ckof.ownfin/core-ui-local";
import { Icons } from "@rshbintech.ckof.ownfin/icons";
import { ProductSelector } from "src/client/shared/ui/product-selector";
import { getCurrencySymbol } from "src/client/common";
import { formatPaymentScheduleShort } from "src/client/shared/utils/format-schedule/format-schedule";
import { INPUT_MAX_LENGHT } from "src/client/shared/constants";
import { useMemo, useState } from "react";
import { useAppDispatch, useAppSelector } from "src/hooks";
import {
accountsSelector,
selectRawAccounts,
} from "src/client/model/accounts-payments/selectors";
import { ADD_EXTRA_ACCOUNT } from "src/client/view/auto-payment-edit-page/components/edit-form/constants";
import { setNewAdditionalAccount } from "src/client/model/get-auto-payments/slice";
import { selectNewAdditionalAccount } from "src/client/model/get-auto-payments/selectors";
import styles from "../../styles.scss";
import {
EDIT_PAGE_SECTION_HEADING_TITLE,
AUTOPAYMENT_NAME_LABEL,
AUTOPAYMENT_FREQUENCY_LABEL,
AMOUNT_REQUIRED_ERROR_TEXT,
BOTTOM_SHEETS_EXTRA_ACCOUNT_TITLE,
BOTTOM_SHEETS_EXTRA_ACCOUNT_DESCRIPTION,
EXTRA_ACCOUNT_CHOOSE_BUTTON,
EXTRA_ACCOUNT_SECTION_HEADING_TITLE,
} from "../../constants";
import { getAutoTransferWithScheduleChanges } from "../../utils";
import type { PaymentEditFormProps } from "./types";
export const EditForm = ({
autoPayment,
currency,
activeProductIndex,
amountValue,
nameValue,
scheduleChanges,
isAmountError,
nameInputRef,
formsContainerRef,
bottomRef,
bottomStyle,
onProductChange,
onAmountClick,
onNameChange,
onNameFocus,
onNameBlur,
onScheduleClick,
}: PaymentEditFormProps) => {
const dispatch = useAppDispatch();
const newAdditionalAccount = useAppSelector(selectNewAdditionalAccount);
const [tempSelectedAccount, setTempSelectedAccount] = useState<
string | null | undefined
>(null);
const [isBottomSheetOpen, setBottomSheetOpen] = useState(false);
const accounts = useAppSelector(accountsSelector);
const accountsRowData = useAppSelector(selectRawAccounts);
const filteredAccounts = useMemo(() => {
if (!accounts || !accountsRowData?.[activeProductIndex]) {
return accounts || [];
}
return accounts.filter(
(account) => account.id !== accountsRowData[activeProductIndex].id
);
}, [accounts, accountsRowData, activeProductIndex]);
const displayProduct =
accounts?.find((product) => product.id === newAdditionalAccount) ?? null;
const handleListItemClick = (accountId: string) => {
setTempSelectedAccount((prev) => (prev === accountId ? null : accountId));
};
const handleOpenBottomSheet = () => {
setTempSelectedAccount(newAdditionalAccount);
setBottomSheetOpen(true);
};
const handleClose = () => {
setTempSelectedAccount(null);
setBottomSheetOpen(false);
};
const handleChoose = () => {
dispatch(setNewAdditionalAccount(tempSelectedAccount));
handleClose();
};
const handleProductChange = (index: number | undefined) => {
if (index !== undefined) {
const newDebitAccountId = accountsRowData?.[index]?.id;
if (newDebitAccountId && newAdditionalAccount === newDebitAccountId) {
dispatch(setNewAdditionalAccount(null));
}
onProductChange(index);
}
};
if (!accountsRowData) {
return null;
}
return (
<>
<div className={styles["product-selector-container"]}>
<SectionHeading
title={EDIT_PAGE_SECTION_HEADING_TITLE}
className={styles.header}
/>
<ProductSelector
paymentAccounts={accountsRowData}
autoPayment={autoPayment}
activeProductIndex={activeProductIndex}
onProductChange={handleProductChange}
/>
</div>
<div className={styles["forms-container"]}>
<SectionHeading title={EXTRA_ACCOUNT_SECTION_HEADING_TITLE} />
<BasicListItem
onClick={handleOpenBottomSheet}
className={styles["add-autopayment-button"]}
>
<BaseFormatContainer
textContainer={
newAdditionalAccount && displayProduct?.sum ? (
<div className={styles["text-container"]}>
<Text.Mask level={4} weight="bold" className={styles.text}>
{setAmountMask(
String(displayProduct.sum),
2,
",",
displayProduct?.currency as CurrencyType
)}
</Text.Mask>
<Text.Body level={4} className={styles["description-text"]}>
{`${displayProduct?.type} ${setSmallCardMask(displayProduct?.number as string)}`}
</Text.Body>
</div>
) : (
<div className={styles["text-container"]}>
<Text.Body level={3}>{ADD_EXTRA_ACCOUNT}</Text.Body>
</div>
)
}
rightContainer={
newAdditionalAccount && displayProduct?.substrateColor ? (
<BankCardAF
substrateColor={displayProduct?.substrateColor}
size="xxsmall"
bankLogo={displayProduct?.paymentSystem}
number={displayProduct?.accountNumber}
/>
) : null
}
arrowContainer={<Icons.ChevronRightMini fill="var(--fg-primary)" />}
arrowContainerClassName={styles.right}
/>
</BasicListItem>
</div>
<div className={styles["amount-input-container"]}>
<AmountInputLinkAF
value={amountValue}
suffix={getCurrencySymbol(currency)}
onClick={onAmountClick}
helperText={isAmountError ? AMOUNT_REQUIRED_ERROR_TEXT : undefined}
error={isAmountError}
decimal={2}
/>
</div>
<div ref={formsContainerRef} className={styles["forms-container"]}>
<TextInput
ref={nameInputRef}
id="text-input"
label={AUTOPAYMENT_NAME_LABEL}
value={nameValue}
onChange={onNameChange}
className={styles["text-input"]}
onFocus={onNameFocus}
onBlur={onNameBlur}
maxLength={INPUT_MAX_LENGHT}
/>
<TextInput
id="select"
value={formatPaymentScheduleShort(
getAutoTransferWithScheduleChanges(autoPayment, scheduleChanges)
)}
label={AUTOPAYMENT_FREQUENCY_LABEL}
onClick={onScheduleClick}
rightIconButton={
<div className={styles["right-icon-wrapper"]}>
<Icons.ChevronRightMini fill="var(--fg-secondary)" />
</div>
}
/>
<div ref={bottomRef} className={styles.bottom} style={bottomStyle} />
</div>
<BottomSheetsCardSelectorAF
products={filteredAccounts}
activeCard={tempSelectedAccount as string}
title={BOTTOM_SHEETS_EXTRA_ACCOUNT_TITLE}
description={BOTTOM_SHEETS_EXTRA_ACCOUNT_DESCRIPTION}
multiline
titlePosition="left"
buttonText={EXTRA_ACCOUNT_CHOOSE_BUTTON}
onButtonClick={handleChoose}
isOpen={isBottomSheetOpen}
onClose={handleClose}
onClickListItem={(_, item) => handleListItemClick(item.data.id)}
safeBottom
topPercent={0}
/>
</>
);
};