Skip to content

Commit

Permalink
feat: upgrade the connect state for pages (#1159)
Browse files Browse the repository at this point in the history
  • Loading branch information
euharrison authored Oct 14, 2024
1 parent f70a6a4 commit 9745a7b
Show file tree
Hide file tree
Showing 26 changed files with 310 additions and 224 deletions.
65 changes: 25 additions & 40 deletions apps/namadillo/src/App/AccountOverview/AccountOverview.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,33 @@
import { Panel, Stack } from "@namada/components";
import { Intro } from "App/Common/Intro";
import { ConnectPanel } from "App/Common/ConnectPanel";
import { PageWithSidebar } from "App/Common/PageWithSidebar";
import MainnetRoadmap from "App/Sidebars/MainnetRoadmap";
import { ShieldAllBanner } from "App/Sidebars/ShieldAllBanner";
import { StakingRewardsPanel } from "App/Staking/StakingRewardsPanel";
import {
applicationFeaturesAtom,
namadaExtensionConnectedAtom,
} from "atoms/settings";
import { useUserHasAccount } from "hooks/useUserHasAccount";
import { applicationFeaturesAtom } from "atoms/settings";
import { useUserHasAccount } from "hooks/useIsAuthenticated";
import { useAtomValue } from "jotai";
import { twMerge } from "tailwind-merge";
import { AccountBalanceContainer } from "./AccountBalanceContainer";
import { NamBalanceContainer } from "./NamBalanceContainer";
import { NavigationFooter } from "./NavigationFooter";

export const AccountOverview = (): JSX.Element => {
const isConnected = useAtomValue(namadaExtensionConnectedAtom);
const hasAccount = useUserHasAccount();
const { claimRewardsEnabled, maspEnabled } = useAtomValue(
applicationFeaturesAtom
);
const userHasAccount = useUserHasAccount();
const { claimRewardsEnabled } = useAtomValue(applicationFeaturesAtom);

const showSidebar = isConnected && hasAccount !== undefined;
if (!userHasAccount) {
return (
<ConnectPanel>
<div className="mb-6">Your Gateway to the Shielded Multichain</div>
</ConnectPanel>
);
}

return (
<PageWithSidebar>
<div className={twMerge("flex w-full", !showSidebar && "col-span-2")}>
{(!isConnected || hasAccount === false) && (
<section className="flex rounded-sm items-center w-full bg-black">
<div className="w-[420px] mx-auto">
<Intro />
</div>
</section>
)}

{isConnected && hasAccount && !claimRewardsEnabled && (
<section className="flex items-center bg-black rounded-sm w-full">
<Stack gap={5} className="my-auto min-w-[365px] mx-auto py-12">
<AccountBalanceContainer />
<NavigationFooter />
</Stack>
</section>
)}

{isConnected && hasAccount && claimRewardsEnabled && (
<div className={twMerge("flex w-full")}>
{claimRewardsEnabled ?
<section className="flex flex-col w-full rounded-sm min-h-full gap-2">
<div className="grid grid-cols-[1.25fr_1fr] gap-2">
<Panel className="pl-4 pr-6 py-5">
Expand All @@ -58,17 +41,19 @@ export const AccountOverview = (): JSX.Element => {
<NavigationFooter />
</Panel>
</section>
)}
: <section className="flex items-center bg-black rounded-sm w-full">
<Stack gap={5} className="my-auto min-w-[365px] mx-auto py-12">
<AccountBalanceContainer />
<NavigationFooter />
</Stack>
</section>
}
</div>

{showSidebar &&
(maspEnabled ?
<aside>
<ShieldAllBanner />
</aside>
: <aside className="bg-black rounded-sm">
<MainnetRoadmap />
</aside>)}
<aside className="flex flex-col gap-2">
<ShieldAllBanner />
<MainnetRoadmap />
</aside>
</PageWithSidebar>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const NavigationFooter = (): JSX.Element => {
<Heading level="h3" className="uppercase text-4xl text-yellow mb-2">
Stake & Vote Now
</Heading>
<Stack gap={3} direction="horizontal">
<Stack gap={3} direction="horizontal" className="justify-center">
<ActionButton
className="border uppercase"
href={routes.staking}
Expand Down
2 changes: 0 additions & 2 deletions apps/namadillo/src/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Toasts } from "App/Common/Toast";
import { AppLayout } from "App/Layout/AppLayout";
import { createBrowserHistory } from "history";
import { useExtensionEvents } from "hooks/useExtensionEvents";
import { useOnNamadaExtensionAttached } from "hooks/useOnNamadaExtensionAttached";
import { useTransactionCallback } from "hooks/useTransactionCallbacks";
import { useTransactionNotifications } from "hooks/useTransactionNotifications";
import { Outlet } from "react-router-dom";
Expand All @@ -12,7 +11,6 @@ export const history = createBrowserHistory({ window });

export function App(): JSX.Element {
useExtensionEvents();
useOnNamadaExtensionAttached();
useTransactionNotifications();
useTransactionCallback();
return (
Expand Down
17 changes: 11 additions & 6 deletions apps/namadillo/src/App/Common/ConnectBanner.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { Panel } from "@namada/components";
import { ConnectExtensionButton } from "App/Common/ConnectExtensionButton";
import { useConnectText } from "hooks/useConnectText";

type ConnectBannerProps = {
text: string;
};
export const ConnectBanner = ({
actionText,
}: {
actionText?: string;
}): JSX.Element => {
const connectText = useConnectText();

export const ConnectBanner = ({ text }: ConnectBannerProps): JSX.Element => {
return (
<Panel className="border border-yellow py-3">
<div className="grid grid-cols-[auto_max-content] items-center pl-15">
<div className="w-full text-yellow text-xl">{text}</div>
<div className="grid grid-cols-[auto_max-content] items-center">
<div className="w-full text-yellow text-xl">
{actionText} {connectText}
</div>
<ConnectExtensionButton />
</div>
</Panel>
Expand Down
13 changes: 7 additions & 6 deletions apps/namadillo/src/App/Common/ConnectExtensionButton.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { ActionButton } from "@namada/components";
import { useUntilIntegrationAttached } from "@namada/integrations";
import { namadaExtensionConnectedAtom } from "atoms/settings";
import { namadaExtensionAttachStatus } from "atoms/settings";
import { useExtensionConnect } from "hooks/useExtensionConnect";
import { useAtomValue } from "jotai";

export const ConnectExtensionButton = (): JSX.Element => {
const extensionAttachStatus = useUntilIntegrationAttached();
const isExtensionConnected = useAtomValue(namadaExtensionConnectedAtom);
const { connect } = useExtensionConnect();
const extensionAttachStatus = useAtomValue(namadaExtensionAttachStatus);
const { connect, isConnected } = useExtensionConnect();

// TODO create an action button when the extension is connected
// but the account is missing, like on useConnectText

return (
<>
{extensionAttachStatus === "attached" && !isExtensionConnected && (
{extensionAttachStatus === "attached" && !isConnected && (
<ActionButton backgroundColor="yellow" size="sm" onClick={connect}>
Connect Keychain
</ActionButton>
Expand Down
48 changes: 48 additions & 0 deletions apps/namadillo/src/App/Common/ConnectPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { ActionButton, Image, Panel } from "@namada/components";
import { ConnectExtensionButton } from "App/Common/ConnectExtensionButton";
import { useConnectText } from "hooks/useConnectText";
import { ReactNode } from "react";
import { twMerge } from "tailwind-merge";
import { DISCORD_URL } from "urls";

export const ConnectPanel = ({
children,
actionText,
}: {
children?: ReactNode;
actionText?: string;
}): JSX.Element => {
const connectText = useConnectText();

return (
<Panel
className={twMerge(
"p-8 min-h-full",
"flex items-center justify-center min-h-full",
"flex flex-col items-center justify-center gap-8"
)}
>
<Image styleOverrides={{ width: "203px" }} imageName="LogoMinimal" />
<h2
className={
"max-w-[500px] uppercase text-center font-medium text-yellow leading-10 text-4xl"
}
>
{children}
{actionText} {connectText}
</h2>
<div className="flex gap-4 mx-auto w-full max-w-[400px]">
<ConnectExtensionButton />
<ActionButton
href={DISCORD_URL}
target="_blank"
rel="noreferrer"
size="sm"
outlineColor="yellow"
>
Community Help
</ActionButton>
</div>
</Panel>
);
};
15 changes: 4 additions & 11 deletions apps/namadillo/src/App/Governance/GovernanceOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import { Panel, SkeletonLoading } from "@namada/components";
import { ConnectBanner } from "App/Common/ConnectBanner";
import { PageWithSidebar } from "App/Common/PageWithSidebar";
import { allProposalsAtom, votedProposalsAtom } from "atoms/proposals";
import { namadaExtensionConnectedAtom } from "atoms/settings";
import {
atomsAreFetching,
atomsAreLoaded,
useNotifyOnAtomError,
} from "atoms/utils";
import { useUserHasAccount } from "hooks/useUserHasAccount";
import { useUserHasAccount } from "hooks/useIsAuthenticated";
import { useAtomValue } from "jotai";
import { AllProposalsTable } from "./AllProposalsTable";
import { LiveGovernanceProposals } from "./LiveGovernanceProposals";
Expand All @@ -17,14 +16,13 @@ import { ProposalsSummary } from "./ProposalsSummary";
import { UpcomingProposals } from "./UpcomingProposals";

export const GovernanceOverview: React.FC = () => {
const isConnected = useAtomValue(namadaExtensionConnectedAtom);
const allProposals = useAtomValue(allProposalsAtom);
const votedProposals = useAtomValue(votedProposalsAtom);
const hasAccount = useUserHasAccount();
const userHasAccount = useUserHasAccount();

// TODO: is there a better way than this to show that votedProposalIdsAtom
// is dependent on isConnected?
const extensionAtoms = isConnected && hasAccount ? [votedProposals] : [];
const extensionAtoms = userHasAccount ? [votedProposals] : [];
const activeAtoms = [allProposals, ...extensionAtoms];

const liveProposals =
Expand All @@ -43,12 +41,7 @@ export const GovernanceOverview: React.FC = () => {
return (
<PageWithSidebar>
<div className="flex flex-col gap-2">
{!isConnected && (
<ConnectBanner text="To vote please connect your account" />
)}
{isConnected && hasAccount === false && (
<ConnectBanner text="To vote please create or import an account using Namada keychain" />
)}
{!userHasAccount && <ConnectBanner actionText="To vote" />}
<ProposalListPanel
title="Live Proposals"
errorText="Unable to load live governance proposals"
Expand Down
9 changes: 4 additions & 5 deletions apps/namadillo/src/App/Governance/ProposalHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {
proposalFamily,
proposalVoteFamily,
} from "atoms/proposals";
import { namadaExtensionConnectedAtom } from "atoms/settings";
import clsx from "clsx";
import { useUserHasAccount } from "hooks/useIsAuthenticated";
import { useAtomValue } from "jotai";
import { AtomWithQueryResult } from "jotai-tanstack-query";
import { FaChevronLeft } from "react-icons/fa";
Expand Down Expand Up @@ -294,12 +294,12 @@ const VoteButton: React.FC<{
proposalId: bigint;
}> = ({ proposal, vote, proposalId }) => {
const navigate = useNavigate();
const isExtensionConnected = useAtomValue(namadaExtensionConnectedAtom);
const userHasAccount = useUserHasAccount();
const canVote = useAtomValue(
canVoteAtom(proposal.data?.startEpoch || BigInt(-1))
);

if (!isExtensionConnected) {
if (!userHasAccount) {
return null;
}

Expand All @@ -313,8 +313,7 @@ const VoteButton: React.FC<{
} else {
const { status } = proposal.data;

const disabled =
!isExtensionConnected || !canVote.data || status !== "ongoing";
const disabled = !userHasAccount || !canVote.data || status !== "ongoing";

const voted = vote.data !== null;
const text = voted ? "Edit Vote" : "Vote";
Expand Down
8 changes: 8 additions & 0 deletions apps/namadillo/src/App/Ibc/IbcLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
import { ConnectPanel } from "App/Common/ConnectPanel";
import { PageWithSidebar } from "App/Common/PageWithSidebar";
import { ShieldAllBanner } from "App/Sidebars/ShieldAllBanner";
import { useUserHasAccount } from "hooks/useIsAuthenticated";
import { Outlet } from "react-router-dom";

export const IbcLayout: React.FC = () => {
const userHasAccount = useUserHasAccount();

if (!userHasAccount) {
return <ConnectPanel actionText="To IBC Transfer" />;
}

return (
<PageWithSidebar>
<Outlet />
Expand Down
6 changes: 3 additions & 3 deletions apps/namadillo/src/App/Layout/TopNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { ConnectExtensionButton } from "App/Common/ConnectExtensionButton";
import { routes } from "App/routes";
import {
applicationFeaturesAtom,
namadaExtensionConnectedAtom,
signArbitraryEnabledAtom,
} from "atoms/settings";
import { useUserHasAccount } from "hooks/useIsAuthenticated";
import { useAtomValue } from "jotai";
import { AiOutlineMessage } from "react-icons/ai";
import { IoSettingsOutline } from "react-icons/io5";
Expand All @@ -14,15 +14,15 @@ import { ActiveAccount } from "./ActiveAccount";
import { SyncIndicator } from "./SyncIndicator";

export const TopNavigation = (): JSX.Element => {
const isExtensionConnected = useAtomValue(namadaExtensionConnectedAtom);
const userHasAccount = useUserHasAccount();
const signArbitraryEnabled = useAtomValue(signArbitraryEnabledAtom);
const { maspEnabled, namTransfersEnabled } = useAtomValue(
applicationFeaturesAtom
);
const location = useLocation();
const navigate = useNavigate();

if (!isExtensionConnected) {
if (!userHasAccount) {
return (
<div className="w-fit justify-self-end">
<ConnectExtensionButton />
Expand Down
12 changes: 11 additions & 1 deletion apps/namadillo/src/App/Masp/MaspLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { ConnectPanel } from "App/Common/ConnectPanel";
import { PageWithSidebar } from "App/Common/PageWithSidebar";
import { routes } from "App/routes";
import { ShieldAllBanner } from "App/Sidebars/ShieldAllBanner";
import { Outlet } from "react-router-dom";
import { useUserHasAccount } from "hooks/useIsAuthenticated";
import { Outlet, useLocation } from "react-router-dom";

export const MaspLayout: React.FC = () => {
const userHasAccount = useUserHasAccount();
const location = useLocation();

if (!userHasAccount && location.pathname !== routes.masp) {
return <ConnectPanel actionText="To shield assets" />;
}

return (
<PageWithSidebar>
<Outlet />
Expand Down
Loading

1 comment on commit 9745a7b

@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.