From 844404126ce76f8c5fc2ed9c0b17ce94db3bdff7 Mon Sep 17 00:00:00 2001 From: Trung-Tin Pham <60747384+AtelyPham@users.noreply.github.com> Date: Fri, 3 Nov 2023 01:58:28 +0700 Subject: [PATCH] feat: adding logic for connect wallet and create note account when user click on the Account tab --- apps/bridge-dapp/src/hooks/useSidebarProps.ts | 31 ++++++++++++++++--- .../src/components/SideBar/Item.tsx | 2 ++ .../src/components/SideBar/SubItem.tsx | 11 ++++--- .../src/components/SideBar/types.ts | 7 +++++ .../src/components/SideBar/useLinkProps.ts | 12 +++++-- libs/webb-ui-components/src/types/index.ts | 21 +++++++++++++ 6 files changed, 72 insertions(+), 12 deletions(-) diff --git a/apps/bridge-dapp/src/hooks/useSidebarProps.ts b/apps/bridge-dapp/src/hooks/useSidebarProps.ts index 21fbdff85c..a952abe829 100644 --- a/apps/bridge-dapp/src/hooks/useSidebarProps.ts +++ b/apps/bridge-dapp/src/hooks/useSidebarProps.ts @@ -1,8 +1,12 @@ import { useWebContext } from '@webb-tools/api-provider-environment'; import BillFillIcon from '@webb-tools/icons/BillFillIcon'; +import { useNoteAccount } from '@webb-tools/react-hooks/useNoteAccount'; import type { SideBarItemProps } from '@webb-tools/webb-ui-components/components/SideBar/types'; +import type { EventFor } from '@webb-tools/webb-ui-components/types'; import { useLocation } from 'react-router'; import sidebar from '../constants/sidebar'; +import useChainsFromRoute from './useChainsFromRoute'; +import { useConnectWallet } from './useConnectWallet'; const accountItemCfg = { name: 'Account', @@ -17,15 +21,32 @@ const accountItemCfg = { * **Must be used inside the `WebbProvider` component**. */ function useSidebarProps() { - const { noteManager } = useWebContext(); const { pathname } = useLocation(); + const { srcTypedChainId } = useChainsFromRoute(); + + const { activeWallet, noteManager } = useWebContext(); + const { hasNoteAccount, setOpenNoteAccountModal } = useNoteAccount(); + const { toggleModal } = useConnectWallet(); + + const handleClick = (event: EventFor<'a', 'onClick'>) => { + event.preventDefault(); + + if (typeof srcTypedChainId !== 'number') { + return; + } + + if (!activeWallet) { + return toggleModal(true, srcTypedChainId); + } + + if (!hasNoteAccount) { + setOpenNoteAccountModal(true); + } + }; const accountItem = { ...accountItemCfg, - info: noteManager?.getKeypair() - ? undefined - : 'Connect your wallet and create a note account to access this feature.', - isDisabled: !noteManager?.getKeypair(), + onClick: noteManager && activeWallet ? undefined : handleClick, } satisfies SideBarItemProps; sidebar.items = [ diff --git a/libs/webb-ui-components/src/components/SideBar/Item.tsx b/libs/webb-ui-components/src/components/SideBar/Item.tsx index c069494724..bf3c16bc73 100644 --- a/libs/webb-ui-components/src/components/SideBar/Item.tsx +++ b/libs/webb-ui-components/src/components/SideBar/Item.tsx @@ -24,6 +24,7 @@ const SideBarItem: FC = ({ setIsActive, isDisabled, pathnameOrHash, + onClick, info, }) => { const [isMounted, setIsMounted] = useState(false); @@ -75,6 +76,7 @@ const SideBarItem: FC = ({ isNext, isDisabled, hasSubItem: subItems.length > 0, + onClick, }); if (!isMounted) return null; diff --git a/libs/webb-ui-components/src/components/SideBar/SubItem.tsx b/libs/webb-ui-components/src/components/SideBar/SubItem.tsx index 81d1a68e17..a0bcf1e3bd 100644 --- a/libs/webb-ui-components/src/components/SideBar/SubItem.tsx +++ b/libs/webb-ui-components/src/components/SideBar/SubItem.tsx @@ -1,12 +1,13 @@ import { ExternalLinkLine } from '@webb-tools/icons'; +import cx from 'classnames'; import React, { useMemo } from 'react'; -import isSideBarItemActive from '../../utils/isSideBarItemActive'; +import type { EventFor } from '../../types'; import { Typography } from '../../typography/Typography'; +import isSideBarItemActive from '../../utils/isSideBarItemActive'; import { Link } from '../Link'; -import cx from 'classnames'; +import WithInfo from './WithInfo'; import { SideBarExtraSubItemProps, SideBarSubItemProps } from './types'; import useLinkProps from './useLinkProps'; -import WithInfo from './WithInfo'; export const SubItem: React.FC< SideBarSubItemProps & SideBarExtraSubItemProps @@ -20,11 +21,13 @@ export const SubItem: React.FC< setItemIsActive, setSubItemIsActive, info, + onClick, pathnameOrHash, }) => { const linkProps = useLinkProps({ href, isInternal, isNext, isDisabled }); - const setIsActive = () => { + const setIsActive = (event: EventFor<'a', 'onClick'>) => { + onClick?.(event); if (setItemIsActive && setSubItemIsActive && isInternal) { setItemIsActive(); setSubItemIsActive(); diff --git a/libs/webb-ui-components/src/components/SideBar/types.ts b/libs/webb-ui-components/src/components/SideBar/types.ts index 6470bf4509..37f7984482 100644 --- a/libs/webb-ui-components/src/components/SideBar/types.ts +++ b/libs/webb-ui-components/src/components/SideBar/types.ts @@ -1,6 +1,7 @@ import type { IconBase } from '@webb-tools/icons/types'; import type { LogoProps } from '../Logo/types'; import type { DialogContentProps } from '@radix-ui/react-dialog'; +import { MouseEventHandler } from 'react'; export type SideBarFooterType = { name: string; @@ -55,6 +56,9 @@ export type SideBarItemProps = { /** The extra info tooltip for the item */ info?: string | React.ReactElement; + /** The callback function when the item is clicked */ + onClick?: MouseEventHandler; + pathnameOrHash?: string; /** The item sub items */ @@ -81,6 +85,9 @@ export type SideBarSubItemProps = { /** The extra info tooltip for the item */ info?: string | React.ReactElement; + /** The callback function when the item is clicked */ + onClick?: MouseEventHandler; + pathnameOrHash?: string; }; diff --git a/libs/webb-ui-components/src/components/SideBar/useLinkProps.ts b/libs/webb-ui-components/src/components/SideBar/useLinkProps.ts index 9339a25ba2..2cbc9e6643 100644 --- a/libs/webb-ui-components/src/components/SideBar/useLinkProps.ts +++ b/libs/webb-ui-components/src/components/SideBar/useLinkProps.ts @@ -7,11 +7,14 @@ import type { SideBarExtraItemProps, SideBarItemProps } from './types'; type Props = SideBarItemProps & SideBarExtraItemProps; function useLinkProps( - args: Pick & { + args: Pick< + Props, + 'isInternal' | 'href' | 'isNext' | 'isDisabled' | 'onClick' + > & { hasSubItem?: boolean; } ) { - const { isInternal, isNext, href, isDisabled, hasSubItem } = args; + const { isInternal, isNext, href, isDisabled, hasSubItem, onClick } = args; return useMemo(() => { if (isDisabled || hasSubItem) { @@ -22,6 +25,7 @@ function useLinkProps( return { href, target: '_blank', + onClick, } as const satisfies PropsOf<'a'>; } @@ -29,6 +33,7 @@ function useLinkProps( return { href, isInternal, + onClick, } as const satisfies PropsOf & { isInternal: true }; } @@ -36,11 +41,12 @@ function useLinkProps( return { to: href, isInternal, + onClick, } as const satisfies PropsOf & { isInternal: true }; } return {}; - }, [hasSubItem, href, isDisabled, isInternal, isNext]); + }, [hasSubItem, href, isDisabled, isInternal, isNext, onClick]); } export default useLinkProps; diff --git a/libs/webb-ui-components/src/types/index.ts b/libs/webb-ui-components/src/types/index.ts index e675de6243..d6d921a473 100644 --- a/libs/webb-ui-components/src/types/index.ts +++ b/libs/webb-ui-components/src/types/index.ts @@ -179,3 +179,24 @@ export type ArrayElement = export type NonNullableArrayItem> = NonNullable>; + +type GetEventHandlers = Extract< + keyof JSX.IntrinsicElements[T], + `on${string}` +>; + +/** + * Provides the event type for a given element and handler. + * + * @example + * + * type MyEvent = EventFor<"input", "onChange">; + */ +export type EventFor< + TElement extends keyof JSX.IntrinsicElements, + THandler extends GetEventHandlers +> = JSX.IntrinsicElements[TElement][THandler] extends + | ((e: infer TEvent) => any) + | undefined + ? TEvent + : never;