import React, { FocusEventHandler, ReactNode, useCallback, useEffect, useMemo, } from "react"; import { ControllerProps, ControllerRenderProps, FieldErrors, } from "react-hook-form"; import { Asset, useAssets } from "../useAssets"; import { useDisplayDecimalDigits } from "../useDisplayDecimalDigits"; import { BuySellContext, BuySellFormProps } from "./context"; import { useBuySellAmountValidation } from "./useBuySellAmountValidation"; import { useBuySellMarketConfigs } from "./useBuySellConfigs"; import { useUpdatePreview } from "./useUpdatePreview"; type SellRecieveRenderProps = { render: (state: { field: ControllerRenderProps & { assets: Asset[]; asset?: Asset; minQuantity: number; hasError?: boolean; maxQuantity: number; availableRemain: number; onSelect?: (value?: Asset | undefined) => void; onFocus?: (e: FocusEventHandler | undefined) => void; getMaxSize?: (value: number) => string | number; stepSize?: number; }; }) => React.ReactElement; renderErrorComponent?: (message?: string) => ReactNode; }; export const SellRecieveController = ({ render, renderErrorComponent, }: SellRecieveRenderProps) => { // const { control } = BuySellContext.useFormContext(); // const [ lastChangedField] = useWatch({ // name: ["fromAsset", "toAsset", "lastChangedField"], // control, // defaultValue: { // lastChangedField: "from", // }, // }); const { lastChangedField } = BuySellContext.useWatch(); // console.log({4:lastChangedField}) const { allAssets } = useAssets(); const { resetRefreshCount, request } = useUpdatePreview({ mode: "to", type: "sell", }); const { filterPrice, getMaxSize, selectedCurrency } = useBuySellMarketConfigs( { mode: "to", }, ); const { setValue, clearErrors, register, getValues } = BuySellContext.useFormContext(); register("shouldCharge"); const assets = useMemo(() => { return allAssets?.filter((i) => i.canCharge) || []; }, [allAssets]); const { truncFix } = useDisplayDecimalDigits(); useEffect(() => { const { toAsset } = getValues(); if (toAsset === undefined) { const symbol = assets?.[0]?.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( () => ({ validate: { check: (value: string | null | undefined) => checkAmount({ value, mode: "to", }), }, }), [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: filterPrice?.tickSize, ...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 ( <> ); };