From 5e7b96ed66db4150b0c699d0f42d81f138c5e321 Mon Sep 17 00:00:00 2001 From: simodrws Date: Tue, 27 Jun 2023 14:09:20 +0200 Subject: [PATCH] feat: masa soulname modal rework --- .eslintignore | 3 +- .../pages/create-soulname/create-soulname.tsx | 351 +++++++++++++----- 2 files changed, 250 insertions(+), 104 deletions(-) diff --git a/.eslintignore b/.eslintignore index d13c3f17..1ff54b56 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,7 +4,8 @@ dist stories typedoc.js test -src/components +# src/components src/provider/modules/custom-sbts +# !src/components/masa-interface/masa-interface/create-soulname/* jest.config.js scripts/buildUtils.js \ No newline at end of file diff --git a/src/components/masa-interface/pages/create-soulname/create-soulname.tsx b/src/components/masa-interface/pages/create-soulname/create-soulname.tsx index fee34470..6f810f8e 100644 --- a/src/components/masa-interface/pages/create-soulname/create-soulname.tsx +++ b/src/components/masa-interface/pages/create-soulname/create-soulname.tsx @@ -1,8 +1,9 @@ +import React, { useCallback, useMemo, useState } from 'react'; +import { PaymentMethod } from '@masa-finance/masa-sdk'; +import { useAsync, useAsyncFn } from 'react-use'; import { Input } from '../../../input'; -import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { useDebounce, useMasa } from '../../../../provider'; import { MasaLoading } from '../../../masa-loading'; -import { PaymentMethod } from '@masa-finance/masa-sdk'; import { Spinner } from '../../../spinner'; import { Select } from '../../../select'; import { InterfaceErrorModal } from '../error-modal'; @@ -22,21 +23,28 @@ export const InterfaceCreateSoulname = (): JSX.Element => { closeModal, company, masa, - forcedPage, + // forcedPage, setForcedPage, reloadSoulnames, soulNameStyle, } = useMasa(); const [enabledMethods, setEnabledMethods] = useState([]); - useEffect(() => { - (async () => { - const enabledMethodsres = - await masa?.contracts.instances.SoulStoreContract.getEnabledPaymentMethods(); + useAsync(async () => { + const enabledMethodsres = + await masa?.contracts.instances.SoulStoreContract.getEnabledPaymentMethods(); - setEnabledMethods(enabledMethodsres as string[]); - })(); - }, [masa]); + setEnabledMethods(enabledMethodsres as string[]); + }, [masa, setEnabledMethods]); + + // useEffect(() => { + // (async () => { + // const enabledMethodsres = + // await masa?.contracts.instances.SoulStoreContract.getEnabledPaymentMethods(); + + // setEnabledMethods(enabledMethodsres as string[]); + // })(); + // }, [masa]); const paymentMethods = useMemo(() => { const tokensAvailable = { @@ -52,11 +60,11 @@ export const InterfaceCreateSoulname = (): JSX.Element => { if ( tokensAvailable[token] && enabledMethods && - enabledMethods.includes(tokensAvailable[token]) + enabledMethods.includes(tokensAvailable[token] as string) ) values.push({ name: token as PaymentMethod, - value: tokensAvailable[token], + value: tokensAvailable[token] as string, }); } @@ -81,29 +89,43 @@ export const InterfaceCreateSoulname = (): JSX.Element => { const debounceSearch = useDebounce(soulname, 1000); - useEffect(() => { - const loadExtension = async () => { - setExtension( - await masa?.contracts.instances.SoulNameContract.extension() - ); - }; - - void loadExtension(); + useAsync(async () => { + setExtension(await masa?.contracts.instances.SoulNameContract.extension()); }, [masa]); - useEffect(() => { - const checkIsAvailable = async () => { - if (masa && debounceSearch) { - setLoadingIsAvailable(true); - setIsAvailable( - await masa.contracts.soulName.isAvailable(debounceSearch as string) - ); - setLoadingIsAvailable(false); - } - }; - - void checkIsAvailable(); - }, [masa, debounceSearch, setLoadingIsAvailable, setIsAvailable]); + // useEffect(() => { + // const loadExtension = async () => { + // setExtension( + // await masa?.contracts.instances.SoulNameContract.extension() + // ); + // }; + + // void loadExtension(); + // }, [masa]); + + useAsync(async () => { + if (masa && debounceSearch) { + setLoadingIsAvailable(true); + setIsAvailable( + await masa.contracts.soulName.isAvailable(debounceSearch as string) + ); + setLoadingIsAvailable(false); + } + }, [masa, debounceSearch, setLoadingIsAvailable]); + + // useEffect(() => { + // const checkIsAvailable = async () => { + // if (masa && debounceSearch) { + // setLoadingIsAvailable(true); + // setIsAvailable( + // await masa.contracts.soulName.isAvailable(debounceSearch as string) + // ); + // setLoadingIsAvailable(false); + // } + // }; + + // void checkIsAvailable(); + // }, [masa, debounceSearch, setLoadingIsAvailable, setIsAvailable]); const soulNameError = useMemo((): string | undefined => { if (masa) { @@ -123,28 +145,53 @@ export const InterfaceCreateSoulname = (): JSX.Element => { const handleErrorConfirmed = () => setError(null); - useEffect(() => { - const updatePrice = async () => { - if (masa && debounceSearch) { - const { length } = masa.soulName.validate(debounceSearch as string); - - let formattedPrice; - try { - formattedPrice = ( - await masa.contracts.soulName.getPrice( - paymentMethod, - length, - registrationPeriod - ) - ).formattedPrice; - } finally { - setRegistrationPrice(formattedPrice); - } + useAsync(async () => { + if (masa && debounceSearch) { + const { length } = masa.soulName.validate(debounceSearch as string); + + let formattedPrice = ''; + + try { + const formattedPriceResult = await masa.contracts.soulName.getPrice( + paymentMethod, + length, + registrationPeriod + ); + formattedPrice = formattedPriceResult.formattedPrice; + } finally { + setRegistrationPrice(formattedPrice); } - }; + } + }, [ + masa, + debounceSearch, + paymentMethod, + registrationPeriod, + setRegistrationPrice, + ]); - void updatePrice(); - }, [masa, debounceSearch, paymentMethod, registrationPeriod]); + // useEffect(() => { + // const updatePrice = async () => { + // if (masa && debounceSearch) { + // const { length } = masa.soulName.validate(debounceSearch as string); + + // let formattedPrice; + // try { + // formattedPrice = ( + // await masa.contracts.soulName.getPrice( + // paymentMethod, + // length, + // registrationPeriod + // ) + // ).formattedPrice; + // } finally { + // setRegistrationPrice(formattedPrice); + // } + // } + // }; + + // void updatePrice(); + // }, [masa, debounceSearch, paymentMethod, registrationPeriod]); const handleChangeSoulname = useCallback( (event: React.ChangeEvent) => { @@ -153,29 +200,30 @@ export const InterfaceCreateSoulname = (): JSX.Element => { [setSoulname] ); - const updatePeriod = (num: number) => { - setRegistrationPeriod(registrationPeriod + num); - }; + const updatePeriod = useCallback( + (num: number) => { + setRegistrationPeriod(registrationPeriod + num); + }, + [registrationPeriod, setRegistrationPeriod] + ); - const handleMinting = useCallback(async () => { + const [, handleMinting] = useAsyncFn(async () => { setLoadingMint(true); try { - if (identity && identity.identityId) { - await purchaseSoulName?.( - soulname, - registrationPeriod, - paymentMethod, - soulNameStyle - ); - } else { - await handlePurchaseIdentityWithSoulname?.( - paymentMethod, - soulname, - registrationPeriod, - soulNameStyle - ); - } + await (identity && identity.identityId + ? purchaseSoulName?.( + soulname, + registrationPeriod, + paymentMethod, + soulNameStyle + ) + : handlePurchaseIdentityWithSoulname?.( + paymentMethod, + soulname, + registrationPeriod, + soulNameStyle + )); if (setForcedPage) { reloadSoulnames?.(); @@ -183,67 +231,158 @@ export const InterfaceCreateSoulname = (): JSX.Element => { } else { closeModal?.(true); } - } catch (error: unknown) { - if (error) { - console.log({ error }); - const errorObject = error as { + } catch (error_: unknown) { + if (error_) { + console.log({ error_ }); + const errorObject = error_ as { code: string; message: string; }; + + const subtitle = + (errorMessages?.[errorObject.code] as string | undefined) ?? + ('Unknown error' as string); + setError({ title: '', - subtitle: errorMessages?.[errorObject.code] ?? 'Unknown error', + subtitle, }); + console.error(`Minting failed! ${errorObject.message}`); } } setLoadingMint(false); }, [ - masa, + // masa, soulname, registrationPeriod, handlePurchaseIdentityWithSoulname, identity, closeModal, paymentMethod, - forcedPage, + // forcedPage, setForcedPage, reloadSoulnames, + purchaseSoulName, + soulNameStyle, ]); - const updatePaymentMethod = (e: unknown) => { + // const handleMinting = useCallback(async () => { + // setLoadingMint(true); + + // try { + // if (identity && identity.identityId) { + // await purchaseSoulName?.( + // soulname, + // registrationPeriod, + // paymentMethod, + // soulNameStyle + // ); + // } else { + // await handlePurchaseIdentityWithSoulname?.( + // paymentMethod, + // soulname, + // registrationPeriod, + // soulNameStyle + // ); + // } + + // if (setForcedPage) { + // reloadSoulnames?.(); + // setForcedPage('successIdentityCreate'); + // } else { + // closeModal?.(true); + // } + // } catch (error: unknown) { + // if (error) { + // console.log({ error }); + // const errorObject = error as { + // code: string; + // message: string; + // }; + // setError({ + // title: '', + // subtitle: errorMessages?.[errorObject.code] ?? 'Unknown error', + // }); + // console.error(`Minting failed! ${errorObject.message}`); + // } + // } + // setLoadingMint(false); + // }, [ + // masa, + // soulname, + // registrationPeriod, + // handlePurchaseIdentityWithSoulname, + // identity, + // closeModal, + // paymentMethod, + // forcedPage, + // setForcedPage, + // reloadSoulnames, + // ]); + + const updatePaymentMethod = useCallback((e: unknown) => { const event = e as { target: { value: PaymentMethod } }; setPaymentMethod(event.target?.value); - }; + }, []); const createSoulnameTitle = useMemo(() => { switch (company) { - case 'Base Universe': - return `Register a ${company} ${extension} Name`; - default: - return `Register a ${extension} Name`; + case 'Base Universe': { + return `Register a ${company} ${String(extension)} Name`; + } + default: { + return `Register a ${String(extension)} Name`; + } } }, [company, extension]); const createSoulnameSubtitle = useMemo(() => { switch (company) { - case 'Base Universe': + case 'Base Universe': { return ( <> Claim your {extension} domain name before it's taken! Domains are FREE on testnet, only pay the gas to mint. ); - default: + } + default: { return ( <> Claim your {extension} domain name. 5+ character domains are{' '} FREE, only pay the gas fee. ); + } } }, [company, extension]); + const LoadingSoulnameAvailible = useMemo(() => { + if (soulname !== '' && soulname.length > 0) { + if (loadingIsAvailable) { + return ( +
+ +
+ ); + } + if (isAvailable) { + return ( +

+ Available +

+ ); + } + return ( +

+ Unavailable +

+ ); + } + return null; + }, [soulname, isAvailable, loadingIsAvailable]); + if (isLoading) return ; if (isLoadingMint) @@ -272,19 +411,19 @@ export const InterfaceCreateSoulname = (): JSX.Element => { ); } return ( -
-
+
+

{createSoulnameTitle}

{createSoulnameSubtitle}

-
+ -
+
{ )}

- {soulname !== '' && soulname.length >= 1 ? ( + {LoadingSoulnameAvailible} + {/* {soulname !== '' && soulname.length > 0 ? ( <> {loadingIsAvailable ? (
@@ -336,7 +476,7 @@ export const InterfaceCreateSoulname = (): JSX.Element => {

)} - ) : null} + ) : null} */}
@@ -361,29 +501,34 @@ export const InterfaceCreateSoulname = (): JSX.Element => { disabled />
- - + +
-
+ -
+
- + + ); };