From 8302c8439b70e412fdb5e6bfd925ce944913bf4b Mon Sep 17 00:00:00 2001 From: Pete Watters <2938440+pete-watters@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:07:01 +0100 Subject: [PATCH] chore: refactor containers to use composition --- .../broadcast-error-dialog.tsx | 4 +- src/app/components/request-password.tsx | 2 +- src/app/features/add-network/add-network.tsx | 2 + .../sip10-token-asset-list.tsx | 2 +- .../bitcoin-choose-fee/bitcoin-choose-fee.tsx | 2 +- src/app/features/container/container.tsx | 148 +------- .../container/containers/container.layout.tsx | 16 + .../containers/footers/available-balance.tsx | 0 .../containers/footers/footer.stories.tsx | 0 .../container}/containers/footers/footer.tsx | 0 .../components/header-action-button.tsx | 0 .../containers/headers/dialog-header.tsx | 9 +- .../container/containers/home/home-header.tsx | 61 ++++ .../container/containers/home/home.layout.tsx | 36 ++ .../onboarding/onboarding-header.tsx | 72 ++++ .../onboarding/onboarding.layout.tsx | 55 +++ .../containers/page/page.context.tsx | 62 ++++ .../container/containers/page/page.header.tsx | 119 +++++++ .../container/containers/page/page.layout.tsx | 13 + .../containers/popup/popup-header.tsx | 37 ++ .../containers/popup/popup.layout.tsx | 106 ++++++ .../container/utils/get-popup-header.ts | 83 ----- .../container/utils/get-title-from-url.ts | 36 -- .../features/container/utils/route-helpers.ts | 80 ----- .../current-account-avatar.tsx | 13 +- .../edit-nonce-dialog/edit-nonce-dialog.tsx | 2 +- .../increase-btc-fee-dialog.tsx | 4 +- .../increase-stx-fee-dialog.tsx | 4 +- .../switch-account-dialog.tsx | 9 +- .../jwt-signing/ledger-sign-jwt-container.tsx | 2 +- .../ledger-stacks-sign-msg-container.tsx | 2 +- .../request-keys/request-keys-flow.tsx | 2 +- .../tx-signing/tx-signing-flow.tsx | 2 +- .../connect-device/connect-ledger-start.tsx | 2 +- .../unsupported-browser.layout.tsx | 2 +- .../components/psbt-request-actions.tsx | 2 +- src/app/features/psbt-signer/psbt-signer.tsx | 2 +- ...trieve-taproot-to-native-segwit.layout.tsx | 4 +- src/app/features/settings/network/network.tsx | 4 +- .../features/settings/sign-out/sign-out.tsx | 4 +- .../features/settings/theme/theme-dialog.tsx | 2 +- .../stacks-high-fee-dialog.tsx | 4 +- .../bitcoin-contract-list.tsx | 3 + .../bitcoin-contract-request.tsx | 2 +- .../choose-asset-to-fund.tsx | 2 + src/app/pages/fund/fund.tsx | 4 + src/app/pages/home/home.tsx | 14 +- .../components/receive-tokens.layout.tsx | 10 +- src/app/pages/receive/receive-dialog.tsx | 8 +- .../choose-crypto-asset.tsx | 4 + .../locked-bitcoin-summary.tsx | 4 +- .../send-inscription-choose-fee.tsx | 2 +- .../send-inscription-form.tsx | 4 +- .../send-inscription-review.tsx | 4 +- .../sent-inscription-summary.tsx | 4 +- .../recipient-accounts-dialog.tsx | 2 +- .../form/brc20/brc20-choose-fee.tsx | 2 + .../brc20/brc20-send-form-confirmation.tsx | 2 +- .../form/brc20/brc20-send-form.tsx | 4 +- .../form/btc/btc-choose-fee.tsx | 2 + .../form/btc/btc-send-form-confirmation.tsx | 4 +- .../form/btc/btc-send-form.tsx | 8 +- .../form/send-form-confirmation.tsx | 2 +- .../form/sip10/sip10-token-send-form.tsx | 2 + .../form/stacks/stacks-common-send-form.tsx | 6 +- .../stacks/stacks-send-form-confirmation.tsx | 8 + .../form/stx/stx-send-form.tsx | 3 +- .../send-crypto-asset-form.routes.tsx | 1 + .../send/sent-summary/brc20-sent-summary.tsx | 4 +- .../send/sent-summary/btc-sent-summary.tsx | 4 +- .../send/sent-summary/stx-sent-summary.tsx | 5 +- .../swap-asset-dialog-base.tsx | 8 +- .../swap-asset-dialog-quote.tsx | 8 +- src/app/pages/swap/components/swap-review.tsx | 2 +- src/app/pages/swap/swap.tsx | 7 +- src/app/pages/unlock.tsx | 3 +- src/app/routes/app-routes.tsx | 321 +++++++++--------- src/app/routes/rpc-routes.tsx | 23 ++ .../containers/container.layout.tsx | 22 -- .../headers/components/big-title-header.tsx | 30 -- .../containers/headers/header.stories.tsx | 22 -- .../components/containers/headers/header.tsx | 90 ----- 82 files changed, 902 insertions(+), 769 deletions(-) create mode 100644 src/app/features/container/containers/container.layout.tsx rename src/app/{ui/components => features/container}/containers/footers/available-balance.tsx (100%) rename src/app/{ui/components => features/container}/containers/footers/footer.stories.tsx (100%) rename src/app/{ui/components => features/container}/containers/footers/footer.tsx (100%) rename src/app/{ui/components => features/container}/containers/headers/components/header-action-button.tsx (100%) rename src/app/{ui/components => features/container}/containers/headers/dialog-header.tsx (66%) create mode 100644 src/app/features/container/containers/home/home-header.tsx create mode 100644 src/app/features/container/containers/home/home.layout.tsx create mode 100644 src/app/features/container/containers/onboarding/onboarding-header.tsx create mode 100644 src/app/features/container/containers/onboarding/onboarding.layout.tsx create mode 100644 src/app/features/container/containers/page/page.context.tsx create mode 100644 src/app/features/container/containers/page/page.header.tsx create mode 100644 src/app/features/container/containers/page/page.layout.tsx create mode 100644 src/app/features/container/containers/popup/popup-header.tsx create mode 100644 src/app/features/container/containers/popup/popup.layout.tsx delete mode 100644 src/app/features/container/utils/get-popup-header.ts delete mode 100644 src/app/features/container/utils/get-title-from-url.ts delete mode 100644 src/app/features/container/utils/route-helpers.ts delete mode 100644 src/app/ui/components/containers/container.layout.tsx delete mode 100644 src/app/ui/components/containers/headers/components/big-title-header.tsx delete mode 100644 src/app/ui/components/containers/headers/header.stories.tsx delete mode 100644 src/app/ui/components/containers/headers/header.tsx diff --git a/src/app/components/broadcast-error-dialog/broadcast-error-dialog.tsx b/src/app/components/broadcast-error-dialog/broadcast-error-dialog.tsx index 946a40edfef..a31064ece04 100644 --- a/src/app/components/broadcast-error-dialog/broadcast-error-dialog.tsx +++ b/src/app/components/broadcast-error-dialog/broadcast-error-dialog.tsx @@ -6,8 +6,8 @@ import get from 'lodash.get'; import { Button, Dialog } from '@leather.io/ui'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; export function BroadcastErrorDialog() { const navigate = useNavigate(); diff --git a/src/app/components/request-password.tsx b/src/app/components/request-password.tsx index 7993607fc71..9c31925af71 100644 --- a/src/app/components/request-password.tsx +++ b/src/app/components/request-password.tsx @@ -10,7 +10,7 @@ import { analytics } from '@shared/utils/analytics'; import { useKeyActions } from '@app/common/hooks/use-key-actions'; import { buildEnterKeyEvent } from '@app/common/hooks/use-modifier-key'; import { WaitingMessages, useWaitingMessage } from '@app/common/hooks/use-waiting-message'; -import { Footer } from '@app/ui/components/containers/footers/footer'; +import { Footer } from '@app/features/container/containers/footers/footer'; import { Card } from '@app/ui/layout/card/card'; import { Page } from '@app/ui/layout/page/page.layout'; diff --git a/src/app/features/add-network/add-network.tsx b/src/app/features/add-network/add-network.tsx index f3a23a4e31c..c99d1195dd1 100644 --- a/src/app/features/add-network/add-network.tsx +++ b/src/app/features/add-network/add-network.tsx @@ -5,6 +5,7 @@ import { Stack, styled } from 'leather-styles/jsx'; import { Button } from '@leather.io/ui'; import { ErrorLabel } from '@app/components/error-label'; +import { useUpdatePageHeaderContext } from '@app/features/container/containers/page/page.context'; import { Card } from '@app/ui/layout/card/card'; import { Page } from '@app/ui/layout/page/page.layout'; @@ -13,6 +14,7 @@ import { useAddNetwork } from './use-add-network'; export function AddNetwork() { const { error, initialFormValues, loading, onSubmit } = useAddNetwork(); + useUpdatePageHeaderContext({ title: 'Add Network' }); return ( diff --git a/src/app/features/asset-list/stacks/sip10-token-asset-list/sip10-token-asset-list.tsx b/src/app/features/asset-list/stacks/sip10-token-asset-list/sip10-token-asset-list.tsx index 3a8933f4dfd..81a3ebcf260 100644 --- a/src/app/features/asset-list/stacks/sip10-token-asset-list/sip10-token-asset-list.tsx +++ b/src/app/features/asset-list/stacks/sip10-token-asset-list/sip10-token-asset-list.tsx @@ -25,7 +25,7 @@ export function Sip10TokenAssetList({ {tokens.map(token => ( closeWindow()); useOnSignOut(() => closeWindow()); @@ -63,117 +27,13 @@ export function Container() { useEffect(() => void analytics.page('view', `${pathname}`), [pathname]); - const variant = getPageVariant(pathname); - - const displayHeader = !isLandingPage(pathname) && !isNoHeaderPopup(pathname); - const isSessionLocked = getIsSessionLocked(pathname); - - // TODO: Refactor? This is very hard to manage with dynamic routes. Temporarily - // added a fix to catch the swap route: '/swap/:base/:quote?' - function getOnGoBackLocation(pathname: RouteUrls) { - if (pathname.includes('/swap')) return navigate(RouteUrls.Home); - switch (pathname) { - case RouteUrls.Fund.replace(':currency', 'STX'): - case RouteUrls.Fund.replace(':currency', 'BTC'): - case RouteUrls.SendCryptoAssetForm.replace(':symbol', 'stx'): - case RouteUrls.SendCryptoAssetForm.replace(':symbol', 'btc'): - return navigate(RouteUrls.Home); - case RouteUrls.SendStxConfirmation: - return navigate(RouteUrls.SendCryptoAssetForm.replace(':symbol', 'stx')); - case RouteUrls.SendBtcConfirmation: - return navigate(RouteUrls.SendCryptoAssetForm.replace(':symbol', 'btc')); - default: - return navigate(-1); - } - } - if (!hasStateRehydrated) return ; - const showLogoSm = variant === 'home' || isSessionLocked || isKnownPopupRoute(pathname); - const hideSettings = - isKnownPopupRoute(pathname) || isSummaryPage(pathname) || variant === 'onboarding'; - - const isLogoClickable = variant !== 'home' && !isRpcRoute(pathname); return ( <> - {isShowingSwitchAccount && ( - setIsShowingSwitchAccount(false)} - /> - )} - - getOnGoBackLocation(pathname) : undefined} - onClose={isSummaryPage(pathname) ? () => navigate(RouteUrls.Home) : undefined} - settingsMenu={ - hideSettings ? null : ( - - } - toggleSwitchAccount={() => setIsShowingSwitchAccount(!isShowingSwitchAccount)} - /> - ) - } - networkBadge={ - - } - title={getTitleFromUrl(pathname)} - logo={ - !hideLogo(pathname) && ( - - navigate(RouteUrls.Home) : undefined} - /> - - ) - } - account={ - showAccountInfo(pathname) && ( - - setIsShowingSwitchAccount(!isShowingSwitchAccount) - } - /> - } - > - - - ) - } - totalBalance={ - showBalanceInfo(pathname) && ( - - ) - } - /> - ) : null - } - > - - + + ); } diff --git a/src/app/features/container/containers/container.layout.tsx b/src/app/features/container/containers/container.layout.tsx new file mode 100644 index 00000000000..eaa190a389a --- /dev/null +++ b/src/app/features/container/containers/container.layout.tsx @@ -0,0 +1,16 @@ +import { Flex } from 'leather-styles/jsx'; + +interface ContainerLayoutProps { + content?: React.JSX.Element | React.JSX.Element[]; + header?: React.JSX.Element | null; +} +export function ContainerLayout({ content, header }: ContainerLayoutProps) { + return ( + + {header} + + {content} + + + ); +} diff --git a/src/app/ui/components/containers/footers/available-balance.tsx b/src/app/features/container/containers/footers/available-balance.tsx similarity index 100% rename from src/app/ui/components/containers/footers/available-balance.tsx rename to src/app/features/container/containers/footers/available-balance.tsx diff --git a/src/app/ui/components/containers/footers/footer.stories.tsx b/src/app/features/container/containers/footers/footer.stories.tsx similarity index 100% rename from src/app/ui/components/containers/footers/footer.stories.tsx rename to src/app/features/container/containers/footers/footer.stories.tsx diff --git a/src/app/ui/components/containers/footers/footer.tsx b/src/app/features/container/containers/footers/footer.tsx similarity index 100% rename from src/app/ui/components/containers/footers/footer.tsx rename to src/app/features/container/containers/footers/footer.tsx diff --git a/src/app/ui/components/containers/headers/components/header-action-button.tsx b/src/app/features/container/containers/headers/components/header-action-button.tsx similarity index 100% rename from src/app/ui/components/containers/headers/components/header-action-button.tsx rename to src/app/features/container/containers/headers/components/header-action-button.tsx diff --git a/src/app/ui/components/containers/headers/dialog-header.tsx b/src/app/features/container/containers/headers/dialog-header.tsx similarity index 66% rename from src/app/ui/components/containers/headers/dialog-header.tsx rename to src/app/features/container/containers/headers/dialog-header.tsx index 40d0f58093a..4fed3c77c90 100644 --- a/src/app/ui/components/containers/headers/dialog-header.tsx +++ b/src/app/features/container/containers/headers/dialog-header.tsx @@ -7,9 +7,10 @@ import { CloseIcon, IconButton } from '@leather.io/ui'; interface DialogHeaderProps { onClose?(): void; title?: ReactNode; + variant?: 'default' | 'large'; } -export function DialogHeader({ onClose, title }: DialogHeaderProps) { +export function DialogHeader({ onClose, title, variant = 'default' }: DialogHeaderProps) { return ( {title && ( - + {title} )} diff --git a/src/app/features/container/containers/home/home-header.tsx b/src/app/features/container/containers/home/home-header.tsx new file mode 100644 index 00000000000..9e7e1df4bc6 --- /dev/null +++ b/src/app/features/container/containers/home/home-header.tsx @@ -0,0 +1,61 @@ +import { ReactNode, useState } from 'react'; + +import { SettingsSelectors } from '@tests/selectors/settings.selectors'; +import { Flex, Grid, GridItem, HStack, styled } from 'leather-styles/jsx'; + +import { HamburgerIcon } from '@leather.io/ui'; + +import { SwitchAccountDialog } from '@app/features/dialogs/switch-account-dialog/switch-account-dialog'; + +import { Settings } from '../../../settings/settings'; + +interface HomeHeaderProps { + networkBadge?: ReactNode; + logo?: ReactNode; +} + +export function HomeHeader({ networkBadge, logo }: HomeHeaderProps) { + const [isShowingSwitchAccount, setIsShowingSwitchAccount] = useState(false); + return ( + <> + {isShowingSwitchAccount && ( + setIsShowingSwitchAccount(false)} + /> + )} + + + + {logo} + + + {/* This grid item could be un-needed */} + + + + {networkBadge} + } + toggleSwitchAccount={() => setIsShowingSwitchAccount(!isShowingSwitchAccount)} + /> + + + + + + ); +} diff --git a/src/app/features/container/containers/home/home.layout.tsx b/src/app/features/container/containers/home/home.layout.tsx new file mode 100644 index 00000000000..a4458c8c622 --- /dev/null +++ b/src/app/features/container/containers/home/home.layout.tsx @@ -0,0 +1,36 @@ +import { Outlet } from 'react-router-dom'; + +import { ChainID } from '@stacks/transactions'; +import { Box } from 'leather-styles/jsx'; + +import { Logo, NetworkModeBadge } from '@leather.io/ui'; + +import { useCurrentNetworkState } from '@app/store/networks/networks.hooks'; + +import { ContainerLayout } from '../container.layout'; +import { HomeHeader } from './home-header'; + +export function HomeLayout() { + const { chain, name: chainName } = useCurrentNetworkState(); + + return ( + + } + logo={ + + + + } + /> + } + content={} + /> + ); +} diff --git a/src/app/features/container/containers/onboarding/onboarding-header.tsx b/src/app/features/container/containers/onboarding/onboarding-header.tsx new file mode 100644 index 00000000000..4416f51d731 --- /dev/null +++ b/src/app/features/container/containers/onboarding/onboarding-header.tsx @@ -0,0 +1,72 @@ +import { ReactNode } from 'react'; + +import { SharedComponentsSelectors } from '@tests/selectors/shared-component.selectors'; +import { Flex, Grid, GridItem, HStack, styled } from 'leather-styles/jsx'; + +import { ArrowLeftIcon } from '@leather.io/ui'; + +import { HeaderActionButton } from '../headers/components/header-action-button'; + +interface HeaderProps { + onClose?(): void; + onGoBack?(): void; + title?: ReactNode; + settingsMenu?: ReactNode; + networkBadge?: ReactNode; + logo?: ReactNode; +} + +export function OnboardingHeader({ onGoBack, networkBadge, logo }: HeaderProps) { + const logoItem = onGoBack || logo; + + return ( + + {/* + This could probably be a Flex? Or maybe better to keep grid to share code + Have a grid wrapper with an empty div middle? or that accepts children? and auto cols? + */} + + + {logoItem && ( + + {onGoBack && ( + } + onAction={onGoBack} + dataTestId={SharedComponentsSelectors.HeaderBackBtn} + /> + )} + {logo} + + )} + + + + {/* {title && {title}} */} + + + {/* ViewSecretKey needs to show network badge */} + + {networkBadge} + + + + + ); +} diff --git a/src/app/features/container/containers/onboarding/onboarding.layout.tsx b/src/app/features/container/containers/onboarding/onboarding.layout.tsx new file mode 100644 index 00000000000..9be69a05327 --- /dev/null +++ b/src/app/features/container/containers/onboarding/onboarding.layout.tsx @@ -0,0 +1,55 @@ +import { Outlet, useLocation, useNavigate } from 'react-router-dom'; + +import { ChainID } from '@stacks/transactions'; +import { OnboardingSelectors } from '@tests/selectors/onboarding.selectors'; +import { Box } from 'leather-styles/jsx'; + +import { Logo, NetworkModeBadge } from '@leather.io/ui'; + +import { RouteUrls } from '@shared/route-urls'; + +import { useCurrentNetworkState } from '@app/store/networks/networks.hooks'; + +import { ContainerLayout } from '../container.layout'; +import { OnboardingHeader } from './onboarding-header'; + +export function OnboardingLayout() { + const navigate = useNavigate(); + const { pathname: locationPathname } = useLocation(); + const pathname = locationPathname as RouteUrls; + + const { chain, name: chainName } = useCurrentNetworkState(); + + const displayHeader = !pathname.match(RouteUrls.Onboarding); + + return ( + navigate(-1)} + networkBadge={ + + } + logo={ + // fixme this RouteUrls.ViewSecretKey needs work to show logo when viewing key but not when entering password + // maybe I can use a context here also to update the header when its unlocked? ? + pathname !== RouteUrls.ViewSecretKey && ( + + navigate(RouteUrls.Home)} + /> + + ) + } + /> + ) : null + } + content={} + /> + ); +} diff --git a/src/app/features/container/containers/page/page.context.tsx b/src/app/features/container/containers/page/page.context.tsx new file mode 100644 index 00000000000..a884d3df294 --- /dev/null +++ b/src/app/features/container/containers/page/page.context.tsx @@ -0,0 +1,62 @@ +import { ReactNode, createContext, useContext, useEffect, useReducer } from 'react'; + +import { RouteUrls } from '@shared/route-urls'; + +interface HeaderPayloadState { + title?: string; + isSummaryPage?: boolean; + isSessionLocked?: boolean; + isSettingsVisibleOnSm?: boolean; + onBackLocation?: RouteUrls; + onClose?(): void; +} + +interface UpdateAction { + type: 'update'; + payload: HeaderPayloadState; +} + +interface ResetAction { + type: 'reset'; +} +type Action = UpdateAction | ResetAction; + +const initialPageState = { isSessionLocked: false, isSettingsVisibleOnSm: true }; +const pageReducer = (state: HeaderPayloadState, action: Action): HeaderPayloadState => { + switch (action.type) { + case 'update': + return { ...state, ...action.payload }; + case 'reset': + default: + return initialPageState; + } +}; + +const PageContext = createContext< + { state: HeaderPayloadState; dispatch: React.Dispatch } | undefined +>(undefined); + +export function PageProvider({ children }: { children: ReactNode }) { + const [state, dispatch] = useReducer(pageReducer, initialPageState); + const value = { state, dispatch }; + return {children}; +} + +export const usePageContext = () => { + const context = useContext(PageContext); + if (context === undefined) { + throw new Error('usePageContext must be used within a PageProvider'); + } + return context; +}; + +export function useUpdatePageHeaderContext(payload: HeaderPayloadState) { + const { dispatch } = usePageContext(); + + useEffect(() => { + dispatch({ type: 'update', payload }); + return () => { + dispatch({ type: 'reset' }); + }; + }); +} diff --git a/src/app/features/container/containers/page/page.header.tsx b/src/app/features/container/containers/page/page.header.tsx new file mode 100644 index 00000000000..641bcf4cb49 --- /dev/null +++ b/src/app/features/container/containers/page/page.header.tsx @@ -0,0 +1,119 @@ +import { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; + +import { ChainID } from '@stacks/transactions'; +import { OnboardingSelectors } from '@tests/selectors/onboarding.selectors'; +import { SettingsSelectors } from '@tests/selectors/settings.selectors'; +import { SharedComponentsSelectors } from '@tests/selectors/shared-component.selectors'; +import { Box, Flex, Grid, GridItem, HStack, styled } from 'leather-styles/jsx'; + +import { ArrowLeftIcon, CloseIcon, HamburgerIcon, Logo, NetworkModeBadge } from '@leather.io/ui'; + +import { RouteUrls } from '@shared/route-urls'; + +import { SwitchAccountDialog } from '@app/features/dialogs/switch-account-dialog/switch-account-dialog'; +import { useCurrentNetworkState } from '@app/store/networks/networks.hooks'; + +import { Settings } from '../../../settings/settings'; +import { HeaderActionButton } from '../headers/components/header-action-button'; +import { usePageContext } from './page.context'; + +function LogoBox({ isSessionLocked }: { isSessionLocked: boolean | undefined }) { + const navigate = useNavigate(); + return ( + + navigate(RouteUrls.Home)} + /> + + ); +} + +export function PageHeader() { + const [isShowingSwitchAccount, setIsShowingSwitchAccount] = useState(false); + const navigate = useNavigate(); + const { chain, name: chainName } = useCurrentNetworkState(); + + const { + state: { title, isSummaryPage, isSessionLocked, isSettingsVisibleOnSm, onBackLocation }, + } = usePageContext(); + + // pages with nested dialogs need a custom back location to prevent re-opening the dialog + const onGoBack = onBackLocation ? () => navigate(onBackLocation) : () => navigate(-1); + const canGoBack = !isSummaryPage && !isSessionLocked; + + return ( + <> + {isShowingSwitchAccount && ( + setIsShowingSwitchAccount(false)} + /> + )} + + + + + {canGoBack && ( + } + onAction={onGoBack} + dataTestId={SharedComponentsSelectors.HeaderBackBtn} + /> + )} + + + + + {pageTitle} + + + + + + {!isSummaryPage && ( + + + } + toggleSwitchAccount={() => setIsShowingSwitchAccount(!isShowingSwitchAccount)} + /> + + )} + {isSummaryPage && ( + } + dataTestId={SharedComponentsSelectors.HeaderCloseBtn} + onAction={() => navigate(RouteUrls.Home)} + /> + )} + + + + + + ); +} diff --git a/src/app/features/container/containers/page/page.layout.tsx b/src/app/features/container/containers/page/page.layout.tsx new file mode 100644 index 00000000000..03b7a0860d0 --- /dev/null +++ b/src/app/features/container/containers/page/page.layout.tsx @@ -0,0 +1,13 @@ +import { Outlet } from 'react-router-dom'; + +import { ContainerLayout } from '../container.layout'; +import { PageProvider } from './page.context'; +import { PageHeader } from './page.header'; + +export function PageLayout() { + return ( + + } content={} /> + + ); +} diff --git a/src/app/features/container/containers/popup/popup-header.tsx b/src/app/features/container/containers/popup/popup-header.tsx new file mode 100644 index 00000000000..be3c22b132c --- /dev/null +++ b/src/app/features/container/containers/popup/popup-header.tsx @@ -0,0 +1,37 @@ +import { ReactNode } from 'react'; + +import { Flex, Grid, GridItem, HStack, styled } from 'leather-styles/jsx'; + +interface PopupHeaderProps { + account?: ReactNode; + totalBalance?: ReactNode; + networkBadge?: ReactNode; + logo?: ReactNode; +} + +export function PopupHeader({ account, totalBalance, networkBadge, logo }: PopupHeaderProps) { + const logoItem = logo || account; + // styled.header could be its own wrapper component we pass a child that could be grid or flex + return ( + + + + {logoItem && {account ? account : logo}} + + + + {networkBadge} + {totalBalance && totalBalance} + + + + + ); +} diff --git a/src/app/features/container/containers/popup/popup.layout.tsx b/src/app/features/container/containers/popup/popup.layout.tsx new file mode 100644 index 00000000000..053c99ecd85 --- /dev/null +++ b/src/app/features/container/containers/popup/popup.layout.tsx @@ -0,0 +1,106 @@ +import { useState } from 'react'; +import { Outlet, useLocation } from 'react-router-dom'; + +import { ChainID } from '@stacks/transactions'; +import { Box } from 'leather-styles/jsx'; + +import { Flag, Logo, NetworkModeBadge } from '@leather.io/ui'; + +import { RouteUrls } from '@shared/route-urls'; + +import { CurrentAccountAvatar } from '@app/features/current-account/current-account-avatar'; +import { CurrentAccountName } from '@app/features/current-account/current-account-name'; +import { SwitchAccountDialog } from '@app/features/dialogs/switch-account-dialog/switch-account-dialog'; +import { useCurrentNetworkState } from '@app/store/networks/networks.hooks'; + +import { TotalBalance } from '../../total-balance'; +import { ContainerLayout } from '../container.layout'; +import { PopupHeader } from './popup-header'; + +function showHeader(pathname: RouteUrls) { + switch (pathname) { + case RouteUrls.RpcGetAddresses: + case RouteUrls.ChooseAccount: + return false; + default: + return true; + } +} + +function showAccountInfo(pathname: RouteUrls) { + switch (pathname) { + case RouteUrls.TransactionRequest: + case RouteUrls.ProfileUpdateRequest: + case RouteUrls.RpcSendTransfer: + return true; + default: + return false; + } +} + +function showBalanceInfo(pathname: RouteUrls) { + switch (pathname) { + case RouteUrls.ProfileUpdateRequest: + case RouteUrls.RpcSendTransfer: + return true; + default: + return false; + } +} + +export function PopupLayout() { + const [isShowingSwitchAccount, setIsShowingSwitchAccount] = useState(false); + const { pathname: locationPathname } = useLocation(); + const pathname = locationPathname as RouteUrls; + + const { chain, name: chainName } = useCurrentNetworkState(); + + const isHeaderVisible = showHeader(pathname); + + return ( + <> + {isShowingSwitchAccount && ( + setIsShowingSwitchAccount(false)} + /> + )} + + } + logo={ + + + + } + account={ + showAccountInfo(pathname) && ( + } + onClick={() => setIsShowingSwitchAccount(!isShowingSwitchAccount)} + cursor="pointer" + > + + + ) + } + totalBalance={ + // We currently only show displayAddresssBalanceOf="all" in the total balance component + showBalanceInfo(pathname) && + } + /> + ) : undefined + } + content={} + /> + + ); +} diff --git a/src/app/features/container/utils/get-popup-header.ts b/src/app/features/container/utils/get-popup-header.ts deleted file mode 100644 index 805ed8c0101..00000000000 --- a/src/app/features/container/utils/get-popup-header.ts +++ /dev/null @@ -1,83 +0,0 @@ -/** - * POPUP header logic notes here -> https://github.com/leather-io/extension/issues/4371#issuecomment-1919114939 - */ -import { RouteUrls } from '@shared/route-urls'; - -export function isRpcRoute(pathname: RouteUrls) { - //RouteUrls.RpcReceiveBitcoinContractOffer - if (pathname.match('/bitcoin-contract-offer')) return true; - switch (pathname) { - case RouteUrls.PsbtRequest: - case RouteUrls.SignatureRequest: - case RouteUrls.RpcStacksSignature: - case RouteUrls.RpcSignBip322Message: - case RouteUrls.RpcStacksSignature: - case RouteUrls.RpcSignPsbt: - case RouteUrls.RpcSignPsbtSummary: - case RouteUrls.RpcSendTransfer: - case RouteUrls.RpcSendTransferChooseFee: - case RouteUrls.RpcSendTransferConfirmation: - case RouteUrls.RpcSendTransferSummary: - return true; - default: - return false; - } -} - -export function showAccountInfo(pathname: RouteUrls) { - switch (pathname) { - case RouteUrls.TransactionRequest: - case RouteUrls.ProfileUpdateRequest: - case RouteUrls.RpcSendTransfer: - return true; - default: - return false; - } -} - -export function showBalanceInfo(pathname: RouteUrls) { - switch (pathname) { - case RouteUrls.ProfileUpdateRequest: - case RouteUrls.RpcSendTransfer: - return true; - case RouteUrls.TransactionRequest: - default: - return false; - } -} - -export function getDisplayAddresssBalanceOf(pathname: RouteUrls) { - // TODO it's unclear when to show ALL or STX balance here - switch (pathname) { - case RouteUrls.TransactionRequest: - case RouteUrls.ProfileUpdateRequest: - case RouteUrls.RpcSendTransfer: - return 'all'; - default: - return 'stx'; - } -} - -export function isKnownPopupRoute(pathname: RouteUrls) { - if (pathname.match('/bitcoin-contract-offer')) return true; - switch (pathname) { - case RouteUrls.TransactionRequest: - case RouteUrls.ProfileUpdateRequest: - case RouteUrls.PsbtRequest: - case RouteUrls.SignatureRequest: - case RouteUrls.RpcGetAddresses: - case RouteUrls.RpcSendTransfer: - case RouteUrls.SignatureRequest: - case RouteUrls.RpcSignBip322Message: - case RouteUrls.RpcStacksSignature: - case RouteUrls.RpcSignPsbt: - case RouteUrls.RpcSignPsbtSummary: - case RouteUrls.RpcSendTransfer: - case RouteUrls.RpcSendTransferChooseFee: - case RouteUrls.RpcSendTransferConfirmation: - case RouteUrls.RpcSendTransferSummary: - return true; - default: - return false; - } -} diff --git a/src/app/features/container/utils/get-title-from-url.ts b/src/app/features/container/utils/get-title-from-url.ts deleted file mode 100644 index 42ed7fe7a01..00000000000 --- a/src/app/features/container/utils/get-title-from-url.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { RouteUrls } from '@shared/route-urls'; - -export function getTitleFromUrl(pathname: RouteUrls) { - if (pathname.match(RouteUrls.SendCryptoAsset)) { - // don't show send on first step of send flow or popuop transfer - if (pathname === RouteUrls.SendCryptoAsset) return undefined; - if (pathname === RouteUrls.RpcSendTransfer) return undefined; - return 'Send'; - } - - switch (pathname) { - case RouteUrls.AddNetwork: - return 'Add a network'; - case RouteUrls.BitcoinContractList: - return 'Bitcoin Contracts'; - case RouteUrls.BitcoinContractLockSuccess: - return 'Locked Bitcoin'; - case RouteUrls.SendBrc20ChooseFee: - return 'Choose fee'; - case RouteUrls.SendBrc20Confirmation: - case RouteUrls.SwapReview: - case RouteUrls.SendBrc20Confirmation: - case '/send/btc/confirm': - return 'Review'; - case RouteUrls.Swap: - return 'Swap'; - case RouteUrls.SentStxTxSummary: - case RouteUrls.SentBtcTxSummary: - return 'Sent'; - case RouteUrls.SentBrc20Summary: - return 'Creating transfer inscription'; - case RouteUrls.SendBrc20Confirmation: - default: - return undefined; - } -} diff --git a/src/app/features/container/utils/route-helpers.ts b/src/app/features/container/utils/route-helpers.ts deleted file mode 100644 index 7e7f66f31fa..00000000000 --- a/src/app/features/container/utils/route-helpers.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { RouteUrls } from '@shared/route-urls'; - -import { isKnownPopupRoute } from './get-popup-header'; - -function isHomePage(pathname: RouteUrls) { - return ( - pathname === RouteUrls.Home || - pathname.match(RouteUrls.Activity) || - pathname.match(RouteUrls.Receive) || - pathname.match(RouteUrls.SendOrdinalInscription) - ); -} - -export function isLandingPage(pathname: RouteUrls) { - return pathname.match(RouteUrls.Onboarding); // need to match get-started/ledger -} - -function isOnboardingPage(pathname: RouteUrls) { - return ( - pathname === RouteUrls.BackUpSecretKey || - pathname === RouteUrls.SetPassword || - pathname === RouteUrls.SignIn || - pathname === RouteUrls.ViewSecretKey - ); -} - -function isFundPage(pathname: RouteUrls) { - return ( - pathname === RouteUrls.Fund.replace(':currency', 'STX') || - pathname === RouteUrls.Fund.replace(':currency', 'BTC') - ); -} - -export function getPageVariant(pathname: RouteUrls) { - if (isFundPage(pathname)) return 'fund'; - if (isHomePage(pathname)) return 'home'; - if (isOnboardingPage(pathname)) return 'onboarding'; - return 'page'; -} - -export function getIsSessionLocked(pathname: RouteUrls) { - return pathname === RouteUrls.Unlock; -} - -export function isSummaryPage(pathname: RouteUrls) { - /* TODO refactor the summary routes to make this cleaner - we need to block going back from summary pages catching the dynamic routes: - SentBtcTxSummary = '/sent/btc/:txId', - SentStxTxSummary = '/sent/stx/:txId', - SentBrc20Summary = '/send/brc20/:ticker/summary', - RpcSignPsbtSummary = '/sign-psbt/summary', - RpcSendTransferSummary = '/send-transfer/summary', - */ - return pathname.match('/sent/stx/') || pathname.match('/sent/btc/' || pathname.match('summary')); -} - -export function canGoBack(pathname: RouteUrls) { - if (getIsSessionLocked(pathname) || isKnownPopupRoute(pathname) || isSummaryPage(pathname)) { - return false; - } - return true; -} - -export function hideLogo(pathname: RouteUrls) { - return pathname === RouteUrls.RpcGetAddresses || pathname === RouteUrls.ViewSecretKey; -} - -export function isNoHeaderPopup(pathname: RouteUrls) { - return pathname === RouteUrls.RpcGetAddresses || pathname === RouteUrls.ChooseAccount; -} - -export function hideSettingsOnSm(pathname: RouteUrls) { - switch (pathname) { - case RouteUrls.SendCryptoAsset: - case RouteUrls.FundChooseCurrency: - return true; - default: - return false; - } -} diff --git a/src/app/features/current-account/current-account-avatar.tsx b/src/app/features/current-account/current-account-avatar.tsx index 3f264aad94c..91e8890eb23 100644 --- a/src/app/features/current-account/current-account-avatar.tsx +++ b/src/app/features/current-account/current-account-avatar.tsx @@ -1,5 +1,3 @@ -import { memo } from 'react'; - import { CircleProps } from 'leather-styles/jsx'; import { useCurrentAccountDisplayName } from '@app/common/hooks/account/use-account-names'; @@ -9,17 +7,12 @@ import { AccountAvatar } from '@app/ui/components/account/account-avatar/account interface CurrentAccountAvatar extends CircleProps { toggleSwitchAccount(): void; } -export const CurrentAccountAvatar = memo(({ toggleSwitchAccount }: CurrentAccountAvatar) => { +export function CurrentAccountAvatar() { const stacksAccount = useCurrentStacksAccount(); const name = useCurrentAccountDisplayName(); if (!stacksAccount) return null; return ( - toggleSwitchAccount()} - publicKey={stacksAccount.stxPublicKey} - /> + ); -}); +} diff --git a/src/app/features/dialogs/edit-nonce-dialog/edit-nonce-dialog.tsx b/src/app/features/dialogs/edit-nonce-dialog/edit-nonce-dialog.tsx index 35389fa1f3d..6b572abeb07 100644 --- a/src/app/features/dialogs/edit-nonce-dialog/edit-nonce-dialog.tsx +++ b/src/app/features/dialogs/edit-nonce-dialog/edit-nonce-dialog.tsx @@ -10,7 +10,7 @@ import { StacksSendFormValues, StacksTransactionFormValues } from '@shared/model import { useOnMount } from '@app/common/hooks/use-on-mount'; import { openInNewTab } from '@app/common/utils/open-in-new-tab'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { EditNonceForm } from './components/edit-nonce-form'; diff --git a/src/app/features/dialogs/increase-fee-dialog/increase-btc-fee-dialog.tsx b/src/app/features/dialogs/increase-fee-dialog/increase-btc-fee-dialog.tsx index 8a382bca309..3ba46c1c23e 100644 --- a/src/app/features/dialogs/increase-fee-dialog/increase-btc-fee-dialog.tsx +++ b/src/app/features/dialogs/increase-fee-dialog/increase-btc-fee-dialog.tsx @@ -14,10 +14,10 @@ import { useLocationStateWithCache } from '@app/common/hooks/use-location-state' import { getBitcoinTxValue } from '@app/common/transactions/bitcoin/utils'; import { BitcoinCustomFeeInput } from '@app/components/bitcoin-custom-fee/bitcoin-custom-fee-input'; import { BitcoinTransactionItem } from '@app/components/bitcoin-transaction-item/bitcoin-transaction-item'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useBtcCryptoAssetBalanceNativeSegwit } from '@app/query/bitcoin/balance/btc-balance-native-segwit.hooks'; import { useCurrentAccountNativeSegwitIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; import { IncreaseFeeActions } from './components/increase-fee-actions'; import { useBtcIncreaseFee } from './hooks/use-btc-increase-fee'; diff --git a/src/app/features/dialogs/increase-fee-dialog/increase-stx-fee-dialog.tsx b/src/app/features/dialogs/increase-fee-dialog/increase-stx-fee-dialog.tsx index 216d4bb1c89..34b4ba95d9a 100644 --- a/src/app/features/dialogs/increase-fee-dialog/increase-stx-fee-dialog.tsx +++ b/src/app/features/dialogs/increase-fee-dialog/increase-stx-fee-dialog.tsx @@ -23,12 +23,12 @@ import { safelyFormatHexTxid } from '@app/common/utils/safe-handle-txid'; import { stxFeeValidator } from '@app/common/validation/forms/fee-validators'; import { LoadingSpinner } from '@app/components/loading-spinner'; import { StacksTransactionItem } from '@app/components/stacks-transaction-item/stacks-transaction-item'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useStacksBroadcastTransaction } from '@app/features/stacks-transaction-request/hooks/use-stacks-broadcast-transaction'; import { useToast } from '@app/features/toasts/use-toast'; import { useCurrentStacksAccountAddress } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; import { useSubmittedTransactionsActions } from '@app/store/submitted-transactions/submitted-transactions.hooks'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; import { IncreaseFeeActions } from './components/increase-fee-actions'; import { IncreaseFeeField } from './components/increase-fee-field'; diff --git a/src/app/features/dialogs/switch-account-dialog/switch-account-dialog.tsx b/src/app/features/dialogs/switch-account-dialog/switch-account-dialog.tsx index 4f1724f28e7..e93f52ae5d7 100644 --- a/src/app/features/dialogs/switch-account-dialog/switch-account-dialog.tsx +++ b/src/app/features/dialogs/switch-account-dialog/switch-account-dialog.tsx @@ -7,21 +7,16 @@ import { Button, Dialog } from '@leather.io/ui'; import { useCreateAccount } from '@app/common/hooks/account/use-create-account'; import { useWalletType } from '@app/common/use-wallet-type'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useCurrentAccountIndex } from '@app/store/accounts/account'; import { useFilteredBitcoinAccounts } from '@app/store/accounts/blockchain/bitcoin/bitcoin.ledger'; import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; import { VirtuosoWrapper } from '@app/ui/components/virtuoso'; import { AccountListUnavailable } from './components/account-list-unavailable'; import { SwitchAccountListItem } from './components/switch-account-list-item'; -export interface SwitchAccountOutletContext { - isShowingSwitchAccount: boolean; - setIsShowingSwitchAccount(isShowing: boolean): void; -} - interface SwitchAccountDialogProps { isShowing: boolean; onClose(): void; diff --git a/src/app/features/ledger/flows/jwt-signing/ledger-sign-jwt-container.tsx b/src/app/features/ledger/flows/jwt-signing/ledger-sign-jwt-container.tsx index 975596b33a7..e50c91fa55c 100644 --- a/src/app/features/ledger/flows/jwt-signing/ledger-sign-jwt-container.tsx +++ b/src/app/features/ledger/flows/jwt-signing/ledger-sign-jwt-container.tsx @@ -17,6 +17,7 @@ import { useDefaultRequestParams } from '@app/common/hooks/use-default-request-s import { useKeyActions } from '@app/common/hooks/use-key-actions'; import { useScrollLock } from '@app/common/hooks/use-scroll-lock'; import { makeLedgerCompatibleUnsignedAuthResponsePayload } from '@app/common/unsafe-auth-response'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useCancelLedgerAction } from '@app/features/ledger/utils/generic-ledger-utils'; import { getStacksAppVersion, @@ -26,7 +27,6 @@ import { useCurrentStacksAccount, useStacksAccounts, } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; import { useLedgerNavigate } from '../../hooks/use-ledger-navigate'; import { checkLockedDeviceError, useLedgerResponseState } from '../../utils/generic-ledger-utils'; diff --git a/src/app/features/ledger/flows/stacks-message-signing/ledger-stacks-sign-msg-container.tsx b/src/app/features/ledger/flows/stacks-message-signing/ledger-stacks-sign-msg-container.tsx index c0436f993c7..44cd7117eb0 100644 --- a/src/app/features/ledger/flows/stacks-message-signing/ledger-stacks-sign-msg-container.tsx +++ b/src/app/features/ledger/flows/stacks-message-signing/ledger-stacks-sign-msg-container.tsx @@ -12,6 +12,7 @@ import { UnsignedMessage, whenSignableMessageOfType } from '@shared/signature/si import { useScrollLock } from '@app/common/hooks/use-scroll-lock'; import { appEvents } from '@app/common/publish-subscribe'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useCancelLedgerAction } from '@app/features/ledger/utils/generic-ledger-utils'; import { getStacksAppVersion, @@ -21,7 +22,6 @@ import { } from '@app/features/ledger/utils/stacks-ledger-utils'; import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; import { StacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.models'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; import { useLedgerAnalytics } from '../../hooks/use-ledger-analytics.hook'; import { useLedgerNavigate } from '../../hooks/use-ledger-navigate'; diff --git a/src/app/features/ledger/generic-flows/request-keys/request-keys-flow.tsx b/src/app/features/ledger/generic-flows/request-keys/request-keys-flow.tsx index 5be63817bbc..bbc24daea9a 100644 --- a/src/app/features/ledger/generic-flows/request-keys/request-keys-flow.tsx +++ b/src/app/features/ledger/generic-flows/request-keys/request-keys-flow.tsx @@ -3,7 +3,7 @@ import { Outlet } from 'react-router-dom'; import { Dialog } from '@leather.io/ui'; import { useScrollLock } from '@app/common/hooks/use-scroll-lock'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useLedgerNavigate } from '../../hooks/use-ledger-navigate'; import { LedgerRequestKeysContext, LedgerRequestKeysProvider } from './ledger-request-keys.context'; diff --git a/src/app/features/ledger/generic-flows/tx-signing/tx-signing-flow.tsx b/src/app/features/ledger/generic-flows/tx-signing/tx-signing-flow.tsx index b08d07d70a7..a75585990ac 100644 --- a/src/app/features/ledger/generic-flows/tx-signing/tx-signing-flow.tsx +++ b/src/app/features/ledger/generic-flows/tx-signing/tx-signing-flow.tsx @@ -3,7 +3,7 @@ import { Outlet } from 'react-router-dom'; import { Dialog } from '@leather.io/ui'; import { useScrollLock } from '@app/common/hooks/use-scroll-lock'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { LedgerTxSigningContext, LedgerTxSigningProvider } from './ledger-sign-tx.context'; diff --git a/src/app/features/ledger/generic-steps/connect-device/connect-ledger-start.tsx b/src/app/features/ledger/generic-steps/connect-device/connect-ledger-start.tsx index 9db6583a8aa..c4a206f9291 100644 --- a/src/app/features/ledger/generic-steps/connect-device/connect-ledger-start.tsx +++ b/src/app/features/ledger/generic-steps/connect-device/connect-ledger-start.tsx @@ -7,7 +7,7 @@ import { closeWindow } from '@shared/utils'; import { doesBrowserSupportWebUsbApi, whenPageMode } from '@app/common/utils'; import { openIndexPageInNewTab } from '@app/common/utils/open-in-new-tab'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { immediatelyAttemptLedgerConnection } from '../../hooks/use-when-reattempt-ledger-connection'; import { ConnectLedger } from './connect-ledger'; diff --git a/src/app/features/ledger/generic-steps/unsupported-browser/unsupported-browser.layout.tsx b/src/app/features/ledger/generic-steps/unsupported-browser/unsupported-browser.layout.tsx index 4486d86e91e..ff5aa2b8020 100644 --- a/src/app/features/ledger/generic-steps/unsupported-browser/unsupported-browser.layout.tsx +++ b/src/app/features/ledger/generic-steps/unsupported-browser/unsupported-browser.layout.tsx @@ -4,8 +4,8 @@ import { styled } from 'leather-styles/jsx'; import { Dialog, Link } from '@leather.io/ui'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { UnsupportedBrowserImg } from '@app/features/ledger/illustrations/ledger-illu-unsupported-browser'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; import { LedgerTitle } from '../../components/ledger-title'; import { LedgerWrapper } from '../../components/ledger-wrapper'; diff --git a/src/app/features/psbt-signer/components/psbt-request-actions.tsx b/src/app/features/psbt-signer/components/psbt-request-actions.tsx index 6b8746b8b7f..eb42855ace5 100644 --- a/src/app/features/psbt-signer/components/psbt-request-actions.tsx +++ b/src/app/features/psbt-signer/components/psbt-request-actions.tsx @@ -1,6 +1,6 @@ import { Button } from '@leather.io/ui'; -import { Footer } from '@app/ui/components/containers/footers/footer'; +import { Footer } from '@app/features/container/containers/footers/footer'; interface PsbtRequestActionsProps { isLoading?: boolean; diff --git a/src/app/features/psbt-signer/psbt-signer.tsx b/src/app/features/psbt-signer/psbt-signer.tsx index 50073036c2d..cf53e6ae825 100644 --- a/src/app/features/psbt-signer/psbt-signer.tsx +++ b/src/app/features/psbt-signer/psbt-signer.tsx @@ -11,11 +11,11 @@ import { RouteUrls } from '@shared/route-urls'; import { closeWindow } from '@shared/utils'; import { SignPsbtArgs } from '@app/common/psbt/requests'; +import { Footer } from '@app/features/container/containers/footers/footer'; import { useBreakOnNonCompliantEntity } from '@app/query/common/compliance-checker/compliance-checker.query'; import { useOnOriginTabClose } from '@app/routes/hooks/use-on-tab-closed'; import { useCurrentAccountNativeSegwitIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks'; import { useCurrentAccountTaprootIndexZeroSigner } from '@app/store/accounts/blockchain/bitcoin/taproot-account.hooks'; -import { Footer } from '@app/ui/components/containers/footers/footer'; import { Card } from '@app/ui/layout/card/card'; import { CardContent } from '@app/ui/layout/card/card-content'; diff --git a/src/app/features/retrieve-taproot-to-native-segwit/components/retrieve-taproot-to-native-segwit.layout.tsx b/src/app/features/retrieve-taproot-to-native-segwit/components/retrieve-taproot-to-native-segwit.layout.tsx index d72d6a97620..fdc899933fd 100644 --- a/src/app/features/retrieve-taproot-to-native-segwit/components/retrieve-taproot-to-native-segwit.layout.tsx +++ b/src/app/features/retrieve-taproot-to-native-segwit/components/retrieve-taproot-to-native-segwit.layout.tsx @@ -2,8 +2,8 @@ import { Flex, styled } from 'leather-styles/jsx'; import { BtcAvatarIcon, Button, Callout, Dialog } from '@leather.io/ui'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { Card } from '@app/ui/layout/card/card'; interface RetrieveTaprootToNativeSegwitLayoutProps { diff --git a/src/app/features/settings/network/network.tsx b/src/app/features/settings/network/network.tsx index a79ef308ab0..98ca74595e1 100644 --- a/src/app/features/settings/network/network.tsx +++ b/src/app/features/settings/network/network.tsx @@ -8,11 +8,11 @@ import { Button, Dialog } from '@leather.io/ui'; import { RouteUrls } from '@shared/route-urls'; import { analytics } from '@shared/utils/analytics'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { NetworkListItem } from '@app/features/settings/network/network-list-item'; import { useCurrentNetworkState, useNetworksActions } from '@app/store/networks/networks.hooks'; import { useNetworks } from '@app/store/networks/networks.selectors'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; const defaultNetworkIds = Object.values(WalletDefaultNetworkConfigurationIds) as string[]; diff --git a/src/app/features/settings/sign-out/sign-out.tsx b/src/app/features/settings/sign-out/sign-out.tsx index 04e83ee6e6b..63f0b05bdb6 100644 --- a/src/app/features/settings/sign-out/sign-out.tsx +++ b/src/app/features/settings/sign-out/sign-out.tsx @@ -5,8 +5,8 @@ import { Flex, HStack, styled } from 'leather-styles/jsx'; import { Button, Callout, Dialog } from '@leather.io/ui'; import { useWalletType } from '@app/common/use-wallet-type'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; interface SignOutDialogProps { isShowing: boolean; diff --git a/src/app/features/settings/theme/theme-dialog.tsx b/src/app/features/settings/theme/theme-dialog.tsx index 96cd5117739..58691c8ebf0 100644 --- a/src/app/features/settings/theme/theme-dialog.tsx +++ b/src/app/features/settings/theme/theme-dialog.tsx @@ -5,7 +5,7 @@ import { Dialog } from '@leather.io/ui'; import { analytics } from '@shared/utils/analytics'; import { UserSelectedTheme, themeLabelMap, useThemeSwitcher } from '@app/common/theme-provider'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { ThemeListItem } from './theme-list-item'; diff --git a/src/app/features/stacks-high-fee-warning/stacks-high-fee-dialog.tsx b/src/app/features/stacks-high-fee-warning/stacks-high-fee-dialog.tsx index 9ebcd5850e7..c6708acb371 100644 --- a/src/app/features/stacks-high-fee-warning/stacks-high-fee-dialog.tsx +++ b/src/app/features/stacks-high-fee-warning/stacks-high-fee-dialog.tsx @@ -7,8 +7,8 @@ import { Button, Caption, Dialog, ErrorIcon, Link, Title } from '@leather.io/ui' import { StacksSendFormValues } from '@shared/models/form.model'; import { openInNewTab } from '@app/common/utils/open-in-new-tab'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useStacksHighFeeWarningContext } from './stacks-high-fee-warning-container'; diff --git a/src/app/pages/bitcoin-contract-list/bitcoin-contract-list.tsx b/src/app/pages/bitcoin-contract-list/bitcoin-contract-list.tsx index 0c645eb5c2c..e3a0d5bea5b 100644 --- a/src/app/pages/bitcoin-contract-list/bitcoin-contract-list.tsx +++ b/src/app/pages/bitcoin-contract-list/bitcoin-contract-list.tsx @@ -10,6 +10,7 @@ import { } from '@app/common/hooks/use-bitcoin-contracts'; import { useOnMount } from '@app/common/hooks/use-on-mount'; import { FullPageLoadingSpinner } from '@app/components/loading-spinner'; +import { useUpdatePageHeaderContext } from '@app/features/container/containers/page/page.context'; import { BitcoinContractListItemLayout } from './components/bitcoin-contract-list-item-layout'; @@ -19,6 +20,8 @@ export function BitcoinContractList() { const [isLoading, setLoading] = useState(true); const [isError, setError] = useState(false); + useUpdatePageHeaderContext({ title: 'Bitcoin Contracts' }); + useOnMount(() => { const fetchAndFormatBitcoinContracts = async () => { const fetchedBitcoinContracts = await getAllActiveBitcoinContracts(); diff --git a/src/app/pages/bitcoin-contract-request/bitcoin-contract-request.tsx b/src/app/pages/bitcoin-contract-request/bitcoin-contract-request.tsx index 19d7ddcdc02..da08f7d6291 100644 --- a/src/app/pages/bitcoin-contract-request/bitcoin-contract-request.tsx +++ b/src/app/pages/bitcoin-contract-request/bitcoin-contract-request.tsx @@ -13,8 +13,8 @@ import { } from '@app/common/hooks/use-bitcoin-contracts'; import { useOnMount } from '@app/common/hooks/use-on-mount'; import { initialSearchParams } from '@app/common/initial-search-params'; +import { Footer } from '@app/features/container/containers/footers/footer'; import { useCurrentAccountNativeSegwitSigner } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks'; -import { Footer } from '@app/ui/components/containers/footers/footer'; import { Card } from '@app/ui/layout/card/card'; import { CardContent } from '@app/ui/layout/card/card-content'; diff --git a/src/app/pages/fund/choose-asset-to-fund/choose-asset-to-fund.tsx b/src/app/pages/fund/choose-asset-to-fund/choose-asset-to-fund.tsx index d67188eab31..de20649061f 100644 --- a/src/app/pages/fund/choose-asset-to-fund/choose-asset-to-fund.tsx +++ b/src/app/pages/fund/choose-asset-to-fund/choose-asset-to-fund.tsx @@ -11,11 +11,13 @@ import { CurrentStacksAccountLoader } from '@app/components/loaders/stacks-accou import { StxAssetItemBalanceLoader } from '@app/components/loaders/stx-balance-loader'; import { BtcCryptoAssetItem } from '@app/features/asset-list/bitcoin/btc-crypto-asset-item/btc-crypto-asset-item'; import { StxCryptoAssetItem } from '@app/features/asset-list/stacks/stx-crypo-asset-item/stx-crypto-asset-item'; +import { useUpdatePageHeaderContext } from '@app/features/container/containers/page/page.context'; import { Card } from '@app/ui/layout/card/card'; import { Page } from '@app/ui/layout/page/page.layout'; export function ChooseCryptoAssetToFund() { const navigate = useNavigate(); + useUpdatePageHeaderContext({ isSettingsVisibleOnSm: false, onBackLocation: RouteUrls.Home }); const navigateToFund = useCallback( (symbol: string) => navigate(RouteUrls.Fund.replace(':currency', symbol)), diff --git a/src/app/pages/fund/fund.tsx b/src/app/pages/fund/fund.tsx index 506bf98b4e4..1764af66ec2 100644 --- a/src/app/pages/fund/fund.tsx +++ b/src/app/pages/fund/fund.tsx @@ -10,6 +10,7 @@ import type { import { RouteUrls } from '@shared/route-urls'; import { FullPageLoadingSpinner } from '@app/components/loading-spinner'; +import { useUpdatePageHeaderContext } from '@app/features/container/containers/page/page.context'; import { useCurrentAccountNativeSegwitIndexZeroSignerNullable } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks'; import { useCurrentStacksAccount } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; @@ -28,6 +29,9 @@ export function FundPage() { const currentStxAccount = useCurrentStacksAccount(); const bitcoinSigner = useCurrentAccountNativeSegwitIndexZeroSignerNullable(); const { currency = 'STX' } = useParams(); + useUpdatePageHeaderContext({ + onBackLocation: RouteUrls.FundChooseCurrency, + }); const fundCryptoCurrencyMap: Record = { BTC: { diff --git a/src/app/pages/home/home.tsx b/src/app/pages/home/home.tsx index 0e323f01bd3..aae20bd2617 100644 --- a/src/app/pages/home/home.tsx +++ b/src/app/pages/home/home.tsx @@ -1,4 +1,5 @@ -import { Route, useNavigate, useOutletContext } from 'react-router-dom'; +import { useState } from 'react'; +import { Route, useNavigate } from 'react-router-dom'; import { RouteUrls } from '@shared/route-urls'; @@ -7,7 +8,7 @@ import { useOnboardingState } from '@app/common/hooks/auth/use-onboarding-state' import { useTotalBalance } from '@app/common/hooks/balance/use-total-balance'; import { useOnMount } from '@app/common/hooks/use-on-mount'; import { ActivityList } from '@app/features/activity-list/activity-list'; -import { SwitchAccountOutletContext } from '@app/features/dialogs/switch-account-dialog/switch-account-dialog'; +import { SwitchAccountDialog } from '@app/features/dialogs/switch-account-dialog/switch-account-dialog'; import { FeedbackButton } from '@app/features/feedback-button/feedback-button'; import { Assets } from '@app/pages/home/components/assets'; import { homePageModalRoutes } from '@app/routes/app-routes'; @@ -23,8 +24,7 @@ import { HomeTabs } from './components/home-tabs'; export function Home() { const { decodedAuthRequest } = useOnboardingState(); - const { isShowingSwitchAccount, setIsShowingSwitchAccount } = - useOutletContext(); + const [isShowingSwitchAccount, setIsShowingSwitchAccount] = useState(false); const navigate = useNavigate(); const account = useCurrentStacksAccount(); const currentAccountIndex = useCurrentAccountIndex(); @@ -58,6 +58,12 @@ export function Home() { } > + {isShowingSwitchAccount && ( + setIsShowingSwitchAccount(false)} + /> + )} diff --git a/src/app/pages/receive/components/receive-tokens.layout.tsx b/src/app/pages/receive/components/receive-tokens.layout.tsx index d476f84da4a..2adfbb48353 100644 --- a/src/app/pages/receive/components/receive-tokens.layout.tsx +++ b/src/app/pages/receive/components/receive-tokens.layout.tsx @@ -8,9 +8,9 @@ import { token } from 'leather-styles/tokens'; import { AddressDisplayer, Button, Dialog } from '@leather.io/ui'; import { useLocationState } from '@app/common/hooks/use-location-state'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { Header } from '@app/ui/components/containers/headers/header'; interface ReceiveTokensLayoutProps { address: string; @@ -29,14 +29,14 @@ export function ReceiveTokensLayout(props: ReceiveTokensLayoutProps) { return ( Receive
{title} } - onGoBack={() => navigate(backgroundLocation ?? '..')} + onClose={() => navigate(backgroundLocation ?? '..')} /> } isShowing diff --git a/src/app/pages/receive/receive-dialog.tsx b/src/app/pages/receive/receive-dialog.tsx index 57ef07fcd89..cc9af22fcca 100644 --- a/src/app/pages/receive/receive-dialog.tsx +++ b/src/app/pages/receive/receive-dialog.tsx @@ -10,11 +10,11 @@ import { RouteUrls } from '@shared/route-urls'; import { analytics } from '@shared/utils/analytics'; import { useLocationState } from '@app/common/hooks/use-location-state'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useBackgroundLocationRedirect } from '@app/routes/hooks/use-background-location-redirect'; import { useZeroIndexTaprootAddress } from '@app/store/accounts/blockchain/bitcoin/bitcoin.hooks'; import { useCurrentAccountNativeSegwitAddressIndexZero } from '@app/store/accounts/blockchain/bitcoin/native-segwit-account.hooks'; import { useCurrentStacksAccountAddress } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; -import { Header } from '@app/ui/components/containers/headers/header'; import { ReceiveCollectibles } from './components/receive-collectibles'; import { ReceiveTokens } from './components/receive-tokens'; @@ -86,10 +86,10 @@ export function ReceiveDialog({ type = 'full' }: ReceiveDialogProps) { return ( navigate(backgroundLocation ?? '..')} + onClose={() => navigate(backgroundLocation ?? '..')} /> } onClose={() => navigate(backgroundLocation ?? '..')} diff --git a/src/app/pages/send/choose-crypto-asset/choose-crypto-asset.tsx b/src/app/pages/send/choose-crypto-asset/choose-crypto-asset.tsx index 3942c3452c1..a0b6471a7b0 100644 --- a/src/app/pages/send/choose-crypto-asset/choose-crypto-asset.tsx +++ b/src/app/pages/send/choose-crypto-asset/choose-crypto-asset.tsx @@ -5,12 +5,16 @@ import { Box, styled } from 'leather-styles/jsx'; import { RouteUrls } from '@shared/route-urls'; import { AssetList } from '@app/features/asset-list/asset-list'; +// import { useUpdatePageHeaderContext } from '@app/features/container/containers/page/page.context'; import { useConfigBitcoinSendEnabled } from '@app/query/common/remote-config/remote-config.query'; import { Card } from '@app/ui/layout/card/card'; export function ChooseCryptoAsset() { const navigate = useNavigate(); const isBitcoinSendEnabled = useConfigBitcoinSendEnabled(); + // this seems to stop memory leak but we shouldn't show 'Send' in the header on this page + // maybe route state would be better? + // useUpdatePageHeaderContext({ isSettingsVisibleOnSm: false, title: 'Send' }); function navigateToSendForm(symbol: string, contractId?: string) { if (symbol === 'BTC' && !isBitcoinSendEnabled) return navigate(RouteUrls.SendBtcDisabled); diff --git a/src/app/pages/send/locked-bitcoin-summary/locked-bitcoin-summary.tsx b/src/app/pages/send/locked-bitcoin-summary/locked-bitcoin-summary.tsx index 9b47b1928c5..9df8ec88ba9 100644 --- a/src/app/pages/send/locked-bitcoin-summary/locked-bitcoin-summary.tsx +++ b/src/app/pages/send/locked-bitcoin-summary/locked-bitcoin-summary.tsx @@ -10,14 +10,16 @@ import { analytics } from '@shared/utils/analytics'; import { useBitcoinExplorerLink } from '@app/common/hooks/use-bitcoin-explorer-link'; import { useClipboard } from '@app/common/hooks/use-copy-to-clipboard'; import { InfoCardAssetValue, InfoCardBtn } from '@app/components/info-card/info-card'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { useUpdatePageHeaderContext } from '@app/features/container/containers/page/page.context'; import { useToast } from '@app/features/toasts/use-toast'; -import { Footer } from '@app/ui/components/containers/footers/footer'; import { Card } from '@app/ui/layout/card/card'; import { CardContent } from '@app/ui/layout/card/card-content'; export function LockBitcoinSummary() { const { state } = useLocation(); const toast = useToast(); + useUpdatePageHeaderContext({ title: 'Locked Bitcoin' }); const { txId, txMoney, txFiatValue, txFiatValueSymbol, symbol, txLink } = state; diff --git a/src/app/pages/send/ordinal-inscription/send-inscription-choose-fee.tsx b/src/app/pages/send/ordinal-inscription/send-inscription-choose-fee.tsx index 3f44a7b911f..1dc2ff43022 100644 --- a/src/app/pages/send/ordinal-inscription/send-inscription-choose-fee.tsx +++ b/src/app/pages/send/ordinal-inscription/send-inscription-choose-fee.tsx @@ -14,7 +14,7 @@ import { import { LoadingSpinner } from '@app/components/loading-spinner'; import { BitcoinChooseFee } from '@app/features/bitcoin-choose-fee/bitcoin-choose-fee'; import { useValidateBitcoinSpend } from '@app/features/bitcoin-choose-fee/hooks/use-validate-bitcoin-spend'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useSendInscriptionState } from './components/send-inscription-container'; import { useSendInscriptionFeesList } from './hooks/use-send-inscription-fees-list'; diff --git a/src/app/pages/send/ordinal-inscription/send-inscription-form.tsx b/src/app/pages/send/ordinal-inscription/send-inscription-form.tsx index 339f28d5c5e..093d495fc8c 100644 --- a/src/app/pages/send/ordinal-inscription/send-inscription-form.tsx +++ b/src/app/pages/send/ordinal-inscription/send-inscription-form.tsx @@ -10,8 +10,8 @@ import { RouteUrls } from '@shared/route-urls'; import { ErrorLabel } from '@app/components/error-label'; import { InscriptionPreview } from '@app/components/inscription-preview-card/components/inscription-preview'; import { InscriptionPreviewCard } from '@app/components/inscription-preview-card/inscription-preview-card'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { RecipientAddressTypeField } from '../send-crypto-asset-form/components/recipient-address-type-field'; import { CollectibleAsset } from './components/collectible-asset'; diff --git a/src/app/pages/send/ordinal-inscription/send-inscription-review.tsx b/src/app/pages/send/ordinal-inscription/send-inscription-review.tsx index 24e26acf4d4..bce742e9221 100644 --- a/src/app/pages/send/ordinal-inscription/send-inscription-review.tsx +++ b/src/app/pages/send/ordinal-inscription/send-inscription-review.tsx @@ -13,11 +13,11 @@ import { analytics } from '@shared/utils/analytics'; import { FormAddressDisplayer } from '@app/components/address-displayer/form-address-displayer'; import { InfoCardRow, InfoCardSeparator } from '@app/components/info-card/info-card'; import { InscriptionPreview } from '@app/components/inscription-preview-card/components/inscription-preview'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks'; import { useAppDispatch } from '@app/store'; import { inscriptionSent } from '@app/store/ordinals/ordinals.slice'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; import { Card } from '@app/ui/layout/card/card'; import { InscriptionPreviewCard } from '../../../components/inscription-preview-card/inscription-preview-card'; diff --git a/src/app/pages/send/ordinal-inscription/sent-inscription-summary.tsx b/src/app/pages/send/ordinal-inscription/sent-inscription-summary.tsx index 8cbcff5c829..07716728ec1 100644 --- a/src/app/pages/send/ordinal-inscription/sent-inscription-summary.tsx +++ b/src/app/pages/send/ordinal-inscription/sent-inscription-summary.tsx @@ -14,9 +14,9 @@ import { copyToClipboard } from '@app/common/utils/copy-to-clipboard'; import { FormAddressDisplayer } from '@app/components/address-displayer/form-address-displayer'; import { InfoCardBtn, InfoCardRow, InfoCardSeparator } from '@app/components/info-card/info-card'; import { InscriptionPreview } from '@app/components/inscription-preview-card/components/inscription-preview'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useToast } from '@app/features/toasts/use-toast'; -import { Footer } from '@app/ui/components/containers/footers/footer'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; import { Card } from '@app/ui/layout/card/card'; import { InscriptionPreviewCard } from '../../../components/inscription-preview-card/inscription-preview-card'; diff --git a/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-dialog/recipient-accounts-dialog.tsx b/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-dialog/recipient-accounts-dialog.tsx index 3af89fdde84..e15020b8079 100644 --- a/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-dialog/recipient-accounts-dialog.tsx +++ b/src/app/pages/send/send-crypto-asset-form/components/recipient-accounts-dialog/recipient-accounts-dialog.tsx @@ -6,9 +6,9 @@ import { Box } from 'leather-styles/jsx'; import { Dialog } from '@leather.io/ui'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useFilteredBitcoinAccounts } from '@app/store/accounts/blockchain/bitcoin/bitcoin.ledger'; import { useStacksAccounts } from '@app/store/accounts/blockchain/stacks/stacks-account.hooks'; -import { DialogHeader } from '@app/ui/components/containers/headers/dialog-header'; import { VirtuosoWrapper } from '@app/ui/components/virtuoso'; import { AccountListItem } from './account-list-item'; diff --git a/src/app/pages/send/send-crypto-asset-form/form/brc20/brc20-choose-fee.tsx b/src/app/pages/send/send-crypto-asset-form/form/brc20/brc20-choose-fee.tsx index 3c43058f2aa..56046bec5d0 100644 --- a/src/app/pages/send/send-crypto-asset-form/form/brc20/brc20-choose-fee.tsx +++ b/src/app/pages/send/send-crypto-asset-form/form/brc20/brc20-choose-fee.tsx @@ -21,6 +21,7 @@ import { useBitcoinFeesList } from '@app/components/bitcoin-fees-list/use-bitcoi import { LoadingSpinner } from '@app/components/loading-spinner'; import { BitcoinChooseFee } from '@app/features/bitcoin-choose-fee/bitcoin-choose-fee'; import { useValidateBitcoinSpend } from '@app/features/bitcoin-choose-fee/hooks/use-validate-bitcoin-spend'; +import { useUpdatePageHeaderContext } from '@app/features/container/containers/page/page.context'; import { useToast } from '@app/features/toasts/use-toast'; import { useBrc20Transfers } from '@app/query/bitcoin/ordinals/brc20/brc20-tokens.hooks'; import { useSignBitcoinTx } from '@app/store/accounts/blockchain/bitcoin/bitcoin.hooks'; @@ -40,6 +41,7 @@ function useBrc20ChooseFeeState() { export function BrcChooseFee() { const toast = useToast(); + useUpdatePageHeaderContext({ title: 'Choose fee' }); const navigate = useNavigate(); const { amount, recipient, ticker, utxos, holderAddress } = useBrc20ChooseFeeState(); const generateTx = useGenerateUnsignedNativeSegwitTx(); diff --git a/src/app/pages/send/send-crypto-asset-form/form/brc20/brc20-send-form-confirmation.tsx b/src/app/pages/send/send-crypto-asset-form/form/brc20/brc20-send-form-confirmation.tsx index 9eb2af315e1..7fa951cb787 100644 --- a/src/app/pages/send/send-crypto-asset-form/form/brc20/brc20-send-form-confirmation.tsx +++ b/src/app/pages/send/send-crypto-asset-form/form/brc20/brc20-send-form-confirmation.tsx @@ -17,9 +17,9 @@ import { InfoCardRow, InfoCardSeparator, } from '@app/components/info-card/info-card'; +import { Footer } from '@app/features/container/containers/footers/footer'; import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks'; import { useBrc20Transfers } from '@app/query/bitcoin/ordinals/brc20/brc20-tokens.hooks'; -import { Footer } from '@app/ui/components/containers/footers/footer'; import { Card } from '@app/ui/layout/card/card'; import { CardContent } from '@app/ui/layout/card/card-content'; diff --git a/src/app/pages/send/send-crypto-asset-form/form/brc20/brc20-send-form.tsx b/src/app/pages/send/send-crypto-asset-form/form/brc20/brc20-send-form.tsx index bc3ffd79965..b4bcb8e29f0 100644 --- a/src/app/pages/send/send-crypto-asset-form/form/brc20/brc20-send-form.tsx +++ b/src/app/pages/send/send-crypto-asset-form/form/brc20/brc20-send-form.tsx @@ -10,8 +10,8 @@ import { Brc20AvatarIcon, Button, Callout, Link } from '@leather.io/ui'; import { convertAmountToBaseUnit, formatMoney } from '@leather.io/utils'; import { openInNewTab } from '@app/common/utils/open-in-new-tab'; -import { AvailableBalance } from '@app/ui/components/containers/footers/available-balance'; -import { Footer } from '@app/ui/components/containers/footers/footer'; +import { AvailableBalance } from '@app/features/container/containers/footers/available-balance'; +import { Footer } from '@app/features/container/containers/footers/footer'; import { Card } from '@app/ui/layout/card/card'; import { CardContent } from '@app/ui/layout/card/card-content'; diff --git a/src/app/pages/send/send-crypto-asset-form/form/btc/btc-choose-fee.tsx b/src/app/pages/send/send-crypto-asset-form/form/btc/btc-choose-fee.tsx index 7a08c2c58ed..1bd2fc6f833 100644 --- a/src/app/pages/send/send-crypto-asset-form/form/btc/btc-choose-fee.tsx +++ b/src/app/pages/send/send-crypto-asset-form/form/btc/btc-choose-fee.tsx @@ -11,6 +11,7 @@ import { useBitcoinFeesList } from '@app/components/bitcoin-fees-list/use-bitcoi import { BitcoinChooseFee } from '@app/features/bitcoin-choose-fee/bitcoin-choose-fee'; import { useValidateBitcoinSpend } from '@app/features/bitcoin-choose-fee/hooks/use-validate-bitcoin-spend'; +// import { useUpdatePageHeaderContext } from '@app/features/container/containers/page/page.context'; import { useSendBitcoinAssetContextState } from '../../family/bitcoin/components/send-bitcoin-asset-container'; import { useBtcChooseFee } from './use-btc-choose-fee'; @@ -22,6 +23,7 @@ export function useBtcChooseFeeState() { } export function BtcChooseFee() { + // useUpdatePageHeaderContext({ title: 'Send' }); const { isSendingMax, txValues, utxos } = useBtcChooseFeeState(); const { selectedFeeType, setSelectedFeeType } = useSendBitcoinAssetContextState(); const { amountAsMoney, previewTransaction } = useBtcChooseFee(); diff --git a/src/app/pages/send/send-crypto-asset-form/form/btc/btc-send-form-confirmation.tsx b/src/app/pages/send/send-crypto-asset-form/form/btc/btc-send-form-confirmation.tsx index b54a4b4b730..e2aac5d94c8 100644 --- a/src/app/pages/send/send-crypto-asset-form/form/btc/btc-send-form-confirmation.tsx +++ b/src/app/pages/send/send-crypto-asset-form/form/btc/btc-send-form-confirmation.tsx @@ -34,8 +34,9 @@ import { InfoCardRow, InfoCardSeparator, } from '@app/components/info-card/info-card'; +import { Footer } from '@app/features/container/containers/footers/footer'; +// import { useUpdatePageHeaderContext } from '@app/features/container/containers/page/page.context'; import { useCurrentNativeSegwitUtxos } from '@app/query/bitcoin/address/utxos-by-address.hooks'; -import { Footer } from '@app/ui/components/containers/footers/footer'; import { Card } from '@app/ui/layout/card/card'; import { CardContent } from '@app/ui/layout/card/card-content'; @@ -56,6 +57,7 @@ function useBtcSendFormConfirmationState() { export function BtcSendFormConfirmation() { const navigate = useNavigate(); + // useUpdatePageHeaderContext({ title: 'Review' }); const { tx, recipient, fee, arrivesIn, feeRowValue } = useBtcSendFormConfirmationState(); const transaction = useMemo(() => btc.Transaction.fromRaw(hexToBytes(tx)), [tx]); diff --git a/src/app/pages/send/send-crypto-asset-form/form/btc/btc-send-form.tsx b/src/app/pages/send/send-crypto-asset-form/form/btc/btc-send-form.tsx index db36e2fa060..33fd3e3ba43 100644 --- a/src/app/pages/send/send-crypto-asset-form/form/btc/btc-send-form.tsx +++ b/src/app/pages/send/send-crypto-asset-form/form/btc/btc-send-form.tsx @@ -9,8 +9,8 @@ import { useCryptoCurrencyMarketDataMeanAverage } from '@leather.io/query'; import { BtcAvatarIcon, Button, Callout, Link } from '@leather.io/ui'; import { formatMoney } from '@leather.io/utils'; -import { AvailableBalance } from '@app/ui/components/containers/footers/available-balance'; -import { Footer } from '@app/ui/components/containers/footers/footer'; +import { AvailableBalance } from '@app/features/container/containers/footers/available-balance'; +import { Footer } from '@app/features/container/containers/footers/footer'; import { Card } from '@app/ui/layout/card/card'; import { CardContent } from '@app/ui/layout/card/card-content'; @@ -28,7 +28,6 @@ const symbol: CryptoCurrencies = 'BTC'; export function BtcSendForm() { const routeState = useSendFormRouteState(); const marketData = useCryptoCurrencyMarketDataMeanAverage('BTC'); - const { balance, calcMaxSpend, @@ -42,6 +41,9 @@ export function BtcSendForm() { validationSchema, } = useBtcSendForm(); + // with this enabled ChooseCryptoAsset re-renders in a loop + // useUpdatePageHeaderContext({ title: 'Send' }); + return ( {token => ( diff --git a/src/app/pages/send/send-crypto-asset-form/form/stacks/stacks-common-send-form.tsx b/src/app/pages/send/send-crypto-asset-form/form/stacks/stacks-common-send-form.tsx index 94cb620296d..636a7bafadf 100644 --- a/src/app/pages/send/send-crypto-asset-form/form/stacks/stacks-common-send-form.tsx +++ b/src/app/pages/send/send-crypto-asset-form/form/stacks/stacks-common-send-form.tsx @@ -15,10 +15,11 @@ import { RouteUrls } from '@shared/route-urls'; import { FeesRow } from '@app/components/fees-row/fees-row'; import { NonceSetter } from '@app/components/nonce-setter'; +import { AvailableBalance } from '@app/features/container/containers/footers/available-balance'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { useUpdatePageHeaderContext } from '@app/features/container/containers/page/page.context'; import { useUpdatePersistedSendFormValues } from '@app/features/popup-send-form-restoration/use-update-persisted-send-form-values'; import { HighFeeDialog } from '@app/features/stacks-high-fee-warning/stacks-high-fee-dialog'; -import { AvailableBalance } from '@app/ui/components/containers/footers/available-balance'; -import { Footer } from '@app/ui/components/containers/footers/footer'; import { Card } from '@app/ui/layout/card/card'; import { CardContent } from '@app/ui/layout/card/card-content'; @@ -51,6 +52,7 @@ export function StacksCommonSendForm({ }: StacksCommonSendFormProps) { const navigate = useNavigate(); const { onFormStateChange } = useUpdatePersistedSendFormValues(); + useUpdatePageHeaderContext({ title: 'Send' }); return ( } /> + }> navigate(RouteUrls.Swap)} header={ -
Choose asset
to swap } - variant="bigTitle" - onGoBack={() => navigate(RouteUrls.Swap)} + variant="large" + onClose={() => navigate(RouteUrls.Swap)} /> } > diff --git a/src/app/pages/swap/components/swap-asset-dialog/swap-asset-dialog-quote.tsx b/src/app/pages/swap/components/swap-asset-dialog/swap-asset-dialog-quote.tsx index 81ce10f70b3..8e24a419440 100644 --- a/src/app/pages/swap/components/swap-asset-dialog/swap-asset-dialog-quote.tsx +++ b/src/app/pages/swap/components/swap-asset-dialog/swap-asset-dialog-quote.tsx @@ -2,7 +2,7 @@ import { Dialog } from '@leather.io/ui'; import { RouteUrls } from '@shared/route-urls'; -import { Header } from '@app/ui/components/containers/headers/header'; +import { DialogHeader } from '@app/features/container/containers/headers/dialog-header'; import { useSwapNavigate } from '../../hooks/use-swap-navigate'; import { useSwapContext } from '../../swap.context'; @@ -17,14 +17,14 @@ export function SwapAssetDialogQuote() { isShowing onClose={() => navigate(RouteUrls.Swap)} header={ -
Choose asset
to receive } - variant="bigTitle" - onGoBack={() => navigate(RouteUrls.Swap)} + variant="large" + onClose={() => navigate(RouteUrls.Swap)} /> } > diff --git a/src/app/pages/swap/components/swap-review.tsx b/src/app/pages/swap/components/swap-review.tsx index c7f8675f6d3..86d10728440 100644 --- a/src/app/pages/swap/components/swap-review.tsx +++ b/src/app/pages/swap/components/swap-review.tsx @@ -5,7 +5,7 @@ import { SwapSelectors } from '@tests/selectors/swap.selectors'; import { Button } from '@leather.io/ui'; import { LoadingKeys, useLoading } from '@app/common/hooks/use-loading'; -import { Footer } from '@app/ui/components/containers/footers/footer'; +import { Footer } from '@app/features/container/containers/footers/footer'; import { Card } from '@app/ui/layout/card/card'; import { CardContent } from '@app/ui/layout/card/card-content'; diff --git a/src/app/pages/swap/swap.tsx b/src/app/pages/swap/swap.tsx index 260777648e1..b5c90c2281b 100644 --- a/src/app/pages/swap/swap.tsx +++ b/src/app/pages/swap/swap.tsx @@ -7,8 +7,11 @@ import { useFormikContext } from 'formik'; import { Button } from '@leather.io/ui'; import { isUndefined } from '@leather.io/utils'; +import { RouteUrls } from '@shared/route-urls'; + import { LoadingSpinner } from '@app/components/loading-spinner'; -import { Footer } from '@app/ui/components/containers/footers/footer'; +import { Footer } from '@app/features/container/containers/footers/footer'; +import { useUpdatePageHeaderContext } from '@app/features/container/containers/page/page.context'; import { Card } from '@app/ui/layout/card/card'; import { CardContent } from '@app/ui/layout/card/card-content'; @@ -18,6 +21,8 @@ import { SwapFormValues } from './hooks/use-swap-form'; import { useSwapContext } from './swap.context'; export function Swap() { + // Swap uses routed dialogs to choose assets so needs onBackLocation to go Home + useUpdatePageHeaderContext({ title: 'Swap', onBackLocation: RouteUrls.Home }); const { isFetchingExchangeRate, swappableAssetsBase, swappableAssetsQuote } = useSwapContext(); const { dirty, isValid, setFieldValue, values, validateForm } = useFormikContext(); diff --git a/src/app/pages/unlock.tsx b/src/app/pages/unlock.tsx index da4ad908c1a..0d51ebc8a8f 100644 --- a/src/app/pages/unlock.tsx +++ b/src/app/pages/unlock.tsx @@ -1,10 +1,11 @@ import { Outlet, useNavigate } from 'react-router-dom'; import { RequestPassword } from '@app/components/request-password'; +import { useUpdatePageHeaderContext } from '@app/features/container/containers/page/page.context'; export function Unlock() { const navigate = useNavigate(); - + useUpdatePageHeaderContext({ isSessionLocked: true }); // Here we want to return to the previous route. The user could land on any // page when the wallet is locked, so we can't assume as single route. const returnToPreviousRoute = () => navigate(-1); diff --git a/src/app/routes/app-routes.tsx b/src/app/routes/app-routes.tsx index be665b76641..f19131798ac 100644 --- a/src/app/routes/app-routes.tsx +++ b/src/app/routes/app-routes.tsx @@ -1,4 +1,3 @@ -import { Suspense } from 'react'; import { Navigate, Route, @@ -14,7 +13,11 @@ import { RouteUrls } from '@shared/route-urls'; import { LoadingSpinner } from '@app/components/loading-spinner'; import { AddNetwork } from '@app/features/add-network/add-network'; import { Container } from '@app/features/container/container'; -import { EditNonceDialog } from '@app/features/dialogs/edit-nonce-dialog/edit-nonce-dialog'; +// import { HomeLayout } from '@app/ui/pages/home.layout'; - TODO rename this other home wrapper +import { HomeLayout } from '@app/features/container/containers/home/home.layout'; +import { OnboardingLayout } from '@app/features/container/containers/onboarding/onboarding.layout'; +import { PageLayout } from '@app/features/container/containers/page/page.layout'; +import { PopupLayout } from '@app/features/container/containers/popup/popup.layout'; import { IncreaseBtcFeeDialog } from '@app/features/dialogs/increase-fee-dialog/increase-btc-fee-dialog'; import { IncreaseStxFeeDialog } from '@app/features/dialogs/increase-fee-dialog/increase-stx-fee-dialog'; import { leatherIntroDialogRoutes } from '@app/features/dialogs/leather-intro-dialog/leather-intro-dialog'; @@ -28,7 +31,6 @@ import { UnsupportedBrowserLayout } from '@app/features/ledger/generic-steps'; import { ConnectLedgerStart } from '@app/features/ledger/generic-steps/connect-device/connect-ledger-start'; import { RetrieveTaprootToNativeSegwit } from '@app/features/retrieve-taproot-to-native-segwit/retrieve-taproot-to-native-segwit'; import { BitcoinContractList } from '@app/pages/bitcoin-contract-list/bitcoin-contract-list'; -import { BitcoinContractRequest } from '@app/pages/bitcoin-contract-request/bitcoin-contract-request'; import { ChooseAccount } from '@app/pages/choose-account/choose-account'; import { ChooseCryptoAssetToFund } from '@app/pages/fund/choose-asset-to-fund/choose-asset-to-fund'; import { FundPage } from '@app/pages/fund/fund'; @@ -39,7 +41,6 @@ import { WelcomePage } from '@app/pages/onboarding/welcome/welcome'; import { ReceiveBtcModal } from '@app/pages/receive/receive-btc'; import { ReceiveStxModal } from '@app/pages/receive/receive-stx'; import { RequestError } from '@app/pages/request-error/request-error'; -import { RpcSignStacksTransaction } from '@app/pages/rpc-sign-stacks-transaction/rpc-sign-stacks-transaction'; import { BroadcastError } from '@app/pages/send/broadcast-error/broadcast-error'; import { LockBitcoinSummary } from '@app/pages/send/locked-bitcoin-summary/locked-bitcoin-summary'; import { sendOrdinalRoutes } from '@app/pages/send/ordinal-inscription/ordinal-routes'; @@ -49,10 +50,12 @@ import { UnauthorizedRequest } from '@app/pages/unauthorized-request/unauthorize import { Unlock } from '@app/pages/unlock'; import { ViewSecretKey } from '@app/pages/view-secret-key/view-secret-key'; import { AccountGate } from '@app/routes/account-gate'; +// import { RouteWrapper } from '@app/routes/components/route-wrapper'; import { receiveRoutes } from '@app/routes/receive-routes'; import { legacyRequestRoutes } from '@app/routes/request-routes'; import { rpcRequestRoutes } from '@app/routes/rpc-routes'; +// is the gate maybe the place to wrap instead? import { OnboardingGate } from './onboarding-gate'; export function SuspenseLoadingSpinner() { @@ -81,186 +84,170 @@ function useAppRoutes() { return sentryCreateBrowserRouter( createRoutesFromElements( }> - }> - - - - } - > - {homePageModalRoutes} + }> + {/* FIXME don't duplicate RouterErrorBoundary just for layout */} + }> + + + + } + > + {homePageModalRoutes} + + + }> + }> + } + /> + }> + {ledgerStacksTxSigningRoutes} + + } + /> + }> + {ledgerBitcoinTxSigningRoutes} + - } - /> - }> {ledgerStacksTxSigningRoutes} - - } - /> - }> - {ledgerBitcoinTxSigningRoutes} - - {ledgerStacksTxSigningRoutes} + } /> + } /> + } /> - - }> - - - - } - /> - } /> - } /> - } /> - - - - } - > - } /> } + path={RouteUrls.AddNetwork} + element={ + + + + } + /> + + + + } + > + {ledgerJwtSigningRoutes} + + + + + } + > + } /> + } /> + + + + + } + > + } /> + + + {sendCryptoAssetFormRoutes} + + }> + {leatherIntroDialogRoutes} + + } /> + + + + } /> - {requestBitcoinKeysRoutes} - {requestStacksKeysRoutes} - - - - - } - /> - { - const { SetPasswordRoute } = await import( - '@app/pages/onboarding/set-password/set-password' - ); - return { Component: SetPasswordRoute }; - }} - /> - - - - - } - /> - - - - } - /> - - - - } - > - {ledgerJwtSigningRoutes} - - - - - - } - > - } /> - } /> - - - - - } - > - } /> + {alexSwapRoutes} + - {sendCryptoAssetFormRoutes} + }> + }> + + + + } + > + } /> + } + /> + + {requestBitcoinKeysRoutes} + {requestStacksKeysRoutes} + - - - - } - /> - }> - {leatherIntroDialogRoutes} - + + + + } + /> + { + const { SetPasswordRoute } = await import( + '@app/pages/onboarding/set-password/set-password' + ); + return { Component: SetPasswordRoute }; + }} + /> - {legacyRequestRoutes} - {rpcRequestRoutes} - } /> - - - - } - /> + + + + } + /> - - - - } - > - } /> + + + + } + /> + - { - const { RpcSignBip322MessageRoute } = await import( - '@app/pages/rpc-sign-bip322-message/rpc-sign-bip322-message' - ); - return { Component: RpcSignBip322MessageRoute }; - }} - > - {ledgerBitcoinTxSigningRoutes} + }> + }> + {legacyRequestRoutes} + {rpcRequestRoutes} - - {alexSwapRoutes} - - {/* Catch-all route redirects to onboarding */} - } /> + + {/* Catch-all route redirects to onboarding */} + } /> ) ); diff --git a/src/app/routes/rpc-routes.tsx b/src/app/routes/rpc-routes.tsx index 8893db05c47..0d8e5a69fab 100644 --- a/src/app/routes/rpc-routes.tsx +++ b/src/app/routes/rpc-routes.tsx @@ -3,13 +3,16 @@ import { Route } from 'react-router-dom'; import { RouteUrls } from '@shared/route-urls'; +import { EditNonceDialog } from '@app/features/dialogs/edit-nonce-dialog/edit-nonce-dialog'; import { ledgerBitcoinTxSigningRoutes } from '@app/features/ledger/flows/bitcoin-tx-signing/ledger-bitcoin-sign-tx-container'; import { ledgerStacksMessageSigningRoutes } from '@app/features/ledger/flows/stacks-message-signing/ledger-stacks-sign-msg.routes'; +import { BitcoinContractRequest } from '@app/pages/bitcoin-contract-request/bitcoin-contract-request'; import { RpcGetAddresses } from '@app/pages/rpc-get-addresses/rpc-get-addresses'; import { rpcSendTransferRoutes } from '@app/pages/rpc-send-transfer/rpc-send-transfer.routes'; import { RpcSignPsbt } from '@app/pages/rpc-sign-psbt/rpc-sign-psbt'; import { RpcSignPsbtSummary } from '@app/pages/rpc-sign-psbt/rpc-sign-psbt-summary'; import { RpcStacksMessageSigning } from '@app/pages/rpc-sign-stacks-message/rpc-sign-stacks-message'; +import { RpcSignStacksTransaction } from '@app/pages/rpc-sign-stacks-transaction/rpc-sign-stacks-transaction'; import { AccountGate } from '@app/routes/account-gate'; import { SuspenseLoadingSpinner } from './app-routes'; @@ -66,5 +69,25 @@ export const rpcRequestRoutes = ( > {ledgerStacksMessageSigningRoutes} + + }> + + + + } + /> + + + + } + > + } /> + ); diff --git a/src/app/ui/components/containers/container.layout.tsx b/src/app/ui/components/containers/container.layout.tsx deleted file mode 100644 index 6167da4552d..00000000000 --- a/src/app/ui/components/containers/container.layout.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import { Flex } from 'leather-styles/jsx'; - -interface ContainerLayoutProps { - children: React.JSX.Element | React.JSX.Element[]; - header: React.JSX.Element | null; -} -export function ContainerLayout({ children, header }: ContainerLayoutProps) { - return ( - - {header} - - {children} - - - ); -} diff --git a/src/app/ui/components/containers/headers/components/big-title-header.tsx b/src/app/ui/components/containers/headers/components/big-title-header.tsx deleted file mode 100644 index b64910a12b9..00000000000 --- a/src/app/ui/components/containers/headers/components/big-title-header.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { ReactNode } from 'react'; - -import { SharedComponentsSelectors } from '@tests/selectors/shared-component.selectors'; -import { Flex, styled } from 'leather-styles/jsx'; - -import { CloseIcon } from '@leather.io/ui'; - -import { HeaderActionButton } from './header-action-button'; - -interface BigTitleHeaderProps { - onClose?(): void; - title?: ReactNode; -} - -export function BigTitleHeader({ onClose, title }: BigTitleHeaderProps) { - return ( - - {title} - {onClose && ( - - } - dataTestId={SharedComponentsSelectors.HeaderCloseBtn} - onAction={onClose} - /> - - )} - - ); -} diff --git a/src/app/ui/components/containers/headers/header.stories.tsx b/src/app/ui/components/containers/headers/header.stories.tsx deleted file mode 100644 index d6b48b0b883..00000000000 --- a/src/app/ui/components/containers/headers/header.stories.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import type { Meta } from '@storybook/react'; - -import { Header as Component, HeaderProps } from './header'; - -const meta: Meta = { - component: Component, - tags: ['autodocs'], - title: 'Containers/Header', - args: { - variant: 'home', - }, -}; - -export default meta; - -export function Header(args: HeaderProps) { - return null} onGoBack={() => null} />; -} - -export function PageHeader(args: HeaderProps) { - return null} />; -} diff --git a/src/app/ui/components/containers/headers/header.tsx b/src/app/ui/components/containers/headers/header.tsx deleted file mode 100644 index 285d5e58d36..00000000000 --- a/src/app/ui/components/containers/headers/header.tsx +++ /dev/null @@ -1,90 +0,0 @@ -import { ReactNode } from 'react'; - -import { SharedComponentsSelectors } from '@tests/selectors/shared-component.selectors'; -import { Flex, Grid, GridItem, HStack, styled } from 'leather-styles/jsx'; - -import { ArrowLeftIcon, CloseIcon } from '@leather.io/ui'; - -import { BigTitleHeader } from './components/big-title-header'; -import { HeaderActionButton } from './components/header-action-button'; - -type HeaderVariants = 'page' | 'home' | 'onboarding' | 'bigTitle' | 'fund'; - -export interface HeaderProps { - variant: HeaderVariants; - onClose?(): void; - onGoBack?(): void; - title?: ReactNode; - account?: ReactNode; - totalBalance?: ReactNode; - settingsMenu?: ReactNode; - networkBadge?: ReactNode; - logo?: ReactNode; -} - -export function Header({ - variant, - onClose, - onGoBack, - account, - totalBalance, - settingsMenu, - networkBadge, - title, - logo, -}: HeaderProps) { - const logoItem = onGoBack || logo || account; - - return ( - - - - {logoItem && ( - - {variant !== 'home' && onGoBack ? ( - } - onAction={onGoBack} - dataTestId={SharedComponentsSelectors.HeaderBackBtn} - /> - ) : undefined} - {account ? account : logo} - - )} - - - {title && {title}} - - - - {networkBadge} - {totalBalance && totalBalance} - {settingsMenu} - {variant !== 'bigTitle' && onClose && ( - } - dataTestId={SharedComponentsSelectors.HeaderCloseBtn} - onAction={onClose} - /> - )} - - - - {variant === 'bigTitle' && } - - ); -}