import React, { ReactNode, useCallback, useEffect, useMemo } from "react"; import { ControllerProps, ControllerRenderProps, FieldErrors, } from "react-hook-form"; import { Asset, useAssets, useDefaultCurrency } from "../.."; import { useDisplayDecimalDigits } from "../useDisplayDecimalDigits"; import { BuySellContext, BuySellFormProps } from "./context"; import { useBuySellAmountValidation } from "./useBuySellAmountValidation"; import { useBuySellMarketConfigs } from "./useBuySellConfigs"; import { useUpdatePreview } from "./useUpdatePreview"; type BuyRecieveRenderProps = { render: (state: { field: ControllerRenderProps & { assets: Asset[]; asset?: Asset; minQuantity: number; maxQuantity: number; hasError?: boolean; availableRemain: number; onSelect?: (value?: Asset | undefined) => void; onFocus?: (e: any) => void; getMaxSize?: (value: number) => string | number; stepSize?: number; }; }) => React.ReactElement; renderErrorComponent?: (message?: string) => ReactNode; }; export const BuyRecieveController = ({ render, renderErrorComponent, }: BuyRecieveRenderProps) => { const { lastChangedField } = BuySellContext.useWatch(); const { allAssets } = useAssets(); const { request, resetRefreshCount } = useUpdatePreview({ mode: "to", type: "buy", }); // const { control } = BuySellContext.useFormContext(); // const [lastChangedField] = useWatch({ // name: ["fromAsset", "toAsset", "lastChangedField"], // control, // defaultValue: { // lastChangedField: "from", // }, // }); // console.log({2:lastChangedField}) const { filterLotSize, getMaxSize, selectedCurrency } = useBuySellMarketConfigs({ mode: "to", }); const { setValue, clearErrors, register, getValues } = BuySellContext.useFormContext(); const { defaultCrypto } = useDefaultCurrency(); register("shouldCharge"); const assets = useMemo( () => allAssets?.filter( (item) => item.canTrade && item.currencyType === "Crypto", ) || [], [allAssets], ); const { truncFix } = useDisplayDecimalDigits(); useEffect(() => { const { toAsset } = getValues(); if (toAsset === undefined) { const symbol = assets?.find( ({ symbol }) => symbol === defaultCrypto, )?.symbol; setValue("toAsset", symbol); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [assets]); const { checkAmount, minimumTo, maximumTo } = useBuySellAmountValidation(); const clearFormErrors = useCallback( (errors: FieldErrors) => { if (Object.values(errors).length > 0) { clearErrors(); } }, // eslint-disable-next-line react-hooks/exhaustive-deps [], ); const rules = useMemo(() => { return { validate: { check: (value: string | null | undefined) => checkAmount({ value, mode: "to", }), }, }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [checkAmount]); const renderForm: ControllerProps["render"] = useCallback( ({ field: { onChange, value, ...rest }, formState, fieldState }) => { return ( <> {render({ field: { value: value, assets, availableRemain: truncFix( selectedCurrency?.availableRemain || 0, selectedCurrency?.symbol, ), minQuantity: minimumTo || 0, maxQuantity: maximumTo || 0, asset: selectedCurrency, hasError: value ? !!fieldState.error : false, getMaxSize, async onSelect(asset?: Asset) { if (selectedCurrency?.symbol !== asset?.symbol) { onChange(""); setValue("fromAmount", ""); const symbol = await new Promise( (res) => { res(asset?.symbol); }, ); setValue("toAsset", symbol); clearFormErrors(formState.errors); } }, onFocus() { lastChangedField !== "to" && setValue("lastChangedField", "to"); }, onChange(value) { if (value === "") { setValue("fromAmount", ""); } clearFormErrors(formState.errors); request(); resetRefreshCount(); onChange(value); lastChangedField !== "to" && setValue("lastChangedField", "to"); }, stepSize: filterLotSize?.stepSize, ...rest, }, })} {renderErrorComponent && renderErrorComponent( fieldState.error ? fieldState.error.message : "", )} ); }, // eslint-disable-next-line react-hooks/exhaustive-deps [ assets, clearFormErrors, getMaxSize, lastChangedField, render, selectedCurrency, truncFix, minimumTo, maximumTo, resetRefreshCount, ], ); return ( <> ); };