import React, { ReactNode, useCallback, useEffect, useMemo } from "react"; import { ControllerProps, ControllerRenderProps, FieldErrors, } from "react-hook-form"; import { Asset, useAssets } from "../useAssets"; import { useDefaultCurrency } from "../useDefaultCurrency"; import { useDisplayDecimalDigits } from "../useDisplayDecimalDigits"; import { BuySellContext, BuySellFormProps } from "./context"; import { useBuySellAmountValidation } from "./useBuySellAmountValidation"; import { useBuySellMarketConfigs } from "./useBuySellConfigs"; import { useUpdatePreview } from "./useUpdatePreview"; type SellSpendRenderProps = { 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?: (mesfromAmounte?: string) => ReactNode; }; export const SellSpendController = ({ render, renderErrorComponent, }: SellSpendRenderProps) => { // const { control } = BuySellContext.useFormContext(); // const [ lastChangedField] = useWatch({ // name: ["fromAsset", "toAsset", "lastChangedField"], // control, // defaultValue: { // lastChangedField: "from", // }, // }); const { lastChangedField } = BuySellContext.useWatch(); // console.log({3:lastChangedField}) const { allAssets } = useAssets(); const { request, resetRefreshCount } = useUpdatePreview({ mode: "from", type: "sell", }); const { filterLotSize, getMaxSize, selectedCurrency } = useBuySellMarketConfigs({ mode: "from", }); 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 { fromAsset } = getValues(); if (fromAsset === undefined) { const symbol = assets?.find( ({ symbol }) => symbol === defaultCrypto, )?.symbol; setValue("fromAsset", symbol); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [assets]); const { checkAmount, minimumFrom, maximumFrom } = useBuySellAmountValidation(); const clearFormErrors = useCallback( (errors: FieldErrors) => { if (Object.values(errors).length > 0) { clearErrors(); } }, // eslint-disable-next-line react-hooks/exhaustive-deps [], ); const rules = useMemo( () => ({ validate: { check: (value: string | null | undefined) => checkAmount({ value, mode: "from", }), }, }), [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: minimumFrom || 0, maxQuantity: maximumFrom || 0, asset: selectedCurrency, hasError: value ? !!fieldState.error : false, getMaxSize, async onSelect(asset?: Asset) { if (selectedCurrency?.symbol !== asset?.symbol) { onChange(""); setValue("toAmount", ""); const symbol = await new Promise( (res) => { res(asset?.symbol); }, ); setValue("fromAsset", symbol); clearFormErrors(formState.errors); } }, onFocus() { lastChangedField !== "from" && setValue("lastChangedField", "from"); }, onChange(value) { if (value === "") { setValue("toAmount", ""); } clearFormErrors(formState.errors); request(); resetRefreshCount(); onChange(value); lastChangedField !== "from" && setValue("lastChangedField", "from"); }, 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, minimumFrom, maximumFrom, resetRefreshCount, ], ); return ( ); };