Skip to content

Commit

Permalink
Namadillo: Top Navigation improvements (#1475)
Browse files Browse the repository at this point in the history
* feat(namadillo): top navigation modal components

* feat(namadillo): adding copy to clipboard feature to tx hash
  • Loading branch information
pedrorezende authored Jan 7, 2025
1 parent 4b87ef6 commit 741fbec
Show file tree
Hide file tree
Showing 9 changed files with 209 additions and 17 deletions.
30 changes: 30 additions & 0 deletions apps/namadillo/src/App/Common/AssetsModalCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Stack } from "@namada/components";
import clsx from "clsx";

type AssetsModalCard = {
title: string;
icon: React.ReactNode;
onClick: () => void;
} & React.PropsWithChildren;

export const AssetsModalCard = ({
title,
icon,
children,
onClick,
}: AssetsModalCard): JSX.Element => {
return (
<Stack
gap={6}
onClick={onClick}
className={clsx(
"w-[220px] h-full items-stretch pb-8 pt-2.5 px-4 border rounded-md border-transparent transition-colors cursor-pointer",
"items-center text-white text-center hover:border-yellow"
)}
>
<h3 className="text-xl font-medium">{title}</h3>
<aside className="max-w-[78px]">{icon}</aside>
<div className="text-base/tight">{children}</div>
</Stack>
);
};
4 changes: 2 additions & 2 deletions apps/namadillo/src/App/Common/ModalContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ export const ModalContainer = ({
>
<IoClose />
</i>
<header className="flex w-full justify-center items-center relative mb-3 text-xl text-medium">
<header className="flex w-full justify-center items-center relative mb-3 text-lg text-medium">
{header}
</header>
<div
className={twMerge("flex-1 overflow-hidden", contentClassName)}
className={twMerge("flex-1 overflow-hidden py-6", contentClassName)}
{...otherContentProps}
>
{children}
Expand Down
46 changes: 46 additions & 0 deletions apps/namadillo/src/App/Common/SelectOptionModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Modal } from "@namada/components";
import { AssetsModalCard } from "./AssetsModalCard";
import { ModalContainer } from "./ModalContainer";

type Entry = {
title: string;
onClick: () => void;
icon: React.ReactNode;
children: React.ReactNode;
};

type SelectOptionModalProps = {
title: string;
onClose: () => void;
items: Entry[];
};

export const SelectOptionModal = ({
title,
onClose,
items,
}: SelectOptionModalProps): JSX.Element => {
return (
<Modal onClose={onClose}>
<ModalContainer
header={title}
onClose={onClose}
containerProps={{ className: "!w-auto !h-auto bg-rblack" }}
contentProps={{ className: "pt-0 mt-3" }}
>
<ul className="grid grid-cols-[1fr_1px_1fr] gap-4 pt-1">
{items.map((item, index) => (
<>
<li key={index}>
<AssetsModalCard {...item}>{item.children}</AssetsModalCard>
</li>
{index + 1 < items.length && (
<li className="w-px bg-white -my-1" />
)}
</>
))}
</ul>
</ModalContainer>
</Modal>
);
};
45 changes: 45 additions & 0 deletions apps/namadillo/src/App/Common/ShieldAssetsModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { routes } from "App/routes";
import { wallets } from "integrations";
import { getAssetImageUrl } from "integrations/utils";
import { useNavigate } from "react-router-dom";
import { namadaAsset } from "utils";
import { SelectOptionModal } from "./SelectOptionModal";

type ShieldAssetsModal = {
onClose: () => void;
};

export const ShieldAssetsModal = ({
onClose,
}: ShieldAssetsModal): JSX.Element => {
const navigate = useNavigate();
const goTo = (url: string): void => {
navigate(url);
onClose();
};

return (
<SelectOptionModal
title="Shield Assets"
onClose={onClose}
items={[
{
title: "IBC Shield",
icon: <img src={wallets.keplr.iconUrl} className="w-full" />,
onClick: () => goTo(routes.ibc),
children: "Shield external assets over IBC to Namada",
},
{
title: "Internal Shield",
icon: (
<span className="flex w-full bg-yellow rounded-md">
<img src={getAssetImageUrl(namadaAsset())} className="w-full" />
</span>
),
onClick: () => goTo(routes.maspShield),
children: "Shield Assets from your Namada transparent account",
},
]}
/>
);
};
46 changes: 46 additions & 0 deletions apps/namadillo/src/App/Common/UnshieldAssetsModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { routes } from "App/routes";
import { wallets } from "integrations";
import { getAssetImageUrl } from "integrations/utils";
import { useNavigate } from "react-router-dom";
import { namadaAsset } from "utils";
import { SelectOptionModal } from "./SelectOptionModal";

type UnshieldAssetsModal = {
onClose: () => void;
};

export const UnshieldAssetsModal = ({
onClose,
}: UnshieldAssetsModal): JSX.Element => {
const navigate = useNavigate();
const goTo = (url: string): void => {
navigate(url);
onClose();
};

return (
<SelectOptionModal
title="Unshield Assets"
onClose={onClose}
items={[
{
title: "IBC Unshield",
icon: <img src={wallets.keplr.iconUrl} className="w-full" />,
onClick: () => goTo(routes.ibcWithdraw),
children: "Unshield assets over IBC to an IBC chain",
},
{
title: "Internal Unshield",
icon: (
<span className="flex w-full bg-yellow rounded-md">
<img src={getAssetImageUrl(namadaAsset())} className="w-full" />
</span>
),
onClick: () => goTo(routes.maspUnshield),
children:
"Unshield assets from your Namada shielded to transparent account",
},
]}
/>
);
};
41 changes: 33 additions & 8 deletions apps/namadillo/src/App/Layout/TopNavigation.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { ActionButton } from "@namada/components";
import { ConnectExtensionButton } from "App/Common/ConnectExtensionButton";
import { ShieldAssetsModal } from "App/Common/ShieldAssetsModal";
import { TransactionInProgressSpinner } from "App/Common/TransactionInProgressSpinner";
import { IbcLogo } from "App/Ibc/assets/IbcLogo";
import { UnshieldAssetsModal } from "App/Common/UnshieldAssetsModal";
import { routes } from "App/routes";
import {
applicationFeaturesAtom,
signArbitraryEnabledAtom,
} from "atoms/settings";
import { useUserHasAccount } from "hooks/useIsAuthenticated";
import { useAtomValue } from "jotai";
import { useState } from "react";
import { AiOutlineMessage } from "react-icons/ai";
import { IoSettingsOutline } from "react-icons/io5";
import { useLocation, useNavigate } from "react-router-dom";
Expand All @@ -17,6 +19,9 @@ import { NamadaAccount } from "./NamadaAccount";
import { SyncIndicator } from "./SyncIndicator";

export const TopNavigation = (): JSX.Element => {
const [shieldingModalOpen, setShieldingModalOpen] = useState(false);
const [unshieldingModalOpen, setUnshieldingModalOpen] = useState(false);

const userHasAccount = useUserHasAccount();
const signArbitraryEnabled = useAtomValue(signArbitraryEnabledAtom);
const { maspEnabled, namTransfersEnabled } = useAtomValue(
Expand All @@ -35,20 +40,32 @@ export const TopNavigation = (): JSX.Element => {

return (
<div className="flex-1 flex items-center gap-4 sm:gap-6">
<div className="hidden lg:flex gap-2">
<div className="hidden lg:grid lg:grid-cols-3 gap-2">
{maspEnabled && (
<ActionButton
className="py-2"
size="xs"
onClick={() => setShieldingModalOpen(true)}
>
Shield Assets
</ActionButton>
)}
{maspEnabled && (
<ActionButton href={routes.ibc} size="sm" className="px-4">
<div className="flex items-center gap-1">
Shield Assets over <IbcLogo />
</div>
<ActionButton
className="py-2"
outlineColor="yellow"
size="xs"
onClick={() => setUnshieldingModalOpen(true)}
>
Unshield
</ActionButton>
)}
{(maspEnabled || namTransfersEnabled) && (
<ActionButton
href={routes.transfer}
size="sm"
className="py-2"
size="xs"
backgroundColor="white"
className="min-w-[140px]"
>
Transfer
</ActionButton>
Expand Down Expand Up @@ -87,6 +104,14 @@ export const TopNavigation = (): JSX.Element => {
<NamadaAccount />
<KeplrAccount />
</div>

{shieldingModalOpen && (
<ShieldAssetsModal onClose={() => setShieldingModalOpen(false)} />
)}

{unshieldingModalOpen && (
<UnshieldAssetsModal onClose={() => setUnshieldingModalOpen(false)} />
)}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Asset } from "@chain-registry/types";
import { Tooltip } from "@namada/components";
import { CopyToClipboardControl } from "@namada/components";
import { shortenAddress } from "@namada/utils";
import { Timeline, TransactionStep } from "App/Common/Timeline";
import { AssetImage } from "App/Transfer/AssetImage";
Expand Down Expand Up @@ -155,11 +155,11 @@ export const TransferTransactionTimeline = ({
{stepDescription[transaction.currentStep || "sign"]}
</h2>
{transaction.hash && (
<span className="text-xs text-center block text-neutral-600">
<span className="my-1 text-sm text-center block text-neutral-600">
Transaction hash:{" "}
<span className="relative group/tooltip">
<span className="inline-flex gap-1">
{shortenAddress(transaction.hash, 8, 8)}
<Tooltip>{transaction.hash}</Tooltip>
<CopyToClipboardControl value={transaction.hash} />
</span>
</span>
)}
Expand Down
2 changes: 1 addition & 1 deletion apps/namadillo/src/integrations/assets/keplr.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions packages/components/src/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ export const Modal = ({
transition={{ duration: 0 }}
exit={{ opacity: 0 }}
onClick={onClose}
className="fixed top-0 left-0 w-full h-full cursor-pointer backdrop-blur-lg z-[1000] bg-rblack/50"
className="fixed top-0 left-0 w-full h-full cursor-pointer backdrop-blur-lg z-[9998] bg-rblack/50"
/>
<div
{...props}
role="dialog"
className={twMerge(
clsx(
"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-20 z-[1001]",
"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 z-20 z-[9999]",
className
)
)}
Expand Down

1 comment on commit 741fbec

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.