Skip to content

Commit

Permalink
rework onboarding flow
Browse files Browse the repository at this point in the history
  • Loading branch information
holic committed Oct 17, 2024
1 parent 3586519 commit d8d9d97
Show file tree
Hide file tree
Showing 17 changed files with 227 additions and 309 deletions.
8 changes: 5 additions & 3 deletions packages/entrykit/src/AccountModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@ export function AccountModal() {
"links:decoration-neutral-500 hover:links:decoration-orange-500",
)}
>
<AccountModalErrorBoundary>
<AccountModalContent />
</AccountModalErrorBoundary>
<div className="flex-grow flex flex-col">
<AccountModalErrorBoundary>
<AccountModalContent />
</AccountModalErrorBoundary>
</div>

<a
href="https://mud.dev"
Expand Down
2 changes: 1 addition & 1 deletion packages/entrykit/src/AccountModalContent.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useConnectorClient } from "wagmi";
import { ConnectWallet } from "./onboarding/ConnectWallet";
import { ConnectWallet } from "./ConnectWallet";
import { ConnectedSteps } from "./onboarding/ConnectedSteps";
import { useEntryKitConfig } from "./EntryKitConfigProvider";

Expand Down
7 changes: 2 additions & 5 deletions packages/entrykit/src/AppInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useAppInfo } from "./useAppInfo";
import { usePreloadImage } from "./usePreloadImage";

export function AppInfo() {
const { appName, appOrigin, appIcon } = useAppInfo();
const { appName, appIcon } = useAppInfo();

const { data: hasAppIcon, isLoading: appIconLoading } = usePreloadImage(appIcon);

Expand All @@ -19,10 +19,7 @@ export function AppInfo() {
)
) : null}
</div>
<div className="flex flex-col gap-1 items-center justify-center">
<div className="text-2xl text-white">{appName}</div>
<div className="text-sm font-mono">{appOrigin}</div>
</div>
<div className="text-2xl text-white text-center">{appName}</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useAccount } from "wagmi";
import { Button } from "../ui/Button";
import { useAccountModal } from "../useAccountModal";
import { Button } from "./ui/Button";
import { useAccountModal } from "./useAccountModal";
import { useConnectModal } from "@rainbow-me/rainbowkit";
import { useMutation } from "@tanstack/react-query";
import { usePasskeyConnector } from "../usePasskeyConnector";
import { AppInfo } from "../AppInfo";
import { usePasskeyConnector } from "./usePasskeyConnector";
import { AppInfo } from "./AppInfo";

