diff --git a/client/src/app/components/nova/address/AccountAddressView.tsx b/client/src/app/components/nova/address/AccountAddressView.tsx index d0580c7ac..a818ab1ba 100644 --- a/client/src/app/components/nova/address/AccountAddressView.tsx +++ b/client/src/app/components/nova/address/AccountAddressView.tsx @@ -3,7 +3,7 @@ import React from "react"; import { useAccountAddressState } from "~/helpers/nova/hooks/useAccountAddressState"; import Spinner from "../../Spinner"; import Bech32Address from "../../nova/address/Bech32Address"; -import AssociatedOutputs from "./section/association/AssociatedOutputs"; +import { AddressPageTabbedSections } from "./section/AddressPageTabbedSections"; import AddressBalance from "./AddressBalance"; interface AccountAddressViewProps { @@ -11,9 +11,9 @@ interface AccountAddressViewProps { } const AccountAddressView: React.FC = ({ accountAddress }) => { - const [state] = useAccountAddressState(accountAddress); - const { accountAddressDetails, totalBalance, availableBalance, isAccountDetailsLoading } = state; - const isPageLoading = isAccountDetailsLoading; + const [state, setState] = useAccountAddressState(accountAddress); + const { accountAddressDetails, totalBalance, availableBalance, isAccountDetailsLoading, isAssociatedOutputsLoading } = state; + const isPageLoading = isAccountDetailsLoading || isAssociatedOutputsLoading; return (
@@ -45,12 +45,11 @@ const AccountAddressView: React.FC = ({ accountAddress
-
-
-

Associated Outputs

-
- -
+ setState({ isAssociatedOutputsLoading: val })} + /> )} diff --git a/client/src/app/components/nova/address/AnchorAddressView.tsx b/client/src/app/components/nova/address/AnchorAddressView.tsx index 19045e588..26133497d 100644 --- a/client/src/app/components/nova/address/AnchorAddressView.tsx +++ b/client/src/app/components/nova/address/AnchorAddressView.tsx @@ -4,16 +4,16 @@ import { useAnchorAddressState } from "~/helpers/nova/hooks/useAnchorAddressStat import Spinner from "../../Spinner"; import AddressBalance from "./AddressBalance"; import Bech32Address from "./Bech32Address"; -import AssociatedOutputs from "./section/association/AssociatedOutputs"; +import { AddressPageTabbedSections } from "./section/AddressPageTabbedSections"; interface AnchorAddressViewProps { anchorAddress: AnchorAddress; } const AnchorAddressView: React.FC = ({ anchorAddress }) => { - const [state] = useAnchorAddressState(anchorAddress); - const { anchorAddressDetails, totalBalance, availableBalance, isAnchorDetailsLoading } = state; - const isPageLoading = isAnchorDetailsLoading; + const [state, setState] = useAnchorAddressState(anchorAddress); + const { anchorAddressDetails, totalBalance, availableBalance, isAnchorDetailsLoading, isAssociatedOutputsLoading } = state; + const isPageLoading = isAnchorDetailsLoading || isAssociatedOutputsLoading; return (
@@ -45,12 +45,11 @@ const AnchorAddressView: React.FC = ({ anchorAddress })
-
-
-

Associated Outputs

-
- -
+ setState({ isAssociatedOutputsLoading: val })} + /> )} diff --git a/client/src/app/components/nova/address/Ed25519AddressView.tsx b/client/src/app/components/nova/address/Ed25519AddressView.tsx index 4b6ea5adc..937111802 100644 --- a/client/src/app/components/nova/address/Ed25519AddressView.tsx +++ b/client/src/app/components/nova/address/Ed25519AddressView.tsx @@ -3,15 +3,17 @@ import React from "react"; import { useEd25519AddressState } from "~/helpers/nova/hooks/useEd25519AddressState"; import AddressBalance from "./AddressBalance"; import Bech32Address from "./Bech32Address"; -import AssociatedOutputs from "./section/association/AssociatedOutputs"; +import { AddressPageTabbedSections } from "./section/AddressPageTabbedSections"; +import Spinner from "../../Spinner"; interface Ed25519AddressViewProps { ed25519Address: Ed25519Address; } const Ed25519AddressView: React.FC = ({ ed25519Address }) => { - const [state] = useEd25519AddressState(ed25519Address); - const { ed25519AddressDetails, totalBalance, availableBalance } = state; + const [state, setState] = useEd25519AddressState(ed25519Address); + const { ed25519AddressDetails, totalBalance, availableBalance, isAssociatedOutputsLoading } = state; + const isPageLoading = isAssociatedOutputsLoading; return (
@@ -21,6 +23,7 @@ const Ed25519AddressView: React.FC = ({ ed25519Address

{ed25519AddressDetails.label?.replace("Ed25519", "Address")}

+ {isPageLoading && }
@@ -42,12 +45,11 @@ const Ed25519AddressView: React.FC = ({ ed25519Address
-
-
-

Associated Outputs

-
- -
+ setState({ isAssociatedOutputsLoading: val })} + /> )} diff --git a/client/src/app/components/nova/address/ImplicitAccountCreationAddressView.tsx b/client/src/app/components/nova/address/ImplicitAccountCreationAddressView.tsx index e989dbf1a..03e25303c 100644 --- a/client/src/app/components/nova/address/ImplicitAccountCreationAddressView.tsx +++ b/client/src/app/components/nova/address/ImplicitAccountCreationAddressView.tsx @@ -3,15 +3,17 @@ import React from "react"; import { useImplicitAccountCreationAddressState } from "~/helpers/nova/hooks/useImplicitAccountCreationAddressState"; import AddressBalance from "./AddressBalance"; import Bech32Address from "./Bech32Address"; -import AssociatedOutputs from "./section/association/AssociatedOutputs"; +import Spinner from "../../Spinner"; +import { AddressPageTabbedSections } from "./section/AddressPageTabbedSections"; interface ImplicitAccountCreationAddressViewProps { implicitAccountCreationAddress: ImplicitAccountCreationAddress; } const ImplicitAccountCreationAddressView: React.FC = ({ implicitAccountCreationAddress }) => { - const [state] = useImplicitAccountCreationAddressState(implicitAccountCreationAddress); - const { implicitAccountCreationAddressDetails, totalBalance, availableBalance } = state; + const [state, setState] = useImplicitAccountCreationAddressState(implicitAccountCreationAddress); + const { implicitAccountCreationAddressDetails, totalBalance, availableBalance, isAssociatedOutputsLoading } = state; + const isPageLoading = isAssociatedOutputsLoading; return (
@@ -22,6 +24,7 @@ const ImplicitAccountCreationAddressView: React.FC

{implicitAccountCreationAddressDetails.label?.replace("Ed25519", "Address")}

+ {isPageLoading && }
@@ -42,12 +45,11 @@ const ImplicitAccountCreationAddressView: React.FC
-
-
-

Associated Outputs

-
- -
+ setState({ isAssociatedOutputsLoading: val })} + /> )} diff --git a/client/src/app/components/nova/address/NftAddressView.tsx b/client/src/app/components/nova/address/NftAddressView.tsx index e47ab889b..a13f2d3c1 100644 --- a/client/src/app/components/nova/address/NftAddressView.tsx +++ b/client/src/app/components/nova/address/NftAddressView.tsx @@ -4,16 +4,16 @@ import { useNftAddressState } from "~/helpers/nova/hooks/useNftAddressState"; import Spinner from "../../Spinner"; import AddressBalance from "./AddressBalance"; import Bech32Address from "./Bech32Address"; -import AssociatedOutputs from "./section/association/AssociatedOutputs"; +import { AddressPageTabbedSections } from "./section/AddressPageTabbedSections"; interface NftAddressViewProps { nftAddress: NftAddress; } const NftAddressView: React.FC = ({ nftAddress }) => { - const [state] = useNftAddressState(nftAddress); - const { nftAddressDetails, totalBalance, availableBalance, isNftDetailsLoading } = state; - const isPageLoading = isNftDetailsLoading; + const [state, setState] = useNftAddressState(nftAddress); + const { nftAddressDetails, totalBalance, availableBalance, isNftDetailsLoading, isAssociatedOutputsLoading } = state; + const isPageLoading = isNftDetailsLoading || isAssociatedOutputsLoading; return (
@@ -45,12 +45,11 @@ const NftAddressView: React.FC = ({ nftAddress }) => {
-
-
-

Associated Outputs

-
- -
+ setState({ isAssociatedOutputsLoading: val })} + /> )} diff --git a/client/src/app/components/nova/address/section/AddressPageTabbedSections.tsx b/client/src/app/components/nova/address/section/AddressPageTabbedSections.tsx new file mode 100644 index 000000000..82ba54e4a --- /dev/null +++ b/client/src/app/components/nova/address/section/AddressPageTabbedSections.tsx @@ -0,0 +1,50 @@ +import React, { useState } from "react"; +import associatedOuputsMessage from "~assets/modals/stardust/address/associated-outputs.json"; +import TabbedSection from "../../../hoc/TabbedSection"; +import AssociatedOutputs from "./association/AssociatedOutputs"; +import { IAddressDetails } from "~/models/api/nova/IAddressDetails"; + +enum DEFAULT_TABS { + AssocOutputs = "Outputs", +} + +const buildDefaultTabsOptions = (associatedOutputCount: number) => ({ + [DEFAULT_TABS.AssocOutputs]: { + disabled: associatedOutputCount === 0, + counter: associatedOutputCount, + infoContent: associatedOuputsMessage, + }, +}); + +interface IAddressPageTabbedSectionsProps { + readonly addressDetails: IAddressDetails; + readonly setAssociatedOutputsLoading: (isLoading: boolean) => void; +} + +export const AddressPageTabbedSections: React.FC = ({ addressDetails, setAssociatedOutputsLoading }) => { + const [outputCount, setOutputCount] = useState(0); + + if (!addressDetails) { + return null; + } + + const defaultSections = [ + , + ]; + + const tabEnums = DEFAULT_TABS; + const defaultTabsOptions = buildDefaultTabsOptions(outputCount); + const tabOptions = defaultTabsOptions; + const tabbedSections = defaultSections; + + return ( + + {tabbedSections} + + ); +}; diff --git a/client/src/helpers/nova/hooks/useAccountAddressState.ts b/client/src/helpers/nova/hooks/useAccountAddressState.ts index 2ffcb4698..76c649eb5 100644 --- a/client/src/helpers/nova/hooks/useAccountAddressState.ts +++ b/client/src/helpers/nova/hooks/useAccountAddressState.ts @@ -14,6 +14,7 @@ export interface IAccountAddressState { totalBalance: number | null; availableBalance: number | null; isAccountDetailsLoading: boolean; + isAssociatedOutputsLoading: boolean; } const initialState = { @@ -22,6 +23,7 @@ const initialState = { totalBalance: null, availableBalance: null, isAccountDetailsLoading: true, + isAssociatedOutputsLoading: false, }; /** diff --git a/client/src/helpers/nova/hooks/useAnchorAddressState.ts b/client/src/helpers/nova/hooks/useAnchorAddressState.ts index 9392ffb39..b11062bce 100644 --- a/client/src/helpers/nova/hooks/useAnchorAddressState.ts +++ b/client/src/helpers/nova/hooks/useAnchorAddressState.ts @@ -14,6 +14,7 @@ export interface IAnchorAddressState { availableBalance: number | null; totalBalance: number | null; isAnchorDetailsLoading: boolean; + isAssociatedOutputsLoading: boolean; } const initialState = { @@ -22,6 +23,7 @@ const initialState = { totalBalance: null, availableBalance: null, isAnchorDetailsLoading: true, + isAssociatedOutputsLoading: false, }; /** diff --git a/client/src/helpers/nova/hooks/useEd25519AddressState.ts b/client/src/helpers/nova/hooks/useEd25519AddressState.ts index eba0b46f0..d5cbffe8b 100644 --- a/client/src/helpers/nova/hooks/useEd25519AddressState.ts +++ b/client/src/helpers/nova/hooks/useEd25519AddressState.ts @@ -10,12 +10,14 @@ export interface IEd25519AddressState { ed25519AddressDetails: IAddressDetails | null; totalBalance: number | null; availableBalance: number | null; + isAssociatedOutputsLoading: boolean; } const initialState = { ed25519AddressDetails: null, totalBalance: null, availableBalance: null, + isAssociatedOutputsLoading: false, }; /** diff --git a/client/src/helpers/nova/hooks/useImplicitAccountCreationAddressState.ts b/client/src/helpers/nova/hooks/useImplicitAccountCreationAddressState.ts index bf5052233..e569462b6 100644 --- a/client/src/helpers/nova/hooks/useImplicitAccountCreationAddressState.ts +++ b/client/src/helpers/nova/hooks/useImplicitAccountCreationAddressState.ts @@ -11,12 +11,14 @@ export interface IImplicitAccountCreationAddressState { implicitAccountCreationAddressDetails: IAddressDetails | null; totalBalance: number | null; availableBalance: number | null; + isAssociatedOutputsLoading: boolean; } const initialState = { implicitAccountCreationAddressDetails: null, totalBalance: null, availableBalance: null, + isAssociatedOutputsLoading: false, }; /** diff --git a/client/src/helpers/nova/hooks/useNftAddressState.ts b/client/src/helpers/nova/hooks/useNftAddressState.ts index 0b8035ade..aa361ccca 100644 --- a/client/src/helpers/nova/hooks/useNftAddressState.ts +++ b/client/src/helpers/nova/hooks/useNftAddressState.ts @@ -14,6 +14,7 @@ export interface INftAddressState { totalBalance: number | null; availableBalance: number | null; isNftDetailsLoading: boolean; + isAssociatedOutputsLoading: boolean; } const initialState = { @@ -22,6 +23,7 @@ const initialState = { isNftDetailsLoading: true, totalBalance: null, availableBalance: null, + isAssociatedOutputsLoading: false, }; /**