export function ConnectWallet() {
const userAccount = useAccount();
Expand Down Expand Up @@ -33,7 +33,7 @@ export function ConnectWallet() {
{/* TODO: render appImage if available? */}
<AppInfo />
</div>
<div className="flex flex-col gap-2">
<div className="self-center flex flex-col gap-2 w-60">
<div className="flex flex-col">
<Button
className="self-auto flex justify-center"
Expand Down
51 changes: 51 additions & 0 deletions packages/entrykit/src/onboarding/Allowance.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Hex } from "viem";
import { useAllowance } from "./useAllowance";
import { PendingIcon } from "../icons/PendingIcon";
import { useClaimGasPass } from "./useClaimGasPass";
import { Button } from "../ui/Button";
import { Balance } from "../ui/Balance";
import { useEffect } from "react";
import { minGasBalance } from "./common";

export type Props = {
isExpanded: boolean;
isActive: boolean;
userAddress: Hex;
};

export function Allowance({ isActive, isExpanded, userAddress }: Props) {
const allowance = useAllowance(userAddress);
const claimGasPass = useClaimGasPass();

// TODO: improve pending state since this is kicked off automatically and showing a pending button is weird
useEffect(() => {
if (isActive && claimGasPass.status === "idle" && allowance.data && allowance.data.allowance < minGasBalance) {
claimGasPass.mutate(userAddress);
}
}, [allowance.data, claimGasPass, isActive, userAddress]);

// TODO: show error if allowance fails to load
// TODO: show claim error

return (
<div className="flex flex-col gap-4">
<div className="flex justify-between gap-4">
<div>
<div>Allowance</div>
<div className="font-mono text-white">
{allowance.data ? <Balance wei={allowance.data.allowance} /> : <PendingIcon />}
</div>
</div>
<Button
variant={isActive ? "primary" : "secondary"}
className="flex-shrink-0 text-sm p-1 w-28"
pending={claimGasPass.status === "pending"}
onClick={() => claimGasPass.mutate(userAddress)}
>
Top up
</Button>
</div>
{isExpanded ? <p className="text-sm">Your allowance is used to pay for onchain computation.</p> : null}
</div>
);
}
76 changes: 0 additions & 76 deletions packages/entrykit/src/onboarding/ClaimGasPass.tsx

This file was deleted.

34 changes: 32 additions & 2 deletions packages/entrykit/src/onboarding/ConnectedSteps.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
import { useState } from "react";
import { ConnectedClient } from "../common";
import { Steps } from "./Steps";
import { useSteps } from "./useSteps";
import { twMerge } from "tailwind-merge";

export type Props = {
userClient: ConnectedClient;
};

export function ConnectedSteps({ userClient }: Props) {
const steps = useSteps(userClient);
return <Steps steps={steps} />;

// TODO: detect if just connected and, if so, dismiss

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [selectedStepId, setSelectedStepId] = useState<null | string>(null);
const nextStep = steps.find((step) => step.content != null && !step.isComplete);
const completedSteps = steps.filter((step) => step.isComplete);
const activeStep =
(selectedStepId != null ? steps.find((step) => step.id === selectedStepId) : null) ??
nextStep ??
(completedSteps.length < steps.length ? completedSteps.at(-1) : null);

return (
<div className="px-8 flex-grow flex flex-col divide-y divide-neutral-800">
{steps.map((step) => {
const isActive = step === activeStep;
const isExpanded = isActive || completedSteps.length === steps.length;
return (
// TODO: remove onclick, just for debugging for now
<div
key={step.id}
className={twMerge("py-8 flex flex-col justify-center", isActive ? "flex-grow" : null)}
// onClick={() => setSelectedStepId(step.id)}
>
{step.content({ isActive, isExpanded })}
</div>
);
})}
</div>
);
}
61 changes: 0 additions & 61 deletions packages/entrykit/src/onboarding/ConnectedWallet.tsx

This file was deleted.

16 changes: 0 additions & 16 deletions packages/entrykit/src/onboarding/Finalize.tsx

This file was deleted.

62 changes: 62 additions & 0 deletions packages/entrykit/src/onboarding/Session.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { useAppAccountClient } from "../useAppAccountClient";
import { Button } from "../ui/Button";
import { useSetupAppAccount } from "./useSetupAppAccount";
import { useAccountModal } from "../useAccountModal";
import { ConnectedClient } from "../common";

export type Props = {
isActive: boolean;
isExpanded: boolean;
userClient: ConnectedClient;
registerSpender: boolean;
registerDelegation: boolean;
};

export function Session({ isActive, isExpanded, userClient, registerSpender, registerDelegation }: Props) {
const { closeAccountModal } = useAccountModal();
const appAccountClient = useAppAccountClient(userClient.account.address);
const setup = useSetupAppAccount();

const isReady = !registerDelegation && !registerDelegation;

return (
<div className="flex flex-col gap-4">
<div className="flex justify-between gap-4">
<div>
<div>Session</div>
<div className="font-mono text-white">{isReady ? "Approved" : "Set up"}</div>
</div>
{isReady ? (
<Button variant={isActive ? "primary" : "secondary"} className="flex-shrink-0 text-sm p-1 w-28" disabled>
{/* TODO: revoke */}
Revoke
</Button>
) : (
<Button
variant={isActive ? "primary" : "secondary"}
className="flex-shrink-0 text-sm p-1 w-28"
pending={!appAccountClient.data || setup.status === "pending"}
onClick={
appAccountClient.data
? async () => {
await setup.mutateAsync({
userClient,
appAccountAddress: appAccountClient.data.account.address,
registerSpender,
registerDelegation,
});
closeAccountModal();
}
: undefined
}
>
Approve
</Button>
)}
</div>
{isExpanded ? (
<p className="text-sm">You can perform actions in this app without interruptions for approvals.</p>
) : null}
</div>
);
}
Loading

0 comments on commit d8d9d97

Please sign in to comment.